diff --git a/Behaviors.md b/Behaviors.md index bfc83e0..6e43f1e 100644 --- a/Behaviors.md +++ b/Behaviors.md @@ -128,7 +128,9 @@ shown on the node and editable in the inspector. `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` + `Ignore one-way` (fall through one-way colliders and tiles for some seconds — see [Colliders](Colliders#one-way)), + `Set tile` with the data nodes `Tile at`, `World to cell`, `Cell to world` and the constant `Tile` + (read and change the cells of a placed tilemap while the game runs — see [Tilemaps](Tilemaps#from-a-behavior)). 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 (e.g. `Move.scale = 1`), shown on the node and in the inspector. diff --git a/Development.md b/Development.md index e25f367..94abdb2 100644 --- a/Development.md +++ b/Development.md @@ -14,7 +14,7 @@ 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 [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) -node tools/seed-e2e.mjs && node tools/e2e.mjs # 1351 editor checks, screenshots in /tmp/gm-e2e-*.png +node tools/seed-e2e.mjs && node tools/e2e.mjs # 1356 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/Tilemaps.md b/Tilemaps.md index 3939ae1..88d3e2a 100644 --- a/Tilemaps.md +++ b/Tilemaps.md @@ -146,6 +146,41 @@ tile is on the same step, so animated water does not run out of phase between tw Drawing is done with **one mesh per tile and layer** rather than one sprite per cell, so a map of a thousand cells costs as many draw calls as it has tiles on that layer. +## From a behavior + +A behavior reads and changes the cells of a placed map while the game runs (#135). Four nodes do +it, each taking the placed map as its `tilemap` input: + +- **`Tile at`** gives the tile in a cell (`tile`, empty for none) and `empty`. It reads the moment + it is asked, so a `Set tile` earlier in the same flow is already seen. A cell outside the grid or + on a layer the map does not have reads as empty. +- **`Set tile`** puts a tile into a cell, or empties it when no tile is given. `done` says whether + it could: not on something that is no tilemap, not on a missing layer, not outside the grid, and + not with an asset that is no tile. +- **`World to cell`** turns a world point into a cell, `inside` saying whether that cell is on the + grid. This is how a figure finds the cell it stands on. The map may be moved, turned, scaled and + mirrored. +- **`Cell to world`** gives the middle of a cell in world units, the way back. + +A **`Tile`** node hands out one tile as a constant: something for `Set tile` to put down, or to +compare what `Tile at` read with (`Equals`). + +Cells count in whole columns and rows, `0, 0` being the top-left corner, as in the panel. The +layer is picked **by name** from the layers of all tilemaps in the project, since the node does not +know which map it will be given. The index would move whenever the layers are reordered. *First +layer* means the first layer of whatever map arrives; two layers of one name are the upper one. + +What a behavior sets **belongs to that one placement and to the run**: + +- The run keeps its changes per placed map, laid over the asset's cells. A second placement of the + same map is left alone. +- The changed cell is drawn at once, the autotile edges of its neighbours follow, and its collision + is rebuilt: a `Move` later in the same frame already meets the new cell, and a falling body lands + on it. +- **Nothing is written back.** After Stop the map is the one that was painted. The editor run is no + exception: the scene view shows the changed cells while the run lasts and the painted ones again + once it ends, and the project never sees them. + ## Collision Whether a cell blocks is a property of the **tile**, not of the map or the layer: switch **Solid**