NPC dialogue

Usage guide of npc.dialogue: dialogue documents, typed lines, up to four choices that run actions, the talk_to mission step, settings and defaults, the dialogue.lines service, events, hooks and the HUD variables.

Source: module-kits:kits/npc_dialogue/usage/en.mdView Markdown source

Also read offline — CLI: grip-forge docs npc-dialogueMCP tool: gripforge_docs { "topic": "npc-dialogue" }

Talking to NPCs (npc.dialogue) #

Make an NPC talk: the player interacts with it, its lines are typed on screen, and the player may pick between up to four choices that run actions or lead to another dialogue. The quest side (givers, talk_to steps) is described in the quests guide; the NPCs themselves in the NPC guide. Readable offline: gripforge docs npc-dialogue, or the MCP tool gripforge_docs (topic npc-dialogue).

What it is for #

npc.dialogue owns the conversation: which text to show for an NPC and a topic, how it is typed, when it moves on, what a choice does. It registers every NPC that has something to say with interaction.use ("Talk to <name>"), so the player starts a conversation with the interaction key. It shows nothing by itself beyond HUD variables and the presentation module (the speaker, the line typed so far and up to four choices); the look is the HUD's.

Turn it on #

gripforge_gamekit_install   { project_id: "gkp_…", id: "npc.dialogue" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "npc.dialogue",
                              config: { "charsPerSecond": 50, "pauseWorld": true } }

It requires npc.behavior, interaction.use, hud.bind and game.engine. An NPC is known by the id of its document in npcs (the npc.brain.npcId of npc.core, or a component dialogue.npc set to that id on a placed instance). The simplest content is the dialogue.lines of the NPC document:

{ "id": "elder", "name": "Elder", "dialogue": { "lines": { "greet": ["Hi.", "Bye."] } } }

First example #

<!-- test: kits/game_engine/host/tests/npc_dialogue.rs::a_choice_runs_its_actions_and_continues_to_the_next_dialogue --> A dialogues document with a choice that runs an action and continues with another dialogue:

{ "id": "d_offer", "npc": "elder", "topic": "offer", "speaker": "Old Elder", "lines": ["Help?"],
  "choices": [ { "id": "yes", "text": "Yes", "next": "d_thanks", "then": [ { "set_var": { "path": "helped", "value": true } } ] } ] }
{ "id": "d_thanks", "topic": "thanks", "lines": ["Thanks."] }

Calling dialogue.lines.say(npc, "offer") with the entity id of the NPC (or interacting) opens the conversation; the line is typed, the variable dialogue.choice.1 reads "Yes", key 1 picks it, the action runs, and d_thanks follows. A talk_to mission step on topic thanks completes when that dialogue ends.

Settings and defaults #

SettingTypeDefaultMeaning
charsPerSecondnumber, 5 to 20040typing speed of a line
autoAdvanceSecondsnumber, 0 to 304a fully typed line moves on by itself after this delay; 0 turns it off. The last line of a dialogue with choices always waits
pauseWorldbooleanfalsepause the game during the conversation (the dialogue clock keeps running)

All three are open to mods.

Content: the dialogues collection #

FieldMeaning
idrequired, unique; a choice next or say can name it
npcnpcs document that offers it as a topic; without it the dialogue is reached by id only
topicdefault greet
speakerdefault: the name of the NPC document
linesrequired, at least one string
choicesup to 4 of { id, text, next?, then? }; next is a dialogue id or a topic of the same NPC (absent: the dialogue ends); then is a list of trigger actions run when picked

A key (topic or dialogue id) resolves to the dialogues document with that id, then to a document of this NPC with that topic, then to dialogue.lines[key] of the NPC document. Texts go through i18n.text when that kit is installed, so a line can be a translation key.

Services, events, variables, hooks #

  • dialogue.lines (service): say(npc, topic?) opens a conversation, current() describes the running one, active(), advance(), choose(index | id), end(reason?), topics(npc).
  • start_dialogue (action): open a dialogue without an interaction (a cut-in), { npc?, dialogue? }. Ignored while another one runs. Mission step talk_to { npc?, topic? } completes when a dialogue of that NPC (and topic) ends by finished or choice.
  • dialogue.started, dialogue.choice, dialogue.ended (events): { npc, npcId, topic }, plus { choice, index } and { reason }. The reasons are finished, choice, cancelled, walked_away, despawned, or the one given to end().
  • dialogue.refused (event): a hook cancelled a start or a choice.
  • dialogue.active, dialogue.speaker, dialogue.text, dialogue.choices, dialogue.choice.1 to dialogue.choice.4 (variables): for the HUD; dialogue.text is the line typed so far.
  • dialogue.next, dialogue.choice_1 to dialogue.choice_4 (actions of the input map): next line (E, Enter, mouse button 2 by default) and choices (keys 1 to 4). dialogue.next finishes the typing of the line, then goes to the next one.
  • dialogue.start (hook): before a dialogue opens; topic is mutable; cancellable.
  • dialogue.choose (hook): before a choice is taken; choice is mutable; cancellable (the choices keep waiting).
  • dialogue.advance (hook): before a line is revealed or advanced, with origin auto, input or service; cancellable. A voice kit uses it to hold the automatic advance while a clip plays.

Hooks and modding #

A mod can change the three settings and replace or add dialogues documents; hooks let a game or a mod rewrite the topic, refuse a start, or swap a choice. The conversation is saved with the game and resumes on the same line.

Engines #

The conversation logic is the same Rust code on the web, natively and in the engine wrappers. The line, the speaker and the choices are HUD variables, drawn by the HUD of each engine.

When it does not do what you expect #

  • The NPC cannot be talked to: it has no document in npcs and no dialogue.npc component, or nothing to say (no dialogue and no dialogue.lines).
  • Nothing opens and dialogue.refused fires: a dialogue.start tap cancelled it.
  • A second dialogue does not start: one conversation runs at a time.
  • The conversation closes by itself: the player walked more than 6 metres away (walked_away), or the NPC was removed (despawned).
  • A choice list is cut: only the first four choices exist.
  • A line does not advance by itself: autoAdvanceSeconds is 0, or it is the last line and choices wait.

Limits #

No branching beyond four choices per dialogue, no conditions on choices (put them in the then actions or in separate dialogues), no voice (see the voice kit of the quests guide), no camera work.

Versions #

Kit 1.4.0; service dialogue.lines 1.1.0. 1.4.0 added the dialogue.advance hook.