Recent Changes - Search:

User Documentation

Developer Documentation



PmWiki ?

edit SideBar

Doc /


WARNING: This is highly outdated! Us don't use .dialog files anymore!

Read the Correct guide in Doxygen wiki.

Thanks by the attention.

This page explains how to write a dialog, and also how to add a character to the game. If you are interested in translating dialogs, please contact the translation project.


Dialogs in freedroidRPG reside in dialogs/*.dialog (repo version) A dialog works by letting the user select dialog options (or "nodes"). Each node represents one thing the player can tell the NPC, and can contain replies from the NPC, as well as a piece of Lua script to interact with the game engine.

Any non-recognized string in a .dialog file represents a comment and is ignored. "recognized" strings are the ones that specify the beginning of the file, the Lua scripts for initialization/startup, or dialog options.

All dialogs should be checked using the dialog validator (discussed below).

Implementing the dialog

The name of the file should be
or, in case of a subdialog,
and placed in the dialogs/ folder.

An entry needs to be added to *npcs[] in src/npc.c (don't use the .dialog extension here), so that the dialog can be assigned to characters within the game.

You may want to create a new map label for your NPC, see EditingLevels? for how to do this.

Finally a new droid/npc has to be created with your dialog. This is done by adding an entry in the file map/ReturnOfTux.droids needs to be set to have DialogSectionToUse="NameOfCharacter (like before, don't use the .dialog extension here).

Top level

FirstTime LuaCode

At the general level, dialogs can take a block <FirstTime LuaCode> </LuaCode>. This is a block of code that will be executed the first time the player talks to the NPC (and only the first time). It cannot be used in subdialogs. Its intended use is to properly set which dialog options should be shown the first time, since they are all disable by default. Use show() for this. Calling anything else than show() is likely to be a mistake of yours, check out EveryTime below.

EveryTime LuaCode

The block <EveryTime LuaCode> </LuaCode> is very similar to FirstTime, except that it will be executed every time the player talks to the NPC. This can be useful to check whether a quest has been accomplished, or for options you always want to be turned back on when starting to talk to an NPC even after it has been turned off during a previous dialog. There are no arbitrary limitations so you can do anything you wish.



A node is where things happen in the dialogs. It generally consists of an option that will be selectable by Tux at some point in the dialog, which is why it is also referred to as an option. But since it's not strictly necessary for Tux to select it, the term option is not 100% correct (e.g. it can also be run automatically via FirstTime).

Available fields

A node follows the following structure:

First line

Nr=0 Text=_"Some text for Tux to say" Topic=_"The topic of this node"

Nr= The Nr=number is a file unique ID for the node and the value is between 0-99. It's a very bad idea to use the exact string Nr= anywhere else in the dialog file other than to define a node.
The number order of the nodes in the dialog file is irrelevant, though it's recommended to use sequential number order since makes it makes it easier to find what is where by the next person helping out.

A node number 99 is required, as this is the node that the "ESC" key activates. (This is checked by the dialog validator below.)

This field corresponds to what Tux is going to say when the node is run. The _ is a gettext marker for "this should be translated". Use it if the text in the field corresponds to something that Tux is actually saying, if this is a placeholder string do not place a _. (See below for placeholder strings.)

This field corresponds to the topic name of the node. The field is optional, the default value of the field is the empty string (root topic). To have more information about it, see Dialog topic.

Second line

The field OptionSample is used to indicate what sound file is associated to the text. It is optional, and can take a special value "NO_TEXT". This value means that the text in the Text field will not appear on screen and be skipped completely. In this case the Text field ought to contain a little place holder string identifying that it is a bug, the dialog, and the node. An example "BUG Dixon node 23" so bugs are easier to spot.

Using Lua

The field <LuaCode> contains a piece of Lua code that will be executed whenever this option is run. It can jump to another option, end the dialog, show or hide options, run subdialogs, and basically do anything that API allows.

For standard dialog we use the following lua functions from map/script_helpers.lua:

  • npc_says(_"Sometext") something the NPC says
  • tux_says(_"Something") if it is something that the player "tux" says

We also have:

  • npc_says_random(_"Sometext", _"Some equivalent text", _"additional equivalent text", ...) randomly selects one of the texts, so there is a bit of variation
  • cli_says(_"terminal$") which displays blue text, like a command prompt

Codestyle notes

To make writing and reading dialogs easier, as well as for translations, we have adopted some style guidelines. These are not checked by the Dialog Validator, as they are not errors in the sense of causing problems for the user, but rather they are something done to make life easier for your fellow writers/developers.


We follow the Linux style CodingConventions. That is to say we indent a TAB character for each level down. It ends up looking like this:
if (test_1) then

npc_says(_"You are fat.")
if (test_2) then
tux_says(_"I resemble that.")


npc_says(_"You are not fat.")


Translation support/Gettext

The core FreedroidRPG group no longer maintains translations, however there is a semi-separate translation project that does. Many people contribute to both projects.

The extent of support in core FreedroidRPG for the translation project is appending gettext characters '_' to the beginning of all strings that we think should be translated. An example:
npc_says(_"String to be translated.")
npc_says("String to not be translated.)
npc_says_random(_"Translate this!", _"And this!", _"Also this!")

Most strings should use this, although there are a few exceptions (including strings with only formatting in them).

Including Variables

According to the gettext manual, it is significantly easier to translate entire sentences rather than fragments concatenated together, so please use string.format() when you are putting variables into your text. The function string.format() has been integrated to function tux_says, npc_says and cli_says. So please do:
npc_says(_"Hello %s, I see you are doing well today.", get_player_name())
Rather than:
npc_says(string.format(_"Hello %s, I see you are doing well today.", get_player_name()))
npc_says(_"Hello " .. get_player_name() .. _", I see you are doing well today.")

This isn't consistently applied throughout the dialogs yet.

Other whitespace stuff

We follow the Linux-style for calling functions (comma space variable). See:
npc_says_random(_"text2", _"Correct")

Text Color

The player speaks in orange, the npc speaks in white, and a computer prompt is in blue. This is mostly handled by the selection of the tux_says(), npc_says(), and cli_says() functions. However, if the NPC is a robot or computer and needs to emphasize something (in blue), it can be done using the [b][/b] indicators, e.g. [b]emphasized text[/b]. Coloring like this should be done sparingly to not at all.

Dialog topic


The dialog topics is used to make easily any sub-dialog. They allow multi-level dialog by divide it between many topics. Each topic have a pool of node, each node have only a topic and it can't be changed. You can only show a node with this topic equals to the current topic. All other node is hidden.

Dialog topic is saved in a stack. Current topic is pushed on the top level by a lua function. The maximum depth of topic is 10.

Root topic

The root topic is the empty string (""). The root topic is the first level of the topic stack. A dialog begin by the root topic. The root topic is the default value of the field Topic and you can not indicate it.

Lua function

topic("A topic")
The function push the current topic on the top level in the topic stack. The maximum depth of topic is 10.

The function pop the current topic on the top level in the topic stack. You can't pop the root topic.


The lua API is much more extensive than the above, and allows many aspects of characters and NPCs to be modified through the dialogs (in addition to being a full on programming language, see the manual).

There are two lists of custom functions available from LuaCode blocks:

In lua.c, look for "luaL_register", this is where the Lua functions are listed.

Dialog Validator

Dialogs can be checked against errors in running the lua code by using the dialog validator. To run, execute freedroidRPG on the command-line with "-b dialog". E.g.: ./src/freedroidRPG -b dialog

Most errors executing the lua code, will be marked (and with some terminals, highlighted in red).

Submitting Patches

If you are using subversion do: svn diff >patch.diff

and then upload the patch to the Review Board.

Of course it may help to contact us before/while you work on your patch.

Edit - History - Print - Recent Changes - Search
Page last modified on Wed, 08 Jan 14 17:17:27 +0000