active-logic / elk Goto Github PK
View Code? Open in Web Editor NEWBehavior tree scripting and interpreters for Unity
License: GNU Affero General Public License v3.0
Behavior tree scripting and interpreters for Unity
License: GNU Affero General Public License v3.0
Not sure I'd go all the way to detailing non invocations, but prop evals really feel like they're missing from the call graph, for debugging purposes.
Display one line from the BT which helps quickly determine what the agent are doing.
With a bit of luck showing the lowest frequency occurence along the chain should be informative enough.
When an invocation fails, raising may be cleaner than returning null; affects InvocationEval
and (indirectly) BTL-BinEval
. Even if we prefer returning a value, an explicit 'status-able null' should be prefered.
Main issue - do reflect harder in CSharpBindings
!
Mainly useful to avoid getting back to C# for the sake of just testing a threshold
Currently BTL imports via a list of designated components in the BTL component inspector; this will not scale when specialized modules refer specialized somponents.
Runtime supports these operators (tested) and the parser could support them but applying C# operator precedence fails simple parsing cases. RtL eval order needed?
afaik current implementation will convert ints to floats.
C# does not support "wildcard" arguments when resolving function bindings.
Options:
Will enable (but doesn't realize) safer parsing.
Literal
and Keyword
typesTaking BTL as an example:
scene
domain (optional)Do we stop here? Nope, Already seeing prominent use cases where we'd like to bind additional domains.
Often the function exists but cannot bind for another reason. Common cases include parameter type mismatch.
A similar but different case is when resolution becomes transiently ambiguous because of a null argument.
Larger BT projects work better with a half dozen modules or more.
Dependency management does not live up to how dependencies actually want to work.
include
style dependencies are okay if we have a relatively concise interface between the BT and C#
In practice C# needs to expose ad-hoc properties which often have strong cohesion with just a subtree or task.
using
dependencies are the way to go, and there may be a need for local (function level) variants.
APIs provided for tying granular actions (from executors) to intent but this essentially is catching stacks "in flight" as such only the leaf node would be designated as running, completed or failed.
Intent recording does capture high level goals so there is at least 'some, mostly dependable' support.
Academic flair to this; not prioritizing
Site binding allows a client (native side) to identify the call site for a given function; useful for cleanly implementing BT memory nodes.
AL defines a number of useful unary operators
Modules need private functions; useful to hide details and avoid name collisions
#33 - cache function bindings
#65 - cache property/field bindings)
#66 - avoid allocs when pushing/popping function arguments
Call-graph / call stack logging causes mostly avoidable allocations; can turn this off but reducing allocs the better approach (agents use the call stack to remember own actions)
Related: AL update allows enabling AL optimized without breaking BTL logging (mainly needed to silence allocs from AL logging).
Beyond commenting (let's have comments, shall we!)... Looking at the more complex BTs I worked with, not being able to directly relate a subtask to specific requirements has proven a downside.
There is also not consistently a strict correlation between PRs and feature requests (often a feature request generates several PRs)
I would find it interesting to have attributes, like this:
[tag1, ...] task foo => ...
Using attributes to represent features will enable turning features on/off if desired, as well as tracking what changes a feature has motivated.
Also not that simple (later features tend to generate hidden dependencies on earlier features) but overall a nice to have.
When passing null arguments to functions returning status, in general intended behaviour is to either cancel or condone the task; sometimes the function itself can make an informed decision; sometimes it makes more sense for the caller to decide.
Example:
task Attack(target, weapon) => Equip(weapon) && Strike(target);
A good implementation of Equip
should not fail silently. Then, assuming a bare-handed attack is acceptable, let's use the ?
unary operator:
# Will condone Equip (do not invoke; return true) if 'weapon' is null
task Attack(target, weapon) => Equip(weapon?) && Strike(target);
Meanwhile the above function wouldn't be good if it made an agent equip a weapon while no target is defined; in this case, use the !
operator to fail early if a null is passed as target:
# Fail and do not run the task if 'target' is null
task Attack(target!, weapon) => Equip(weapon?) && Strike(target);
Following #46, availing wards in function declarations would be neat. Probably.
The task
keyword easily discriminates separate subtasks in a BTL source file.
This means that:
Likely, key perf bottleneck solved in #33, other areas which may need attention:
When prototyping, testing, or working with scripted events, it can be useful to just quickly access scene objects without going through a dedicated apperception component:
using scene; # scene access, built-in but optional
Task OneTrick => Activate(BigSwitch); # Where 'BigSwitch' is a scene object
Helps configure AIs around a common base.
Doing this programmatically is useful when the configuration method is indirect; for example when configuring abilities based on traits, stats or combinations thereof.
Memory driven behaviors allow an agent to leverage knowledge from their past actions. While a special case with regard to memory (which would include a record of what they have seen/heard and so forth...) this is especially useful in many scenarios.
Proposing a did x [since y]
syntax
An example (only greet once, not over and over!)
task Encounter(target)
=> !did Encounter(target) && GoGreet(target);
Easily implemented through stack trace recording.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.