Skip to content

Style the in-game terminal panel like OpenRA's native chat UI#13

Merged
amphetamarina merged 2 commits into
mainfrom
AMP-231-style-terminal-panel-chat-ui
Jun 1, 2026
Merged

Style the in-game terminal panel like OpenRA's native chat UI#13
amphetamarina merged 2 commits into
mainfrom
AMP-231-style-terminal-panel-chat-ui

Conversation

@amphetamarina
Copy link
Copy Markdown
Owner

Summary

Reframes the in-game terminal panel (ClankerTerminalWidget) to read as a native
OpenRA interface element, modelled on the engine's in-game chat panel, instead of a
bare dark overlay. Closes AMP-231.

The panel now has:

  • a framed dialog background wrapping the live terminal grid;
  • a mode toggle that cycles which terminal the panel mirrors: t1 → … → tN → All;
  • a composer row — type a line, press Enter, and it is sent to the bound agent via
    the existing /agent/ask endpoint; in All mode it broadcasts to every terminal
    (the grid shows an "All terminals — input broadcasts to N agents" placeholder);
  • a close (X) button using the engine chat's lobby-bits/kick glyph, which
    dismisses the panel and clears the selection.

Approach

The engine's chat logic (IngameChatLogic) is not reusable — it is bound to the
network order system and its message log is a TextNotificationsDisplay (a scrolling
list 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 / Background skins).

The panel's "bound terminal" is centralised in ClankerBridge, reusing the existing
streamed-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/ask route.

Changes

  • ClankerBridge.cs — panel-binding API: BoundTerminal + AllTerminals sentinel,
    TerminalIds, SetBoundTerminal / CycleBoundTerminal, SendComposed.
  • ClankerTerminalLogic.cs (new) — wires the mode/composer/close controls and
    reconciles map selection with the binding; toggles panel visibility.
  • ClankerTerminalWidget.cs — renders from the bound terminal, paints the All-view
    placeholder, 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.
  • Manual: confirmed working in-game (native chrome renders, toggle cycles
    t1 → … → All, composer sends to the agent, X dismisses the panel).

🤖 Generated with Claude Code

amphetamarina and others added 2 commits May 31, 2026 22:36
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>
@amphetamarina amphetamarina merged commit e9f7e8d into main Jun 1, 2026
2 checks passed
@amphetamarina amphetamarina deleted the AMP-231-style-terminal-panel-chat-ui branch June 1, 2026 10:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant