Describe sprite preview, machine ports and shared local machines
The wiki catches up with the last four commits in the code repo. - Concepts: new paragraph Sprite preview. Architecture lists SpritePreview.ts and previewFit.ts. - State-machines: a Start input or a Variables node can name the machine it carries. A called behavior now shares the caller's local machines instead of starting empty. - Behaviors: the warning at Run behavior for a different machine, the shared local machines and Get world position in the data nodes. - Scene-editing: a half sentence on Get world position. - Development: e2e sum 1744. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent
1d9e589d07
commit
70697cce9a
6 files changed
+41
-15
No files matched your search
+3
-1
@@ -281,7 +281,9 @@ src/editor/inspector/ Inspector panel, host (what a section builds into, and `e
|
|||||||
every variable), shapeSection (the shapes of a vector drawing: the list, the four order
|
every variable), shapeSection (the shapes of a vector drawing: the list, the four order
|
||||||
buttons and the style of the picked one, #129; Fill type and Line type with the stop bar,
|
buttons and the style of the picked one, #129; Fill type and Line type with the stop bar,
|
||||||
the picked stop's rows or the texture, #186), portSection, aspectAction,
|
the picked stop's rows or the texture, #186), portSection, aspectAction,
|
||||||
objectQueries/vectorRows/parentRow, cutSection (the Nine-slice and Sorting rows, shared by the frame and the drawing inspectors, #308)
|
objectQueries/vectorRows/parentRow, cutSection (the Nine-slice and Sorting rows, shared by the frame and the drawing inspectors, #308),
|
||||||
|
SpritePreview (a sprite as `syncSpriteMesh` draws it in the scene) + previewFit (whole device
|
||||||
|
pixels per unit, the corner on one)
|
||||||
src/editor/panels/ AssetPanel, assetGroups (groups by type and their order, #176), assetIcons (one SVG per
|
src/editor/panels/ AssetPanel, assetGroups (groups by type and their order, #176), assetIcons (one SVG per
|
||||||
asset type in icons/, shared by the panel, the + menu, the tabs and Scene objects,
|
asset type in icons/, shared by the panel, the + menu, the tabs and Scene objects,
|
||||||
plus the List, Game, Plugins and User management tabs' own four, which stand for no asset),
|
plus the List, Game, Plugins and User management tabs' own four, which stand for no asset),
|
||||||
|
|||||||
+8
-4
@@ -220,7 +220,7 @@ the inspector).
|
|||||||
the given object, nearer levels first, the order `Child by name` searches in), `Children` (the
|
the given object, nearer levels first, the order `Child by name` searches in), `Children` (the
|
||||||
children of an object; with **recursive** every object below it, level by level) and
|
children of an object; with **recursive** every object below it, level by level) and
|
||||||
`Objects of asset` (every instance of the chosen asset, spawned ones included),
|
`Objects of asset` (every instance of the chosen asset, spawned ones included),
|
||||||
`Variables`, `Properties` (every property row of the target's type, the transform rows `scale`, `rotation`, `mirrorX`, `mirrorY` included — how a graph turns a sprite), `Get position` (local and world), `Get Z` (the object's own `z` and `world z`, summed up with its parents'), `Is enabled`, literals `Number`/`Text`/`Boolean`/`Texture`/`State machine`/`Sound`/`Scene`/`Animation`/`Asset`, `Texture size` (a texture's, frame's or pixel art's own size in pixels, 0 for none — wired into a sprite's `width`/`height`, a picture shows pixel for pixel), `Add/Subtract/Multiply/Divide`,
|
`Variables`, `Properties` (every property row of the target's type, the transform rows `scale`, `rotation`, `mirrorX`, `mirrorY` included — how a graph turns a sprite), `Get position` (local and world), `Get world position` (only the world `x`/`y`), `Get Z` (the object's own `z` and `world z`, summed up with its parents'), `Is enabled`, literals `Number`/`Text`/`Boolean`/`Texture`/`State machine`/`Sound`/`Scene`/`Animation`/`Asset`, `Texture size` (a texture's, frame's or pixel art's own size in pixels, 0 for none — wired into a sprite's `width`/`height`, a picture shows pixel for pixel), `Add/Subtract/Multiply/Divide`,
|
||||||
`Min/Max/Abs/Sqrt/Clamp`, `Lerp` (from a to b as t runs from 0 to 1, t held in 0…1; the setting
|
`Min/Max/Abs/Sqrt/Clamp`, `Lerp` (from a to b as t runs from 0 to 1, t held in 0…1; the setting
|
||||||
*Ease* bends the way: *Linear*, *In* starts slow, *Out* ends slow, *In-out* both, all quadratic,
|
*Ease* bends the way: *Linear*, *In* starts slow, *Out* ends slow, *In-out* both, all quadratic,
|
||||||
or *Curve*, which follows the [curve asset](Curves) picked in the *Curve* row and may overshoot b;
|
or *Curve*, which follows the [curve asset](Curves) picked in the *Curve* row and may overshoot b;
|
||||||
@@ -372,7 +372,8 @@ the inspector).
|
|||||||
removing takes the edges hanging on it in *every* graph that calls the behavior. A call is a
|
removing takes the edges hanging on it in *every* graph that calls the behavior. A call is a
|
||||||
**call, not an inlining**: the nested graph runs in its own pulse cache with a fresh copy of its
|
**call, not an inlining**: the nested graph runs in its own pulse cache with a fresh copy of its
|
||||||
variable defaults, so values travel in and out through the ports and nothing else. That makes a
|
variable defaults, so values travel in and out through the ports and nothing else. That makes a
|
||||||
call repeatable and keeps a nested behavior free of hidden state. A behavior that would run
|
call repeatable and keeps a nested behavior free of hidden state. The one exception are local
|
||||||
|
state machines, which belong to the instance running the call (see *Keep* below). A behavior that would run
|
||||||
itself raises an error instead of looping; there is one start and one end node per behavior.
|
itself raises an error instead of looping; there is one start and one end node per behavior.
|
||||||
A behavior **without a start node** is called from its **On start** nodes instead, all of them in
|
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
|
graph order, as when it starts on its own. It takes no inputs then, but its end node still hands
|
||||||
@@ -427,7 +428,8 @@ the inspector).
|
|||||||
a call inside a call has one per outer node. It follows today's declarations: a variable added
|
a call inside a call has one per outer node. It follows today's declarations: a variable added
|
||||||
since starts at its default, a removed one is dropped, and one whose kind changed starts over.
|
since starts at its default, a removed one is dropped, and one whose kind changed starts over.
|
||||||
The kept value lives as long as the object does in the run and is never saved. Local state
|
The kept value lives as long as the object does in the run and is never saved. Local state
|
||||||
machines of the called behavior are not kept, they start in no state every call. For state
|
machines need no Keep: a call reads and moves the states of the instance running it, so they
|
||||||
|
carry over from call to call anyway (see *State machines*). For state
|
||||||
shared between objects, use a Variables asset or a behavior object in the scene (see
|
shared between objects, use a Variables asset or a behavior object in the scene (see
|
||||||
*Cross-object state* below).
|
*Cross-object state* below).
|
||||||
Three ways in and out of a call: **drag** a behavior out of the asset panel onto the graph and it
|
Three ways in and out of a call: **drag** a behavior out of the asset panel onto the graph and it
|
||||||
@@ -437,7 +439,9 @@ the inspector).
|
|||||||
stays in the same tab, and the trail belongs to that tab: a behavior opened any other way comes
|
stays in the same tab, and the trail belongs to that tab: a behavior opened any other way comes
|
||||||
up in a tab of its own, without a trail, and switching back brings the trail back with it. And a call that cannot
|
up in a tab of its own, without a trail, and switching back brings the trail back with it. And a call that cannot
|
||||||
do anything **says so on the node** — no behavior picked, the behavior deleted,
|
do anything **says so on the node** — no behavior picked, the behavior deleted,
|
||||||
or neither a start node nor an On start in it. The last one is the one worth naming: without
|
or neither a start node nor an On start in it. It also warns when a State machine input is set
|
||||||
|
to another machine than the one its Start input carries (see *State machines*). The missing
|
||||||
|
start is the one worth naming: without
|
||||||
either there is no way in, so the call is skipped and the flow simply carries on at its `exec` output. A missing
|
either there is no way in, so the call is skipped and the flow simply carries on at its `exec` output. A missing
|
||||||
*end* node is not a defect — a call is always synchronous, "done" is the nested flow running out,
|
*end* node is not a defect — a call is always synchronous, "done" is the nested flow running out,
|
||||||
and the end node only decides what comes back.
|
and the end node only decides what comes back.
|
||||||
|
|||||||
+7
@@ -288,6 +288,13 @@ without rows is left out.
|
|||||||
with a header of its own (*Layers*, *Frames*, *Shapes*) folds with a click on that header, clear
|
with a header of its own (*Layers*, *Frames*, *Shapes*) folds with a click on that header, clear
|
||||||
of its plus, and takes the notes and buttons under it along.
|
of its plus, and takes the notes and buttons under it along.
|
||||||
|
|
||||||
|
**Sprite preview.** A sprite, placed or as an asset, ends its inspector with a **Preview** group:
|
||||||
|
the sprite as the scene draws it, with its picture or frame, nine-slice, tint and shader, on the
|
||||||
|
scene's background. A placed sprite shows its own overrides. An edit shows at once, also while a
|
||||||
|
value is dragged, and a shader with a Time node keeps moving while the group is open. The picture
|
||||||
|
is fitted into the group and magnified by whole device pixels at most 8 times, so pixel art stays
|
||||||
|
sharp; a sprite larger than the group is shrunk to fit.
|
||||||
|
|
||||||
The asset panel and **Scene objects** share the left column; the divider between them drags
|
The asset panel and **Scene objects** share the left column; the divider between them drags
|
||||||
the height from one to the other, and dragged all the way either keeps its header. The split is a
|
the height from one to the other, and dragged all the way either keeps its header. The split is a
|
||||||
share of the column, so a taller or shorter window keeps it.
|
share of the column, so a taller or shorter window keeps it.
|
||||||
|
|||||||
+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)
|
# 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/snapshots.test.php # the snapshot store (#231), the same way
|
||||||
php tests/php/releases.test.php # the release store (#266), 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 # 1742 editor checks, screenshots in /tmp/gm-e2e-*.png
|
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1744 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
|
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 start [GM_STEPS] # the same run detached, see below
|
||||||
./e2e.sh status # live progress, or the last run's result
|
./e2e.sh status # live progress, or the last run's result
|
||||||
|
|||||||
+2
-1
@@ -179,7 +179,8 @@ scene opens fully collapsed — which rows are open is view state of the panel,
|
|||||||
the project — and selecting an object anywhere (viewport, `Add collider…`, `Create container`)
|
the project — and selecting an object anywhere (viewport, `Add collider…`, `Create container`)
|
||||||
unfolds the way down to it and scrolls it into view, so a selection is never hidden. In
|
unfolds the way down to it and scrolls it into view, so a selection is never hidden. In
|
||||||
play mode entities carry the same `parent` link: moving a parent entity moves its subtree,
|
play mode entities carry the same `parent` link: moving a parent entity moves its subtree,
|
||||||
`Destroy` removes it. `Get position` exposes both the local and the world coordinates.
|
`Destroy` removes it. `Get position` exposes both the local and the world coordinates,
|
||||||
|
`Get world position` only the world ones.
|
||||||
|
|
||||||
**Groups in the hierarchy (#241).** A group is a folder for top-level objects — 100 crates under
|
**Groups in the hierarchy (#241).** A group is a folder for top-level objects — 100 crates under
|
||||||
one foldable row, say. It is editor looks only: parents, positions and behaviors stay exactly as
|
one foldable row, say. It is editor looks only: parents, positions and behaviors stay exactly as
|
||||||
|
|||||||
+20
-8
@@ -95,15 +95,25 @@ state lives in the *machine* — so nothing cleans up there, and the edge stays
|
|||||||
lost, though: the behavior's node shows the key as a **ghost port** with the edge dashed in the
|
lost, though: the behavior's node shows the key as a **ghost port** with the edge dashed in the
|
||||||
warning colour, and *Disconnect* on its right-click menu removes it. Put the state back and the
|
warning colour, and *Disconnect* on its right-click menu removes it. Put the state back and the
|
||||||
edge works again. Which machine the
|
edge works again. Which machine the
|
||||||
ports belong to is read off the graph, not off a running value — the inline pick, or a
|
ports belong to is read off the graph, not off a running value — the inline pick, a
|
||||||
`State machine` literal wired in; a variable or an `Item at` feeding the input yields no state
|
`State machine` literal wired in, or an input of the behavior's **Start** node of the kind
|
||||||
ports, exactly as `Run behavior` knows its behavior only as a setting. That machine is still not
|
State machine with a machine picked next to its name in the inspector. A variable of that kind
|
||||||
|
read by a `Variables` node works the same way: the machine is picked next to the variable's row.
|
||||||
|
The pick only names the states, the value the variable holds at run time is not checked against
|
||||||
|
it. An `Item at` or anything else feeding the input yields no state ports, exactly as
|
||||||
|
`Run behavior` knows its behavior only as a setting. That machine is still not
|
||||||
stuck: `Set state by name` names the state as text, `State branch` leaves along `else`, and
|
stuck: `Set state by name` names the state as text, `State branch` leaves along `else`, and
|
||||||
`Current state` answers as always. The price is spelled out, not hidden — a name is typed, so a
|
`Current state` answers as always. The price is spelled out, not hidden — a name is typed, so a
|
||||||
typo is possible where a port made it impossible, which is what `not found` is there for.
|
typo is possible where a port made it impossible, which is what `not found` is there for.
|
||||||
Picking another machine
|
Picking another machine
|
||||||
orphans the edges of the old states, the way any setting that decides a node's ports does.
|
orphans the edges of the old states, the way any setting that decides a node's ports does.
|
||||||
|
|
||||||
|
A Start input with a machine picked has that machine **picked in advance** on every node running
|
||||||
|
the behavior. Another pick there is allowed, but the node warns (`"machine" expects "Doors"`):
|
||||||
|
the called graph asks for the states of its own machine, so with another one every state would
|
||||||
|
read as never entered. A **local** machine handed in is the caller's: the called graph reads and
|
||||||
|
moves the very state the calling instance holds (see *The current state while playing* below).
|
||||||
|
|
||||||
Two more read it as **data** rather than as a flow, both pure readers (no exec ports, answered
|
Two more read it as **data** rather than as a flow, both pure readers (no exec ports, answered
|
||||||
whenever they are asked):
|
whenever they are asked):
|
||||||
|
|
||||||
@@ -148,9 +158,9 @@ The rules, all of them worth knowing before wiring a graph on them:
|
|||||||
whose events keep moving the machine stops the run with an endless-loop error, like the step limit.
|
whose events keep moving the machine stops the run with an endless-loop error, like the step limit.
|
||||||
- Who hears it follows the **scope**: a local machine is heard by the instance that moved it alone,
|
- Who hears it follows the **scope**: a local machine is heard by the instance that moved it alone,
|
||||||
a global one by **every** instance with a matching event node — which is the point of sharing a
|
a global one by **every** instance with a matching event node — which is the point of sharing a
|
||||||
state. A move a nested `Run behavior` makes to a *local* machine dies with the call and is not
|
state. A move made inside a `Run behavior`, however deep, counts as a move of the instance that
|
||||||
reported, even where the called behavior keeps variables (see *Behaviors*); a move it makes to a
|
runs the call: its own `On state entered` and `On state exited` hear it. The event nodes of the
|
||||||
global one is a move like any other.
|
called graph itself stay silent, like every event there.
|
||||||
|
|
||||||
## The current state while playing
|
## The current state while playing
|
||||||
|
|
||||||
@@ -164,8 +174,10 @@ gone the moment the run stops. Play repaints the tab the way it repaints the Beh
|
|||||||
|
|
||||||
**A local machine's current state is the behavior instance's own**, kept beside its variables
|
**A local machine's current state is the behavior instance's own**, kept beside its variables
|
||||||
(`NodeContext.states`, machine id → state id): two crates running the same behavior are in
|
(`NodeContext.states`, machine id → state id): two crates running the same behavior are in
|
||||||
states of their own, and a behavior run through `Run behavior` starts in no state,
|
states of their own. A behavior run through `Run behavior` has no states of its own: it reads and
|
||||||
and again with every call. A **global** one is kept for the run instead (`SharedState.states`, built
|
moves those of the instance that runs the call, however deep, so a state one call sets is still set
|
||||||
|
in the next one, and the call begins in the start state like the instance does. Two characters
|
||||||
|
running the same behavior therefore stay apart, each with its calls. A **global** one is kept for the run instead (`SharedState.states`, built
|
||||||
once per run in `core/graph/sharedState.ts`) and every instance reads and moves that one — which
|
once per run in `core/graph/sharedState.ts`) and every instance reads and moves that one — which
|
||||||
bag a node touches is decided by the machine's scope, not by the node (`stateBag`). Neither
|
bag a node touches is decided by the machine's scope, not by the node (`stateBag`). Neither
|
||||||
survives a stop: both begin the next Play at the start state again, or in no state where there is
|
survives a stop: both begin the next Play at the start state again, or in no state where there is
|
||||||
|
|||||||
Reference in new issue
Block a user