bhouston / behave-graph Goto Github PK
View Code? Open in Web Editor NEWOpen, extensible, small and simple behaviour-graph execution engine. Discord here: https://discord.gg/mrags8WyuH
License: Other
Open, extensible, small and simple behaviour-graph execution engine. Discord here: https://discord.gg/mrags8WyuH
License: Other
It should be possible to listen to any event by a string identifier. And it should be possible to call any custom event by string identifier.
This will enable a web based node interface to highlight which nodes are executing.
needs exporting in index.ts
This would allow for importing into: https://github.com/beeglebug/behave-flow
Implement a means to save in a JSON format compatible with the readGraph call.
Basically allow for Socket or Socket style syntax and have it work correctly. This would allow for better type checking of values passed around sockets.
This makes no sense so prevent it from happening.
Several flow nodes are throwing errors when you attempt to run a graph, complaining about attempting to set output values on flow sockets.
I think i've fixed flipflop, as that was the one I was attempting to use when I saw the issue, but I suspect some of the others are still doing it (I was hesitant to touch things like "flow/sequence" which seem incomplete anyway)
Right now state is stored in the graph without any type information. Thus it can pass out a number to a getString state node. This is unsafe. The state store should be typed and enforce those types at run-time.
Do not require nodes to output their results in a purely synchonous fashion. Allow for async output of results. Support this natively so it is not a big hack.
This should be compatible with the multiple outputs per node feature: #1
The types that flow through the graph should not be limited to only those pre-defined in this library. This probably means we have to move away from an enum and towards a list of registered types.
This should be another evaluateWithinTimeslice( milliseconds: number ) call.
Currently the library only supports types that are a single JSON element, not complex types.
I am starting to wonder if the main method of evaluating these behavior graphs is actually a stack rather than a work queue.
The reason why a stack would be easier is:
I think that once the stack is completed, you go back to look for new events?
I think this doesn't handle the case where you want to "break" a for-loop. In those cases you either need a loop in the graph (non-DAG) or as Unity does it, it has an event that is raised in the loopBody and then executes and sets a "break" flow socket on the for-loop (but this violates the stack execution model, as the events wouldn't be fired until the for-loop is done.)
Thus this isn't yet sufficient.
Currently this is not in a true library form, rather it just allows for local tests to be run. For this to be truly usable, it needs to be converted and published to an npm accessible library.
@javagl pointed out this spelling mistake.
We should have explicit error messages when a socket link goes to a non-existent node or it connects to a non-existent socket on that node.
Prove that it can work!
See if you can learn from https://twitter.com/hmans/status/1556971439386918914?s=21&t=3GtLvLF_P85x-9azSLYm9w
I just ran into a case of a hand written graph json that had duplicate node ids and it just overwrote one during import. That is dangerous and not proper.
It should be possible to listen to state identifiers and have an event fire when the state is changed.
Q: Should there be a central registry of state data? Like a list of member variables, or should I keep the very arbitrary map-based method? The central registry on a per graph basis may lead to better type checking.
This would allow for external editors (e.g https://github.com/beeglebug/behave-flow) to add positional data or other forms of augmented data and have it persist untouched.
This is required for the "for loop" node in Unreal Engine and Unity Visual Scripting.
https://docs.unrealengine.com/4.26/en-US/ProgrammingAndScripting/Blueprints/UserGuide/FlowControl/
Also required by "Sequence". These nodes wait for the subgraph connected to their output flow socket to execute and then they will pass execution to either to the same output flow socket (loopBody) or to another flow output socket (complete.).
In the current implementation, it is required that one trigger Events explicitly. You can see this in all of the examples where after loading the graph, one triggers the "events/start" event explicitly.
Instead, one could have all events in the graph execute immediately upon startup and they all return promises, which means that they are pending. And then when they fire, they resolve their promises. This would make it much simpler to add new event types to the system.
Having this checked in makes it a bit tougher for other developers to use their own workspace settings when working on the project, it should probably be removed and gitignored.
This is a larger question about how a behave-graph graph interacts/binds itself to some external environment, be it a threejs scene or something else.
This codesandbox is me experimenting with a simple connection between a graph and a threejs scene, but at the moment the connection is very manual.
https://codesandbox.io/s/behave-graph-three-test-ijdzj6
What i'm wondering, is what do we think that connection will eventually look like? I imagine a node such as my test "input/mouseClick" would also have an input of some sort to select a mesh in the scene (in this case the cube), and then would only be triggered by clicks on that cube.
We would then also want a way to transmit effects back into the scene, for example I might want a graph which looks like the following:
const graphDef: GraphJSON = {
nodes: [
{
id: "1",
type: "input/mouseClick",
},
{
id: "2",
type: "material/setColor",
inputs: {
text: {
value: "#0000FF",
},
flow: {
links: [
{
nodeId: "1",
socket: "flow",
},
],
},
},
},
],
};
ie, when the user clicks on the cube, the material changes colour to blue.
I think it would be really useful to sketch out some more "real world" examples of graphs which actually do something in a less abstract environment to get an idea of what changes might be required in the core library to support the required nodes.
Add an invalid example that uses an unsupported valuetyoename and ensure it fails to pass validation
Something to use on the website, discord, etc.
It would be nice to have Assert nodes that check for a specific input and fail otherwise. This would allow one to create a large series of graphs that if they run successful are basically unit tests for the system.
I added custom event node (StartWithOutputNode
) with output socket
I want to trigger this node with value
graphEvaluator.triggerEvents(
"event/startWithOutput",
new Map([["str", "provided string"]])
);
Expected: "provided string" in log
Actual: empty message in log
Add a for loop and a sequence example in an unsupported sub folder of examples.
We should validate that a graph is a true DAG and contains no degenerate loops.
Now the test suite is working, we can port all the "invalid" examples to test cases. I've done some of them already, but left the deletion of the examples for now.
If you try to set a value or link for a socket who actually doesn't exist on the specified node, error out.
At the moment, readGraphFromJSON
and writeGraphToJSON
both deal with a type of any
, which is fine, but open to errors.
For better interoperability with other code, it would be good to specify a type for the JSON version of a graph.
It should be relatively easy to create a Three.jS example once we have it running in the browser via #3.
And also ensure that if a node is not in async, it doesn't fire async commits.
Enforcing typing alignment:
Let's say there is an event that fires, "door state", and it has an output value called "isOpen." If it fires 2 separate times, one with "isOpen = true" and a second "isOpen = false." then I guess we have to somehow set these values on the event when it fires as output values.
In order to support for-loops and delayed sequences, I need to be able to return outputs multiple times so that the downstream graph executes multiple times.
How should this be done?
I think at minimum a promise should be returned and then it will resolve when the next set of outputs are ready. And part of that response will be another promise if there are subsequent outputs that should be waited upon.
This needs a nice API.
ESLint couldn't find the plugin "eslint-plugin-react".
looks like a dependency of eslint-config-airbnb?
From experience, prettier is the nicest solution to keeping a clean, consistently formatted codebase while removing any possible arguments about the details. It's used by thousands of other open source JS projects, so contributors will be familiar with it.
We could auto format everything once in a single cleanup commit and be done with it, most modern IDE's will handle prettier automatically and format on save.
We can then strip out most of the eslint config (certainly any bits pertaining to code formatting).
it would be nice to see in the examples this:
import { Node } from 'behaviour-graph';
Rather than:
import { Node } from '../../../dist/lib/index';
I think this can be done with some config variables in the tsconfig.json file...
Right now I only have command line examples. Having an example that runs in the web browser would be very nice.
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.