Dialogue scripting

Teraurge uses a custom markup language for its dialogue files that allows for branching and dynamic dialogue structure and behaviour. The code can be viewed and edited in basically any text editor, but it is recommended to use a syntax highlighter which is available for Notepad++. There is also a Visual Studio Code extension that includes realtime script error checking and notifications in addition to syntax highlighting.

Starting
To get started, create a folder for your character in database/characters/. The folder name should be same as the character name. Do not use uppercase letters in the folder name. If the name contains spaces, replace them with with underscores.

All characters require a diag.txt file because it's the first dialogue file the game loads when the character is first encountered. The scripting functions allow changing .txt files for a character but the diag.txt is always required. Other dialogue txt file names should start with "diag_" so they can differentiated from other types of txt files. All characters also require a stats.txt file for the character stats.

Basic syntax
The dialogue files are divided into blocks that each contains at least one index, which is the displayed dialogue text, and at least one pointer, which are the player's choices on the bottom of the screen. These blocks are separated by double vertical lines ||.

Index names are enclosed in { } brackets at the start of a line, followed by the character dialogue. Typically, the character dialogue is broken into three pieces, divided by apostrophes: top text box, "character dialogue", bottom text box. The text boxes are used for non-spoken dialogue. Certain HTML tags can be used to format the text (bold, italics, line break, and font size). All dialogue files have to start with the {start} index.

Pointer names are enclosed in [ ] brackets and are indented by a tab, followed by the player response. Pointers are used to direct to the index with the same name.

In one block, there can be multiple indexes. This is to prevent having to duplicate player options for screens that could share them (for example, a questions hub). While indexes must have their names specified, their contents can be left empty.

This is a simple example code: || {start} Top text box. "Spoken dialogue" Bottom text box. [opt_1] Option 1 [opt_2] Option 2 || {opt_1} "Option 1" [opt_2] Option 2 [start] Go to start index. || {opt_2} "Option 2" [opt_1] Option 1 [start] Go to start index. ||

Comments
Single line comments are preceded by >> while multi-line comments are enclosed in the NOTES text. Think of them like // and /* */ in C-based languages. It is recommended to divide large chunks of code with empty lines and a comment labeling what part of dialogue they are for improved readability (both yours and a possible contributor's). Don't  place comments at the end of a pointer or an index, they won't be recognised and will be displayed in the game! Only place them after block dividers ||, before indexes! NOTES This is an example character, there are many like it, but this one's mine. Blah blah. I can do multiple lines, isn't that cool? NOTES || >>Single-line comment; greeting {index} The stranger waves at you. "Hello." [pointer1] Hello. [ | end_encounter] Bye. ||

Variables naming guidelines
To avoid confusing flag names and to help other writers extend your text you should use these guidelines to name your different flags, counters and other variables you add with the dialogue functions.


 * To keep flag size down, do not use articles in flag names (the, an, a).
 * Do not use special characters in flag names. Only use letters and numbers.
 * Do not use spaces in variable names, use underscore (_) instead.
 * Only use lowercase characters in flag names.

Give the flag a name that describes the thing it records.
 * No: flag_12
 * Yes: taodal_market_money_stolen_by_player

Keep flags specific to avoid conflicts with future flags.
 * No: guard_killed
 * Yes: taodal_gate_guard_killed_by_player

If the flag is tied to a specific character you should always put the character's name first. For example, if player killed someone and you want a flag for it, refer to it after the name.
 * No: player_killed_tornoth
 * Yes: tornoth_killed_by_player

This will make searching for flags with debug tools easier as all character-relevant flags will be in alphabetical order and other writers can quickly figure out what the flag is for.

This naming convention should be used with other variables that are relevant to a specific character. If variables are not specific to a character you should use quest/event/place name instead. If the variable is specific to the player just use “pc” (player character) as the prefix.

Syntax
Showif and hideif are special functions that will show a dialogue option only if a specified requirement is met. Showif is placed at the end of the dialogue option text and not in the “[ ]” brackets. Keep in mind you have to leave a space between the end of the text and the showif function.

Hideif works exactly like showif except, like the name implies, it hides a dialogue option if a specified requirement is met. There can be multiple conditions on one line and they currently work in an AND fashion (ie. for a speech option with two showif conditions to appear, both conditions need to be met)

{index} Top text box. "Spoken character dialogue." Bottom text box. [pointer] Dialogue option 1 [pointer] Dialogue option 2  //showif.has_flag.show_option_2  ||

List of conditions
Use //showif. or //hideif. and add any of the following: (items in parentheses must be replaced and parentheses removed.)

Syntax
Dialogue functions are usually used to direct the flow of dialogue based on player stats or other mechanisms. They can do many things but they cannot hide dialogue options in the same way //hideif and //showif can.

Functions can be placed inside inside both pointer brackets [ ] or index brackets { }. A vertical line | must be used to separate the pointer/index from the function. If function directs to a pointer, you can leave the pointer name empty. If multiple functions are used in a single pointer/index, separate them by a comma and space.

{index | function } [pointer | function ] [pointer | function1, function2 , function3 ] [ | function pointer1 pointer2 ] [ | function1, function2 pointer1 pointer2 ]

Shop functions
Shops work a little differently from most of the dialogue. Besides the start_shop function that can be called from a normal dialogue file, others are used strictly in diag_shop.txt. If you want the shopkeeper to react to you attempting to buy or sell certain items, you can use specially named indexes, where (item name) is the internal name of the specified good you want to buy or sell:

sell_(item name) buy_(item name)

Shop dialogues don't necessarily need to have pointers (player choices) after their indexes if the index immediately enables the shopping interface again.