diff --git a/README.md b/README.md index a402f61..97315c0 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,9 @@ analyze their contents. A lightweight, client-only pnpm monorepo. | `packages/mesh` | 2D shapes + extrusion into 3D mesh geometry | Isomorphic | | `packages/shared` | Shared types + zod schemas | Isomorphic | -See [`docs/architecture.md`](docs/architecture.md) for the architecture and -[`docs/implementation-plan.md`](docs/implementation-plan.md) for the plan. +See [`docs/overview.md`](docs/overview.md) for the docs index, +[`docs/architecture.md`](docs/architecture.md) for the architecture, and +[`docs/status/implementation-plan.md`](docs/status/implementation-plan.md) for the plan. ## Setup diff --git a/apps/web/src/components/viewers/sharedResources.ts b/apps/web/src/components/viewers/sharedResources.ts index 5307288..7f22301 100644 --- a/apps/web/src/components/viewers/sharedResources.ts +++ b/apps/web/src/components/viewers/sharedResources.ts @@ -30,7 +30,7 @@ export function tintedColor(base: THREE.Color, tint: THREE.Color): THREE.Color { * the same image. * * These caches live for the session (like drei's global texture cache) and are - * not disposed on unmount; see `docs/full-setup-view.md`. + * not disposed on unmount; see `docs/status/full-setup-view.md`. */ const geometryCache = new Map(); diff --git a/docs/architecture.md b/docs/architecture.md index 750740a..7251a36 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -2,8 +2,8 @@ > **Scope:** The system's architecture and dependency graph. For implementation > details (files, endpoints, build order), see -> [`implementation-plan.md`](./implementation-plan.md). For the rationale behind -> key decisions, see [`decisions.md`](./decisions.md). +> [`status/implementation-plan.md`](./status/implementation-plan.md). For the +> rationale behind key decisions, see [`decisions.md`](./decisions.md). ## Overview diff --git a/docs/bgm-commands.md b/docs/bgm/commands.md similarity index 94% rename from docs/bgm-commands.md rename to docs/bgm/commands.md index a3f3ece..f6b4972 100644 --- a/docs/bgm-commands.md +++ b/docs/bgm/commands.md @@ -1,14 +1,14 @@ # bgm-commands -Command execution for [bgm](./bgm-format.md) board games, built into -[`@tts/tabletop`](./bgm-tabletop.md). A command is a unit of scripted +Command execution for [bgm](./format.md) board games, built into +[`@tts/tabletop`](./tabletop.md). A command is a unit of scripted interaction — focus the camera, wait for a tap, move a part, show a caption — that runs against the tabletop state store and render layer. This doc covers **command execution**: the async lifecycle, run contexts, and tap interaction. The message layer above this — how commands are *declared* and *fired* (triggers, orchestrators, the message queue) — is specified in -[`bgm-engine.md`](./bgm-engine.md). Commands are async functions registered +[`engine.md`](./engine.md). Commands are async functions registered with the engine's handler registry; `@tts/tabletop` provides the concrete commands that mutate the tabletop store and render layer. @@ -16,7 +16,7 @@ commands that mutate the tabletop store and render layer. A command is an async function that returns a result. Every command ends in one of three states, emitted as a message discriminated on the type suffix -(see `bgm-engine.md` §3): +(see `engine.md` §3): - `:done` — completed normally. - `:cancel` — interrupted (a newer command superseded it, the user skipped, @@ -124,7 +124,7 @@ cancel, so a cancelled `wait: tap` never leaks a handler. ## 5. run context The context a command receives is the handle to everything it can affect. The -engine defines the base `RunContext` (see `bgm-engine.md` §5): `signal` +engine defines the base `RunContext` (see `engine.md` §5): `signal` (cancellation), `emit`, `wait`, and `enableTrigger`/`disableTrigger`. Tabletop extends it with the handles commands need to mutate the board: @@ -142,12 +142,12 @@ interface TabletopRunContext extends RunContext { The tap detector reads trigger points from a runtime map keyed by part id; it does not care where they are declared. Declaration (on the part definition, in a setup, or in a script) is the deferred "how to declare" half and lives in -`bgm-format.md`. +`format.md`. ## Open decisions - **Where commands are declared** — the `script` role and its schema - (`bgm-format.md`), deferred. + (`format.md`), deferred. - **Animation** — a general "ease toward target placement" layer (preferred) vs explicit per-move tweens. - **Camera** — `CameraControls` (drei) vs hand-rolled. diff --git a/docs/bgm-engine.md b/docs/bgm/engine.md similarity index 96% rename from docs/bgm-engine.md rename to docs/bgm/engine.md index 8ba9102..ff5c024 100644 --- a/docs/bgm-engine.md +++ b/docs/bgm/engine.md @@ -1,7 +1,7 @@ # bgm-engine -The message layer that drives [bgm](./bgm-format.md) board games, built into -[`@tts/engine`](./architecture.md). It unifies the two halves of scripted +The message layer that drives [bgm](./format.md) board games, built into +[`@tts/engine`](../architecture.md). It unifies the two halves of scripted interaction — *declaring* what should happen and *executing* it — into a single reactive loop: **messages** flow through a **queue**, and **handlers** react to them. @@ -9,7 +9,7 @@ them. This doc covers the message model (what flows), the queue and its tick (how it flows), and the handlers (who reacts). Command *execution* — the async lifecycle, run contexts, and tap interaction — is specified in -[`bgm-commands.md`](./bgm-commands.md); this doc is the layer above it. +[`commands.md`](./commands.md); this doc is the layer above it. ## package split @@ -19,7 +19,7 @@ is node-testable in isolation (mirroring `@tts/extract`'s isomorphic, zero-dep style). It defines the contract — `Message`, the handler registry, `Trigger`, `Orchestrator`, and `RunContext`. -[`@tts/tabletop`](./bgm-tabletop.md) is one consumer of that contract: it +[`@tts/tabletop`](./tabletop.md) is one consumer of that contract: it registers the built-in commands (`move`, `focus`, `caption`, `enableSurface`, ...) that mutate the tabletop store and drive the render layer. The engine never imports tabletop; tabletop depends on the engine for the message types @@ -94,7 +94,7 @@ it cannot re-enter itself. ### interaction messages Interaction is the player's input, reported to the engine as messages. Only -tap interaction is supported (see `bgm-commands.md` §4). +tap interaction is supported (see `commands.md` §4). ```ts interface TapMessage { diff --git a/docs/bgm-format.md b/docs/bgm/format.md similarity index 100% rename from docs/bgm-format.md rename to docs/bgm/format.md diff --git a/docs/bgm-tabletop.md b/docs/bgm/tabletop.md similarity index 79% rename from docs/bgm-tabletop.md rename to docs/bgm/tabletop.md index 87d8002..dfff70d 100644 --- a/docs/bgm-tabletop.md +++ b/docs/bgm/tabletop.md @@ -1,6 +1,6 @@ # bgm-tabletop -a r3f based interactive component library to work with [bgm](./bgm-format.md) board games. will be used somewhere in the `web` app's bgm inspector routes. +a r3f based interactive component library to work with [bgm](./format.md) board games. will be used somewhere in the `web` app's bgm inspector routes. ## 1. stack @@ -47,14 +47,14 @@ the render map is per enabled surface: a piece may appear on more than one enabl ## 4. stacking -the format's stacking strategy (`curve` / `limit` / `align` / `steps` / `tilt` / `zStart` / `zEnd`, see `bgm-format.md` §4) is implemented as a hook, e.g. `useStacking(route.stacking, index, stackSize)`, returning the offset/rotation to apply to a piece: `{ x, y, rotation, z, tilt }`. `x`/`y`/`rotation` come from the `curve`; `z` is the surface-normal height ramped from `zStart` to `zEnd`; `tilt` is the rotation about the card's local Y (long) axis, applied to every part. `PartPlacement` consumes it. +the format's stacking strategy (`curve` / `limit` / `align` / `steps` / `tilt` / `zStart` / `zEnd`, see `format.md` §4) is implemented as a hook, e.g. `useStacking(route.stacking, index, stackSize)`, returning the offset/rotation to apply to a piece: `{ x, y, rotation, z, tilt }`. `x`/`y`/`rotation` come from the `curve`; `z` is the surface-normal height ramped from `zStart` to `zEnd`; `tilt` is the rotation about the card's local Y (long) axis, applied to every part. `PartPlacement` consumes it. ## 5. commands Scripted interaction — focus, tap-to-advance, move, caption — is built on an -async command layer. See [`bgm-commands.md`](./bgm-commands.md) for command +async command layer. See [`commands.md`](./commands.md) for command execution (lifecycle, run contexts, tap interaction), and -[`bgm-engine.md`](./bgm-engine.md) for the message layer above it (the queue, +[`engine.md`](./engine.md) for the message layer above it (the queue, triggers, and orchestrators that declare and fire commands). ## 6. usage diff --git a/docs/decisions.md b/docs/decisions.md index 0722373..47d2913 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -2,7 +2,7 @@ > **Scope:** The rationale behind key design decisions. For the system's > architecture, see [`architecture.md`](./architecture.md). For the concrete -> build plan, see [`implementation-plan.md`](./implementation-plan.md). +> build plan, see [`status/implementation-plan.md`](./status/implementation-plan.md). > > Each entry records the decision, the context, and the alternatives considered. > New entries are appended; existing entries are updated only to correct facts, @@ -275,7 +275,7 @@ group starts (e.g. a `camera` group so a second focus cancels the first). **Context:** The user wants to script interaction sequences — focus, caption, title, highlight, tap-to-advance, move, camera away. The state store and render layer already exist; what's missing is a way to drive them over time -and react to input. Design: [`bgm-commands.md`](./bgm-commands.md). +and react to input. Design: [`bgm/commands.md`](./bgm/commands.md). **Alternatives considered:** A single monolithic script interpreter. Rejected — commands as self-contained async units are testable in isolation and let diff --git a/docs/overview.md b/docs/overview.md new file mode 100644 index 0000000..f99907a --- /dev/null +++ b/docs/overview.md @@ -0,0 +1,25 @@ +# Docs + +The documentation is split into the living specs, which describe how the +system works today, and the status/plans, which track development iterations +and go stale as work lands. + +## Specs — how the system works + +| Doc | Covers | +| --- | --- | +| [`architecture.md`](./architecture.md) | System architecture and the package dependency graph | +| [`decisions.md`](./decisions.md) | Key design decisions and the rationale behind them | +| [`bgm/format.md`](./bgm/format.md) | The board game manifest (bgm) format spec | +| [`bgm/engine.md`](./bgm/engine.md) | The bgm message layer: queue, triggers, orchestrators | +| [`bgm/commands.md`](./bgm/commands.md) | bgm command execution: lifecycle, run contexts, tap interaction | +| [`bgm/tabletop.md`](./bgm/tabletop.md) | The r3f tabletop component library | + +## Status & plans (dev logs) + +| Doc | Covers | +| --- | --- | +| [`status/implementation-plan.md`](./status/implementation-plan.md) | Original build plan | +| [`status/bgm-loader.md`](./status/bgm-loader.md) | bgm loader — what's built, works, missing | +| [`status/bgm-tabletop.md`](./status/bgm-tabletop.md) | bgm tabletop — implementation plan / status | +| [`status/full-setup-view.md`](./status/full-setup-view.md) | Full-setup view plan | \ No newline at end of file diff --git a/docs/bgm-loader-status.md b/docs/status/bgm-loader.md similarity index 97% rename from docs/bgm-loader-status.md rename to docs/status/bgm-loader.md index dd2b86c..82a53df 100644 --- a/docs/bgm-loader-status.md +++ b/docs/status/bgm-loader.md @@ -1,7 +1,7 @@ # bgm Loader — Status > WIP. What's built, what works, what's missing, and the known issues. -> Spec: [`bgm-format.md`](./bgm-format.md). +> Spec: [`../bgm/format.md`](../bgm/format.md). ## What's built @@ -30,7 +30,7 @@ A real 52-card deck: a single `card` part expanded by `$variants` into 52 cards, ### `packages/tabletop` — rendering library (new) -A standalone r3f library that renders bgm parts. `PartView`/`PartMesh` build a mesh from a `Part` definition via `@tts/mesh` (size/fillet, face/back sprite UVs, traced `shape` or rect fallback). Proxy calls (`/asset`, `/trace`) default to `@tts/http` handlers and are overridable via `TabletopProvider`. Plan: [`bgm-tabletop-plan.md`](./bgm-tabletop-plan.md). +A standalone r3f library that renders bgm parts. `PartView`/`PartMesh` build a mesh from a `Part` definition via `@tts/mesh` (size/fillet, face/back sprite UVs, traced `shape` or rect fallback). Proxy calls (`/asset`, `/trace`) default to `@tts/http` handlers and are overridable via `TabletopProvider`. Plan: [`bgm-tabletop.md`](./bgm-tabletop.md). ### `packages/http` — shared proxy HTTP (new) @@ -71,5 +71,5 @@ The vite plugin itself lives in `packages/bgm/src/vite.ts` (exported from `@tts/ - **`$variants` URL paths** — spec mentions file/URL; URLs deferred. - **zod `SerializedPackage` shape for the emitted JSON** — the plugin emits `SerializedPackage` objects; a zod schema for the emitted module would give runtime validation beyond the ambient `declare module`. - **`setup` value expansion** — `type` without `id` → all parts of that type is documented but not implemented in the loader (it's a game-state init concern; noted as future). -- **Surface mounting is validated but not resolved** — `mount`/`children`/`surfaces` are parsed and validated, but the loader doesn't resolve child→parent relationships or enforce that a setup's `surfaces`/a surface's `children` reference existing surfaces. That's a game-state/rendering concern (see `docs/bgm-tabletop.md`). +- **Surface mounting is validated but not resolved** — `mount`/`children`/`surfaces` are parsed and validated, but the loader doesn't resolve child→parent relationships or enforce that a setup's `surfaces`/a surface's `children` reference existing surfaces. That's a game-state/rendering concern (see `../bgm/tabletop.md`). - Docs for the loader itself (this file is the start). diff --git a/docs/bgm-tabletop-plan.md b/docs/status/bgm-tabletop.md similarity index 92% rename from docs/bgm-tabletop-plan.md rename to docs/status/bgm-tabletop.md index 4b42f01..ec25aad 100644 --- a/docs/bgm-tabletop-plan.md +++ b/docs/status/bgm-tabletop.md @@ -1,8 +1,9 @@ # bgm-tabletop — Implementation Plan / Status -> **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). +> **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:** items 1–8 implemented and the full tabletop scene is wired into > the web app's setup detail route (`/bgm/:id/setups/:type/:setup`). The > part-inspection route renders `PartView` from the library. @@ -75,7 +76,7 @@ useful slice and unblocks the web app's part inspection route immediately. ### 3. State store (`state.ts`) ✅ -Source-of-truth game state per `bgm-tabletop.md` §2: +Source-of-truth game state per `../bgm/tabletop.md` §2: ```ts interface GameState { @@ -96,7 +97,7 @@ interface PartState { 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. + `../bgm/tabletop.md`); the render map is keyed by piece id. ### 4. Setup seeding (`setup.ts`) ✅ @@ -104,7 +105,7 @@ interface PartState { `Setup` — enables its `surfaces` (or all when omitted) and applies its ordered `setup` placements (each moves its `parts` to a `path`). - `setup` value expansion: a bare `type` (no id) expands to all parts of that - type (documented in `bgm-format.md` §3; the loader doesn't do this — it's a + 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`) ✅ @@ -126,7 +127,7 @@ interface PartState { ### 7. Stacking (`stacking.ts`) ✅ - `useStacking(route.stacking, index, stackSize)` → `{ x, y, rotation, z, tilt }`. -- Implements the format's positioning process (`bgm-format.md` §4): step +- Implements the format's positioning process (`../bgm/format.md` §4): step length from curve length / `max(steps, count-1)`, alignment (`start`/`end`/ `center`), and `limit` (`0` all, `n` first n, `-n` last n). - `z` ramps linearly from `zStart` to `zEnd` across the curve's span; `tilt` @@ -174,7 +175,7 @@ consumers share them (see Open decisions). ## Commands (not yet implemented) -Scripted interaction is designed in [`bgm-commands.md`](./bgm-commands.md): +Scripted interaction is designed in [`../bgm/commands.md`](../bgm/commands.md): async commands with `ok`/`cancel`/`error` results, per-invocation run contexts, fire-and-forget vs self-managed waiting, and tap interaction with part-local trigger points. Implementation order: types + run-context manager, diff --git a/docs/full-setup-view.md b/docs/status/full-setup-view.md similarity index 100% rename from docs/full-setup-view.md rename to docs/status/full-setup-view.md diff --git a/docs/implementation-plan.md b/docs/status/implementation-plan.md similarity index 97% rename from docs/implementation-plan.md rename to docs/status/implementation-plan.md index 0d8bb2b..46a687c 100644 --- a/docs/implementation-plan.md +++ b/docs/status/implementation-plan.md @@ -2,8 +2,8 @@ > **Scope:** The concrete build plan — files, endpoints, dependencies, build > order. For the system's architecture and dependency graph, see -> [`architecture.md`](./architecture.md). For the rationale behind key decisions, -> see [`decisions.md`](./decisions.md). +> [`../architecture.md`](../architecture.md). For the rationale behind key decisions, +> see [`../decisions.md`](../decisions.md). A lightweight, client-only pnpm monorepo for searching the Tabletop Simulator Steam Workshop, fetching full TTS save files, and analyzing their contents. @@ -55,7 +55,16 @@ tts-workshop/ ├── .npmrc ├── .env.example # STEAM_API_KEY, PORT ├── docs/ -│ └── implementation-plan.md # this file +│ ├── overview.md +│ ├── architecture.md +│ ├── decisions.md +│ ├── bgm/ +│ │ ├── format.md +│ │ ├── engine.md +│ │ ├── commands.md +│ │ └── tabletop.md +│ └── status/ +│ └── implementation-plan.md # this file ├── apps/ │ ├── proxy/ │ │ ├── package.json diff --git a/packages/bgm/src/collect.ts b/packages/bgm/src/collect.ts index cd2eeac..3d5ce42 100644 --- a/packages/bgm/src/collect.ts +++ b/packages/bgm/src/collect.ts @@ -11,7 +11,7 @@ * their `include` patterns, and assembles the package's parts, surfaces, * and setups. * - * See docs/bgm-format.md for the format's concrete behavior. + * See docs/bgm/format.md for the format's concrete behavior. */ import * as path from 'node:path'; import picomatch from 'picomatch'; diff --git a/packages/bgm/src/parse.ts b/packages/bgm/src/parse.ts index 29982ac..d158f4f 100644 --- a/packages/bgm/src/parse.ts +++ b/packages/bgm/src/parse.ts @@ -2,7 +2,7 @@ * Parse raw definition files (yaml/json/toml text) into JSON objects. * * A def file's document can be either a single JSON object (the root) or a - * list of objects; both are handled per docs/bgm-format.md §3. In list mode, + * list of objects; both are handled per docs/bgm/format.md §3. In list mode, * each object is a separate definition. */ import * as fs from 'node:fs'; diff --git a/packages/bgm/src/schemas.ts b/packages/bgm/src/schemas.ts index c6916cb..6a39924 100644 --- a/packages/bgm/src/schemas.ts +++ b/packages/bgm/src/schemas.ts @@ -3,7 +3,7 @@ * * These validate the raw definition objects (after `$variants` expansion) * and produce the typed `Part` / `Surface` / `Setup` / `PackageDef` values. - * See docs/bgm-format.md for the format's concrete behavior. + * See docs/bgm/format.md for the format's concrete behavior. */ import { z } from 'zod'; import type { PackageDef, Part, Setup, Surface } from './types.js'; diff --git a/packages/bgm/src/types.ts b/packages/bgm/src/types.ts index 6f7f97f..7925ad7 100644 --- a/packages/bgm/src/types.ts +++ b/packages/bgm/src/types.ts @@ -5,7 +5,7 @@ * discovered as JSON objects from yaml/json/toml files and from markdown * code blocks, then assembled into a `Package` (see `collect.ts` / `emit.ts`). * - * The concrete behavior of the format is described in `docs/bgm-format.md`. + * The concrete behavior of the format is described in `docs/bgm/format.md`. */ /** Part value types. */ diff --git a/packages/bgm/src/variants.ts b/packages/bgm/src/variants.ts index ded4495..203aac8 100644 --- a/packages/bgm/src/variants.ts +++ b/packages/bgm/src/variants.ts @@ -2,7 +2,7 @@ * The `$variants` directive: parse a CSV into a typed object array and * extend the original object with each row. * - * Per docs/bgm-format.md §1: + * Per docs/bgm/format.md §1: * - The CSV's first row is the header, the second row is the type declaration * (`string`, `number`, `string[]`, `[number;number;number;number]`, ...), * the remaining rows are data. diff --git a/packages/tabletop/src/stacking.ts b/packages/tabletop/src/stacking.ts index 910d4b5..c5f56a5 100644 --- a/packages/tabletop/src/stacking.ts +++ b/packages/tabletop/src/stacking.ts @@ -1,5 +1,5 @@ /** - * Stacking — the format's positioning process (`bgm-format.md` §4). + * Stacking — the format's positioning process (`docs/bgm/format.md` §4). * * Given a route's `stacking` strategy and a piece's position in its path's * stack, compute the offset/rotation to apply. Parts are spread along an SVG