Solarus solarus-0.9.1
Text and dialog files syntax specification

We specify here the data files that provide the strings and the dialogs displayed during the game. Such files are locaed in the directory languages/XX/text where XX should be replaced by the language code (e.g. en or fr). When translating the game, most of the work consists in translating those files. See the How to translate a quest page if you are interested in translating the game (and you should also contact us).

Strings

The engine needs to display some string in the menus. All these strings are loaded from the file languages/XX/text/strings.dat. As an example, we give here the languages/fr/text/strings.dat file of Zelda Mystery of Solarus DX. The syntax and the translation instructions are explained in the comments.

# Language: French

# This file contains the strings displayed during the game in the current language.
# Each line represents a string, representing by its key and then its value.
# The key and the value are separated by one or several tabulation characters.
# The key cannot contain whitespaces and cannot be changed. Only the value has to be translated.
# This file must be encoded in UTF-8.

# The strings having a key with "caption" are displayed
# in the caption text area of the pause menu. They can have one or two lines
# (separated by the '$' character) and a line should never exceed 20 characters.
# For all other strings, the maximum length is indicated in the comments below.

# Map submenu
map.caption.world_map			Carte du Monde
map.caption.dungeon_name_1		Donjon de la Forêt
map.caption.dungeon_name_2		Caverne de Roc
map.caption.dungeon_name_3		Antre de$Maître Arbror
map.caption.dungeon_name_4		Palais de Beaumont
map.caption.dungeon_name_5		Ancien$Château
map.caption.dungeon_name_6		Caverne d'Inferno
map.caption.dungeon_name_7		Temple du Cristal
map.caption.dungeon_name_8		Donjon des$Pics Rocheux
map.caption.dungeon_name_9		Temple des Souvenirs
map.caption.dungeon_name_10		Tour des Cieux

# Quest status submenu
quest_status.caption.rupee_bag_1	Sac de Rubis
quest_status.caption.rupee_bag_2	Grand$Sac de Rubis
quest_status.caption.rupee_bag_3	Sac de Rubis$Géant
quest_status.caption.bomb_bag_1		Sac de Bombes
quest_status.caption.bomb_bag_2		Grand$Sac de Bombes
quest_status.caption.bomb_bag_3		Sac de Bombes$Géant
quest_status.caption.quiver_1		Carquois
quest_status.caption.quiver_2		Grand Carquois
quest_status.caption.quiver_3		Carquois Géant
quest_status.caption.world_map		Carte du Monde
quest_status.caption.pieces_of_heart	Fragments de Coeur
quest_status.caption.tunic_1		Cotte de Mailles$verte
quest_status.caption.tunic_2		Cotte de Mailles$bleue
quest_status.caption.tunic_3		Cotte de Mailles$rouge
quest_status.caption.sword_1		Epée du Courage
quest_status.caption.sword_2		Glaive Hylien
quest_status.caption.sword_3		Sabre du Héros
quest_status.caption.sword_4		Lame Purificatrice
quest_status.caption.shield_1		Bouclier
quest_status.caption.shield_2		Bouclier de Feu
quest_status.caption.shield_3		Bouclier Miroir

# Inventory submenu
inventory.caption.item.feather.1			Plume
inventory.caption.item.bombs_counter.1			Bombes
inventory.caption.item.bow.1				Arc
inventory.caption.item.bow.2				Arc & Flèches
inventory.caption.item.boomerang.1			Boomerang
inventory.caption.item.boomerang.2			Super Boomerang
inventory.caption.item.lamp.1				Lanterne
inventory.caption.item.hookshot.1			Grappin
inventory.caption.item.bottle_1.1			Flacon Magique$(Vide)
inventory.caption.item.bottle_1.2			Flacon Magique$(Eau)
inventory.caption.item.bottle_1.3			Flacon Magique$(Potion rouge)
inventory.caption.item.bottle_1.4			Flacon Magique$(Potion verte)
inventory.caption.item.bottle_1.5			Flacon Magique$(Potion blue)
inventory.caption.item.bottle_1.6			Flacon Magique$(Fée)

inventory.caption.item.pegasus_shoes.1			Bottes de Pégase
inventory.caption.item.mystic_mirror.1			Miroir Mystique
inventory.caption.item.cane_of_somaria.1		Canne de Somaria
inventory.caption.item.apples_counter.1			Pommes
inventory.caption.item.pains_au_chocolat_counter.1	Pains au Chocolat
inventory.caption.item.croissants_counter.1		Croissants
inventory.caption.item.bottle_2.1			Flacon Magique$(Vide)
inventory.caption.item.bottle_2.2			Flacon Magique$(Eau)
inventory.caption.item.bottle_2.3			Flacon Magique$(Potion rouge)
inventory.caption.item.bottle_2.4			Flacon Magique$(Potion verte)
inventory.caption.item.bottle_2.5			Flacon Magique$(Potion blue)
inventory.caption.item.bottle_2.6			Flacon Magique$(Fée)

inventory.caption.item.rock_key.1			Clé de Roc
inventory.caption.item.bone_key.1			Clé d'Os
inventory.caption.item.clay_key.1			Clé de Terre
inventory.caption.item.level_4_way.1			Tarte aux Pommes
inventory.caption.item.level_4_way.2			Lingots d'or
inventory.caption.item.level_4_way.3			Edelweiss
inventory.caption.item.level_4_way.4			Précis d'escrime
inventory.caption.item.flippers.1			Palmes
inventory.caption.item.magic_cape.1			Cape Magique
inventory.caption.item.bottle_3.1			Flacon Magique$(Vide)
inventory.caption.item.bottle_3.2			Flacon Magique$(Eau)
inventory.caption.item.bottle_3.3			Flacon Magique$(Potion rouge)
inventory.caption.item.bottle_3.4			Flacon Magique$(Potion verte)
inventory.caption.item.bottle_3.5			Flacon Magique$(Potion bleue)
inventory.caption.item.bottle_3.6			Flacon Magique$(Fée)

inventory.caption.item.iron_key.1			Clé de Fer
inventory.caption.item.stone_key.1			Clé de Pierre
inventory.caption.item.wooden_key.1			Clé de Bois
inventory.caption.item.ice_key.1			Clé de Glace
inventory.caption.item.glove.1				Poigne de Fer
inventory.caption.item.glove.2				Poigne d'Or
inventory.caption.item.fire_stones_counter.1		Pierres de Feu
inventory.caption.item.bottle_4.1			Flacon Magique$(Vide)
inventory.caption.item.bottle_4.2			Flacon Magique$(Eau)
inventory.caption.item.bottle_4.3			Flacon Magique$(Potion rouge)
inventory.caption.item.bottle_4.4			Flacon Magique$(Potion verte)
inventory.caption.item.bottle_4.5			Flacon Magique$(Potion blue)
inventory.caption.item.bottle_4.6			Flacon Magique$(Fée)

# Options submenu
options.caption.press_action_change_mode	Appuyez sur Action$pour changer de mode
options.caption.press_action_customize_key	Appuyez sur Action pour$configurer cette touche
options.caption.press_key			Appuyez sur une touche$du clavier ou du joypad
# names of video modes (maximum 26 characters)
options.video_mode_0				Fenêtre 640x480
options.video_mode_1				Fenêtre 640x480 lisse
options.video_mode_2				Fenêtre 320x240
options.video_mode_3				Plein écran étiré
options.video_mode_4				Plein écran étiré (large)
options.video_mode_5				Plein écran lisse
options.video_mode_6				Plein écran lisse (large)
options.video_mode_7				Plein écran centré
options.video_mode_8				Plein écran centré (large)
# column headers of the keyboard/joypad customization table (maximum 10 characters)
options.commands_column				Commandes
options.keyboard_column				Clavier
options.joypad_column				Joypad

# Game controls customization (maximum 10 characters)
controls.game_key_1		Action
controls.game_key_2		Epée
controls.game_key_3		Obj gauche
controls.game_key_4		Obj droit
controls.game_key_5		Pause
controls.game_key_6		Droite
controls.game_key_7		Haut
controls.game_key_8		Gauche
controls.game_key_9		Bas

# Dialog to save the game
save_dialog.yes			Oui
save_dialog.no			Non
save_dialog.save_question_0	Voulez-vous sauvegarder
save_dialog.save_question_1	votre progression ?
save_dialog.continue_question_0	Voulez-vous continuer
save_dialog.continue_question_1	la partie ?

# Savegame selection menu (with maximum 45 characters for phase titles)
selection_menu.phase.select_file	Veuillez choisir un fichier
selection_menu.phase.choose_mode	Choisissez un mode de jeu
selection_menu.phase.choose_name	Quel est votre nom ?
selection_menu.phase.confirm_erase	Etes-vous sûr ?
selection_menu.phase.erase_file		Quel fichier voulez-vous effacer ?
selection_menu.phase.options		Appuyez sur Espace pour modifier
selection_menu.phase.options.changing	<  > : choisir, Espace : valider
selection_menu.erase			Effacer
selection_menu.cancel			Annuler
selection_menu.big_yes			OUI
selection_menu.big_no			NON
selection_menu.empty			Vide
selection_menu.options			Options
selection_menu.back			Retour
selection_menu.options.language		Langue
selection_menu.options.video_mode	Mode
selection_menu.options.music_volume	Volume de la musique
selection_menu.options.sound_volume	Volume des sons

# Title screen
title_screen.website		www.zelda-solarus.com
title_screen.press_space	Appuyez sur espace

Dialogs

Dialogs are all messages shown to the player in the dialog box during the game. They are all defined in the file languages/XX/text/dialogs.lua. Some dialogs are triggered by the engine and others by the quest.

It is a Lua file encoded in UTF-8. You don't have to know Lua to add, change or translate dialogs. We give here the full specification of the dialog file, with instructions for quest makers and translators.

Before solarus 0.9.1, the dialogs were an ini file with a more complicated syntax. Translating dialogs was error prone. In tools/data_files_converstion/, we provide a script to convert your old dialog files to the new Lua format.

Lines starting with the characters '--' are comments and are ignored by the engine.

The definition of a dialog starts with dialog{ and ends with }. Inside the braces, the properties of the dialog are specified. Properties are declared with the syntax key = value and separated with commas. It is allowed to have an extra comma after the last property. Properties with string values should be enclosed between double quotes, except when specified otherwise. Each dialog may have the following properties:

  • id: a string (between double quotes) identifying the dialog. The id allows the engine and the scripts to refer to the message they want to display. If you are translating dialogs, you must never translate the id!
  • text: content of the dialog. If you are translating dialogs, text is the only value to translate. The text has usually several lines. In the game, it will be displayed in groups of 3 lines because the dialog box has space for 3 lines. Each group of 3 lines is called a message. The text should be enclosed between [[ and ]], which is the Lua notation for multiline strings. A line shoud not exceed 23 characters. To make sure you don't exceed this limit, you can put a comment of 23 dashes (but place this comment outside the string). And you should use an editor with a fixed width font.
  • skip: defines what happens when the player tries to skip the dialog (by pressing the sword key). There are three possible values:
    • "none" or nil (default): the message cannot be skipped.
    • "current": if the key is pressed, the current group of 3 lines is immediately shown (instead of being displayed letter by letter). This allows to get to the next message faster.
    • "all": the whole sequence of messages can be skipped. The dialog box is immediataly closed and the next groups of 3 lines will not be displayed at all. Use this only for non-essential dialogs that can be read again later. The value of skip takes effect applies until the dialog box is closed.
  • icon: displays a small image of 16*16 pixels in the dialog box. The value is a number that identifies the icon in the icon image file. The icon (if any) is displayed on the left of the message and the text cannot exceed 20 characters (instead of 23 when there is no icon). The icon remains displayed in the next message, until its value is changed or the dialog box is closed. A value of -1 or nil means that you want to remove the icon.
  • next: id of the next dialog to display, between double quotes. If this value is not set, the dialog box is closed when the current dialog is finished.

During the last message (group of 3 lines) of a dialog, if next is set, then an arrow is displayed on the bottom of the dialog box to indicate that there will be a next dialog. If next is not set, then this arrow is replaced by a square to indicate that this message was the last one. A message having a question (see below) is always displayed with an arrow.

Sometimes, even if a dialog is finished, you may want to show an arrow. This is typically the case when you know that another dialog will start immediately, but you don't know which one yet (a script will decide at the last moment). In this case, you can set an empty string ("") as the value of next to indicate that the dialog will be followed by another one, unknown for now. This will display the arrow instead of the square, but everything works exactly as if the value next was not set.

  • question: if set to true, the last message (group of 3 lines) of the dialog will be displayed as a question with two choices. The first line of the message is considered as the question and the two other lines are the two possible answers. Those two lines are then limited to 20 characters (instead of 23 when there is no question) because a cursor lets the player choose his answer. It is possible to have both a question and an icon: then, the maximum number of character is the last two lines is 17.

If there is a question, you can define a value next2. next specifies the message to show when the first answer is selected. next2 specifies the message to show when the second answer is selected. As for next, if next2 is unspecified and the player chooses the second answer, the sequence stops and the dialog box is closed. If the value of skip is "all" in a dialog with a question, then everything works as if it was "current" instead of "all".

  • Finally, there exists special characters that you can put in the text of a message:
    • $0: makes a break of one second in the letter scrolling,
    • $1: set the letter scrolling speed to slow,
    • $2: set the letter scrolling speed to medium,
    • $3: set the letter scrolling speed to fast (default),
    • $v: inserts the value of a variable in the message (but the engine or a script must specify this value). The letter scrolling speed applies until the dialog box is closed.

Here is an small example of a dialog file.

dialog{
  id = "wise_man",
  skip = "current",
  question = true,
  next = "wise_man.thanks",
  next2 = "wise_man.insisting",
  text = [[
I can feel courage in
you, $v.
Do you think you can
protect the Princess?
Definitely!
No way
  ]],
}
-----------------------

dialog{
  id = "wise_man.insisting",
  question = true,
  next = "wise_man.thanks",
  next2 = "wise_man.insisting",
  text = [[
$v, I beg you.
You are the only
one able to protect
our kingdom...
Sure
No way
  ]],
}
-----------------------

dialog{
  id = "wise_man.thanks",
  text = [[
I knew I could count on
your immense bravery.
  ]],
}
-----------------------