feat(tabletop): add state, setup, mounting, and stacking
Implement the tabletop library's game state store, setup seeding with bare-type expansion, surface mount tree resolution, part placement, and the stacking positioning process with a dependency-free SVG path helper. Wire the public API and add unit plus vite integration tests.
This commit is contained in:
@@ -3,7 +3,8 @@
|
||||
> **Scope:** A standalone r3f component library that renders [bgm](./bgm-format.md)
|
||||
> board games: a state store, surface mounting, part placement with stacking,
|
||||
> and per-part meshes. Design: [`bgm-tabletop.md`](./bgm-tabletop.md).
|
||||
> **Status:** planning — no code yet.
|
||||
> **Status:** items 1–8 implemented; web part-inspection route renders `PartView`
|
||||
> from the library. Remaining: wiring the full tabletop scene into a web route.
|
||||
|
||||
## Goal
|
||||
|
||||
@@ -42,7 +43,7 @@ packages/tabletop/
|
||||
|
||||
## Work items
|
||||
|
||||
### 1. Package scaffold
|
||||
### 1. Package scaffold ✅
|
||||
|
||||
- New `packages/tabletop` workspace package (`pnpm-workspace.yaml` already
|
||||
globs `packages/*`).
|
||||
@@ -51,7 +52,7 @@ packages/tabletop/
|
||||
`@types/three`.
|
||||
- `tsconfig.json` mirroring `packages/bgm`'s (strict, ESM, `dist` output).
|
||||
|
||||
### 2. Part meshes + export + web integration
|
||||
### 2. Part meshes + export + web integration ✅
|
||||
|
||||
First deliverable: `PartView` renders a single part's mesh from its definition,
|
||||
reusing `@tts/mesh` geometry (not the web app's viewers). This is the smallest
|
||||
@@ -71,7 +72,7 @@ useful slice and unblocks the web app's part inspection route immediately.
|
||||
(`/bgm/:id/parts/:type/:part`) to render `PartView` from the library, proving
|
||||
it end-to-end.
|
||||
|
||||
### 3. State store (`state.ts`)
|
||||
### 3. State store (`state.ts`) ✅
|
||||
|
||||
Source-of-truth game state per `bgm-tabletop.md` §2:
|
||||
|
||||
@@ -89,7 +90,7 @@ interface GameState {
|
||||
- **Assumption**: each piece id is unique within a path (documented in
|
||||
`bgm-tabletop.md`); the render map is keyed by piece id.
|
||||
|
||||
### 4. Setup seeding (`setup.ts`)
|
||||
### 4. Setup seeding (`setup.ts`) ✅
|
||||
|
||||
- `SetupLoader`: side-effect-only component that seeds the store from a
|
||||
`Setup` — enables its `surfaces` (or all when omitted) and places parts on
|
||||
@@ -98,7 +99,7 @@ interface GameState {
|
||||
type (documented in `bgm-format.md` §3; the loader doesn't do this — it's a
|
||||
game-state init concern, so it lives here).
|
||||
|
||||
### 5. Surface mounting (`mount.ts`)
|
||||
### 5. Surface mounting (`mount.ts`) ✅
|
||||
|
||||
- Resolve the surface mount tree from `Surface.mount` + `Surface.children`:
|
||||
- `kind: table` — root, world space.
|
||||
@@ -108,13 +109,13 @@ interface GameState {
|
||||
surface isn't rendered. Child surfaces mount relative to their parent's
|
||||
anchor (`x`/`y`/`rotation`).
|
||||
|
||||
### 6. Part placement (`placement.ts`)
|
||||
### 6. Part placement (`placement.ts`) ✅
|
||||
|
||||
- `PartPlacement`: stable per-part component that positions a part on a surface
|
||||
location from the derived render state (route anchor + candidate anchor).
|
||||
- Applies the route's stacking strategy via `useStacking`.
|
||||
|
||||
### 7. Stacking (`stacking.ts`)
|
||||
### 7. Stacking (`stacking.ts`) ✅
|
||||
|
||||
- `useStacking(route.stacking, index, stackSize)` → `{ offset, rotation }`.
|
||||
- Implements the format's positioning process (`bgm-format.md` §4): step
|
||||
@@ -122,7 +123,7 @@ interface GameState {
|
||||
`center`), and `limit` (`0` all, `n` first n, `-n` last n).
|
||||
- Curve length from an SVG path string (small helper; no new dep).
|
||||
|
||||
### 8. Public API (`index.ts`)
|
||||
### 8. Public API (`index.ts`) ✅
|
||||
|
||||
Export `SetupLoader`, `WorldSurfaceView`, `HudSurfaceView`, `PartPlacement`,
|
||||
`PartView`, `useStacking`, and the store hooks. The web app consumes these; the
|
||||
|
||||
Reference in New Issue
Block a user