feat(bgm): add surface mounting and setup surfaces

This commit is contained in:
2026-08-09 21:03:20 +08:00
parent 4e18ab5bc8
commit 599fb6a76d
8 changed files with 187 additions and 10 deletions
+56 -3
View File
@@ -193,11 +193,29 @@ tables. It does not affect part placement; placement lives in the state store
(see §4). A surface need not cover every part — parts with no matching route on
this surface are simply not shown.
A surface also declares how it is **mounted**: as the root table surface, on a
HUD area, or as a child of another surface. `mount` is always an object, with
`x`, `y`, and `rotation` (defaulting to `0`) anchoring it like a route. The
`kind` selects the mount type:
- `table` — the root table surface (default).
- `hud` — mounted to a HUD area, e.g. a player's hand.
- `child` — mounted relative to a parent surface. A surface lists its
`children` (`type#id` refs) so a surface can be repeated, like a player
board; each child is mounted relative to its parent's anchor.
```yaml
type: board
id: harbor
role: surface
size: [300, 200]
mount:
kind: table
x: 0
y: 0
rotation: 0
children:
- board#player
layout:
- route: /dock/:seat
candidates:
@@ -208,19 +226,49 @@ layout:
rotation: 0
```
```yaml
type: hud
id: hand
role: surface
size: [200, 100]
mount:
kind: hud
area: bottom-left
```
```yaml
type: board
id: player
role: surface
size: [200, 200]
mount:
kind: child
x: 100
y: 50
rotation: 0
```
### setup
`setup` seeds the state store. Each valid game state is a valid setup.
`setup` seeds the state store: the enabled surfaces and the part placement.
Each valid game state is a valid setup.
```yaml
role: setup
type: game
id: main
surfaces:
- board#harbor
- hud#hand
setup:
/dock/0: harbor:boat#fleet
/deck: harbor:card
```
`surfaces` lists the surfaces enabled at the start. A surface not listed is
disabled and not rendered. When `surfaces` is omitted, all surfaces are
enabled.
The value on a setup path can be either a string, or a string list.
The string can either be a one part string, or a type without an id.
@@ -233,13 +281,18 @@ When id is omitted, it expands to all parts in that type during game state initi
### Game state
The board's state is a **state store**: a map from path to a **stack** of
parts. It is the authoritative record of where every part is placed.
The board's state is a **state store**: the set of **enabled surfaces** and a
map from path to a **stack** of parts. It is the authoritative record of which
surfaces are in play and where every part is placed.
A path is a URL path with named params, like `/dock/1`.
A part is identified by a `package:type#id` string.
A surface is enabled or disabled; a disabled surface is not rendered. Setup
seeds the enabled set (see §3), and it changes at runtime as the game
progresses (e.g. enabling the main board after an expansion-chooser scene).
### Routing
A route is a **visualization route**: it maps a part to a location on a