93 lines
4.4 KiB
Markdown
93 lines
4.4 KiB
Markdown
# IdleSpectator harness reference
|
|
|
|
## WorldBox wiki
|
|
|
|
Use https://the-official-worldbox-wiki.fandom.com/wiki/The_Official_Worldbox_Wiki when designing Spectator priorities or Chronicle events (Units lovers/friends, World History, kings, traits, war, disasters).
|
|
|
|
Chronicle records **life/world events**, not spectator watch notes.
|
|
Watch caption covers live focus context.
|
|
Vanilla tooltips (`Tooltip`, `TooltipLibrary`, `tooltips/tooltip_actor`) are candidates for future UI polish.
|
|
|
|
## Architecture
|
|
|
|
```text
|
|
scripts/harness-run.sh
|
|
-> starts WorldBox if needed
|
|
-> writes IdleSpectator/.harness/commands.jsonl
|
|
-> touches reset + auto-dismiss
|
|
-> regression: loops named scenarios sequentially
|
|
AgentHarness.Update() (in-game)
|
|
-> executes commands on Unity main thread
|
|
-> FreezeDirector unless director_run is active
|
|
-> writes results.jsonl + last-result.json
|
|
-> logs [HARNESS]/[ASSERT]/[SNAP]
|
|
```
|
|
|
|
## Why not OS input?
|
|
|
|
Wayland makes `xdotool`/`ydotool` unreliable.
|
|
Truth lives in engine state (`MoveCamera`, tips, settings), so drive the mod API directly.
|
|
|
|
## Timing
|
|
|
|
InterestDirector and SpeciesDiscovery use `Time.unscaledTime`.
|
|
WorldBox 5x game speed does not advance those clocks.
|
|
Use harness `fast_timing` + `director_run` / `age_current` for scheduling tests.
|
|
|
|
## Hard-won failure modes
|
|
|
|
| Symptom | Cause | Fix |
|
|
|---------|-------|-----|
|
|
| Welcome closes, idle never starts | commands.jsonl rewritten same length; offset at EOF | runner writes `offset=0` + `reset` |
|
|
| Steps run before world ready | `wait_world` requeued to back | `RequeueFront` |
|
|
| Tip says crab, focus is angle | watch fell back to nearest unit | require matching asset; use `pick_unit`/`asset=auto` |
|
|
| Spawn then "no unit for asset" | miracle spawns die on bad tiles | prefer `pick_unit` for critical paths |
|
|
| Flaky health/no_bad mid-scenario | ambient retarget while harness busy | `FreezeDirector` unless `director_run` |
|
|
| Steam hang after tests | `Application.Quit` | leave game running |
|
|
| Director tests take forever | production dwell/rotate | `fast_timing` (not game 5x) |
|
|
| Game never opens / `Cannot run as root user` | Shell sandboxed; Steam rejects root-like env | re-run launch/`harness-run.sh` with Shell `required_permissions: ["all"]` |
|
|
| Old mod still loaded after edit | NML caches until restart | kill `.../common/worldbox/worldbox`, bump `mod.json`, relaunch with `all` perms |
|
|
| Harness says ready but mod broken | Stale `Harmony patches applied` / missed `error CS` | runner fails boot on IdleSpectator `error CS`; ready requires Harmony in current (truncated) Player.log |
|
|
| Harness stuck on `o...` forever | Launch marker written into Player.log then wiped by Unity | do not put boot markers in Player.log; wait for process + Harmony |
|
|
|
|
## Useful asserts
|
|
|
|
- `health` - idle + focus + power bar hidden + `bad==0`
|
|
- `tip_matches_unit` - tip asset equals focus unit asset; if tip starts with `New species:`, label species must match
|
|
- `no_bad` - StateProbe bad counter is zero
|
|
- `enabled` / `show_watch_reasons` - mod settings
|
|
- `current_tier` / `would_accept_curiosity` - director scheduling
|
|
- `focus_same` - after `remember_focus` (ghost guard)
|
|
- `presented` / `pending_discovery` - species discovery buffer
|
|
- `caption_layout_ok` - dossier panel size/layout bounds (catches off-panel text)
|
|
- `screenshot` harness action writes `.harness/<name>.png` via Unity ScreenCapture
|
|
|
|
## Screenshots
|
|
|
|
Harness `screenshot` writes:
|
|
|
|
- `IdleSpectator/.harness/<name>.png` - full frame
|
|
- `IdleSpectator/.harness/<name>-dossier.png` - **exact dossier rect** (`ReadPixels`)
|
|
|
|
For HUD work:
|
|
|
|
1. Prefer reading `*-dossier.png` (wait ~1s after the run).
|
|
2. Validate with `./scripts/crop-dossier-hud.py --strict IdleSpectator/.harness/hud-*-dossier.png`
|
|
3. Do not judge layout from raw 2880p frames.
|
|
4. Player-pasted shots override harness crops.
|
|
|
|
## Extending scenarios
|
|
|
|
Edit `IdleSpectator/HarnessScenarios.cs`:
|
|
|
|
1. Add steps with `Step(id, action, ...)`.
|
|
2. Register name in `Build`.
|
|
3. Add the name to `REGRESSION_SCENARIOS` in `scripts/harness-run.sh` when it should gate merges.
|
|
4. Run `./scripts/harness-run.sh <name>` then `--repeat 3 critical_smoke` (and `regression` for suite-level changes).
|
|
|
|
Keep critical_smoke deterministic:
|
|
|
|
- `dismiss_windows` / `wait_world` first
|
|
- `pick_unit` before tip/focus asserts
|
|
- `reset_counters` after spectator+focus before health (StateProbe only; use `value=all` only at batch start)
|
|
- `simulate_input` last for manual-exit coverage
|