ICU format
ICU is the placeholder syntax StoryBonsai uses inside text fields that
need to vary at runtime. When a writer types Hello {name}, the runtime
swaps {name} for the current value of the name variable before the
line is shown. ICU also handles plurals (one item vs five items),
branching on a string value (he vs she vs they), and ordinal forms
(1st, 2nd, 3rd).
You will type ICU in three places: the text of a
Dialogue event, the template of a
Set Variable (Text) event, and the
source text of a custom locale string (the text_* entries resolved by
Localize). The Online ICU Sandbox
listed under See also lets you try a template in a browser editor
without opening StoryBonsai.
Placeholders
A bare placeholder is a name in curly braces. The runtime substitutes the value of the matching variable or event-resolution argument at fire time.
Hello {name}. becomes Hello Kim. when name is the string Kim.
What populates a placeholder depends on the host field. Variables are the usual source on dialogue and set-variable-text events; localization argument bindings cover custom locale strings. The placeholder name itself has no type or formatting modifier; pick the variable or argument with the value you want to print, and the runtime prints it verbatim.
Plural
A plural picks one branch from a list of numeric forms based on the
value of a number argument. The forms are zero, one, two, few,
many, other, plus exact matches written as =0, =1, and so on.
StoryBonsai requires every plural to include an other branch as the
catch-all. Without it the editor will not export the project.
You have {n, plural, one {# arrow} other {# arrows}} left. becomes
You have 5 arrows left. when n is 5, and You have 1 arrow left.
when n is 1.
The # inside a branch substitutes the number that was matched. The
same shortcut works inside selectordinal branches.
Offset
offset:N subtracts N from the number before it picks a branch. The
# inside the branch then prints the reduced number, which is useful
when the speaker shouldn’t be included in the count.
{n, plural, offset:1 =0 {nobody} one {you and # other} other {you and # others}}
resolves to you and 2 others when n is 3.
Select
A select picks a branch by matching its string argument against named
keys. Keys match exactly; male and Male are different keys. Every
select needs an other branch, which is the fallback StoryBonsai uses
when no key matches.
{pronoun, select, he {He nods.} she {She nods.} they {They nod.} other {They nod.}}
resolves to She nods. when pronoun is she.
Use it for any small fixed set of cases that change a sentence’s wording: character pronouns, faction membership, weapon types.
Select ordinal
A select ordinal picks one branch based on the ordinal form of a number.
English uses one for 1st, two for 2nd, few for 3rd, and
other for the rest; other languages use a different mix. Selectordinal
works the same way as plural here: the other branch is mandatory in
StoryBonsai, and a template missing one fails the export gate.
{place, selectordinal, one {#st} two {#nd} few {#rd} other {#th}}
resolves to 3rd when place is 3. The # inside the branch
substitutes the original number, exactly as it does inside a plural
branch.
Nesting
Constructs nest inside each other’s branches. The inner construct is its own argument with its own rules; the outer construct picks a branch first, then the inner runs against the chosen branch’s text.
{count, plural, one {{tone, select, warm {an old friend} other {an acquaintance}}} other {a crowd}}
resolves to an old friend when count is 1 and tone is warm,
and a crowd when count is 5.
You can nest as deeply as you need, but every layer still has to be a valid construct on its own.
Literal braces
Wrap a literal { or } in apostrophes to print it as a character
instead of opening a placeholder. The apostrophes are quote marks for
the braces; they do not appear in the output.
Press '{'ESC'}' for {action}. resolves to Press {ESC} for menu. when
action is menu.
What’s not here
- Date, time, and number type-format placeholders. Constructs like
{n, number, percent}or{when, date, short}are not supported. Pre-format the value into a string variable before the line runs, then reference that variable from the template. Studio code can take a parseable value, like an ISO date, and write back the locale-appropriate display form. - Custom format types. A writer cannot register a new type name
(
{thing, mytype, …}) for the runtime to call. The set of supported constructs is the one listed above.
See also
- Online ICU Sandbox: try templates live in a browser editor.
- ICU MessageFormat reference: the full ICU spec.
- Dialogue: event whose text field accepts an ICU template.
- Set Variable (Text): event that resolves an ICU template into a string variable.
- Variable: string-typed variables can hold resolved templates.
- Localize: expression-side lookup for custom locale strings.