Candy Logo Copyright © 2025-2026 Candy Arts

Translating Other Content
Candy Dialogue Engine's own localization tables cover Actor names and UI texts. Anything else your Dialogues display, such as item names, place names or quest titles, is translated through localization tables of your own, with the translate() function. Adding a Localization Table To add a table, create a script in the Candy_DE/Scripts/User_Data/Localization_Tables folder. The script extends CandyDataTable and declares one variable, which contains the table:
extends CandyDataTable var item_names = { "Iron Sword": { "French": "Épée en fer", "Japanese": "鉄の剣", }, "Healing Potion": { "French": "Potion de soin", "Japanese": "回復薬", }, }
Each key is a text in the Default language, and contains its translation in each language. Language names must be spelled exactly as in your Variation names (see Translating Speech). The table doesn't need to be registered. When the game starts, the table becomes a property of the candy_de autoload, named after the variable: candy_de.item_names. Name the script after its variable, such as Item_Names.gd. Sub-folders only sort the tables. The scripts you add to this folder are 'safe': updates never overwrite or remove them. Rules for your own tables:
  • Don't name the variable like an existing table or a setting in Candy_Properties.gd, such as display_names or language.
  • Don't name two scripts identically, even in different sub-folders. Only one of them is loaded, and the duplicate is reported.
  • Only declare variables in the script. It is read once when the game starts, then discarded.
The translate() Function translate() returns the translation of a text in a localization table, in the current language of an Engine:
CandyWriting.get_shared().translate(engine, caller, text, table)
ArgumentDescription
engineThe Engine whose current language applies.
callerThe object making the call. Pass self.
textThe text to translate: a key of the table.
tableThe table's variable name, such as "item_names". It can also be a ¢ expression that returns a Dictionary.
When the table has no entry for the text, or the entry has none for the Engine's current language, translate() returns the text unchanged. When the table can't be found, or the text's entry isn't a Dictionary of translations, it reports an error and also returns the text unchanged. translate() reads every localization table, including Candy Dialogue Engine's own, such as display_names. The Engine determines its current language when it starts a Dialogue, and when its refresh_language() function is called (see Translating Speech). Before either has happened, the Engine has no language yet, and translate() returns every text unchanged. If your game code translates texts before the Engine's first Dialogue, such as on a title screen, call the Engine's refresh_language() first. Translating in Your Game Code Call translate() wherever your game code displays a text that Dialogues also refer to. For example, an inventory script displaying an item name:
var engine: CandyEngine = $DialogueUI/CandyEngine item_label.text = CandyWriting.get_shared().translate(engine, self, "Iron Sword", "item_names")
Display the returned text, but don't store it in place of the original. Your data must retain the text in the Default language, so that it can be translated again when the language changes. For Actor names, call the functions described in Translating Names instead. Translating in Dialogues In a Dialogue, translate() can be called from any ¢ expression (see CandyRef Expressions). In an expression, self is the Engine running the Dialogue, so it is passed as both the Engine and the caller. For example, a Spoken Line displays the name of the player's current weapon with a text variable. Its Default and French Variations contain the same expression:
Default Is that ¤¢CandyWriting.get_shared().translate(self, self, globals.weapon, "item_names")¤ new? French C'est nouveau, ¤¢CandyWriting.get_shared().translate(self, self, globals.weapon, "item_names")¤ ?
If globals.weapon is "Iron Sword", the Default Variation displays "Is that Iron Sword new?" and the French Variation displays "C'est nouveau, Épée en fer ?". The same expression translates an Actor property that isn't a name, such as a title stored in Title: ¤¢CandyWriting.get_shared().translate(self, self, candy_de.actors.Ryn.Title, "actor_titles")¤, with a table of your own named actor_titles.