The KRILL_DEMO_CONTROL file-channel hook understood select / view /
center / fit / reset / screen:swarm / screen:canvas / scroll:fleet
— all navigation and selection. There was no way to make the client avatar
open its speech bubble with narration text, so demo context that couldn’t be
shown on the canvas (why a node won, what a phase label means) had to be
added by hand in post-production voice-over.
Not a bug — a missing capability. The underlying plumbing already existed:
ScreenCore.announceDialog(text: String) sets the backing _demoDialog
state, avatareSpeechBubbleContent exposes it, and ClientScreen already
renders it as a speech bubble whenever no menu is open (production already
uses this path for the “servers unreachable” notice). DemoControl’s command
vocabulary in composeApp/src/desktopMain/kotlin/krill/zone/main.kt simply
never routed a command to it.
say:<text> to the DemoControl poller’s when block, calling the
existing screenCore.announceDialog(cmd.removePrefix("say:")).say: with no text clears the bubble (announceDialog("")), mirroring how
reset already dismisses it.announceDialog_setsAvatarSpeechBubbleContent and
announceDialog_emptyString_clearsSpeechBubble to ScreenCoreTest.kt
covering the setter behaviour the new command relies on.When a ScreenCore capability is added for one caller (production UI, a
menu action) but is generically useful for demo/automation, wire it into the
DemoControl vocabulary in the same PR rather than leaving it as a gap that
has to be discovered and filed separately later.