Menu System β Full Specification
Status: ACTIVE (design reference) Agent: opencode/ext-agent (sandshrew) Timestamp UTC: 2026-05-12T00:10:00Z Claim: synthesis | 2026-05-12T00:05:00Z Session: Comprehensive menu tree β every layer from hex grid to raw output, mapped to LangGraph configs
Prior Context
- [[nested-menu-protocol]] β Initial menu tree sketch
- [[langgraph-node-config-catalog]] β 12 configurable node dimensions
- [[output-summary-protocol]] β Summary rendering + zoom-in
- [[langgraph-context-curation-pattern]] β Cross-node context routing
- [[langgraph-live-prompt-injection]] β Player corrections at nodes
- [[example-slice-walkthrough]] β 5-turn gameplay example
LEVEL 0: Hex Grid
__ __ __ __ __ __
__/00\__/01\__/02\__/03\__/04\__/05\__
/06\__/07\__/08\__/09\__/10\__/11\__/12\
\__/13\__/14\__/15\__/16\__/17\__/18\__/ β = unit sprite
/19\__/20\__/21\__/22\__/23\__/24\__/25\
\__/26\__/27\__/28\__/29\__/30\__/31\__/
/32\__/33\__/34\__/35\__/ \__/ \__/ \
\__/ \__/ \__/ \__/ \__/ \__/ \__/
ββββββββββββββββββββββββββββββββββββββββββββββββββ
UNITS: Rif(5) Echo(3) Sherpa(4) | [A] HEX [X] UNIT LIST [SELECT] PHASE MAP
ββββββββββββββββββββββββββββββββββββββββββββββββββ
Sidebar (top status line):
- Turn counters per unit: Rif(5) Echo(3) Sherpa(4)
- Active phase indicator: highlighted phase name
- Unit quick-select: X cycles through units, jumps cursor to their hex
Input: D-pad moves cursor across hexes. A selects current hex. X cycles unit focus. SELECT toggles phase color overlay.
State read: state["nodes"], state["units"], phase labels from state["nodes"][hex_id]["phase"]
LEVEL 1: Tile Menu
Opens when A is pressed on a hex. Shows what's on this tile.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HEX 14 β Design STATUS: ACTIVE β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β βΆ Rif β Designer β
β Model: deepseek-v4 / opencode Turn: 5 β
β Trail: 3 items | Access: 5 sources | History: 4 hexesβ
β β
β βΆ Node: Hex 14 β
β Phase: Design | Status: in_progress β
β Output: 4 sections | Edges: 6 reachable β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [X] Unit Menu [Y] Node Menu [A] Quick Move [B] Backβ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
If NO unit on this hex: Unit section shows "No unit present." Quick Move greyed out. If NO node on this hex (empty terrain): Node section shows terrain type only. Node Menu greyed out.
State read: state["nodes"]["14"], state["units"]["rif"] (if rif.position == "14")
LEVEL 2a: Unit Menu
Opened with X from Tile Menu. Shows everything about the unit.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β UNIT: Rif β Designer TURN: 5 β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β βΆ Status β Active at Hex 14, in_progress β
β βΆ Config β deepseek-v4 / opencode / [read,write]β
β βΆ Trail β 3 items from prior hexes β
β βΆ Access β 5 sources available, 1 blocked β
β βΆ History β 4 hexes visited, 3 outputs produced β
β βΆ Move β Select destination, configure β
β βΆ Interact β Live terminal (if unit is active) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [A] Select [B] Back β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Configs in play: Unit identity, agent config (#4), access lists (#5)
LEVEL 3a: Unit Status
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β STATUS: Rif β Hex 14 (Design) in_progress β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Current task: "Design sprite sheet layout" β
β Last action: Agent responded. 180 tokens. 1.4s. β
β Chain of thought: β
β "RG40XXV runs pygame 2.5.2. Hex tiles should be..." β
β Corrections pending: 1 ("128px too heavy β reconsider") β
β Node output: 4 sections (draft) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [Y] View Output [B] Back β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
State read: state["units"]["rif"], state["node_player_prompts"]["14"], state["nodes"]["14"]["output_summary"]
LEVEL 3b: Unit Config
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CONFIG: Rif β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Model: deepseek-v4 [Change] β
β Harness: opencode [Change] β
β Tools: [read] [write] [bash] [Edit] β
β Temperature: 0.7 [Adjust] β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [A] Select [B] Back β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Edits write to state["units"]["rif"]["config"] via Command(update=...).
Config in play: Agent config (#4)
LEVEL 3c: Trail Context
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β TRAIL: Rif β Accumulated Context β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Hex 01 (Planning) β Scope definition β
β β Hex 06 (Research) β Sprite format research (curated) β
β β Hex 08 (Research) β Tile dimension analysis β
β β Hex 12 (Define) β Requirements spec β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [A] Toggle [X] Select All [Y] Clear All [B] Back β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Toggle which trail items travel with the unit to the next hex. Unchecked items are left behind (explicit block at destination).
State read/write: state["units"]["rif"]["trail_context"]
LEVEL 3d: Access Lists
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ACCESS: Rif β Allowed Context β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ALLOWED: β
β βΆ node_01/output (Planning β scope) β
β βΆ node_06/output (Research β sprite formats) β
β βΆ wiki/langgraph-docs.md (LangGraph documentation) β
β βΆ routed/14/from_06 (Curated for Hex 14) β
β β
β BLOCKED: β
β βΆ node_12/output (Define β conflicting spec) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [A] Add [X] Remove [B] Back β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Config in play: Access lists (#5)
LEVEL 3e: Traversal History
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HISTORY: Rif β Traversal β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β T1: Hex 01 (Planning) β Scope definition β
β Output: wiki/planning/scope.md β
β T2: Hex 08 (Research) β Tile dimensions β
β Output: wiki/research/tile-dims.md β
β T3: Hex 06 (Research) β Sprite formats β
β Output: wiki/research/sprite-formats.md β
β T4: Hex 14 (Design) β Sprite layout (ACTIVE) β
β Output: (in progress) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [A] Jump to hex [Y] View output [B] Back β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
"A" jumps the cursor to that hex on the grid. "Y" opens that hex's output.
State read: state["units"]["rif"]["history"]
LEVEL 3f: Move Unit β LEVEL 4: Move Config
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MOVE: Rif β Hex 15 (Design) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β βΆ Config for this move: β
β Model: deepseek-v4 [Change] β
β Harness: opencode [Change] β
β β
β βΆ Context to bring: β
β β Hex 01 output (scope) β
β β Hex 06 output (sprite formats) β
β β Hex 08 output (tile dimensions) β
β β
β βΆ Context to block at destination: β
β (none selected) [Add block] β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [A] Confirm Move [B] Cancel β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Confirm β RG sends invoke({action: "move", unit: "rif", target: "15", move_config: {...}}). LangGraph activates hex 15's node function with the unit's config, trail, and blocks.
Configs in play: Agent config (#4), access lists (#5), node function (#2), edges (#8)
LEVEL 3g: Interactive Terminal
Available when unit is active (agent running or at interrupt). This is the "watch and talk" interface.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β TERMINAL: Rif @ Hex 14 (Design) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [Agent] Researching sprite sheet layout... β
β [Agent] Comparing pygame 2.5.2 capabilities... β
β [Agent] Recommendation: 128Γ128 px sprites. β
β β
β β interrupt: "Review output." [Accept] [Correct] β
β β
β > β β
β (type to send correction, redirect, or ask question) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [A] Send [B] Close terminal β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The terminal shows:
- Live runtime.stream_writer output as the agent works
- The chain of thought as it develops
- The interrupt prompt when the agent pauses
- A text input for the player to type corrections, questions, or redirects
What the player types is sent via Command(resume={"action": "correct", "prompt": "..."}) or added to node_player_prompts if the unit is between turns.
Configs in play: Interrupt (#9), streaming (#11), live prompt injection, node function (#2)
LEVEL 2b: Node Menu
Opened with Y from Tile Menu. Shows everything about the hex's node.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β NODE: Hex 14 β Design in_progress β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β βΆ Properties β Phase, status, output locale β
β βΆ Output β 4 sections (draft) β
β βΆ Edges β 6 reachable hexes β
β βΆ Config β Prompt template, model defaults β
β βΆ History β 3 units visited, 2 outputs produced β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [A] Select [B] Back β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Configs in play: Phase label (#3), status (#7), output locale (#6)
LEVEL 3h: Node Properties
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β PROPERTIES: Hex 14 β Design β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Phase: Design β
β Status: in_progress β
β Output at: wiki/design/sprite-layout.md β
β Created: 2026-05-11 β
β Last active: Turn 4 (Rif) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [B] Back β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
State read: state["nodes"]["14"]["phase"], state["nodes"]["14"]["status"], state["nodes"]["14"]["output_locale"]
LEVEL 3i: Output Summary β LEVEL 4a/4b
Shown when node is completed (has output to review).
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β OUTPUT β Hex 06 (Sherpa) STATUS: DONE β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Sprite Asset Research β
β β
β βΆ Recommendation [FINAL] β
β Use PNG 32Γ32 px, sprite sheets. β
β β
β βΆ Tile Dimensions [FINAL] β
β Flat-top hex, 100Γ87 px for 6Γ6 grid. β
β β
β βΆ Color Depth [FINAL] β
β RGBA for transparency. β
β β
β βΆ Performance [OPEN] β
β Sprite sheets vs individual files? β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [A] Zoom in [X] Route to... [Y] Full page [B] Backβ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
A on section β LEVEL 4a (Expanded):
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β βΆ Recommendation [FINAL] β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β PNG format at 32Γ32 pixels is optimal for RG40XXV. β
β Pygame 2.5.2 supports RGBA PNGs with alpha channel. β
β Sprite sheets reduce file I/O vs individual files. β
β 7 terrain tiles + 3 unit icons fit in one 256Γ256 sheet.β
β β
β Source: wiki/research/sprite-formats.md#recommendation β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [Y] Full page [B] Back to summary β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Y β LEVEL 4b (Full Output β cross-device):
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FULL OUTPUT β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β wiki/research/sprite-formats.md β
β β
β This page is too dense for the RG screen. β
β β
β Open on Mac? [A] Yes β
β Force render on RG? [X] Yes (will scroll) β
β Copy link to clipboard? [Y] Yes β
β β
β [B] Back β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
State read: state["nodes"]["06"]["output_summary"]. Config in play: Output locale (#6)
LEVEL 3j: Edges β LEVEL 4c: Routing Action
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β EDGES: Hex 14 β Reachable Hexes β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β βΆ Hex 07 (Research) [Route] β
β βΆ Hex 08 (Research) [Route] β completed β
β βΆ Hex 13 (Define) [Route] β
β βΆ Hex 15 (Design) [Route] β
β βΆ Hex 21 (Design) [Route] β
β βΆ Hex 22 (Develop) [Route] β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [A] Select target [B] Back β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
A on target β LEVEL 4c (Routing Action):
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ROUTE: Hex 14 (Design) β Hex 22 (Develop) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Source output: 4 sections, status: in_progress β
β Target prompt: "Develop implementation for: {task}" β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [A] Curate Context β
β Agent reads Hex 14 output, filters for Hex 22's β
β prompt thrust. Produces targeted subset. β
β β
β [X] Point Wholesale β
β Hex 22 gets full pointer to Hex 14 output. β
β No curation β target can pull anything. β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [A] Curate [X] Point [B] Cancel β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Curate β agent runs β writes to state["routed_context"]["22"]["from_14"] β adds to target's access list.
Configs in play: Edges (#8), output locale (#6), access lists (#5), curation node function
LEVEL 3k: Node Config
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CONFIG: Hex 14 β Design β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Prompt template: β
β "Design a solution for: {task}. Consider: {context}." β
β [Edit] β
β β
β Default model: deepseek-v4 [Change] β
β Default harness: opencode [Change] β
β β
β Player corrections (1): β
β β "128px too heavy β consult Sherpa's research" β
β [View] [Clear] β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [A] Select [B] Back β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
State read/write: state["nodes"]["14"]["config"], state["node_player_prompts"]["14"]
LEVEL 3l: Node History
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HISTORY: Hex 14 β Past Activity β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β T3: Rif (Designer) β "Design sprite layout" β
β Status: in_progress (correction pending) β
β β
β Prior: β
β (no previous units visited this hex) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [A] View unit [B] Back β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
State read: state["nodes"]["14"]["history"]
Full Menu Tree (Collapsed View)
HEX GRID [L0]
β
βββ A on hex β TILE MENU [L1]
β
βββ X β UNIT MENU [L2a]
β βββ Status [L3a] β View Output
β βββ Config [L3b] β Edit model/harness/tools
β βββ Trail [L3c] β Toggle items
β βββ Access [L3d] β Add/remove allowed/blocked
β βββ History [L3e] β Jump to hex / View output
β βββ Move [L3f] β select hex β MOVE CONFIG [L4] β Confirm β invoke()
β βββ Interact [L3g] β LIVE TERMINAL
β βββ Watch stream_writer output
β βββ See chain of thought
β βββ Type corrections β Command(resume)
β βββ Type redirects β node_player_prompts
β
βββ Y β NODE MENU [L2b]
β βββ Properties [L3h]
β βββ Output [L3i] (if completed)
β β βββ A on section β EXPANDED [L4a]
β β β βββ Y β FULL OUTPUT [L4b] (cross-device)
β β βββ X β Route to other node
β βββ Edges [L3j] β select target β ROUTING ACTION [L4c]
β β βββ Curate Context β agent runs β adds to access
β β βββ Point Wholesale β adds pointer
β βββ Config [L3k] β Edit prompt template, view corrections
β βββ History [L3l] β View past activity at this node
β
βββ A (Quick Move) β select hex β confirm move (no config)
LangGraph Config β Menu Level Mapping
| Config (#) | Config Name | Menu Levels |
|---|---|---|
| 1 | Node identity | L0 (hex labels), L1 (hex ID) |
| 2 | Node function | L3g (terminal β agent execution) |
| 3 | Phase label | L0 (color border), L1 (phase display) |
| 4 | Agent config | L3b (view/edit), L3f (move override) |
| 5 | Access lists | L3c (trail), L3d (allow/block), L4c (routing) |
| 6 | Output locale | L3i (output summary), L4a (expanded), L4b (full) |
| 7 | Node status | L1 (status badge), L3h (properties) |
| 8 | Edges | L3j (edge list), L4c (routing target) |
| 9 | Interrupt | L3g (terminal β interrupt prompt) |
| 10 | Recursion limit | (not surfaced in menus) |
| 11 | Streaming | L3g (terminal β live output) |
| 12 | Cache policy | (not surfaced in menus) |
Input Mapping
| Button | Context | Action |
|---|---|---|
| D-pad | Grid | Move cursor between hexes |
| D-pad | Menu | Navigate menu items |
| A | Grid | Open Tile Menu |
| A | Menu | Select / Confirm / Drill down |
| B | Any | Back one level |
| X | Grid | Cycle unit focus |
| X | Tile Menu | Open Unit Menu |
| Y | Tile Menu | Open Node Menu |
| Y | Output | Full page (cross-device) |
| SELECT | Grid | Toggle phase color overlay |
| START | Any | Pause menu (save, quit, settings) |
| L1/R1 | Grid | Previous/next unit |
| L2/R2 | Terminal | Page up/down through output |