Narrat 3.3.8 release - Choice tracking, quests with multiple endings, tooltips fixes

Published on October 15, 2023

See this post in better quality with screenshots on the forum

Narrat 3.3.8 has just been released with a bunch of new features :open_mouth:

Breaking Changes

Narrat now officially expects you to use node.js 18 or later rather than 16. If still on 16, simply update your node.js version.

Choices Tracking

Narrat tracks which choices the player has seen. When a dialog choice has been seen before, it adds the .seen-before css class to the dialogue option.

This allows the game to display previously seen choices in a different color or style, to make it obvious what options have been visited.

You can override the seen-before css class to change how seen choices are displayed.

Choice Flags

  • :key: Choice flags to mark choices as “key choices” or anything else you want so they can be customised.

Each type of choice can have a customised style and text template, so you can easily create and re-use different types of choices to make important choices stand out, or add warnings to choices that have side effects, or whatever use of this feature you can think of.

[details=“How to use choice flags”] It is possible to customise how choices are displayed in narrat, by creating a choices.yaml config file.

For example:

# Basic text template that will override the default one in narrat
choiceTextTemplate: '[%{$index}] <span class="choice-text">%{$choice}</span>'
choicePrompts:
  # Specific choice flags to display different types of choices differently
  KEY:
    # Each choice flag can have its own text template
    textTemplate: '<span class="choice-index key-choice-index">%{$index}. </span>⚠️%{$choice} <span style="color:grey;">[KEY CHOICE]</span>'
    # Each choice flag can specify a css class which will be added to the choice line
    cssClass: "key-choice"
  UNIMPORTANT:
    cssClass: "unimportant-choice"

TIP

Remember to add choices: 'data/choices.yaml' or similar to your game’s config.yaml to load the choices.yaml file.

In this config file you can add any amount of choice prompt IDs, allowing the creation of all sorts of custom choice prompt styles.

Here is a simple usage example:

main:
  choice:
  "Let's look around the room"
  "Inspect the table":
    "You inspect the table"
  "Look at the stack of papers":
    "You search through the stack of papers"
  KEY "Move on to the next room":
    "You move on to the next room"
    jump next_room

For a more complicated usage example, this snippet of narrat code was used for testing the feature:

test_choice_tracking:
  choice:
    talk helper idle "Let's test the choice tracking feature!"
    "Normal choice":
      talk helper idle "Choice 1"
    KEY "Key choice":
      talk helper idle "Normal key choice"
    KEY roll testSkillCheck agility 14 "key choice with skill check":
      success:
        talk helper idle "Key choice with skill check"
      failure:
        "failure"
    UNIMPORTANT roll testDicePool "unimportant choice with skill check and condition" if (== true true):
      success:
        talk helper idle "Key choice with skill check and condition"
      failure:
        talk helper idle "Failure"
    "normal choice with condition" if (== true true):
      talk helper idle "Key choice with condition"
    roll testDicePool "normal choice with skill check and condition" if (== true true):
      success:
        talk helper idle "Key choice with condition and skill check"
      failure:
        talk helper idle "Failure"
  jump test_choice_tracking_2


test_choice_tracking_2:
  "Now the choices already picked should be greyed"
  jump test_choice_tracking

Here’s what it looks like in the game (yes it’s ugly, this is meant to be an example of the feature):

[/details]

Tooltips

  • :information_source: Tooltips have been fixed and documented

[details=“How to use tooltips”] Tooltips are a feature that allows games to show information tooltips when hovering certain keywords.

They are fully configurable and automated. All you need is to create a list of tooltips, and the engine will make them appear automatically.

How to use tooltips in narrat

To use this feature, the new tooltips.yaml config file is needed:

tooltips.yaml

Tooltips are created and configured in the tooltips.yaml file:

options:
  width: 350
  keywordsPrefix: "@@"
tooltips:
  - keywords: [bread, breads]
    title: Bread
    description: Bread is a staple food prepared from a dough of flour (usually wheat) and water, usually by baking. Throughout recorded history and around the world, it has been an important part of many cultures' diet. It is one of the oldest human-made foods, having been of significance since the dawn of agriculture, and plays an essential role in both religious rituals and secular culture.

Then, in config.yaml add the path to the file:

tooltips: data/tooltips.yaml

General tooltips config

  • width: Width of tooltip box in pixels
  • keywordsPrefix: The prefix to use before words in scripts to make the tooltip appear

Options for individual tooltips

  • keywords: A list of all possible keywords to match for showing this tooltip. It’s case insensitive.
  • title: The title of the tooltip popup that will appear
  • description: The content of the tooltip popup

Then, to use in scripts, for example:

main:
  talk player idle "I like @@bread"

Having one of the keywords defined in the tooltips with the keywordsPrefix before it will make it be detected as a keyword and show the tooltip

Styling tooltips

You can override css classes used in tooltips to style them, but it’s also possible to configure custom css classes for all tooltips or for individual tooltips:

options:
  styling:
    textCssClass: test
    titleCssClass: test
    cssClass: test
tooltips:
  - keywords: [bread, breads]
    title: Bread 🍞🥖
    styling:
      textCssClass: test
      titleCssClass: test
      cssClass: test

Any of the above css options can be used to make tooltips get custom css classes [/details]

Quests failing and succeeding

[details=“How to use quests success and failure”] uests can also be marked as succeeded or failed. This can be useful if you want some of your quests to have a bad ending, or events that can be missed, etc.

It is possible to create a custom quest description for succeeded or failed quests, so that the quest description text will change when the player has finished it.

quests:
  breadShopping:
    title: Bread Shopping
    description: The helper cat asked you to buy bread for him.
    succeededDescription: You bought bread for the helper cat!
    failedDescription: You didn't buy bread for the helper cat.
    objectives:
      bread:
        description: Buy bread for the helper cat.
      delivery:
        description: Deliver the bread to the helper cat.

Then, in narrat scripts you can make the quest succeed or fail when completing it:

main:
  var succeeded false
  complete_quest breadShopping $succeeded

Passing true will mark the quest as succeeded, false will mark it as failed. The description will update to the success/fail description if they exist.

INFO

Note: Quests are marked as succeeded by default when completed if you don’t pass any second parameter to complete_quest

TIP

The quest_succeeded? and quest_failed? commands are available to check if a quest succeeded/failed

[/details]

Quests with multiple endings

[details=“How to use multiple endings in quests”] Building on the success/failure option for quests, you can also specify any arbitrary endings you want to create. For example:

quests:
  breadShopping:
    title: Bread Shopping
    description: The helper cat asked you to buy bread for him.
    objectives:
      bread:
        description: Buy bread for the helper cat.
      delivery:
        description: Deliver the bread to the helper cat.
    endings:
      boughtBread:
        success: true # This indicates that this ending is considered a success
        description: You bought bread for the helper cat!
      didntBuyBread:
        success: false # This indicates that this ending is considered a failure
        description: You didn't buy bread for the helper cat.
      bakingObsession:
        success: true
        description: You decided to get really into baking and learned to make sourdough. You gave some to the helper cat who was really happy that you made it yourself.

And in scripts, endings can be specified as follows:

main:
  complete_quest breadShopping bakingObsession

Some commands available for quest endings:

  • quest_ending? breadShopping: Returns the id of the ending the quest finished with, if any
  • quest_has_ending? breadShopping bakingObsession: Returns true if the quest finished with the specified ending [/details]

Overriding text template for displaying choices

  • :pencil2: The text template for displaying choices can now be changed by the game (this will soon be implemented in other places to override engine built-in strings)

This is done in the new choices config file.

Other Changes

  • :high_brightness: Games had the selected element highlighted in blue by default which was annoying. The engine now detects changes between gamepad and mouse and disables the selected feedback until the gamepad is used again
  • :gift: Changed the notification message when obtaining only x1 of an item to not show the number

Bug Fixes

  • :framed_picture: Fixed an issue where the empty_layer command could cause errors in some circumstances

Documentation

A lot of documentation has been improved or added:

Plugins

  • :robot: The plugin API has been improved giving access to more narrat features, and there is also a window.narrat object which gives access to the narrat library, allowing easier integration with external game engines or tools (this was released earlier, but not mentioned in release notes). Used for the godot plugin

Technical

  • Updated a bunch of dependencies


Narrat is released under MIT License
Copyright© 2021-present Liana Pigeot