Difference between revisions of "Modding:Tokenizable strings"

From Stardew Valley Wiki
Jump to navigation Jump to search
 
(expand and reorganize into doc page)
Line 3: Line 3:
 
← [[Modding:Index|Index]]
 
← [[Modding:Index|Index]]
  
==From [[Modding:Migrate to Stardew Valley 1.6]]==
+
This page documents '''tokenizable strings''', a built-in way to build display text which can contain any combination of literal text, translations, and placeholder values.
===Tokenizable string format===
 
Stardew Valley 1.6 adds support for literal strings that contain tokens. These are only usable in specific fields (their docs will say 'tokenizable string' with a link to this section).
 
  
====Literal text====
+
==Overview==
Previously you often needed to load text from a [[Modding:Modder Guide/Game Fundamentals#String keys|string key]] in data assets. With this new format, you can use the literal text directly in the asset instead (including Content Patcher tokens):
+
===Overview===
 +
You can only use tokenizable strings in data fields that specifically allow them (which will be indicated in the wiki docs).
  
 +
A tokenizable string can contain any combination of literal text and tokens ([[#Tokens|listed below]]). For example:
 
<syntaxhighlight lang="js">
 
<syntaxhighlight lang="js">
// before
+
"Dialogue": "Welcome to Pierre's! How is [FarmName] doing?"
"Dialogue": "Strings\\StringsFromCSFiles:ShopMenu.cs.11488",
+
</syntaxhighlight>
 +
 
 +
When using [[Modding:Content Patcher|Content Patcher]], you can use its tokens anywhere in the string (including within square brackets); they'll be expanded before the game parses the string. For example, <code><nowiki>"{{Spouse}} would love [ArticleFor [SuggestedItem]] [SuggestedItem]!"</nowiki></code> would output something like "''Abigail would love an Apple!''".
  
// after: literal text supported
+
===Token format===
"Dialogue": "Welcome to Pierre's!",
+
A ''token'' is a predefined placeholder which produces text, wrapped in square brackets. Token names are not case-sensitive, so <samp>[LocalizedText]</samp> and <samp>[LOCALIZEDTEXT]</samp> are equivalent.
  
// after: literal text with Content Patcher tokens
+
For example, this will show a message like "''Welcome to Pierre's! This is raw text''":
"Dialogue": "Welcome to Pierre's, {{PlayerName}}! {{i18n: translatable-text}}",
+
<syntaxhighlight lang="js">
 +
"Dialogue": "[LocalizedText Strings\StringsFromCSFiles:ShopMenu.cs.11488] {{i18n: some-translation}}"
 
</syntaxhighlight>
 
</syntaxhighlight>
  
====Tokens====
+
===Token argument format===
You can inject tokens using square brackets. For example, <code>"[LocalizedText Strings\StringsFromCSFiles:ShopMenu.cs.11488] This is raw text"</code> will show something like "''Welcome to Pierre's! This is raw text''". Token names are not case-sensitive.
+
A token can optionally have arguments (which can in turn contain tokens). In the above example, the <samp>LocalizedText</samp> takes one argument (the translation key to display). Arguments are space-delimited, so you need to use <samp>EscapedText</samp> to pass an argument containing spaces:
 +
<syntaxhighlight lang="js">
 +
"Dialogue": "[LocalizedText [EscapedText Strings\BundleNames:Quality Fish]]"
 +
</syntaxhighlight>
  
Here are the supported tokens:
+
==Tokens==
 +
Here are the tokens provided by the base game:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 84: Line 91:
 
|}
 
|}
  
When passing an input argument for tokens like <samp>ArticleFor</samp>, the input can contain its own nested tokens. For example, <code>"[ArticleFor [SuggestedItem]] [SuggestedItem]"</code> would output something like ''an Apple''.
+
==Extensibility for C# mods==
 
 
If you're using [[Modding:Content Patcher|Content Patcher]], you can use its tokens anywhere in the string (including within square brackets); they'll be expanded before the game parses the string. For example, <code><nowiki>"{{Spouse}} would love [ArticleFor [SuggestedItem]] [SuggestedItem]!"</nowiki></code> would output something like "''Alexa would love an Apple!''".
 
 
 
====Extensibility====
 
 
C# mods can define custom tokens by calling <code>TokenParser.RegisterParser("tokenName", ...)</code>. To avoid conflicts, prefixing custom condition names with your mod ID (like <samp>Example.ModId_TokenName</samp>) is strongly recommended.
 
C# mods can define custom tokens by calling <code>TokenParser.RegisterParser("tokenName", ...)</code>. To avoid conflicts, prefixing custom condition names with your mod ID (like <samp>Example.ModId_TokenName</samp>) is strongly recommended.
  
 
[[Category:Modding]]
 
[[Category:Modding]]

Revision as of 19:44, 21 November 2023

The following describes the upcoming Stardew Valley 1.6, and may change before release.

Index

This page documents tokenizable strings, a built-in way to build display text which can contain any combination of literal text, translations, and placeholder values.

Overview

Overview

You can only use tokenizable strings in data fields that specifically allow them (which will be indicated in the wiki docs).

A tokenizable string can contain any combination of literal text and tokens (listed below). For example:

"Dialogue": "Welcome to Pierre's! How is [FarmName] doing?"

When using Content Patcher, you can use its tokens anywhere in the string (including within square brackets); they'll be expanded before the game parses the string. For example, "{{Spouse}} would love [ArticleFor [SuggestedItem]] [SuggestedItem]!" would output something like "Abigail would love an Apple!".

Token format

A token is a predefined placeholder which produces text, wrapped in square brackets. Token names are not case-sensitive, so [LocalizedText] and [LOCALIZEDTEXT] are equivalent.

For example, this will show a message like "Welcome to Pierre's! This is raw text":

"Dialogue": "[LocalizedText Strings\StringsFromCSFiles:ShopMenu.cs.11488] {{i18n: some-translation}}"

Token argument format

A token can optionally have arguments (which can in turn contain tokens). In the above example, the LocalizedText takes one argument (the translation key to display). Arguments are space-delimited, so you need to use EscapedText to pass an argument containing spaces:

"Dialogue": "[LocalizedText [EscapedText Strings\BundleNames:Quality Fish]]"

Tokens

Here are the tokens provided by the base game:

token format output
[ArticleFor <word>] The grammatical article (a or an) for the given word when playing in English, else blank. For example, [ArticleFor apple] apple will output an apple.
[CharacterName <name>] The translated display name for an NPC, given their internal name.
[DayOfMonth] The numeric day of month, like 5 on spring 5.
[EscapedText]
[EscapedText <text>]
Marks a snippet of text as a single argument, so it can be safely passed into another token's space-delimited arguments even if it's empty or contains spaces.

For example, the SpouseFarmerText expects two arguments separated by spaces. This passes an empty string for the first one, and text containing spaces for the second:

[SpouseFarmerText [EscapedText] [EscapedText spouse 28 63 2]]
[FarmerUniqueID] The target player's unique internal multiplayer ID
[FarmName] The farm name for the current save (without the injected "Farm" text).
[FarmerStat <key>] The value of a tracked stat for the current player. See the PLAYER_STAT game state query for a list of useful stats.

For example:

"You've walked [FarmerStat stepsTaken] so far."
[GenderedText <male text> <female text> Depending on the target player's gender, show either the male text or female text. If the text contains spaces, you'll need to escape them using EscapedText.
[LocalizedText <string key>]
[LocalizedText <string key> <token values>+]
Translation text loaded from the given string key. If the translation has placeholder tokens like {0}, you can add the values after the string key.
[LocationName <location ID>] The translated display name for a location given its ID in Data/Locations.
[PositiveAdjective] A random adjective from the Strings\Lexicon data asset's RandomPositiveAdjective_PlaceOrEvent entry.
[Season] The current season name, like spring.
[SpouseFarmerText <spouse is farmer text> <spouse is NPC text> Show a different text depending on whether the target player's spouse is a player or NPC. If the text contains spaces, you'll need to escape them using EscapedText.
[SpouseGenderedText <male text> <female text>] Equivalent to GenderedText, but based on the gender of the player's NPC or player spouse instead.
[SuggestedItem [interval] [sync key]] (For shops only.) The name of a random item currently available in the shop stock.

The result will be identical for all queries with the same [sync key] during the given [interval] (one of tick, day, season, year), including between players in multiplayer mode. If omitted, they default to day and the shop ID respectively.

Extensibility for C# mods

C# mods can define custom tokens by calling TokenParser.RegisterParser("tokenName", ...). To avoid conflicts, prefixing custom condition names with your mod ID (like Example.ModId_TokenName) is strongly recommended.