docs: reorganize docs into bgm and status folders

Group the bgm spec cluster under docs/bgm and move dev logs and plans under docs/status, add an overview index, and update cross-references in the docs, README, and source comments.
This commit is contained in:
2026-08-16 11:57:19 +08:00
parent cf8ca07850
commit 345832e389
19 changed files with 79 additions and 43 deletions
+2 -2
View File
@@ -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
@@ -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.
+5 -5
View File
@@ -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 {
@@ -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
+2 -2
View File
@@ -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
+25
View File
@@ -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 |
@@ -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).
@@ -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 18 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,
@@ -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