The broad phase of #184: Colliders says how far a move can reach - a rectangle around each collider of the mover, grown by the length of the move, and the rectangle around a ray - and that an obstacle outside it is never tested; Tilemaps gained the section "The cost of outlined cells" with the measured numbers and the advice to draw few corners, since an outlined cell is its own polygon per painted cell; Architecture names solids, cellsWithin and shapeBounds

admin committed 2026-09-20 19:25:59 +02:00
1 parent 77b6aa1646
commit 64a527a3bb
3 files changed
+32 -3

No files matched your search

+5 -3
@@ -68,8 +68,8 @@
```
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), 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/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 —, where one sits in the world, and which cells of a placed map a world rectangle can reach, in cells (`cellsWithin`, #184)), 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, and the rectangle around a shape a broad phase looks at first, #184), 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 (a travelling list may hold live objects, `storedList`
@@ -90,7 +90,9 @@ src/core/time.ts the global clock: one scaled step a frame, shared by the
src/runtime/ World, Entity, System interface, Input tracker, CollisionSystem (the editor run's detection),
solids (what `Move` collides with and how it slides — one-way solids let it through unless
it lands on them —, the first solid a ray meets, which body a collider belongs to, the
CollisionSource both collision systems give the behaviors, the contact of a staying pair), AnimationSystem, BehaviorSystem,
CollisionSource both collision systems give the behaviors, the contact of a staying pair,
and the broad phase of #184 — a move, a ray and the detection ask a body only for the
shapes inside the rectangle they can reach), AnimationSystem, BehaviorSystem,
Audio (the AudioSink a run plays into — the counterpart of Input on the way out)
src/runtime/physics/ engine (loads Rapier once, reports its state, converts between pixels and metres),
PhysicsSystem (Play's collisions: one engine body per rigidbody, free collider and tilemap,
+9
@@ -77,6 +77,15 @@ fast object cannot jump across a thin wall and end up on the other side. Collide
moving object and of anything parented under it travel with it and cannot
block it. `Move` without the setting and `Set position` ignore colliders entirely.
Before any of that is worked out exactly, the move is measured against a **rectangle around each
of its colliders, grown by the length of the whole move** (#184): what lies outside it cannot be
met, because sliding never lengthens what is left of a move, so the object never gets farther from
where it starts than the move is long. Only what that rectangle touches is turned into shapes and
tested; the same rectangle drops what sits on a layer the mover does not meet. A ray does the same
with the rectangle around itself. This changes no result — it decides nothing, it only leaves out
what could not have been reached — but it is what keeps a map of outlined cells from costing a
frame (see [Tilemaps](Tilemaps#the-cost-of-outlined-cells)).
## One-way
A collider with **One-way** on (#155) blocks only what comes from one side: **Blocks from** says
+18
@@ -218,6 +218,24 @@ In the running game the placed map is a **body of its own** in the collision sys
There are no trigger tiles yet: a tile blocks or it does not.
### The cost of outlined cells
Merged rectangles are few, outlined cells are many: every painted cell of an outlined tile is a
polygon of its own, and every one of those is cut into convex pieces that are tested against each
other piece by piece. A map of 20 × 20 outlined cells is 400 solids under one entity, where the
same map of plain solid tiles is a handful of rectangles.
That is why a move, a ray and the editor run's detection each ask the map only for **the cells of
the rectangle they can reach** (#184): the rectangle is taken back into the map's own units –
a turned map through its own axes – and turned into cell coordinates, so cells outside it are never
worked out in world units at all. Measured on a map of 20 × 20 outlined cells of 16 corners each,
one `Move` cost 148 ms before and 0.26 ms after; with 8 corners, 34 ms and 0.27 ms. Nothing about
the result changes — what is left out could not have been met.
A frame still costs what it touches: an object standing **inside** many outlined cells is tested
against each of them, so an outline of a hundred corners around every cell of a lake is dearer than
a few around its shore. Draw as few corners as the shape needs.
### One-way tiles
A solid tile with **One-way (from above)** on (#155) blocks only what comes down on it from above,