From 77b6aa1646e1d1fa39f9b98bfd50fc2354cb4b4a Mon Sep 17 00:00:00 2001 From: MelekTaus Date: Sun, 20 Sep 2026 18:54:17 +0200 Subject: [PATCH] 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 --- Architecture.md | 3 ++- Behaviors.md | 13 +++++++++---- Colliders.md | 23 ++++++++++++++++++++++- Development.md | 2 +- Physics.md | 4 ++-- 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/Architecture.md b/Architecture.md index 0758ca4..99fdda1 100644 --- a/Architecture.md +++ b/Architecture.md @@ -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/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/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), 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, diff --git a/Behaviors.md b/Behaviors.md index 6345e88..ba87353 100644 --- a/Behaviors.md +++ b/Behaviors.md @@ -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 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 list *of objects*: a list is stored in the project file and an object is a live - handle that no reload survives. A set of objects is a list of their names, walked with `Repeat` - and `Object by name`. A list property is shown as a button saying how many items it holds; + 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`. + 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 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`, 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`, - `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 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) · @@ -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`, `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 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` (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 diff --git a/Colliders.md b/Colliders.md index 0fd11c5..89ea618 100644 --- a/Colliders.md +++ b/Colliders.md @@ -149,7 +149,28 @@ check, a laser, a hitscan shot. 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 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 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). + +## 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. diff --git a/Development.md b/Development.md index df1396f..237a196 100644 --- a/Development.md +++ b/Development.md @@ -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 ./build.sh # the same under `set -o pipefail`, for callers that pipe the output php tools/make-user.php # 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 ./e2e.sh start [GM_STEPS] # the same run detached, see below ./e2e.sh status # live progress, or the last run's result diff --git a/Physics.md b/Physics.md index 7aac3ef..4e59a41 100644 --- a/Physics.md +++ b/Physics.md @@ -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, in double precision, and slides over the same seams without catching (#150). - The simulation in the editor run (#148). -- Joints (#154), and "Raycast all" as a list of every hit (#157). Raycasts (#153) with their layer - filter (#158), one-way platforms (#155) and the collision layers themselves (#152) are there, +- Joints (#154). Raycasts (#153) with their layer filter (#158), `Raycast all` with every hit on the + line (#157), one-way platforms (#155) and the collision layers themselves (#152) are there, see [Colliders](Colliders#raycast).