Guide
Match commentary
The commentary box under the board in a match, and the lines of colour in Watch highlights, come from commentary lines. Lines are content: a mod can add its own, switch core ones off, change how often they're said, or rewrite them.
Lines live in any file in data/commentary/. Each file is a JSON array. The editor schema is the commentary lines reference, and the Mod Studio edits them under Media → Commentary. Patches target commentary:<id>.
[
{
"id": "acme.commentary.big-fish",
"trigger": "maxCheckout",
"text": "The big fish! {player} lands 170 and {opponent} can only watch.",
"weight": 2
},
{
"id": "acme.commentary.tenth-maximum",
"trigger": "180",
"condition": { "minN180": 10 },
"text": "That's {n180} maximums for {player}. Double figures!"
}
]| Field | Meaning |
|---|---|
id | Namespaced id, starting with your mod's id |
trigger | The moment it's for (see Triggers) |
condition | Optional. minN180 / maxN180: the player's 180s in the match so far. minScore / maxScore: the score |
text | What the commentator says, with placeholders |
weight | How often it's picked against the other lines for the same moment. Default 1; 0 means never |
When a moment comes up, the match takes every line for its trigger whose condition holds and picks one by weight. The pick is seeded by the match, so watching the same match again gives the same commentary. A moment with no lines passes in silence.
Triggers#
| Trigger | When | Filled |
|---|---|---|
matchStart | The bull-up is won and the match starts. {player} throws first | player, opponent |
180 | A maximum | n180 (this one included) |
ton40 | A visit of 140 or more (not 180) | score |
lowScore | A visit of 26 or less with more than 100 left | score |
bust | A bust | |
missedDoubles | Three darts at a double in a visit, none hit | |
missedMatchDart | A dart at a double for the match, missed | |
nineDarterOn | Two maximums from 501: 141 left after six darts | |
ton | A visit of 100 to 139 | {score} {remaining} |
onAFinish | A visit under 100 that first leaves a score that can be taken out | {score} {remaining} |
steadyScore | A visit of 60 to 99 | {score} {remaining} |
visit | Any other visit that no moment above covers | {score} {remaining} |
checkout | A leg won on a finish under 100 | checkout, darts, score (= the checkout) |
tonPlusCheckout | A leg won on a finish of 100 or more (not 170) | checkout, score |
maxCheckout | A leg won on 170 | checkout, score |
nineDarter | A leg won in nine darts | |
breakOfThrow | A leg won against the throw (not the last leg of the match) | |
setWon | A set won | legs (the score) |
matchWon | The match is over | legs (the score), avg |
conductWarning | The referee warns the player about their conduct | |
legDocked | The referee docks the player a leg; it goes to the opponent | legs (the score) |
matchForfeited | The referee ends the match: the player forfeits it | |
winByTwo | A race won by clear legs reaches its tie-break; the player throws first | legs (the score) |
suddenDeath | The bull-up before a sudden-death leg; the player won it | legs (the score) |
legStart | Not used by the match yet: the loader warns, and such lines are never said |
{player}, {opponent}, {n180}, {legs} and {avg} are filled for every moment. The score a minScore / maxScore condition checks is the visit's score, or the checkout for the leg-winning triggers.
Watch highlights uses the same lines for its moments: 180s, big visits (ton40), busts, nine-darters, nine-dart attempts, breaks of throw, missed match darts and doubles, sets, and legs won (checkout, tonPlusCheckout or maxCheckout by the finish).
Placeholders#
| Placeholder | Filled with |
|---|---|
{player} | The player the moment is about |
{opponent} | The other player |
{score} | The visit's score (or the checkout) |
{n180} | The player's 180s in the match so far |
{checkout} | The checkout |
{darts} | Darts the player took to win the leg |
{legs} | The score in legs, or in sets ("2–1 in sets") |
{avg} | The player's three-dart average in the match |
{remaining} | What the visit left (ton, onAFinish, steadyScore, visit) |
A placeholder a moment doesn't fill reads as nothing. A line using a placeholder that isn't on this list is dropped, with a warning that names it.
Changing the core lines#
The core pack's lines are core.commentary.<name> (in data/commentary/en.json of the core pack). Patch them like any record:
[
{ "target": "commentary:core.commentary.bust2", "patch": { "weight": 0 } },
{ "target": "commentary:core.commentary.co1", "patch": { "weight": 5 } },
{
"target": "commentary:core.commentary.ms2",
"patch": { "text": "{player} wins the bull. Game on." }
}
]The core lines are translated with the game's interface strings (commentary.<name> in the game's locale files), so they follow the player's language. A core line whose text a mod has changed says the mod's text instead, in every language, unless the mod translates it too.
Translating#
Your lines are translated with a content translation patch in locale/<lang>/patches/, like any other content (see Localisation):
[
{
"target": "commentary:acme.commentary.big-fish",
"patch": { "text": "Der große Fisch! {player} checkt 170, und {opponent} kann nur zusehen." }
}
]Keep the placeholders; they're filled the same way in every language.
Saves#
A career keeps the commentary lines it was created with. Commentary is flavour, so a career you load picks up the installed packs' lines, and exhibition matches always use them.
The example-rules mod adds 59 lines for every moment, switches one core line off and translates its lines into German.