quest'n'click 4.5.0 · r1

Built for quest'n'click 4.5.0, revision r1. Whether it is published, and which one is current, is recorded at publication.json.

Dialogues

Français · Type: tutorial + reference · Audience: author · Context: engine repository, created project · Status: ready · Applies from: 4.3.0

How to write a conversation with a character: talk topics that appear and change, choices, the menu's "Bye", and what makes lines read well on a phone. The first part builds one conversation step by step; the second lists the fields.

What you will build

Grandma, in the kitchen, with four topics: one that advances the plot, a running gag that changes each time, one that appears only once the tank is drained, and a guess the player picks from two answers. Talking to her opens the topic menu; "Bye" closes it.

What you need

Steps

  1. Topics. In the room, talk lists the topics per actor: each has a stable id, the line the hero says (topic) and what follows (do). Talking to the actor opens the menu; picking a topic makes the hero say it, then runs do, and the menu comes back until the player picks "Bye".
  1. A gag that changes. Wrap the answer in nth (or cycle, random): a different answer each time, the last one repeating (commands: logic).
  1. A topic that appears. Give it an if: it shows only while the condition holds. Grandpa's "There was no key in the tank!" shows only once tank_drained is set.
  1. A choice. In do, { choice: [...] } offers the player lines to pick; the hero says the picked one, then its do runs. once: true on an option shows it once.
  1. Check it. npm run validate (in a created project, npx quest-n-click validate), then talk to her on the dev server.

The whole room, checked by the validator:

{
  "room": {
    "id": "kitchen",
    "name": "The kitchen",
    "decor": "decor/kitchen",
    "actors": { "grandma": { "char": "grandma", "facing": "left" } },
    "look": { "grandma": "Grandma, stirring a pot." },
    "talk": {
      "grandma": [
        { "id": "ask.key", "topic": "Where is the key?",
          "do": [{ "say": ["grandma", "Somewhere safe. Somewhere wet."] }, { "set": "key_hint" }] },
        { "id": "ask.dinner", "topic": "What's for dinner?",
          "do": [{ "nth": [
            [{ "say": ["grandma", "Soup."] }],
            [{ "say": ["grandma", "Still soup."] }],
            [{ "say": ["grandma", "Soup. It is always soup."] }]
          ], "id": "dinner.count" }] },
        { "id": "ask.tank", "topic": "There was no key in the tank!", "if": "tank_drained",
          "do": [{ "say": ["grandma", "Then try the pantry, dear."] }] },
        { "id": "ask.guess", "topic": "Guess who stole the key?",
          "do": [{ "choice": [
            { "id": "guess.cat", "text": "The cat.", "do": [{ "set": ["guess", "cat"] }, { "say": ["grandma", "Biscuit? Never."] }] },
            { "id": "guess.grandpa", "text": "Grandpa.", "once": true, "do": [{ "set": ["guess", "grandpa"] }, { "say": ["grandma", "Hm. Maybe."] }] }
          ] }] }
      ]
    },
    "hints": [{ "id": "kitchen.hint", "until": "key_hint", "lines": ["Ask Grandma about the key."] }]
  },
  "layout": {
    "walk": { "area": [[20, 300], [620, 300], [630, 395], [10, 395]] },
    "entries": { "default": [320, 360] },
    "actors": { "grandma": { "x": 420, "y": 350 } }
  },
  "characters": {
    "grandma": { "name": "Grandma", "color": "#ff9ec4", "kind": ["person"], "sprites": { "idle": ["grandma/idle"] },
      "hug": "Always.", "refuse": "Keep it, dear." }
  }
}

Talk topics

FieldWhat
idStable id, required in schema 3: the save remembers a heard topic under topic.<id>.
topicThe line the hero says when it is picked (and the menu's label).
ifThe topic shows only while this holds.
doWhat follows.

A topic already heard stays in the menu, marked as seen. A conversation is one action: it is saved once whole at "Bye" (since 4.3.0 each finished topic is saved as soon as it ends, when the conversation is the rest of the action). { seen: 'topic.ask.key' } tests that a topic was heard (conditions).

"Bye" and the hug

globalTalk in game.ts sets what every menu adds: bye (the last entry, "…" when absent), byeLine (what the hero says on leaving, nothing when absent), hug (an extra entry, only when set). Picking the hug makes the hero say it and the character answer with their hug line (♥ when absent). Give each character a hug line and a refuse line: cheap, and players love them.

Choices

{ choice: [{ id, text, do, if?, once?, img? }, …] } works anywhere a command does, in a topic or in a cutscene. Only the options whose if holds are offered; a once option disappears once picked (remembered as choice.<id>); with no option left, nothing is shown. img (a manifest id, a portrait for instance) shows the option as a card with the image and its text as the label (the screen reader's name too); cards come first. The solver tries every option.

Starting a conversation from a script

{ talk: 'grandma' } opens an actor's menu from a rule or a cutscene. A character speaks to the hero without a menu with { say: [...] }; a call is { phone: 'grandma', do: [...] } (commands). A character with no topics answers Talk with the talk fallback (reactions).

Writing good dialogue

More on dialogue in the design of a whole game: puzzle design.

What you learned

Where to go next


Edit the source of this page · Report an error