Feeding Achievements¶
Upcoming SDK release
Achievements ship in an upcoming Scorbit SDK release. This section documents that release ahead of time, so details may still change before it ships.
The SDK evaluates achievements from the same game state your code already reports. There is no
separate achievements input except events (named counters), and no call to ask for evaluation.
Every commit() re-evaluates every achievement for every claimed player.
This page covers what to report, and how to report it, so that achievements authored for your title match what your game actually does.
Before the First Game: Data Directory¶
The SDK caches achievement definitions and the DMD frame bundle on disk. Give it a writable directory that survives reboots, before you create the game state. Without one, the SDK uses a temporary directory, which works but may be emptied on reboot, so definitions are downloaded again.
What the SDK Watches¶
Each commit() records one row of game state. Achievements are derived from these rows only:
| You report | With | Achievements can use it as |
|---|---|---|
| Each player's score | set_score |
Score thresholds |
| The current ball | set_current_ball |
Ball durations, "on ball one" |
| The active player | set_active_player |
Which player each fact belongs to, and each player's time at the machine |
| Active modes | add_mode, add_mode_expiring, remove_mode, clear_modes |
Mode starts, modes running together, how long a mode lasted |
| A mode the player beat | set_mode_completed |
Mode completions |
| A running total | add_event |
Counters such as spinner spins or ramps |
Scores belong to the player you pass to set_score. Mode starts, completions and events belong
to the active player at that commit, so keep set_active_player accurate in multiplayer
games.
Commit Often¶
Evaluation happens on commit(), and commit cadence is also the timing resolution for
achievements: two things reported in the same commit happened at the same instant. Commit at every
meaningful change, and at least once per game loop cycle as the
Game Loop page already recommends. Calls that don't change anything are
cheap.
Mode Names Must Match Exactly¶
An achievement refers to a mode by name, and the name must be byte-for-byte identical to the
string your game passes to add_mode, including any category prefix:
| Your game calls | A rule must reference |
|---|---|
add_mode("MB:Multiball") |
MB:Multiball (not Multiball, not mb:multiball) |
add_mode("NA:Reactor") |
NA:Reactor |
Names are case-sensitive, and are neither trimmed nor normalized. Mode and event names must not
contain ;, =, ,, " or a newline. Those characters are structural in the game log:
add_event ignores a name containing them, and achievements never match a mode named with them.
An existing mode whose name already contains one of these characters keeps working for scoreboards and the game timeline; it just can't be used in an achievement. If it should be, report it under a compliant name, for example in a firmware update.
Keep names stable across firmware versions where you can. A renamed mode silently stops matching every published achievement that refers to it, and published achievements can't be edited to follow the rename.
The Creator Portal learns your names
The platform records every mode and event name your game reports, and offers them to creators authoring achievements for your title. Reporting consistent names is what makes good achievements possible for your game.
Modes That Run vs Modes That Can Be Completed¶
Achievements distinguish two kinds of mode:
- Modes that simply run, such as a multiball. They start, last a while and end, and there is no
failing them. Report them with
add_modeandremove_mode. Achievements count their activations: each time the mode goes from inactive to active. - Modes the player can win or fail, such as a wizard mode or a timed quest. Report the mode as
usual, and when the player succeeds, call
set_mode_completedin the same commit in which you remove it. If the player fails, just remove the mode.
A completed mode is a one-time mark, not a state: it is recorded only in the next commit and is not added to the active mode list.
Report success before the game ends
A mode the game never marks as completed can never satisfy a completion achievement. If your game has a success state for a mode, report it.
Short-lived modes and targets¶
add_mode_expiring adds a mode that removes itself after a few seconds: 3 is recommended, 0 means
3, and anything over 10 is clamped to 10 (Python defaults to 3). It is the right call for momentary
events such as a jackpot or a lit target. Adding it while it is inactive counts as one activation.
Calling it again while it is still active extends it: the timer restarts with the new duration,
and it doesn't count as a new activation, so no separate "extend" call is needed. Achievements see
the expiry at the next commit(). Prefer it to adding a mode and then clearing all modes, which
also ends any multiball or wizard mode that is running.
Events: Named Counters¶
An event is a named 64-bit counter your game adds to: spinner spins, ramp shots, targets hit, lanes completed. Use events for anything you count rather than anything that is on or off.
add_event(name, value)addsvalueto the counter.valuemay be negative to reduce it.- There is no "set" operation: counters only accumulate.
- Like a completed mode, each call is recorded in the next commit only. Several calls before a commit are all recorded.
- In a single-game achievement the counter starts at zero each game. In a lifetime achievement it accumulates across every game the player has played.
Call add_event only when the counter actually changes. Each call marks the game state as changed,
so the next commit() sends an update even if nothing else moved.
Players and Claims¶
Achievements belong to people, so only players who have claimed a slot (see Claiming a Position) can earn them.
- When a player claims a slot, the SDK fetches their stored progress, whenever the claim happens. Lifetime achievements then continue from their real totals.
- Only what happens after the claim counts. A player who claims partway through a game is not credited with anything that slot did before they claimed. Progress is never worked out retroactively.
- Players who never claim earn nothing from that game.
- A claim made after the game ends, or one whose progress is still being fetched when the game ends, earns nothing from that game on the machine.
Prompt players to claim before they play
Because achievements only count from the claim onward, make claiming easy before the first ball: show the claim QR code on the start screen and during ball one (see Claiming a Position), and remind players that achievements are only tracked once they claim.
Balls and Time¶
- Session time is per player. A player's time at the machine is the sum of their own turns, not wall-clock time, so a four-player game produces four different session times.
- A ball ends when the ball number changes, the active player changes, or the game ends.
- Single-ball confinement. Ball durations, mode durations, "within N seconds" windows and "on ball N" conditions never span a ball boundary. Two multiballs on different balls never count as "two multiballs within thirty seconds".
- All durations are in milliseconds.
Next Steps¶
- Achievement Rules: exactly how each fact is counted
- Definitions, Progress and Events: reacting to unlocks