Describe flow ports at Start and End and the On behavior node (#294)
1 parent
022df8b21e
commit
d554dfddbf
3 files changed
+61
-4
No files matched your search
+15
@@ -569,6 +569,21 @@ system `adopt`s them before it starts, so they are no new instances and hear no
|
||||
trace is cleared and timed by the new world, which starts at second zero. `PhysicsSystem.resume`
|
||||
gives each body the velocity when it is made, and forgets the rest after the first sync.
|
||||
|
||||
**A behavior heard by an `On behavior` node is an instance of its own** (#294), on the entity of
|
||||
the behavior holding the node: its own `GraphInterpreter`, trace, local states and `variables` (a
|
||||
copy of the heard behavior's defaults; `behaviorContext` hands these out instead of the entity's
|
||||
props), and a `host` naming the instance and the node that hear it. `BehaviorSystem.syncHeard`
|
||||
builds them when an instance is born and again after every edit to the project, following the
|
||||
chain of behaviors hearing each other and stopping where one would hear itself; a node that is
|
||||
gone takes its instance along, with `On disable` and `On destroy`. Because they stand in the same
|
||||
list as every other instance, the event kinds of a frame, the state events, pause and the scene
|
||||
swap reach them without a second code path. `runPulses` does the two things that differ: before a
|
||||
pulse it reads the inputs of the hearing node into the interpreter's `given`, which the start node
|
||||
hands out, and after it `surface` asks the interpreter for its `ending` — the flow input the end
|
||||
node was reached by last — and pulses the hearing node through the output of that name, and so on
|
||||
up the chain. A call learns the same way which output to take first: `call` returns the `Ending`
|
||||
of the nested frame, and `CallResult.entry` names the start node's output it begins at.
|
||||
|
||||
**A run keeps what each scene stored before it built it.** `GameRun` copies a scene's objects and
|
||||
groups the first time it builds it, and puts them back before it builds it again: the run writes
|
||||
into the scene it is in (`syncToModel`, baking, `spawn`), and a level loaded twice must not start
|
||||
|
||||
+45
-3
@@ -193,7 +193,7 @@ playing use the same two words.
|
||||
set to `a` also hears `A`, and a key picked with Shift held is stored lower-case. A key is let go
|
||||
under the name it went down as, even when Shift changes in between (`1` down, `!` up).
|
||||
- **Node set** (`src/core/graph/nodes/`, one file per node): events `On start`, `On enable`, `On update`, `On disable`, `On destroy` (see *Lifecycle*), `On key down/up/held`,
|
||||
`On timer` (fires on the first frame past each due time; `late` says by how much, so `time - late` is exactly a multiple of the interval), `On collision enter/stay/exit` (stay every frame, or with an interval; while playing enter and stay tell normal, impulse and point of the contact; on a trigger tile of a tilemap all three tell `tile` and `cell x/y`, once per area or with the input `per cell` once per cell, see [Tilemaps](Tilemaps#trigger-tiles)), `On click` (the mouse pressed on the owner — anywhere when it has none), `On mouse wheel` (the wheel turned over the owner, or anywhere without one; `delta` in notches, positive downwards, a trackpad gives fractions), `On animation finished`, `On state entered`, `On state exited` (one output per state, see *State machines*), `Start` · flow `Branch`, `Sequence`, `Repeat`, `For each`, `Find` … `Match`, `Run behavior`, `End`, and the four that move or follow a state machine, `State branch`, `Set state`, `Set state by name`, `State transition` (see *State machines*) · data `Self`, `Owner`, `Parent`, `Object by name`, `Child by name` (the nearest object of that name below the given one: its children, then their children, and so on; within a level the first in hierarchy order, nothing when none is called so), `Name of`,
|
||||
`On timer` (fires on the first frame past each due time; `late` says by how much, so `time - late` is exactly a multiple of the interval), `On collision enter/stay/exit` (stay every frame, or with an interval; while playing enter and stay tell normal, impulse and point of the contact; on a trigger tile of a tilemap all three tell `tile` and `cell x/y`, once per area or with the input `per cell` once per cell, see [Tilemaps](Tilemaps#trigger-tiles)), `On click` (the mouse pressed on the owner — anywhere when it has none), `On mouse wheel` (the wheel turned over the owner, or anywhere without one; `delta` in notches, positive downwards, a trackpad gives fractions), `On animation finished`, `On state entered`, `On state exited` (one output per state, see *State machines*), `On behavior` (another behavior heard as an event, see *A behavior as an event* below), `Start` · flow `Branch`, `Sequence`, `Repeat`, `For each`, `Find` … `Match`, `Run behavior`, `End`, and the four that move or follow a state machine, `State branch`, `Set state`, `Set state by name`, `State transition` (see *State machines*) · data `Self`, `Owner`, `Parent`, `Object by name`, `Child by name` (the nearest object of that name below the given one: its children, then their children, and so on; within a level the first in hierarchy order, nothing when none is called so), `Name of`,
|
||||
`Is asset` (is this object an instance of asset X — how you tell what you collided with),
|
||||
and the plural lookups, each handing on a `list` of objects taken at that moment (destroyed
|
||||
objects are never in it, switched-off ones are, as with the single lookups): `Objects by name`
|
||||
@@ -253,8 +253,8 @@ playing use the same two words.
|
||||
so the canvas and the inspector see a definition that fits *this* node; a node whose ports are
|
||||
derived reads them back off that definition, which is why `run` is handed it. `Sequence` keeps
|
||||
one free output below the last connected one — connecting the spare grows it, unplugging the
|
||||
bottom edge shrinks it again (keys `a`, `b`, `c`, … up to 26). `Run behavior` takes its ports
|
||||
from the behavior it names, and a behavior's `Start`/`End` node declares them. Pointing a call
|
||||
bottom edge shrinks it again (keys `a`, `b`, `c`, … up to 26). `Run behavior` and `On behavior` take their ports
|
||||
from the behavior they name, and a behavior's `Start`/`End` node declares them. Pointing a call
|
||||
at a different behavior **takes the edges of the ports that go away** and gives them back on
|
||||
undo.
|
||||
- **Ports that carry one and the same value** say so with `sharedType` (`{inputs, outputs}`), and
|
||||
@@ -358,6 +358,48 @@ playing use the same two words.
|
||||
A behavior **without a start node** is called from its **On start** nodes instead, all of them in
|
||||
graph order, as when it starts on its own. It takes no inputs then, but its end node still hands
|
||||
back what it is given. With a start node in the graph, its On start nodes stay out of the call.
|
||||
- **More than one way in and out** (flow ports): next to numbers, texts and the other kinds, the
|
||||
port list of a **Start** and an **End** node offers the kind **Flow**. A flow port declared at
|
||||
the End is a further flow *output* of every node running the behavior, one declared at the Start
|
||||
a further flow *input*. They stand above the value ports, below the fixed `exec`, and share
|
||||
their names with the values of the same node; `exec` stays taken.
|
||||
A call that comes in by the input `open` begins at the Start's output `open` and nowhere else;
|
||||
the Start's plain `exec` fires only for a call that came in by `exec`. The values are the same
|
||||
whichever way the call came.
|
||||
On the way out the node goes on **first through the output named like the End's flow input that
|
||||
was reached last, then through `exec`**. `exec` therefore always fires, as it did before there
|
||||
were flow ports, and reads as "and then". A call whose End was reached by `exec` last, or not at
|
||||
all, goes on through `exec` only. One call takes at most one of the further outputs: when its
|
||||
flow reaches the End several times, the last one decides, as it does for the values. Every call
|
||||
decides anew, so a call inside a loop may leave differently each round.
|
||||
A behavior without a Start node has no further ways in, since they are declared there; the ones
|
||||
at its End work all the same. In a behavior that runs on an object and is not called, the
|
||||
Start's outputs never fire, the further ones no more than `exec`.
|
||||
- **A behavior as an event** (`On behavior`): the palette lists every other behavior that has an
|
||||
End node a second time, as **On *name*** among the events. That node has no flow input. The
|
||||
behavior it names **lives at the node** for as long as the behavior around it runs: all of its
|
||||
own events fire as if it were placed on the same object (keys, mouse, `On update`, timers,
|
||||
collisions, animations, state events, and `On start`, `On enable`, `On disable` and `On destroy`
|
||||
in step with the behavior around it), and its variables, timers and local state machines keep
|
||||
their state, **one set per node**. Two nodes hearing the same behavior share nothing, and Keep
|
||||
plays no part here.
|
||||
The node fires **whenever a flow in there reaches the End**: through the output named like the
|
||||
flow input the End was reached by, with the values the End was handed. Unlike a call, the plain
|
||||
`exec` fires only when the End was reached by `exec`; a flow that never gets to the End is not
|
||||
heard at all. The outer flow starts once the inner one has run out, so a flow reaching the End
|
||||
twice is heard once, by the way it took last.
|
||||
The value inputs of the Start node are **inputs of the node**, typed in or connected, and read
|
||||
anew for each of the inner flows; the Start itself never fires, and its flow ports do not show.
|
||||
Example, a "Confirm" that is Space or Enter everywhere: in the behavior *Confirm*, two
|
||||
`On key down` nodes lead to a flow port `pressed` of its End. Any other behavior then holds one
|
||||
node **On Confirm** and wires its `pressed` output; a third key is added in *Confirm* alone.
|
||||
Behaviors may hear each other as deep as you like. A behavior that would hear itself, directly
|
||||
or through others, says so on the node and is not started a second time. Inside a behavior that
|
||||
is *run as a node* an `On behavior` stays silent, like every event there. The node has no
|
||||
**Order** of its own: the events inside carry theirs and run in their kind with everyone else's.
|
||||
Double-click opens the behavior heard, with the breadcrumb of a call. While it runs, its graph
|
||||
lights up like a called one. A node that cannot fire says why: no behavior picked, the behavior
|
||||
deleted, or no End node in it.
|
||||
- **Keep** (the pin on each variable of the called behavior, in its inspector): a kept variable
|
||||
picks up where the last call **from this node, on this object** left it; the others start at
|
||||
their default every call. Every variable starts out not kept, a new one as well as one from a
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ php tests/php/accounts.test.php # the API's accoun
|
||||
# has and the web server's container has not (SKIP there)
|
||||
php tests/php/snapshots.test.php # the snapshot store (#231), the same way
|
||||
php tests/php/releases.test.php # the release store (#266), the same way
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1676 editor checks, screenshots in /tmp/gm-e2e-*.png
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1680 editor checks, screenshots in /tmp/gm-e2e-*.png
|
||||
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step
|
||||
./e2e.sh start [GM_STEPS] # the same run detached, see below
|
||||
./e2e.sh status # live progress, or the last run's result
|
||||
|
||||
Reference in new issue
Block a user