Collision layers and masks: Physics and Colliders describe the layer and the mask of layers a collider meets, that a pair only meets when both masks name the other's layer, and where the names are edited - "Collision layers..." in the toolbar's Project menu, as one undo step, up to 16 of them; API names the project field collisionLayers, Architecture lists collisionLayers and CollisionLayersDialog, Concepts and Tilemaps name the two new inspector rows, Development carries the check sum 1138
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent
b6614c51e4
commit
0b7f0c2ff5
7 files changed
+44
-4
No files matched your search
+4
@@ -32,6 +32,10 @@ of admission. See [Accounts](Accounts).
|
||||
Which editor plugins a project switches on is the project's own field `plugins` (#119); the server
|
||||
has no switch of its own and hands out every plugin file it has.
|
||||
|
||||
The named collision layers are the project's field `collisionLayers` (#152), a list of up to 16
|
||||
names of which the first one is layer 0. A project file without it has the single layer *Default*,
|
||||
which is what every collider is on, so the field needs no format bump either.
|
||||
|
||||
Every project document carries `formatVersion` (`PROJECT_FORMAT_VERSION` in `core/model/Project.ts`,
|
||||
currently 2). There are no load-time migrations: `serialize.ts` reads what it recognises and drops
|
||||
the rest.
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@
|
||||
|
||||
```
|
||||
web/index.html Vite source page (dev) index.html built page (generated, served)
|
||||
src/core/model/ Project (object holders), Asset + AssetTypes, SceneObject, Properties (value types), hierarchy, walk (generic parent/child walks), instance (container content resolved from its template), usages (where an asset is used), container (the cycle guard), placement (what may be dropped where), texture (frames, the slice grid, a frame's collision outlines), polygon (an outline checked, cut into convex pieces and clipped to a rectangle), tile (the three kinds and their block shapes, reading a tile's pictures, the animation step), autotile (which quarter tile a neighbourhood asks for, the 47/16 tiles a block produces, 1 for a plain tile), tilemap (the cells of a layer, which neighbours a cell is joined to, the cells a stroke or a rectangle covers), tilemapCollision (the solid cells of a map, drawn in or out by their tile's collision scale and merged into rectangles, the outlined cells as polygons — an autotile's outlines cut into its quarters and pieced together per cell like its picture —, and where one sits in the world), animation (which frame at time t, a row's value there, what a row may aim at, the players on an object; KeyRef and its lookups) + animationPreview (the root at a frame, written into copies), graphLookup (what a graph sees of the project: behaviors to run, state machines to read), Scope (where a state machine's current state lives: per instance or one for the run — variables are shared by living on a Variables asset instead)
|
||||
src/core/model/ Project (object holders), Asset + AssetTypes, SceneObject, Properties (value types), hierarchy, walk (generic parent/child walks), instance (container content resolved from its template), usages (where an asset is used), container (the cycle guard), placement (what may be dropped where), texture (frames, the slice grid, a frame's collision outlines), polygon (an outline checked, cut into convex pieces and clipped to a rectangle), tile (the three kinds and their block shapes, reading a tile's pictures, the animation step), autotile (which quarter tile a neighbourhood asks for, the 47/16 tiles a block produces, 1 for a plain tile), tilemap (the cells of a layer, which neighbours a cell is joined to, the cells a stroke or a rectangle covers), tilemapCollision (the solid cells of a map, drawn in or out by their tile's collision scale and merged into rectangles, the outlined cells as polygons — an autotile's outlines cut into its quarters and pieced together per cell like its picture —, and where one sits in the world), animation (which frame at time t, a row's value there, what a row may aim at, the players on an object; KeyRef and its lookups) + animationPreview (the root at a frame, written into copies), graphLookup (what a graph sees of the project: behaviors to run, state machines to read), Scope (where a state machine's current state lives: per instance or one for the run — variables are shared by living on a Variables asset instead), collisionLayers (which colliders may meet: the project's named layers, a collider's layer and mask, and the one rule `layersMeet` the engine, Solids and the event pair search all answer by)
|
||||
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/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),
|
||||
|
||||
+21
@@ -104,6 +104,27 @@ from above:
|
||||
|
||||
Tiles can be one-way as well (see [Tilemaps](Tilemaps#one-way-tiles)).
|
||||
|
||||
## Collision layers
|
||||
|
||||
A project has up to 16 named **collision layers** (#152), edited under **Project → Collision
|
||||
layers…**; a new project has one, *Default*. Every collider and every tilemap names the layer it
|
||||
sits on (**Layer**) and the layers it collides with (**Collides with**, a tick per layer).
|
||||
|
||||
**Two things meet only when each one names the layer of the other.** The rule is symmetric, as in
|
||||
the physics engine itself, so there is no pair that collides only one way: giving the player's
|
||||
shots their own layer and leaving the player out of their *Collides with* is enough — the player
|
||||
does not have to be changed as well, but the shots have to name what they *should* hit.
|
||||
|
||||
- The default is layer 0 against every layer, which is what every collider written before there
|
||||
were layers reads as. Nothing collides differently until a layer is named.
|
||||
- One setting decides both: what does not collide reports no event either. To be notified without
|
||||
being blocked, use **Trigger (no blocking)**.
|
||||
- It filters everything alike — the engine in Play, `Move` with *Collide with solids*, and the
|
||||
collision events of the editor run.
|
||||
- A ray is not filtered by layers yet, that is #158.
|
||||
- Only the *last* layer can be removed in the dialog: a collider names its layer by number, so
|
||||
taking one out of the middle would move every collider below it onto another layer.
|
||||
|
||||
## Raycast
|
||||
|
||||
The **Raycast** node (#153) casts a ray from `from x/y` along `dir x/y` (any length, it is made a
|
||||
|
||||
+1
@@ -17,6 +17,7 @@
|
||||
| **Variables asset** | Declarations and nothing else — no graph, no position, never placed. A `Variables` node naming it reads and writes **one value per key for the whole run**, however many graphs point at it. The values start at the declared ones on every Play and are never written back, so playing cannot change the project; while a run is on the asset's inspector shows them live and an edit there reaches the run at once. Two such assets may declare the same name without meeting. See [Behaviors](Behaviors). |
|
||||
| **Run in editor** | A switch only behaviors have (default off). With it on the behavior keeps running while the project is **not** playing — and unlike Play it then edits the *saved* model: what it moves or writes is a real change, autosaved and not on the undo stack. See *Running without Play*. |
|
||||
| **Collider** | A shape (box or circle) for collision detection, placed as a **child** of the object it belongs to (its *body*). Drawn as a green outline in edit mode only. |
|
||||
| **Collision layer** | One of up to 16 named layers of the project (**Project → Collision layers…**). A collider or tilemap names the layer it is on and the layers it **collides with**; two of them meet only when each one names the layer of the other. A new project has one layer, *Default*, which every collider is on and meets — so nothing collides differently until a layer is named. See [Colliders](Colliders#collision-layers). |
|
||||
| **Rigidbody** | Placed as a **child** of an object, it hands that object to the physics engine while playing: it falls with the scene's gravity, bounces and rests on colliders, pushed by what it meets. At most one per object. See [Physics](Physics). |
|
||||
| **Override** | A per-object value that replaces the asset's value for one property. Only changed keys are stored; the inspector paints their label gold and offers a reset (↺) and an **apply** (↑) that writes the value into the asset instead. Both appear only where the value really differs from its base — an override carrying the asset's own value is none. |
|
||||
| **Default** | Every property has a schema default. Asset values that differ from it are marked gold in the inspector and can be reset (↺) the same way an override can. The asset's name in the **Assets** panel carries the same gold while any of them does (`assetDeviates`, `src/core/properties/deviation.ts` — the inspector marks the rows of that same schema, so the list cannot claim a deviation the inspector then fails to show). A behavior's variables are not in it: their default is declared on the variable itself, so the asset value cannot differ from it. |
|
||||
|
||||
+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
|
||||
./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)
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1129 editor checks, screenshots in /tmp/gm-e2e-*.png
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1138 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
|
||||
|
||||
+12
-2
@@ -120,6 +120,16 @@ body shot up from below comes out on top and lands, one sliding sideways goes th
|
||||
falling at 2000 units per second lands with and without CCD. Collision events come on passing
|
||||
through as well: overlapping is colliding.
|
||||
|
||||
## Collision layers in the engine
|
||||
|
||||
Rapier has the rule built in: every collider gets an **interaction group**, its layer in the high
|
||||
16 bits and its *Collides with* mask in the low ones, set as both the collision group (what is
|
||||
detected) and the solver group (what is pushed apart). The engine meets a pair when each side's
|
||||
membership passes the other's filter, which is exactly what
|
||||
[`layersMeet`](Colliders#collision-layers) says — so a pair that the layers keep apart is not
|
||||
reported either, and nothing extra has to be filtered afterwards. Changing a layer rebuilds the
|
||||
body's colliders, since the group sits on the collider itself.
|
||||
|
||||
## Moving bodies from a graph
|
||||
|
||||
| Node | What it does |
|
||||
@@ -157,5 +167,5 @@ 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).
|
||||
- Collision layers (#152) and joints (#154). Raycasts (#153) and one-way platforms (#155) are
|
||||
there, see [Colliders](Colliders#raycast).
|
||||
- Joints (#154), and a ray filtered by collision layers (#158). Raycasts (#153), one-way platforms
|
||||
(#155) and the collision layers themselves (#152) are there, see [Colliders](Colliders#raycast).
|
||||
+4
@@ -150,6 +150,10 @@ that blocks (#173): where two rectangles or the pieces of outlined cells meet, n
|
||||
so a wall of several rectangles or a lake of many pieces shows as one shape. Collision itself keeps
|
||||
the pieces.
|
||||
|
||||
A placed tilemap carries **Layer** and **Collides with** like a collider does, for the whole map
|
||||
(see [Colliders](Colliders#collision-layers)): ground only some things walk on is a map on its own
|
||||
layer. Per layer of the map or per tile it is not — a cell belongs to the map.
|
||||
|
||||
### Collision scale
|
||||
|
||||
A tile's **Collision scale** (1 by default, 0.1 to 2) makes its cells block less or more than
|
||||
|
||||
Reference in new issue
Block a user