Raycast all (#157): Colliders gained the section on the new node - the parallel lists sorted by distance, a collider counting once while a tilemap counts per cell, "max hits" with 0 for all - and lost the line that only the nearest hit is answered; Behaviors lists the node and says what a travelling list may carry and what happens to it when it is stored; Physics names #154 as the only open point; Architecture carries storedList(); Development carries the check sum 1157

admin committed 2026-09-20 18:54:17 +02:00
1 parent bc2a138c8c
commit 77b6aa1646
5 files changed
+36 -9

No files matched your search

+2 -1
@@ -72,7 +72,8 @@ src/core/model/ Project (object holders), Asset + AssetTypes, SceneObject
src/core/properties/ PropertySchema, kinds (one row per value kind), listItems (an item's kind, read off its value), resolve (the only override merge), deviation (what is gold), collider/camera/bounds geometry (with the side a one-way collider blocks from), convex (capsules and polygons: rounded convex pieces against each other), ray (where a ray meets a shape, in double precision), rigidbody (what the engine reads off a rigidbody, a collider's material and the scene), aspect, enabled, editorRun, assetRef/textureRef (how a reference reads), declaredRows (the row a Property node declares in a shader or particle graph, and the params that node has in both) src/core/properties/ PropertySchema, kinds (one row per value kind), listItems (an item's kind, read off its value), resolve (the only override merge), deviation (what is gold), collider/camera/bounds geometry (with the side a one-way collider blocks from), convex (capsules and polygons: rounded convex pieces against each other), ray (where a ray meets a shape, in double precision), rigidbody (what the engine reads off a rigidbody, a collider's material and the scene), aspect, enabled, editorRun, assetRef/textureRef (how a reference reads), declaredRows (the row a Property node declares in a shader or particle graph, and the params that node has in both)
src/core/util/ list (take out, put back and move an item — what a command's undo is made of), vec (dot, the closest point on a segment — shared by the collider maths, the outline hit area and the polygon grips) src/core/util/ list (take out, put back and move an item — what a command's undo is made of), vec (dot, the closest point on a segment — shared by the collider maths, the outline hit area and the polygon grips)
src/core/commands/ undoable commands, CommandStack, SetBagValueCommand base, RenameCommand base (undone by renaming back: variable, struct field, port), one import command shape for texture/font/sound, require.ts (validated lookups, and what an instance may not change), naming.ts src/core/commands/ undoable commands, CommandStack, SetBagValueCommand base, RenameCommand base (undone by renaming back: variable, struct field, port), one import command shape for texture/font/sound, require.ts (validated lookups, and what an instance may not change), naming.ts
src/core/graph/ graph model, NodeRegistry/NodeContext/values, interpreter, dropTarget, nested (behaviors as nodes), src/core/graph/ graph model, NodeRegistry/NodeContext/values (a travelling list may hold live objects, `storedList`
narrows one down to what a PropertyBag may hold, #157), interpreter, dropTarget, nested (behaviors as nodes),
emitGraph (the walk both graph compilers share: each node once, in dependency order; cycles and property names reported), emitGraph (the walk both graph compilers share: each node once, in dependency order; cycles and property names reported),
sharedState (what a run shares: a bag per Variables asset, the state of a global machine), sharedState (what a run shares: a bag per Variables asset, the state of a global machine),
stateMachine (the State node, a machine's states, the ports they become), variablePorts, propertyPorts, stateMachine (the State node, a machine's states, the ports they become), variablePorts, propertyPorts,
+9 -4
@@ -38,9 +38,13 @@ shown on the node and editable in the inspector.
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 or a struct and says so itself, so one list may
hold several kinds at once. A list is hold several kinds at once. A list is
compared by its items, never by identity — otherwise every reload would look like an override. compared by its items, never by identity — otherwise every reload would look like an override.
There is no list *of objects*: a list is stored in the project file and an object is a live There is no **stored** list of objects: a stored list lives in the project file and an object is a
handle that no reload survives. A set of objects is a list of their names, walked with `Repeat` live handle that no reload survives. A list **travelling on an edge** may hold objects, though, and
and `Object by name`. A list property is shown as a button saying how many items it holds; `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`.
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 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 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
belongs to is still on screen. Which list the tab shows is a `ListSlot` (asset property, object belongs to is still on screen. Which list the tab shows is a `ListSlot` (asset property, object
@@ -104,7 +108,7 @@ shown on the node and editable in the inspector.
`Substring`, `Find text`, `Equals`, `Substring`, `Find text`, `Equals`,
lists `List` (a constant), `Fill` (one value repeated — how an empty board is made), `Count`, lists `List` (a constant), `Fill` (one value repeated — how an empty board is made), `Count`,
`Item at`, `Set item` (a *new* list, the one that came in is left alone), `Sub list`, `Item at`, `Set item` (a *new* list, the one that came in is left alone), `Sub list`,
`Join lists`, `Index of`, structs `Pack`/`Expand`, `Join lists`, `Index of` (by identity where the items are objects), structs `Pack`/`Expand`,
`Length`, `Distance`, `Normalize`, `Axis input` (four keys → a `Length`, `Distance`, `Normalize`, `Axis input` (four keys → a
normalized direction, so diagonals are not faster), `Compare`, `And/Or/Not`, `Key is down`, normalized direction, so diagonals are not faster), `Compare`, `And/Or/Not`, `Key is down`,
`Mouse position`, `Mouse button`, `Is hovered`, `Is touching`, `Get velocity`, `Current state` (name and id), `Is in state` (one boolean per state) · `Mouse position`, `Mouse button`, `Is hovered`, `Is touching`, `Get velocity`, `Current state` (name and id), `Is in state` (one boolean per state) ·
@@ -117,6 +121,7 @@ shown on the node and editable in the inspector.
`Load scene` (swaps the running scene once the frame is over — see [Scenes](Scenes)), `Log`, `Stop game`, `Restart game`, `Load scene` (swaps the running scene once the frame is over — see [Scenes](Scenes)), `Log`, `Stop game`, `Restart game`,
`Apply force`, `Apply impulse`, `Set velocity`, `Set angular velocity`, `Set gravity` (see [Physics](Physics)), `Apply force`, `Apply impulse`, `Set velocity`, `Set angular velocity`, `Set gravity` (see [Physics](Physics)),
`Raycast` (what a ray meets first on the layers it looks at: object, collider, point, normal, distance — see [Colliders](Colliders#raycast)), `Raycast` (what a ray meets first on the layers it looks at: object, collider, point, normal, distance — see [Colliders](Colliders#raycast)),
`Raycast all` (everything on that line instead, as parallel lists sorted by distance, with a `count` and a `max hits` — see [Colliders](Colliders#raycast-all)),
`Ignore one-way` (fall through one-way colliders and tiles for some seconds — see [Colliders](Colliders#one-way)). A node type is one file exporting a `NodeDef` `Ignore one-way` (fall through one-way colliders and tiles for some seconds — see [Colliders](Colliders#one-way)). A node type is one file exporting a `NodeDef`
(ports, settings, `run`), listed in `nodes/index.ts`; palette, ports, validation and (ports, settings, `run`), listed in `nodes/index.ts`; palette, ports, validation and
inspector fields are generated from it. A port may declare a `default` for its inline value inspector fields are generated from it. A port may declare a `default` for its inline value
+22 -1
@@ -149,7 +149,28 @@ check, a laser, a hitscan shot.
everything is right now — not about the last physics step. everything is right now — not about the last physics step.
- In the editor run every ray cast shows in the scene view for a quarter of a second: green to - In the editor run every ray cast shows in the scene view for a quarter of a second: green to
where it met something, grey to its end when it met nothing. where it met something, grey to its end when it met nothing.
- Only the first hit for now; a list of all hits (#157) comes later. - **Raycast** says what it meets *first*; **Raycast all** (below) says everything on the line.
- A setting reaches a *running* instance only when that instance starts afresh: the interpreter - A setting reaches a *running* instance only when that instance starts afresh: the interpreter
holds the graph it began with, so a behavior that already runs in the editor keeps casting with holds the graph it began with, so a behavior that already runs in the editor keeps casting with
the layers it started on until it is switched off and on (or Play is pressed). the layers it started on until it is switched off and on (or Play is pressed).
## Raycast all
The **Raycast all** node (#157) casts the same ray and hands back everything it meets, for a shot
that goes through several enemies, a laser, or "what is on this line". It takes the same inputs and
the same settings as Raycast — **Ignore owner**, **Hit triggers**, **Layers** — plus **max hits**.
- The answer is **parallel lists**, sorted by distance: `objects`, `colliders`, `points x`,
`points y`, `normals x`, `normals y`, `distances`, and the plain number `count`. Item `n` of every
list belongs to the same hit, so `Item at` with one index reads a whole hit out of them. Lists
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.
- **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.
- **max hits** above 0 keeps that many of the nearest and leaves the rest out; 0 (the default) keeps
all of them.
- In the editor run the ray is drawn to the **last** thing it met — that is how far it looked.
+1 -1
@@ -13,7 +13,7 @@ npm run check # typecheck + lint + format:check + tests, the gate CI runs
npm run build # writes dist/ and regenerates index.html npm run build # writes dist/ and regenerates index.html
./build.sh # the same under `set -o pipefail`, for callers that pipe the output ./build.sh # the same under `set -o pipefail`, for callers that pipe the output
php tools/make-user.php <name> <password> # an account; every tool signs in (see Accounts) php tools/make-user.php <name> <password> # an account; every tool signs in (see Accounts)
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1153 editor checks, screenshots in /tmp/gm-e2e-*.png node tools/seed-e2e.mjs && node tools/e2e.mjs # 1157 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 -2
@@ -167,6 +167,6 @@ are placed, because what the editor run moves is saved. The nodes above do nothi
crates), kept a gap of up to 1.7 units and knows no friction; `Move` works out its contacts itself, crates), kept a gap of up to 1.7 units and knows no friction; `Move` works out its contacts itself,
in double precision, and slides over the same seams without catching (#150). in double precision, and slides over the same seams without catching (#150).
- The simulation in the editor run (#148). - The simulation in the editor run (#148).
- Joints (#154), and "Raycast all" as a list of every hit (#157). Raycasts (#153) with their layer - Joints (#154). Raycasts (#153) with their layer filter (#158), `Raycast all` with every hit on the
filter (#158), one-way platforms (#155) and the collision layers themselves (#152) are there, line (#157), one-way platforms (#155) and the collision layers themselves (#152) are there,
see [Colliders](Colliders#raycast). see [Colliders](Colliders#raycast).