Recipes
NPC dialog conversations and press-to-talk prompts
The player walks up to a villager and a speech box appears, or presses a key to open a shopkeeper's menu, or picks a reply that branches the conversation. There is no
InteractableComponent or dialog component (stripped); dialog is a trigger, a UI panel, and branching state.engine v1.0.234since script-semantic-patch-ops.v1, action-catalog.v1.0.232, ui.v1, persistence.v1, rendering.v1Copy for LLM
Use this for
talking to an NPC and showing a dialog box; a press-to-talk prompt near a character; branching conversation choices; a quest giver or shopkeeper that shows text; a floating interact label
Not for
physical doors and levers (see doors-buttons-and-interactions); the pickup or inventory itself (see inventory-and-item-pickups); AI-generated dialogue text (no LLM host op, see capability-ceiling)
Pairs with: Doors buttons levers and press-to-interact, UI HUD panels widgets and world nameplates, Inventory item pickups keys and equipping, Input mapping actions bindings keyboard mouse gamepad touch
The recipe
Author the panel with project_create_ui_panel and the logic with project_apply_script_semantic_patch using the ai_safe op pack.
- Show it is talkable: a floating
TextRenderableComponentprompt over the NPC (textSource:"static",text:"Talk [E]"), toggled on while the player is in range. - Detect intent: give the NPC a trigger
ColliderComponent(collision:"trigger") andaddTriggerHandlerfor proximity, or declare aninteractaction (see doors-buttons-and-interactions) andaddActionHandler{ "actionKey":"interact" }for a press-to-talk. - Open the dialog: in a GessaScript body (
replaceScriptFromGessaScript) callctx.ui.openPanelon a dialog panel andctx.ui.setWidgetValueto fill the speaker name and the current line. - Branch on choices: store the conversation node in durable state with
writeTypedStateValue(adialogNodefield); when the player picks a reply, advance the node andsetBooleanStateany flags (met, quest accepted). Read back withreadTypedStateValueto gate later branches. - Close and react:
ctx.ui.closePanelwhen the talk ends, andemitCustomEventaquest.acceptedorshop.openevent other systems (inventory, match) act on.
Pitfalls
- Dialogue TEXT is authored content you write into the panel; there is no LLM or text-generation host op to write lines at runtime (see capability-ceiling).
- Keep the conversation node in durable state, not a local variable, so a reload or a second interaction resumes the right branch.
- Gate the open on proximity; an
interactaction fires everywhere, so confirm the player is near this NPC before opening its panel (the door-handler lesson). - The prompt label is presentation only; the actual talk is the panel plus the handler, not the
TextRenderableComponent.
Verify
simulation_run(qa.run.start) to prove approaching or pressing interact opens the dialog and a choice advances the branch.project_get_graph_snapshotto confirm the trigger or interact handler and the dialog panel exist.