Candy Logo Copyright © 2025-2026 Candy Arts

Lexicon
The Lexicon is a dictionary of keywords found in spoken text. Wherever a keyword appears in a Spoken Line, the Lexicon can: - replace it with another text. - format it with BBCode. - display a tooltip when the mouse hovers over it. - turn it into a clickable link. Keywords aren't marked in Dialogues: the Engine locates them in every Spoken Line on its own. Lexicon Dictionary Lexicon.gd (in User_Data/Data_Tables) is a 'safe' file: updates never overwrite it. Keywords are defined in its lexicon dictionary:
var lexicon = { "*": { "Alice": { "Display": "", "Disabled": "", "BBCode": "[b][color=green]", "Tooltip": "Alice is a student.", "Clickable": false, "Click_Data": [], }, }, }
Variation Keys The top-level keys are matched against the name of the Spoken Line's chosen variation (e.g. "Default", "French", "Default_S=Female"). Each language can therefore define its own keywords.
  • "*" applies to every Variation.
  • A key ending with * (e.g. "Default*") applies to every Variation whose name starts with it.
  • A key without * (e.g. "Default") only applies to the Variation with that exact name.
Keys are case-sensitive, like Variation names: "french" doesn't apply to the French Variation. All the keys that apply to a Line are combined. When a keyword is defined under several of them, the most specific one is used: an exact name first, then the longest key ending with *, then "*". Keyword Entries Each keyword's entry contains the following keys, all optional:
DisplayThe text to display instead of the keyword. If empty, the keyword is displayed as written.
DisabledThe text to display instead of the keyword when the Lexicon is off, with no BBCode, tooltip or click added (see 'Lexicon Off' below). If empty, the keyword is displayed as written.
BBCodeThe BBCode tags to wrap the keyword in, e.g. "[b][color=green]". Only write the opening tags: the Engine adds the closing ones. Don't use [hint] or [url] tags here: the Engine adds them for Tooltip and Clickable.
TooltipText displayed when the mouse hovers over the keyword. If empty, no tooltip is displayed.
ClickableWhether clicking the keyword calls the _on_lexicon_clicked() function, and hovering it the _on_lexicon_hovered() function (see below).
Click_DataAny value, passed to _on_lexicon_clicked() when the keyword is clicked.
Finding Keywords Keywords are found as whole words, and are case-sensitive: "Alice" is found in "Alice's", but not in "alice" or "Malice". What counts as a whole word is set by the word rules (see 'Word Rules' below): by default, a keyword is never found next to a letter, a digit or _, in any language. A keyword can contain several words (e.g. "New York"). When keywords overlap, the longest one is used: "New York" is marked as a whole, even if "York" is also a keyword. Don't use the symbols . + * ? ( ) [ ] { } | ^ $ \ in keywords: they have a special meaning in searches, and the Lexicon then marks the wrong words, or nothing at all. If the displayed word needs one of them, use the Display key: write a plain keyword in the lexicon dictionary and in your Lines, and the symbols in Display.
"Mr_Smith": { "Display": "Mr. Smith", },
The tooltip is placed inside a BBCode tag ([hint=...]), which ends at the first ]. To write ] in a Tooltip, enclose the whole tooltip in quotes, inside the string:
"Tooltip": '"Alice [the student] is late."',
The quotes aren't displayed. Either " or ' can be used, but the tooltip can't contain the kind of quote it's wrapped in. Word Rules The word rules decide which characters may touch a keyword. They are set in the lexicon_word_rules dictionary, in Lexicon_Word_Rules.gd (in User_Data/Data_Tables), a 'safe' file: updates never overwrite it.
var lexicon_word_rules = { "*": { "Word": {"Categories": ["L", "N"], "Characters": ["_"], "Excluded": []}, "Joiners": {"Categories": [], "Characters": []}, }, "French*": { "Joiners": {"Characters": ["-"]}, }, "Japanese*": { "Word": {"Categories": [], "Characters": []}, }, }
A rule is one of two kinds:
RuleCharacters it lists
WordCharacters a keyword is never found next to, on either side. With letters as word characters, "Alice" isn't found in "Malice" or "Éalice".
JoinersCharacters that join two words: a keyword isn't found next to one that is followed, or preceded, by a word character. With - as a joiner, "Jean" isn't found in "Jean-Luc", but is found in "-Jean-" and "Jean - Luc".
Any other character ends a word: with the default rules, "Alice" is found in "Alice's", "(Alice)" and "°Alice". Each rule accepts the following keys:
  • Categories: Unicode categories or scripts, such as "L" (letters of every language), "N" (digits), "Lu" (capital letters), "Han" (Chinese characters) or "Latin".
  • Characters: characters typed one per item, such as ["_", "-", "@"].
  • Excluded (Word only): characters removed from the categories, which then end words.
The top-level keys are Variation keys, as in the lexicon dictionary. For each kind of rule, the most specific key that defines it is used, as a whole: in the example above, French Variations use the "*" key's Word rule and their own Joiners. Japanese Variations have no word characters at all, so keywords are found anywhere in their text, as Japanese writes no spaces between words. A keyword's own characters always match: "Jean-Luc" as a keyword is found as a whole, whatever the rules. When keywords overlap, the longest one is still used. An item that isn't a single character, or a category name Godot doesn't know, is reported in the output and ignored. If the lexicon_word_rules dictionary is missing, the Engine reports it at startup, and the default rules shown above apply. Marked Keywords A word is sometimes a keyword in some Lines only: "June" when it names a character, for example, but not when it names the month. For such a word, write the keyword with a prefix, and display the word without the prefix through the Display key:
"c_June": { "Display": "June", "Tooltip": "June is Alice's sister.", },
Writing "c_June" in a line displays "June" with its Lexicon formatting, while writing "June" alone displays the plain word without formatting. When the Lexicon is off, "c_June" is displayed as written. To display the plain word instead, write it in the keyword's Disabled key:
"c_June": { "Display": "June", "Disabled": "June", "Tooltip": "June is the sister of Alice.", },
Escaped Text The Lexicon never formats text written between the lexicon escape symbols (lexicon_escape_start_symbol and lexicon_escape_end_symbol in Candy_Properties.gd, ¬ by default), and the symbols aren't displayed:
¬June¬ is a month, but June is a student.
The first "June" is displayed as "June" without any formatting, the second is formatted by the Lexicon. Escapes matter most for text the player provides: a player who names their character after a keyword mustn't see their name formatted like the keyword. The template Input Menu can escape what the player types (see Input Menus), and CandySanitizer.lexicon(text) escapes any other value (see Sanitization). To display a lexicon escape symbol as a literal, escape it by doubling it: ¬¬ is displayed as ¬. Clickable Keywords When a clickable keyword is clicked, the Engine calls the _on_lexicon_clicked() function, in the On_Lexicon_Clicked.gd script (in User_Data/Functions). It's a 'safe' file: updates never overwrite it. The function is empty by default: write there what the click does, such as opening a glossary page or a character sheet.
func _on_lexicon_clicked(candy_args: Dictionary, user_args: Array, custom_data: Array): var data = candy_args["data"] var caller = candy_args["caller"] var ui = candy_args["ui"] var keyword = data["keyword"] var keyword_data = data["keyword_click_data"] var keyword_variation = data["keyword_variation"]
  • keyword: the keyword that was clicked, as written in the lexicon dictionary.
  • keyword_click_data: the keyword's Click_Data value.
  • keyword_variation: the Variation key the keyword's entry comes from.
  • caller: the Engine running the Line.
  • ui: the UI Element the keyword was clicked in (e.g. dialogue box, subtitles, chat channel, bubble).
To pause the Dialogue while the click's result is on screen, suspend it (see Suspending Dialogues). Hovered Keywords A keyword's Tooltip requires no code: Godot displays it by itself. To display something of your own while a keyword is hovered, such as a panel with a picture, write it in the _on_lexicon_hovered() function, in the On_Lexicon_Hovered.gd script (in User_Data/Functions). It's a 'safe' file too. The Engine calls it when the mouse enters a clickable keyword, and again when the mouse leaves it. It receives the same values as _on_lexicon_clicked(), and one more:
  • hovered: true when the mouse enters the keyword, false when it leaves it.
func _on_lexicon_hovered(candy_args: Dictionary, user_args: Array, custom_data: Array): if candy_args["hovered"]: my_panel.show_keyword(candy_args["data"]["keyword"]) else: my_panel.hide()
Only clickable keywords are reported: set Clickable to true for every keyword that needs it. A keyword that reacts to the mouse but not to clicks is clickable too, with an _on_lexicon_clicked() that ignores it. Clickable Appearance Clickable keywords are links: by default, Godot underlines them. The underline is disabled through the meta_underlined property of the RichTextLabel displaying the text. Engine Settings The Lexicon can be enabled or disabled for each Dialogue Mode in the Engine settings, under the Lexicon category, through the lexicon_box_mode, lexicon_subtitles_mode, lexicon_chat_mode, lexicon_bubbles_mode, lexicon_barks_mode and lexicon_voice_mode variables. All are enabled by default. The Engine's lexicon_{mode}_mode settings can be overridden by the UI Elements that display speech (dialogue box, subtitles...), by Actor properties (in the actors dictionary) and by Spoken Line data. Lexicon Off When the Lexicon is off for a Line, the Engine still locates its keywords, but only replaces each one with its Disabled text: no BBCode, tooltip or click is added, and Display isn't used. A keyword with no Disabled text is displayed as written. Escaped text is left as written here too. The Dialogue History has no Lexicon formatting either: it records every Line with its keywords replaced by their Disabled text, whether the Lexicon was on or off. BBCode The Lexicon relies on BBCode: the RichTextLabel displaying the text must have bbcode_enabled enabled. Otherwise, the Engine prints an error when the UI Element is loaded. Voice Mode Voice Mode doesn't display text, so formatting, tooltips and clicks don't apply. The Lexicon is still useful with TTS Simple mode: when lexicon_voice_mode is enabled, keywords are replaced with their Display value in the text passed to TTS. For example, a keyword "HP" with a Display of "health points" is read out in full. The keywords' BBCode, tooltip and link tags are stripped from the text TTS reads (the "text" argument of tts()). They remain in its "raw_dialogue" argument. A _TTS Variation is written to be read as it is, so the Lexicon never applies to it, in any TTS mode: neither Display nor Disabled replaces its keywords. Only the lexicon escape symbols are removed from it, so they aren't read aloud.