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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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.
Showif / Hideif function[edit | edit source]
Syntax[edit | edit source]
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[edit | edit source]
Use //showif. or //hideif. and add any of the following: (items in parentheses must be replaced and parentheses removed.)
Condition | Description |
---|---|
clicked | Only useful with //hideif., to remove an option the player has clicked on. |
index_is.(index name) | Checks if the currently displayed index (dialogue screen) name matches the specified index. Useful in all sorts of situations. |
player_sex.(male/female) | Checks if the player is a specific gender. |
has_item.(item) has_item.(item).(optional number) |
Checks if the player has the required item. |
no_item.(item) | Checks if the player doesn't have the required item. |
has_krats.(number) | Checks if the player has the specified amount of krats. |
has_adats.(number) | Checks if the player has the specified amount of adats. |
no_adats.(number) | Checks if the player has no adats. |
has_flag.(flag) | Checks if the player has the required flag. |
no_flag.(flag) | Checks if the player doesn't have the required flag. |
has_stat.(name of the attribute).(number) | Checks if the player stats meet the requirement.
Shorter alternative stat check: (name of the attribute).(number) Example: //showif.intelligence.4 |
rape_filter_off | Checks if the rape filter is off (rape content allowed). |
gore_filter_off | Checks if the gore filter is off (graphically violent content allowed). |
feral_filter_off | Checks if the feral filter is off (feral content allowed). |
time_filter.(more than).(less than) | Checks if the in-game time is between the specified values. The time system is 100 units per day and then it loops back to 0. So 0 and 100 are both midnight. 25 is dawn, 50 is midday and 75 is dusk. |
counter.(counter name).(minimum) | Checks specified counter if it has at least the specified value. |
has_discovered.(location name) | Checks if the player has visited a location with specified environment. |
has_a_save | Checks if any saved game exists. Currently only used for optional skipping of The Witch's introductory sequence. |
note.(note text) | Doesn't actually check for anything; this option is used for leaving notes in the code. Primary use is hiding unfinished/unimplemented branches from the player without resorting to deleting the whole option. |
debug | Checks if debug mode is enabled. |
Dialogue functions[edit | edit source]
Syntax[edit | edit source]
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]
List of functions[edit | edit source]
Graphic functions[edit | edit source]
Function name and syntax | Description |
---|---|
pic (image name) | Loads a fullscreen image and displays it.
Images (.jpg) must be in the character folder. During an image, all character text is shown in a single box. This function is commonly used to show the “sketchy” sex scene pictures. The picture has to be a .jpg to work. In template_character folder, you can find the empty paper-like background used for existing pictures. |
remove_pic | Removes the image and returns to normal dialogue. |
hide_character Also valid: hide_sprite |
Hides the character sprite. Technically it only changes the sprite to none - to unhide the character, use change_sprite. |
character_leave | Hides the character sprite with an animation. |
character_return (sprite name) | Makes a character hidden with character_leave come back with the same type of animation. Sprite name must be specified. |
change_character (new character) | Changes character in the scene. The character sprite doesn't change and doesn't revert to the default sprite, you have to do that manually by following this with a change_sprite. This function only loads the character sprite and the associated stats.txt. The dialogue file is not changed. Used heavily in Tornoth and Shyni's dinner. |
change_environment (environment) | Changes the environment (scene background) and stats associated with it. |
change_sprite (sprite) | Allows you to change the current character's sprite. Sprite must be in the character’s folder. |
change_default_sprite (character) (new_sprite) | This will override default "character.png" sprite with a specified sprite and will use it as the default when loading the character. Sprite must be in the character’s folder. |
change_default_env_background (environment name) (background image filename) | Changes the default background graphic for the environment. |
add_default_env_layer (background image filename) | Adds an image on top of the background graphic. |
Variables operations[edit | edit source]
Function name and syntax | Description |
---|---|
save_index (saved index) | Changes the saved index for the current character. Saved index is the index the character encounter will start from. |
save_index_by_character (character) (saved index) | Changes the saved index for the defined character. Saved index is the index the character encounter will start from. |
change_default_diag_file (character) (filename) | Changes the default dialogue file used in the character encounter for the provided character. |
add_flag (flag name) Also valid: set_flag |
Saves a flag that can be checked. |
remove_flag (flag name) | Removes a flag. |
counter (counter name) (+/-) (number) | Creates a new counter if the counter doesn't exist. - and + control if you are subtracting or adding to the counter value. |
set_counter (counter name) (set number) | Sets the counter to a specific number. |
remove_counter (counter name) | Removes the specified counter. |
add_timer (timer name) (days) trigger: (function & function) | Triggers the defined functions after the specified number of days. |
Index branching[edit | edit source]
Function name and syntax | Description |
---|---|
curated_list (type) | Picks a pointer from the dialogue options depending on the type. //showif and //hideif conditions can be used to enable or disable the pointers. Types: |
change_diag_file (filename) (pointer) | Changes to the specified dialogue file. You'll need to specify the pointer for this function. |
change_to_default_diag (pointer) | Changes to the default dialogue file. |
check_flag (flag name) (without flag pointer) (with flag pointer) | Checks if the player has the specified flag. |
check_item (item name) (without item pointer) (with item pointer) | Checks if the player has the specified item. |
check_counter (counter name) (limit) (lesser pointer) (equals or greater pointer) | Checks the specified counter. If counter value is equal or exceeds the limit, function will use over pointer. Otherwise under pointer is used. |
check_discovery (place name) (not discovered pointer) (is discovered pointer) | Checks if player has found a specific map location. |
check_stat (attribute) (value) (fail pointer)-(pass pointer) | Checks if the player has the required attribute value and sends the conversation to the first pointer if the requirement is not met and the second one if it is. |
check_stat (attribute) (value)-(value)-(value)... (fail pointer)-(value1 pass pointer)-(value2 pass pointer)-(value3 pass pointer) | This allows multiple outcomes based on the player's different levels of an attribute. Values and pointers are separated by hyphens. An example is drinking Obassinian Black in The Shining Pearl where, depending on the player's will level, the result ranges from instant vomiting, delayed hurling to downing the drink without consequences:
[ | check_stat will 6-8-10 ob0-ob1-ob2-ob3] (Drink it) |
sex_gate (male pointer) (female pointer) Also valid: sex_branch and gender_gate |
Will use the first specified pointer if the player character is a male and the second one if the character is a female. |
rape_filter (ON pointer) (OFF pointer) | Will use the first pointer if the rape filter is on and the second one if the rape filter is off. |
feral_filter (ON pointer) (OFF pointer) | Will use the first pointer if the feral filter is on and the second one if the feral filter is off. |
gore_filter (ON pointer) (OFF pointer) | Will use the first pointer if the gore filter is on and the second one if the gore filter is off. |
chance (win percentage) (lose pointer) (win pointer) | Win percentage is the number the roll (1-100) needs to beat to direct to the winning pointer. Otherwise it gets directed to the losing pointer. |
random_pointer (pointer)-(pointer)-(pointer)-(pointer)-(pointer)-(etc) | Function will randomly pick one of the pointers provided. Pointers are separated by hyphens (-). |
day_night_gate (day pointer) (night pointer) | Function will pick a pointer whether it's day or night. |
morn_day_eve_night_gate (morning pointer) (day pointer) (evening pointer) (night pointer) | Function will pick a pointer based on the time of day. |
Inventory functions[edit | edit source]
Function name and syntax | Description |
---|---|
give_money (krats/adats) (amount) | Gives the player a specified amount of money of either currency. A counter name can be specified instead of an amount, and the counter's current value is used. Example: Naigad's quest uses this to give the player either two or three Adats. |
take_money (krats/adats) (amount) | Takes a specified amount of money of either currency from the player. |
give_item (item name) (optional number) | Gives the player the specified item. |
remove_item (item name) (optional number) | Removes the specified item from the player's inventory. |
give_card (card name) | Gives the player a card. |
remove_card (card name) | Takes a card away from the player. |
Miscellaneous functions[edit | edit source]
Function name and syntax | Description |
---|---|
auto_continue (index) | Advance to the specified index after clicking without presenting any dialogue options, instead showing a singular button. Dialogue options in a block are hidden only when indexes using auto_continue are displayed – both can therefore be combined for more compact code. |
end_encounter | Ends the encounter and returns to the map. |
start_encounter (environment) (character) (pointer) | Starts a new encounter with a specified environment and character. Pointer is left empty if you want to use the character’s saved index. (start_encounter is now the essential function when defining encounter lists in environments) |
set_map_location (location) | Moves the player on the map to the specified location.
Consult Meandraco before using this. Map location name is needed. |
start_combat (lose pointer) (win pointer) | Starts combat and, based on whether the player wins or loses, is immediately followed by the respective pointer. |
combat_damage ("character"/"player") (hitpoints) | Damages the character or player by the set number of hitpoints. This is optionally used before starting combat. Don't forget that the health after a fight stays until the end of the encounter and return to the world map. |
combat_heal ("character"/"player") (hitpoints) | Heals the character or player by the set number of hitpoints. This is optionally used before starting combat. The player's health can't go above 40. |
player_death | Activates the 'Game over' screen. |
advance_time (time units) | Advances the in-game time by the amount of time units specified. |
advance_time_to (part of day in time units or text) | Advances the in-game time to the part of the day specified. This has a fade out and fade in effect. Often used for sleeping effect.
Valid time texts: morning, noon, evening, night |
Audio functions[edit | edit source]
Function name and syntax | Description |
---|---|
start_music (filename) (volume) (fade out) (fade in) no_loop | Plays the specified music track (located in audio\music) at specified volume (range 0 - 100) and optional fadeout of the previously played music track and fadein of the specified track (both in seconds with optional decimal point). Use the no_loop flag to play the track only once without repeating.
Recommended values are 70 and less for volume and 5 for fadeout. |
stop_music (fadeout) | Stops the current music with an optional fadeout in seconds. |
play_sound (filename) (volume) | Plays the specified sound (located in audio\sounds) at specified volume (range 0 - 100). There's only one channel for these sounds, so if one is already playing when the function is called, it is cut. |
play_contsound (filename) (volume) (channel 1/2) (fade out) (fade in) | Starts a looping sound (located in audio\sounds just like with play_sound) at specified volume on specified channel (two can play at the same time) with specified fade in and, if another sound was playing on the same channel, fade out of the previous loop. If no sound was playing on the channel, the fade out value effectively delays the sound playback. |
stop_contsound (channel 1/2) (fade out) | Stops the sound playing on specified channel. |
change_env_sounds (filename.volume-filename.volume) | Allows for changing environment sounds and their volume using the same syntax as environment definitions. |
Shop functions[edit | edit source]
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.
Function name and syntax | Description |
---|---|
start_shop (return pointer) | Opens a shop menu with items defined in character's stats.txt and returns to the specified pointer after the player exits the shopping menu. Call this from diag.txt and custom dialogue files, not from diag_shop.txt. |
revert_last_shop_item | Reverts the last transaction based on the index name. For example, when the player attempts to sell underwear to Tornoth, it gets returned to them with a comment above the shopping interface:
{sell_underwear | revert_last_shop_item} "Get that off my table." This is an example where you don't need a list of pointers following the index, since this only displays a character's line above the shopping interface. |
disable_shop | Temporarily closes the shopping interface for dialogue (in diag_shop.txt only) with player choices. If you want to only use a passing comment without disabling the transaction menu, you don't need a function. Not to be confused with returning to regular dialogue which is triggered by the player exiting the interface. |
enable_shop | Returns back to the shopping interface that was hidden with disable_shop. |
World map operations[edit | edit source]
Function name and syntax | Description |
---|---|
discover_location (location) | Discovers a location on the map.
Consult Meandraco before using this. Map location name is needed. |
remove_location (location) | Removes a location on the map.
Consult Meandraco before using this. Map location name is needed. |
add_encounter (environment) (character) Deprecated in v2.10 with the new way of defining environment encounters that can make use of variable checks, conditions and other features. |
Adds the specified encounter to the specified environment. |
remove_encounter (environment) (character) Also deprecated in v2.10. |
Removes the specified encounter from the specified environment. |