Describe objects in structs and lists (#238)
Behaviors gets a paragraph on objects in struct fields and list items. Colliders no longer says a raycast list turns into names. Development counts 1407 e2e checks.
1 parent
e77a6ac00f
commit
96bc416bc3
3 files changed
+24
-21
No files matched your search
+20
-18
@@ -39,25 +39,26 @@ playing use the same two words.
|
||||
type as a setting row (*Type: Sprite*, plus *Behavior: Game* under that type). Textures and
|
||||
scenes are no type here: they are not objects in a running game. A variable is a
|
||||
**number, a text, a yes/no, a colour, a texture, a state machine, an asset, an object, a list or a struct**; a list declares **nothing** about its items —
|
||||
each one is a number, a text, a yes/no, a colour, a texture, a state machine or a struct and says so itself, so one list may
|
||||
each one is a number, a text, a yes/no, a colour, a texture, a state machine, an asset, an object or a struct and says so itself, so one list may
|
||||
hold several kinds at once. A list is
|
||||
compared by its items, never by identity — otherwise every reload would look like an override.
|
||||
There is no **stored** list of objects: a stored list lives in the project file and an object is a
|
||||
live handle that no reload survives. A list **travelling on an edge** may hold objects, though, and
|
||||
`Raycast all` (#157) is what hands one out; `Item at` gives such an item back as the object it is.
|
||||
The moment that list is written into a variable or a property, every object in it becomes its name
|
||||
— that is the one door into a saved value, and nothing alive goes through it. A set of objects
|
||||
that has to *survive* is therefore still a list of names, walked with `Repeat` and `Object by name`.
|
||||
One object on its own **can** be held, by an **object variable**: write the `object` output of
|
||||
`Spawn` (or of `Object by name`, `Child by name`, a collision) into it, and every later frame
|
||||
reads the same object back. It lives for the run only. The file stores the declaration and an
|
||||
empty value, the inspector shows `(null)` and offers nothing to pick, and neither a scene
|
||||
override, a snapshot nor a save of a persistent Variables asset ever holds the object. The handle
|
||||
sits beside the variable rather than in it (`core/graph/objectSlots.ts`), since everything in the
|
||||
variable bag is written back into the scene as an override. A **destroyed** object reads as
|
||||
`(null)`, as does one from a scene that was restarted or left. "Is it still there?" is `Equals`
|
||||
with the variable on `a` and `b` left empty: true once the object is gone. Kept variables of a called behavior (#229) keep their object across calls too,
|
||||
and `Properties` of type *Behavior* reads and writes another behavior's object variable.
|
||||
**Objects** can be held wherever a value can (#238): an **object variable**, an **object field** of a
|
||||
struct (`+ Field → Object`) and an **object item** of a list. Write the `object` output of
|
||||
`Spawn` (or of `Object by name`, `Child by name`, a collision) into one, and every later frame
|
||||
reads the same object back: `Expand` gives the field back as the object, `Item at` the item.
|
||||
`Raycast all` (#157) hands out a list of objects, and written into a list variable it stays one.
|
||||
An object lives for the run only. At rest (in the file, a snapshot, the inspector) its place
|
||||
always holds the empty object, stored as `{"$object": ""}` wherever it sits, and the inspector and
|
||||
the List tab show `(null)` and offer nothing to pick. During a run the object sits right in the
|
||||
value, and every way out of the run empties it again (`core/graph/liveObjects.ts`,
|
||||
`withoutObjects`): the values the editor run writes back into the scene as overrides, the save of
|
||||
a persistent Variables asset, the live values the inspector shows and the test hooks. A struct
|
||||
whose only change is an object therefore writes no override. A list that grew by an object does:
|
||||
the scene learns the new item, as the empty object. A **destroyed** object reads as `(null)`,
|
||||
alone as well as out of a list or a struct, as does one from a scene that was restarted or left.
|
||||
"Is it still there?" is `Equals` with the object on `a` and `b` left empty: true once it is gone.
|
||||
Kept variables of a called behavior (#229) keep their objects across calls too, and `Properties`
|
||||
of type *Behavior* reads and writes another behavior's object variable.
|
||||
A list property is shown as a button saying how many items it holds;
|
||||
clicking it opens the **List** tab, which gives each item a row with the same widget the
|
||||
inspector would use for that kind — a struct item is its fields as rows under each other. The inspector stays visible beside the tab, so what the list
|
||||
@@ -281,7 +282,8 @@ playing use the same two words.
|
||||
at its declared value, and a value whose kind changed is converted like any other value.
|
||||
An **object variable** may sit in a persistent asset too, but is never saved: the object is an
|
||||
instance of that run, and the next run has new ones. It starts every run at `(null)` while the
|
||||
other values go on, and the inspector says so under the switch.
|
||||
other values go on, and the inspector says so under the switch. The same goes for an object in a
|
||||
saved list or struct: the save keeps its place, as the empty object.
|
||||
- **Cross-object state** the other way: a behavior's own variables *are* the properties of its
|
||||
object, so another graph reads and writes them with `Object by name` → `Properties` of type
|
||||
*Behavior*. That reaches one named object, where a Variables asset belongs to no object at all.
|
||||
|
||||
+3
-2
@@ -196,8 +196,9 @@ the same settings as Raycast — **Ignore owner**, **Hit triggers**, **Layers**
|
||||
rather than a run of the flow per hit: that is what `Count`, `Item at` and `Sub list` already work
|
||||
with.
|
||||
- `objects` and `colliders` hold **live objects**, not names — `Item at` gives one back as an object,
|
||||
ready for `Destroy`, `Apply force` or `Name of`. A list only carries them while it travels: written
|
||||
into a variable or a property, each object becomes its name, because nothing saved is alive.
|
||||
ready for `Destroy`, `Apply force` or `Name of`. Written into a list variable they stay objects for
|
||||
the rest of the run; only what leaves the run (a save, the scene) holds the empty object instead,
|
||||
see [Behaviors](Behaviors).
|
||||
- **A collider counts once**, however many convex pieces its shape falls into, and the hit is the
|
||||
first face the ray enters. A **tilemap** counts once per cell the ray goes through, since a map is
|
||||
many solids under one entity — the `collider` of each of those hits is the tilemap.
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ npm run build # writes dist/ and regenerates index.html
|
||||
php tools/make-user.php <name> <password> [admin|user] # an account; every tool signs in (see Accounts)
|
||||
php tests/php/accounts.test.php # the API's account rules, no server needed (CI's gate job)
|
||||
php tests/php/snapshots.test.php # the snapshot store (#231), the same way
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1406 editor checks, screenshots in /tmp/gm-e2e-*.png
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1407 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