clone

a browser grid puzzle game where you push words around to rewrite the rules of each level

Clarify mechanic plan and lifecycle phase contract

Dami committed 850285a
commit
850285a30d9860373868a94977d9400474413af4
parent
17f4f9b719dbb291ec89409f66be561c4045cb0d
author
Dami <dami.etoile@gmail.com>
2 files changed, +22 -10
Mopenspec/changes/add-declarative-mechanic-state-contract/design.md26+++++++++++++++++++-------
Mopenspec/changes/add-declarative-mechanic-state-contract/specs/declarative-mechanic-state/spec.md6+++---
M openspec/changes/add-declarative-mechanic-state-contract/design.md +19 -7
@@ -35,7 +35,8 @@ that all of those boundaries can consume.
3535 3636 After mod normalization, a level may contain a `mechanics` array. Each entry3737 has a stable lowercase `id`, a host-supported `type`, a version, static38-configuration, and a deterministic state schema. Static configuration may38+configuration, and `state: 'derived'` or `state: 'stateful'`. The host adapter,39+not the mod, owns a stateful scalar schema and initial values. Static configuration may3940 identify authored object IDs or channels, but it cannot contain functions,4041 URLs, or values outside the host schema. The host assigns a unique order by4142 mechanic ID and validates all object references before creating a game.
@@ -70,19 +71,23 @@ an explicit empty state contract.
7071 The engine exposes a host-internal lifecycle with deterministic phases:7172 7273 1. `beforeMovement`: inspect the settled state and prepare blockers or intent.73-2. `afterMovement`: observe player and automaton movement before contacts.74-3. `afterTransforms`: observe the final noun/rule projection for the turn.74+2. `afterMovement`: observe player movement before the first rule refresh.75+3. `afterTransforms`: observe the final noun/rule projection after automata76+ movement and the second rule refresh and transform.7577 4. `beforeContacts`: apply mechanic effects that intentionally precede SINK or7678 DEFEAT contacts.7779 5. `afterContacts`: observe destruction and final occupancy.7880 6. `settled`: finalize state and event data.7981 80-The phase order is part of the engine contract. A concrete mechanic must state81-which hooks it uses and whether its state mutation is transactional. Hook82+The phase order is part of the engine contract. The existing player refresh and83+transform, automata advance, and final refresh and transform remain between84+`afterMovement` and `afterTransforms`; no hook sees a half-resolved state in85+that interval. A concrete mechanic must state which hooks it uses. Hook8286 implementations are registered host code selected by a validated type; mod8387 data cannot add a callback.8488 85-Rejected or complexity-blocked turns do not commit mechanic state. A mechanic89+All stateful hook mutation is transactional. Rejected or complexity-blocked90+turns do not commit mechanic state. A mechanic8691 must be deterministic from the authored definition, the prior settled state,8792 and the current phase inputs.8893
@@ -100,7 +105,8 @@ Concrete mechanic specs define their event vocabulary and ordering.
100105 101106 ### Make solver registration mandatory102107 103-The solver codec receives a normalized registry derived from the level. Each108+The solver codec receives the same compiled host-owned mechanic plan as the109+engine. Each104110 stateful registration has a stable mechanic ID, an ordered schema, and a codec105111 version. The registry must encode every dynamic field that can affect a future106112 turn. A derived registration instead identifies its authoritative projection
@@ -109,6 +115,12 @@ Unknown mechanic IDs, fields, types, missing values, or unregistered runtime
109115 state fail with actionable errors. Static authored metadata stays outside the110116 frontier blob.111117 118+The plan supplies explicit codec noun tokens used by a mechanic's static119+configuration. A leftover noun may not occur in the initial board or authored120+vocabulary, so the FRAIL adapter must add both map keys and values before121+codec token indices are assigned. Arbitrary mechanic strings are not assumed122+to be nouns.123+112124 The registry may use fixed authored slots and scalar fields already supported by113125 the codec. If a future mechanic needs arrays, maps, or more than the scalar114126 range, it must add an explicit deterministic codec representation rather than
M openspec/changes/add-declarative-mechanic-state-contract/specs/declarative-mechanic-state/spec.md +3 -3