diff --git a/Architecture.md b/Architecture.md index 7f79c79..63d483f 100644 --- a/Architecture.md +++ b/Architecture.md @@ -80,6 +80,7 @@ src/core/graph/ graph model, NodeRegistry/NodeContext/values (a travellin 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), + savedValues (#166: the SaveArea a run reads persistent Variables assets from and writes them to, and restoring a save through today's declaration), stateMachine (the State node, a machine's states, the ports they become), variablePorts, propertyPorts, lookup (what a node may look up: behaviors, state machines), keyRepeat; nodes/{events,flow,data,action,variable}/.ts src/core/particles/ nodes (the catalogue), compile (a graph → one function per output), diff --git a/Behaviors.md b/Behaviors.md index 56dfbf1..1127f7e 100644 --- a/Behaviors.md +++ b/Behaviors.md @@ -207,6 +207,16 @@ shown on the node and editable in the inspector. next run starts from. Two Variables assets may declare the same name without meeting: the asset is the key, not the name. A coin counter is one such asset with `coins` in it; picking a coin up is one node, `coins` fed through `Add` back into itself. +- **Saved values (savegame)**: tick **Persistent** in a Variables asset's inspector and its values + outlive the run — a highscore, the levels unlocked, the player's settings. The next Play starts + where the last one ended instead of at the declared values. Nothing new is needed in the graph: + the same `Variables` nodes read and write them, and every change is saved as it happens, so a + closed tab loses nothing. The save lives in **this browser**, per project, and never in the + project file. Played and editor runs save apart, so trying a behavior with *Run in editor* does + not touch the player's save. To test a first start again, **Clear saved values** under the switch + forgets that asset, and **Menu → Clear saved data** forgets the whole project. A save is read + through the declaration as it is now: a variable deleted since is dropped, one added since starts + at its declared value, and a value whose kind changed is converted like any other value. - **Cross-object state** the other way: a behavior's own variables *are* the properties of its object, so another graph reads and writes them with `Object by name` → `Properties` of type *Behavior*. That reaches one named object, where a Variables asset belongs to no object at all. diff --git a/Concepts.md b/Concepts.md index 453ad06..ab1a38c 100644 --- a/Concepts.md +++ b/Concepts.md @@ -14,7 +14,7 @@ | **Container** | A reusable group ("prefab"): the asset holds a **template** of objects (asset link, local position, overrides, parent links) centred on its origin. Placing a container stores the container object **and nothing else** — its content is resolved from the template on every read, so a template edit reaches every instance at once. **Create container** turns the current selection into such an asset: the selected objects move into the template and the scene keeps one placed container at their centre (world positions unchanged). The template is edited in the **Container** tab (see [Containers](Containers)) or from an instance through **Apply to container**. | | **Selection** | One or more scene objects. Click selects, `Ctrl`/`Shift`-click adds/removes, dragging on empty scene space draws a rubber band (objects whose position lies inside are selected). Dragging a selected object moves the whole selection; `Delete` removes it; the inspector offers **Create container** and **Remove** for several objects. | | **Behavior** | Logic as an asset: a **node graph** plus the **variables** it declares. Placed like anything else (a diamond symbol in the scene); its parent is the **owner** the graph acts on. | -| **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). | +| **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. A **Persistent** one keeps its values past the end of the run, in this browser: the next Play starts where the last one ended — the savegame. 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*. | | **Run while paused** | The other switch only behaviors have (default off). While a graph has paused the game (`Pause game`), only behaviors with it on are ticked — the pause menu, which is also the only thing that can resume. See *The game pauses itself*. | | **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. | diff --git a/Development.md b/Development.md index e51391f..a19dd59 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 # 1272 editor checks, screenshots in /tmp/gm-e2e-*.png +node tools/seed-e2e.mjs && node tools/e2e.mjs # 1278 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