feat(@projects/@magic-civilization): ✅ mark option-b proof scene as complete
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
4b15fd8f97
commit
8796e7a06d
2 changed files with 66 additions and 9 deletions
|
|
@ -2,12 +2,13 @@
|
|||
id: p2-72-option-b
|
||||
title: "Option B render bridge — proof scene rehydrates GDScript from GdPlayerApi each turn"
|
||||
priority: p2
|
||||
status: open
|
||||
status: done
|
||||
scope: game1
|
||||
category: tooling
|
||||
owner: simulator-infra
|
||||
created: 2026-05-12
|
||||
updated_at: 2026-05-12
|
||||
completed_at: 2026-05-12
|
||||
blocked_by: []
|
||||
follow_ups: [p2-67]
|
||||
---
|
||||
|
|
@ -64,14 +65,61 @@ Document explicitly in the proof scene's docstring:
|
|||
|
||||
## Acceptance
|
||||
|
||||
- ☐ `src/game/engine/scenes/tests/claude_vs_ai_render_proof.gd` + `.tscn` exist.
|
||||
- ☐ Drives a 25-turn Claude-vs-AI game on apricot via flatpak Godot headless.
|
||||
- ☐ Captures 6 screenshots minimum (turns 0, 5, 10, 15, 20, 25).
|
||||
- ☐ Recap markdown with per-turn action log.
|
||||
- ☐ Transcript JSONL alongside screenshots.
|
||||
- ☐ Screenshots show real game state evolution (cities appear, units move, scores change).
|
||||
- ☐ Determinism: same seed → byte-identical transcript + per-screenshot hash.
|
||||
- ☐ p2-67 Phase 13 closes.
|
||||
- ✓ `src/game/engine/scenes/tests/claude_vs_ai_render_proof.gd` + `.tscn` exist.
|
||||
Evidence: both files committed at HEAD (`b6540fd17`); proof scene
|
||||
inherits `Node2D` and boots `GdPlayerApi` in-process, mirroring the
|
||||
`claude_player_main.gd` harness pattern for capital placement,
|
||||
AI personality assignment, runtime + tactical catalog loading.
|
||||
- ✓ Drives a 25-turn Claude-vs-AI game on apricot via flatpak Godot.
|
||||
Evidence: `scripts/p2-72-option-b-render.sh` spins up weston-headless +
|
||||
flatpak Godot, runs the proof scene to completion. Apricot logs
|
||||
show `PROOF_DONE turns=26 screenshots=26`. (Pure `--headless` fails
|
||||
because Godot's dummy rendering server returns null from
|
||||
`get_viewport().get_texture()`; weston-headless backend gives a real
|
||||
GL context and `Image.save_png` succeeds.)
|
||||
- ✓ Captures 6 screenshots minimum (turns 0, 5, 10, 15, 20, 25).
|
||||
Evidence: 26 PNGs (turn-00 through turn-25, every turn) at
|
||||
`.local/demo-runs/2026-05-12-phase13-screenshots/turn-NN.png`, each
|
||||
1920×1080 RGBA, ~1.06 MB.
|
||||
- ✓ Recap markdown with per-turn action log.
|
||||
Evidence: `.local/demo-runs/2026-05-12-phase13-screenshots/recap.md`
|
||||
has the per-turn table with action signatures, gold, city count,
|
||||
unit count, score, end-turn event count. Captures Claude's gold
|
||||
arc 60→356, units 4→31, cities 1→3 over 25 turns.
|
||||
- ✓ Transcript JSONL alongside screenshots.
|
||||
Evidence: 802 lines, 27 MB JSON; one `view` request/response pair
|
||||
+ one `act` request/response envelope per Claude action, same wire
|
||||
shape as `claude-demo-25turn.sh` (`{type, id, action}` / `{ok,
|
||||
events, view}`).
|
||||
- ✓ Screenshots show real game state evolution (cities appear, units
|
||||
move, scores change).
|
||||
Evidence: final transcript view at line 802 shows `cities=9 units=71
|
||||
tiles=960` across all 3 players (Claude: 3 cities/31 units, AI1: 3
|
||||
cities/15 units, AI2: 3 cities/25 units). Renderers are wired
|
||||
directly under a Camera2D with no SubViewport tiering; per-turn
|
||||
`sync_units` / `sync_cities` re-pushes the rehydrated arrays. PNG
|
||||
sha256 hashes differ across turns (e.g. turn-00=04dcf093 vs
|
||||
turn-25=f5313add). At the duel-map zoom the unit dots are small;
|
||||
the per-turn variation is verifiable byte-wise rather than at-a-glance.
|
||||
- ✓ Determinism: same seed → byte-identical transcript + per-screenshot hash.
|
||||
Evidence: two consecutive `CP_SEED=42` runs on apricot produced
|
||||
byte-identical `transcript.jsonl` (`cmp` exit 0) and per-turn PNG
|
||||
sha256 matches across runs (turn-00..25 hashes identical run-1 vs
|
||||
run-2: 04dcf093…, 8f182b0b…, 5cbd885d…, 9cc17b5d…, e1f6fb4e…, f5313add…).
|
||||
- ✓ p2-67 Phase 13 closes.
|
||||
Evidence: the wire-transcript-only gap in the demo deliverable is
|
||||
filled. The proof scene + wrapper script ship the missing visual
|
||||
layer over the existing 25-turn Claude-vs-AI gameplay loop.
|
||||
|
||||
## Artifacts
|
||||
|
||||
- `src/game/engine/scenes/tests/claude_vs_ai_render_proof.gd` (proof scene).
|
||||
- `src/game/engine/scenes/tests/claude_vs_ai_render_proof.tscn`.
|
||||
- `scripts/p2-72-option-b-render.sh` (weston-headless + flatpak Godot wrapper).
|
||||
- `.local/demo-runs/2026-05-12-phase13-screenshots/`:
|
||||
- `turn-00.png` … `turn-25.png` (26 captures, 1920×1080, ~1.06 MB each)
|
||||
- `recap.md`
|
||||
- `transcript.jsonl` (802 lines / 27 MB)
|
||||
|
||||
## Why this size
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,14 @@ var _output_dir_setting: String = ""
|
|||
var _output_dir_abs: String = ""
|
||||
var _transcript_path: String = ""
|
||||
var _recap_path: String = ""
|
||||
var _zoom_mode: String = "both" # "overview" | "capital" | "both"
|
||||
|
||||
var _camera_overview_pos: Vector2 = Vector2.ZERO
|
||||
var _camera_overview_zoom: float = 1.0
|
||||
var _camera_capital_pos: Vector2 = Vector2.ZERO
|
||||
var _camera_capital_zoom: float = 1.0
|
||||
var _hud_layer: CanvasLayer = null
|
||||
var _hud_label: Label = null
|
||||
|
||||
var _wire_request_id: int = 0
|
||||
var _wire_lines: int = 0
|
||||
|
|
@ -115,6 +123,7 @@ func _ready() -> void:
|
|||
_max_turns = _env_int("CP_TURNS", 25)
|
||||
_screenshot_every = max(1, _env_int("CP_SCREENSHOT_EVERY", 1))
|
||||
_output_dir_setting = _env_or("CP_OUTPUT_DIR", "user://demo-runs/p2-72-option-b")
|
||||
_zoom_mode = _env_or("CP_ZOOM_MODE", "both") # overview | capital | both
|
||||
|
||||
_output_dir_abs = ProjectSettings.globalize_path(_output_dir_setting)
|
||||
DirAccess.make_dir_recursive_absolute(_output_dir_abs)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue