Skip to content

Dialogue System Overview

austin-lopez edited this page Apr 11, 2024 · 12 revisions

This project is using Pixel Crushers' Dialogue System (DS) for the majority of the project, with some minor modifications.

How does the dialogue system work?

No idea! But I have a small notion on how its data is structured.

  • DS stores linked DialogueEntry nodes (sometimes labeled as 'subtitles'), indexed by Conversation ID and the Entry ID.
  • Each DialogueEntry has fields that can be customized per-node (more on this later).
  • Internally, there is no difference between a line of text and a choice, they're both a DialogueEntry. When a DialogueEntry has more than one linked node, however, DS will assume that the nodes are choices.

The first node, "What should I do?" is represented in-game as a line of text. All the linked nodes are represented in-game as choices.

How did you fuck up the DS you goober?

I'M SORRY I DIDN'T MEAN TO. But I did make some small additions for the purpose of P&P's systems.

Custom Fields

You can see a dialogue entry's fields by clicking on any node in the "Conversations" tab, and selecting the "All Fields" dropdown.

Fields have both a label and type. For simplicity, I've been making code that assumes the label and type share the same name (e.g. a node with a custom field type of Timespan will also have a label of "Timespan").

Timespan Field

Note: this field was originally called "Duration" and had a slightly different implementation. Some DialogueEntries still use this field and should ideally be updated.

Timespan is a custom field type that determines how much in-game time (in seconds, minutes, or hours) a specific DialogueEntry consumes. You can find its declaration in CustomFieldTimespanType.cs.

  • The Timespan field type has two arguments: an integer, and a unit enum (seconds, minutes, or hours).
  • When the integer is greater than -1, DialogueUtility.cs will override the automatic per-node time calculation add time to the game based on the integer input and the unit. You can see this implementation in DialogueUtility.GetNodeDuration

Points Field

Points is a custom field type that determines how many points a decision is given to the player when selecting a response. You can find its declaration in CustomFieldPointsType.cs.

  • The Points field type has two arguments: the point category (Wellness, Business, or Savvy, and the amount of points.
  • Points are currently associated with the DialogueEntry node, not quests,

Some quirks:

  • Points are only calculated in CustomResponseMenu.cs. This means that points can only be rewarded at the time of clicking a decision.
  • CustomResponseMenu.cs assumes only one entry of a Points field per DialogueEntry, and functionality of having multiple types of points in a decision has neither been built for nor tested.

Time Estimate Field

Unlike the other custom fields, the Time Estimate field uses a custom field type of a different name called a Node field type, declared in CustomFieldNodeType.cs. It is used to calculate how much in-game time a series of nodes will consume.

  • The Time Estimate field is only meant to be used in decision nodes, and accepts two arguments: a Conversation ID, and an Entry ID.
  • To find how much time a decision might take, A DFS algorithm (found in DialogueUtility.cs) is conducted, starting at the decision node, until it finds the node(s) described by each Time Estimate field entry.
  • Multiple Time Estimate fields in a single node are allowed and accounted for.

Possible future changes.

I'm considering changing points to be a Quest field as opposed to a DialogueEntry field.

Quests

Perils and Pitfalls uses Quests for the majority of gameplay tracking.

I've been arbitrarily dividing quests into two categories: "Main" quests and "Low-level" quests.

  • Main quests represent longer, overarching goals that require multiple conditions to be satisfied that don't necessarily take place in a single location.
  • Low-level quests are one-to-one with in-game decisions and are always associated with a specific location.
    • For example, the decision to buy a suit at the Mall satisfies a quest called "Mall/BuySuit".

Quests will usually be in one of four states: "unassigned", "active" "success", or "failure". Decisions will often check for these quest states to evaluate whether they should be displayed or not.

For the most part they can be thought of like this: Low-level quests are used almost entirely for internal decision-tracking, and Main quests are explicit goals for the player to accomplish.

Possible future changes.

I'm considering declaring a custom field that automatically assigns a quest to "success" when making decisions. This will likely be implemented in CustomResponseMenu.cs.

Special Lua Variables

I've set up special variables in the DS to help with game devving, but their function or implementation might not be immediately apparent.

Skip the Introduction

Set debug_skip_intro to true to skip the introduction at the start of the game.

Immediately travel to a specific location.

Set debug_skip_to_location_at_start to a location to start the game at that location. If set to "(None)", then the game proceeds as normal.

Setting debug_skip_to_location_at_start to any location will always skip the intro even if debug_skip_intro is false.

Disable special node types.

Set debug_disable_leave_nodes to true to disable any "Leave" nodes from appearing.

Clone this wiki locally