Model part face in tabletop state

Replace the path->part-list store with a per-part map keyed by part id, so each placed part carries its path, stack index, and face. Derive each path's ordered children for stacking, and flip face-down parts in PartPlacement.
This commit is contained in:
2026-08-10 11:10:16 +08:00
parent 6502fdae4f
commit bc418b2c73
8 changed files with 170 additions and 69 deletions
+11 -4
View File
@@ -80,15 +80,22 @@ Source-of-truth game state per `bgm-tabletop.md` §2:
```ts
interface GameState {
surfaces: Record<string, boolean>; // enabled per surface id
paths: Record<string, string[]>; // path -> part list
parts: Record<string, PartState>; // part id -> placement state
}
interface PartState {
path: string; // the path key this part is on
index: number; // the part's position in its path's stack
face: boolean; // whether the part's face is up
}
```
- A zustand store holding `GameState`.
- **Derived render state**: `game state + surface routes => map of piece id to
`{ surface, route, candidate, index, stackSize }``, per enabled surface.
Computed with a selector/memo so the render list is stable.
- **Assumption**: each piece id is unique within a path (documented in
`{ surface, route, candidate, index, stackSize, face }``, per enabled surface.
Computed with a selector/memo so the render list is stable. A path's ordered
children (for stacking) are derived from the parts map by sorting on `index`.
- **Assumption**: each piece id is unique on the board (documented in
`bgm-tabletop.md`); the render map is keyed by piece id.
### 4. Setup seeding (`setup.ts`) ✅