Skip to content

09. Argument‐Formatted Strings: Phrase Maps

Ketei edited this page Apr 22, 2026 · 5 revisions

I. Introduction and Core Principles

1.1 Purpose and Role

The Phrase Maps tool is a standalone utility designed for creating reusable, dynamically formatted, and conditionally varied text strings.

  • Role: Ideal for UI labels, notifications, system messages, combat text, or any text outside of the main dialogue system that requires dynamic formatting logic.
  • Storage: Each Phrase Map is stored as a single PhraseMap resource file (.tres), which features a custom icon.

Note

Unlike the Discourse tool, which manages localization internally, each PhraseMap resource file corresponds to only one locale. To support multiple languages, you must create separate files for each one (e.g., ui_text_en_US.tres, ui_text_es_MX.tres).
Double-clicking a PhraseMap resource file will automatically open it within the Nexus Forge Phrase Map tool.


II. The Editor Interface (Three-Column Layout)

The editor is designed for managing multiple files and defining complex conditional formatting cases.

2.1 File Management and Locale (Left Column)

This column controls resource loading and sets the context for the phrase map.

  • File Access:
    • A text field at the top allows searching among open files.
    • A vertical three-dot menu provides options to Create New or Open Phrase Map resources.
  • Open Files Tree: Lists all the opened files.
  • Locale Selection:
    • Two dropdown menus allow the user to explicitly define the Language and Country for this Phrase Map file (e.g., "English" and "United States of America" for en_US or "French" + "N/A" for fr).
    • These dropdowns are pre-populated with all locales supported by Godot and default to the user's system language on launch.

Note

The file tree lists all loaded files by name. Hovering over a file displays its full file path in a tooltip.

2.2 Key Creation and Text Definition (Center Column)

This column manages the creation and base text assignment for all phrases.

  • Search Functionality: A search bar allows filtering keys.
  • Creation: A button featuring a dialog bubble and a green '+' adds a new key-value pair to the map.
  • Key/Text Fields: This is where the unique Key (e.g., GREETING) and the Base Text (e.g., Hello {player_name}) are defined.
  • Conflict Resolution: If a newly entered key is identical to an existing key, the text fields for both entries will turn red, signaling a conflict.
  • Case Editing Toggle:
    • A Pencil Icon next to the key/text pair toggles the case editing mode.
    • When pressed, the icon changes to an Unlocked Lock, the Base Text field is disabled (as its content is now managed by cases), and Column 3 is enabled. The Key field remains editable.
    • Pressing the Unlocked Lock icon again saves the cases and re-enables the Base Text field.

Tip

The search bar by default searches on both keys and text, but supports prefixes for targeted searching:

  • key:: Searches only within the unique key fields.
  • text:: Searches only within the assigned base text fields.

Caution

To prevent data loss on save, the editor will automatically solve key conflicts by adding numerical suffixes (1, 2, 3, etc.) to the conflicting or empty keys.

2.3 Conditional Case Management (Right Column)

This column is used to define the complex, argument-based output logic for the selected phrase.

  • Case Search: A search bar allows filtering cases.
  • Format Field Selection:
    • A dropdown lists all format tags (e.g., $player/name, !potion_count, day_time) found in the base text without curly brackets. You select one to define conditional cases for it.
    • A button next to the dropdown (Curly brackets with a green +) adds a new custom case for the selected tag.
  • Case Conflicts: If two custom cases share the exact same condition (e.g., two cases for "1"), the text will turn red.

Tip

The search bar by default searches on both cases and results, but supports prefixes for targeted searching:

  • case:: Searches only within the specific case condition (e.g., "0" or "Jhon").
  • result:: Searches only within the resulting output text.

Note

  • The default case is always visible and cannot be removed.

Caution

To prevent data loss on save, the editor will automatically solve case conflicts by adding numerical suffixes (1, 2, 3, etc.) to the conflicting or empty keys.


III. Advanced Formatting and Conditionals

The Phrase Maps tool combines the power of the Nexus Forge variable system and a specific object for method calling, with standard Godot argument formatting.

3.1 Comprehensive Formatting Support

Phrase Maps support all three primary formatting syntax types within a single phrase definition:

Syntax Name Source Usage
{$...} Variable Access NexusForge.Blackboard Retrieves data (e.g., {$player/level}) from global state.
{!...} Method Call PhraseAPI[1] Calls a function and inserts its return value. Supports stacking (e.g., {!capitalize|!get_player_name}).
{...} Standard Arguments Passed via API call Inserts arguments (e.g., {day_time}) passed explicitly to the get_text function.

Important

When defining conditional cases, the value being checked is always converted to a string before comparison. This is especially important for variable access ({$...}) or method calls ({!...}) that return numbers.
A float value of 1 will be converted to the string "1.0", which will NOT match a custom case defined for the string "1".


IV. Usage in GDScript (API Hooks)

The API is accessed directly from an instance of the loaded PhraseMap resource.

4.1 Primary Formatting Function

Function Signature Purpose Return Type
get_text(key, override_values = {}) Primary Function: Retrieves and formats the phrase text. String

The override_values Dictionary

This dictionary is the key to the tool's flexibility. It provides values for all format types:

  1. Standard Placeholders ({...}): You must provide a key for standard placeholders (e.g., {"day_time": "morning"}).
  2. Expression Overrides ({$...} and {!...}): You can provide a key matching the full expression string (e.g., {"$player/level": "99", "!player_name": "james"}). If these keys exist, the system uses the provided value and skips the internal Blackboard lookup or method call entirely.

4.2 Lifecycle and Management

Function Signature Purpose Return Type
entries() Returns a list of all registered format entries. Array[StringName]
set_entry(key, text = "") Creates a new format entry and sets its base text. -
get_entry(key) Returns the base text of the format entry. String
has_entry(key) Returns true if the format entry key exists. Bool
erase_entry(key) Deletes the format entry. -

4.3 Conditional Case Logic Management

These functions allow granular, programmatic control over the conditional logic.

Function Signature Purpose Return Type
get_valid_formats(phrase_text) Static helper that returns all format tags ({...}) found in a string. Array[String]
get_formats(of) Returns all parts that can be formatted on an entry. Array[String]
has_format(entry, format) Checks if the phrase's base text contains the specified format tag (format). Bool
set_format_default(entry, format, value) Sets the fallback text (default case) for a specific format tag. -
get_case_default(entry, of) Returns the default case text for a format tag. String
set_case(entry, argument, case, value) Sets a custom case condition (case) and its result (value) for a format tag. -
clear_cases(entry, argument Clears all custom cases for a specific format tag. -
get_case(entry, argument, case) Returns the result for a specific custom case. String
has_case(entry, argument, case) Checks if a specific custom case condition exists. Bool

V. Format Example

Tip

  • In order to use the passed down argument in a case text, you need to write down the case between curly braces. (e.g., Using {$player/name}).
  • When creating cases for a format tag you can use the arguments from other tags in your main one. (e.g., Using "There are {!potion_count}" as a case result when editing the cases for $player/name).

Using the text "{!companion_count} collected {potion_count} {$player/name}{$player/companion/name}".

Format Tag Cases Note
!companion_count Default: You and {$player/companion/name}
"0": You've
We're using the passed argument from $player/companion/name in a !companion_count case.
potion_count Default: {potion_count} potions
0: no potions. Well that's a shocker
1: one single potion. Try harder next time
We need to pass this argument via overrides.
$player/name Default: {$player/name}.
mxyzptlk: m-mx...you!
$player/companion/name Default: We needed this info for a case in !companion_count but we don't want it in the final text, so we default to empty so it'll be removed.

Two examples of possible result are:

  • You and Mia collected one single potion. Try harder next time John.
  • You've collected 13 potions m-mx...you!

VI. Footnotes

  1. The default path of the PhraseAPI is: res://addons/nexus_forge/resources/localization/phrase_api.gd

Clone this wiki locally