This removes the need for the hacky `chat "Module:alias"` and `remeber`
config! It is pretty hacky on its own, though. This should really be a
terse script shouldnt it
Simplified syntax: `cue` no longer requires sub-nodes - simply specify `at` or your
interval options on the cue node itself, and set `repeat` to a boolean (previously done via using the `every` subnode vs `once`)
Better accuracy: scheduler now runs outside of tick, allowing sub-second accuracy in
ideal environments. This is still a long way from a proper realtime solution -
queuing is merely asyncio's best-effort, accuracy may vary wildly depending on load!
Cancelation: passing a string as the first argument to cue will give the event a name,
which can be used by a later call to set the event as enabled or disabled.
Additionally, toggling this flag / redefining a named cue will reschedule it if it is
an interval, which you can use to create timeout behaviors!
Added "eval" kdl type for direct python statement execution.
Use like (eval)"1 + 1", (eval)"upper(ctx['data'])", or commit crimes like (eval)"ctx['some_function']()"
"call_plugin_from_kdl" renamed "execute_kdl"
Custom classes are now passed for dynamic parameters, but are still
transparently computed when using execute_kdl - you should only see
these when manually parsing _children, in which case, you can use
"core.Config.compute_dynamic" to deal with them!
The way we load external plugins is by providing a path to the
module folder (which as usual should have a "Plugin" attribute).
This is a bit silly, and doesnt fully manage our issues with, say,
dependencies, but is a step in the right direction maybe?
+ You no longer need to ctrl+c twice
+ A few common crashes have better errors
+ A readme thats actually useful
+ KDL arg types now strictly use getitem