Style the in-game terminal panel like OpenRA's native chat UI#13
Merged
Conversation
Introduce a single source of truth for what the terminal panel targets, reusing the existing streamed-terminal machinery so the upcoming native chrome can cycle terminals and send composed input. - BoundTerminal + an AllTerminals sentinel: a concrete id streams that terminal's grid; All (or null) stops the grid stream. - TerminalIds: a stable, natural-sorted snapshot of the live ids to cycle. - SetBoundTerminal / CycleBoundTerminal: point the panel at an id or the All view, wrapping around the live terminals. - SendComposed: send a typed line to the bound agent(s) via the existing /agent/ask endpoint, broadcasting to every terminal in All mode. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reframe the terminal panel to read as a native OpenRA interface element, modelled on the engine's in-game chat panel: a framed dialog background, a mode toggle button, a composer text row, and a close (X) button in the engine's chrome style. The engine's chat logic is not reusable (it is bound to the network order system and a TextNotificationsDisplay), and a live PTY grid cannot live in a notifications list, so the custom grid widget is kept for content and wrapped in the chat chrome instead. - clanker-terminal.yaml: a Container hosting a Background dialog panel with the grid inset above a bottom row of TERM_MODE / TERM_COMPOSER / TERM_CLOSE (the close uses the lobby-bits kick glyph, as the chat does). - ClankerTerminalLogic: wires the mode button (cycles t1 -> ... -> All via the bridge), the composer (sends a line on Enter), and close (dismisses the panel and clears the selection). Its Tick reconciles map selection with the binding and toggles panel visibility; the outer container stays visible so the logic keeps ticking. - ClankerTerminalWidget: renders from the bound terminal, paints an All-view placeholder, and no longer resolves the selection itself. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reframes the in-game terminal panel (
ClankerTerminalWidget) to read as a nativeOpenRA interface element, modelled on the engine's in-game chat panel, instead of a
bare dark overlay. Closes AMP-231.
The panel now has:
dialogbackground wrapping the live terminal grid;t1 → … → tN → All;the existing
/agent/askendpoint; in All mode it broadcasts to every terminal(the grid shows an "All terminals — input broadcasts to N agents" placeholder);
lobby-bits/kickglyph, whichdismisses the panel and clears the selection.
Approach
The engine's chat logic (
IngameChatLogic) is not reusable — it is bound to thenetwork order system and its message log is a
TextNotificationsDisplay(a scrollinglist of discrete lines), which a live PTY screen grid cannot use. So the custom grid
widget is kept for content and wrapped in the chat chrome (engine
Button/TextField/Backgroundskins).The panel's "bound terminal" is centralised in
ClankerBridge, reusing the existingstreamed-terminal machinery, so the toggle, composer, and grid stay in sync. Direct
keystroke typing into the grid is preserved alongside the composer, so live TUI
control (Ctrl-C, arrows) is not lost. No backend,
shared/, or wire-type changes —cycling and composing reuse existing data and the existing
/agent/askroute.Changes
ClankerBridge.cs— panel-binding API:BoundTerminal+AllTerminalssentinel,TerminalIds,SetBoundTerminal/CycleBoundTerminal,SendComposed.ClankerTerminalLogic.cs(new) — wires the mode/composer/close controls andreconciles map selection with the binding; toggles panel visibility.
ClankerTerminalWidget.cs— renders from the bound terminal, paints the All-viewplaceholder, no longer resolves the selection itself.
clanker-terminal.yaml— native chrome layout (Background dialog + grid + bottom row).Verification
cd command-and-clanker && make— mod builds, 0 errors.bun test— 123 pass, 0 fail.bun run typecheck— clean../utility.sh --check-yaml— passes.t1 → … → All, composer sends to the agent, X dismisses the panel).🤖 Generated with Claude Code