Using variables
Displaying a game's name, picking an image per system.
A variable is written ${…} and Recalbox replaces it at display time.
<text name="titre">
<text>Bienvenue sur ${system}</text>
</text>
→ “Bienvenue sur Super Nintendo”.
In an image path: the most useful
<image name="console" extra="true">
<path>${root}/data/arts/consoles/${system.name}.png</path>
</image>
One single line, and each system displays its own image. The files just have to bear the system's internal name: snes.png, megadrive.png…
Where each variable works
This is the rule that surprises the most, and it comes from the engine:
| Family | Views where it is resolved |
|---|---|
${system…} | Systems and Game list — a list always belongs to a system |
${game…} | Game list and Screensaver — wherever there is a hovered game |
${recalbox…} ${settings…} ${hardware…} ${display…} | everywhere |
A variable used where it does not exist is not replaced: the raw text shows as is, ${game.name} included. The studio only offers the ones that work on the current view.
When the highlighted row is not a game
In the game list, the cursor does not only travel across games: it also lands on folders and on sort headers, those intertitles Recalbox adds as soon as the list is sorted by anything other than alphabetical order. The ${game…} variables still answer, but they then describe a row that has no game:
| Highlighted row | ${game.name} | ${game.releasedate} | ${game.file.name} |
|---|---|---|---|
| a game | its name | its release date | the rom file |
| a folder | the folder name | UNKNOWN | the folder name |
| a sort header | nothing | UNKNOWN | nothing |
A component showing game data therefore has nothing left to say on those rows — and yet it stays on screen, on top of the folder name Recalbox writes at the same moment. Restrict it to game rows:
<text name="sortie" extra="true" showIf="game">
<text>Released: ${game.releasedate}</text>
</text>
The studio takes care of it: as soon as a component uses game data, its visibility switches to “a game”. The component’s Visibility tab lets you open it back up to folders and headers whenever that is what you want.
${root} — never to forget
${root} designates the root of the selected theme. Without it, paths are relative to the file that writes them, and your theme breaks as soon as it is stored differently.
<path>${root}/data/arts/fond.jpg</path> <!-- ✅ -->
<path>../data/arts/fond.jpg</path> <!-- fragile -->
The old $… variables
In old themes you will come across variables without braces:
| Old | What it gives | Current equivalent |
|---|---|---|
$system | the short name — “snes” | ${system.name} |
$theme | the theme's folder | ${root} |
⚠️ $system and ${system} do not give the same thing: the first yields “snes”, the second “Super Nintendo”. They are still accepted, but deprecated: only write the braced form from now on.
The random draw
<path>${random.between(fond1.jpg,fond2.jpg,fond3.jpg)}</path>
<fontSize>${random.range(1,10)}</fontSize>
random.between picks a value at random from the list, random.range a number between two bounds. The draw happens when the theme loads, not on every display.