docs: record editor-first UI-scene convention (ADR 0001)
Capture the direction change from M3-b: UI screens are authored editor-first as .tscn node trees (previewable/arrangeable in the Godot editor), scripts do on-load work only — never build the tree in _ready(). Add ADR 0001, a "UI scene conventions" how-to in client/docs, a §16 mandate in the charter, and mark M3-a/M3-b done in the roadmap. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,49 @@ Put here:
|
||||
|
||||
Cross-cutting design (anything touching both client and api) goes in the root [`/docs`](../../docs), not here.
|
||||
|
||||
## UI scene conventions (shell + all screens)
|
||||
|
||||
Screens are **authored editor-first** — the layout lives in the `.tscn`, not in
|
||||
code. See ADR [0001](../../docs/adr/0001-editor-first-ui-scenes.md) for the why;
|
||||
this is the how. Reference: `scenes/shell/{MainWindowShell,SystemDock,NarrationBook}.tscn`
|
||||
+ `scripts/ui/shell/*.gd`.
|
||||
|
||||
- **The `.tscn` owns the tree.** Author every node in the editor: containers,
|
||||
panels, labels, buttons, art-slot placeholders. Assign the shared theme on the
|
||||
scene root (`theme = game_theme.tres`) and set each node's `theme_type_variation`
|
||||
(from `ThemeKeys`) in the editor, so the scene previews themed. Instance
|
||||
sub-screens (`PackedScene` ext_resource) rather than rebuilding them.
|
||||
- **The script does on-load work only.** `@onready var x := $Path/To/Node` refs,
|
||||
signal/service wiring, animations, and binding state into the authored nodes
|
||||
(label text, colours from `Palette`). Do **not** create nodes in `_ready()`.
|
||||
- **Data-driven repeats = fixed authored slots, bound at runtime.** Author enough
|
||||
turn-order tokens / consumable slots / etc. in the editor; the script fills the
|
||||
first N from state and hides the rest. Previewable now; systems write them later.
|
||||
- **Scene-root sizing.** Give the root a fixed size via offsets (e.g. 1920×1080)
|
||||
for editor preview, but **no full-rect anchors on the root** — a root Control run
|
||||
via F6 collapses to (0,0) under full-rect anchors. Keep `size = get_viewport_rect().size`
|
||||
on `_ready` + a `size_changed` connection (the M3-a collapse lesson).
|
||||
- **Button styling → Button-base variations only.** Never put a PanelContainer
|
||||
variation (`DarkPanel`, `ParchmentCard`) on a `Button`; it has no `normal/hover/
|
||||
pressed` styleboxes so the button renders unskinned. Use the Button-base
|
||||
variations (`PrimaryCTA`, `Tab`, `TabActive`, `Chip`, `DockButton`, `ParchmentButton`).
|
||||
- **`RichTextLabel` prose** reads its dark serif ink from the theme's base
|
||||
`RichTextLabel` style (it does *not* inherit `default_font`/`default_color`).
|
||||
Just add the `RichTextLabel` — don't override its colour per-node.
|
||||
- **Theme is generated.** All colours live in `palette.gd`; `game_theme.tres` is
|
||||
built by `scripts/theme/build_game_theme.gd` (source of truth). To add/adjust a
|
||||
variation, edit the builder + `theme_keys.gd`, then regenerate:
|
||||
`godot --headless -s res://scripts/theme/build_game_theme.gd`. Never hand-edit
|
||||
the `.tres` or put a hex literal in a script or `.tscn`.
|
||||
- **Wiring the DM loop / injectable services.** Follow the shell: a `service`
|
||||
var settable *between* `instantiate()` and `add_child()` lets tests inject a
|
||||
`FakeTransport`-backed `DmService` so on-load calls stay hermetic; `_ready`
|
||||
builds the real `HttpTransport`-backed one when none was injected.
|
||||
- **Visual gate.** Headless GUT proves structure (nodes mount, sizes non-zero,
|
||||
bindings run); it cannot prove rendering. Every screen needs a **human F6
|
||||
eyeball** before it's done. Note shader surfaces (`DarkBay`, vignette) render
|
||||
their texture only on an F6 run, not in the editor.
|
||||
|
||||
## Narrate live smoke (M2 client HTTP loop)
|
||||
|
||||
The `narrate_harness` scene is a throwaway proof of the client → `/dm/narrate`
|
||||
|
||||
Reference in New Issue
Block a user