Reference
Events
Events are the names a mod listens to with ss.on. Every
handler receives a single table, ev, carrying the fields listed in the event's signature below.
Handlers run on the game's main thread, from the frame tick or from the game function that raised the event,
so a slow handler stalls the game for that long. Each handler runs under pcall: an error is logged
with a traceback and the remaining handlers still run. A handler that fails fifty times in a row is removed.
ss.on("race_start", function(ev)
ss.log("green light, mode %s", tostring(ev.mode))
end)Per-tick events#
These events run every frame (sometimes under specific conditions). Most events cost nothing when no mod
listens; draw, ui and input go further and are only raised at all while a
mod has a handler for them.
| Event | Description |
|---|---|
tick(
seconds dt,
integer frame
) |
Runs every frame, in every app state. Executes from the game loop's frame hook; timers and routines are driven from it. Passes the frame time and the number of frames ticked so far. |
draw(
integer width,
integer height
) |
Runs every frame, in every app state. Executes on the game loop, and whatever the handler draws with ss.draw is painted over the frame after the game's own HUD. Passes the size of the back buffer. A ss.draw call outside this event results in an error. |
ui(
integer panels,
integer screen
) |
Runs every frame while one of sshook's custom front-end screens is on stage. This is the frame in which ss.ui widgets are drawn. Passes the number of billboards and the index of the screen on stage. |
input(
integer player,
boolean is_local
) |
Runs once per player per frame, just before the game hands the player's input record to the car: the pad has been sampled and the record filled, and the frame's physics steps have not run. Passes the player's index and whether the player is local. The record can be read and rewritten through vehicle.input.raw; the controls a script holds are applied after the handlers. Does not run while the game is paused. Before the green light the local record carries values no key made, so a handler that wants the pad should wait for race_start. |
Triggered events#
These events only run under specific circumstances.
Game and race state#
| Event | Description |
|---|---|
state(
string from,
string to
) |
Runs when the game moves between its coarse app states: boot, frontend, loading and race. Passes the previous and the new state. |
race_state(
integer id,
string name,
integer from_id,
string from
) |
Runs when the race state machine changes state. The machine is polled every frame while the in-game controller ticks. Passes the new state's id and name and the previous state's id and name. Leaving the race raises one last race_state to none (id -1), after the vehicle, player and prop groups have been emptied. |
race_start(
string mode,
integer mode_index
) |
Runs at the green light, when the race state becomes racing (6). Passes the mode's name and index, as ss.race.mode and ss.race.mode_index report them. The name is nil in a dev-boot race. |
race_finish() |
Runs when the race state goes from racing to finished (7): the local player's race is over. Other cars may still be driving. |
race_results() |
Runs when the race state becomes results (8). |
race_end(
integer last_id,
string last
) |
Runs when the app state leaves the race, through a quit to the menus or a restart. Passes the id and name of the race state the race was in when it ended. By the time the handler runs, ss.vehicles, ss.players, ss.nemesis and ss.props are empty and any object kept from the race is no longer valid, because the level that held them is being freed. |
race_event(
integer id,
string name,
integer arg1,
integer arg2,
integer arg3,
number f1,
integer flag,
integer race_state
) |
Runs when the game's race logic sends itself one of its per-race events, with the record exactly as the game built it. Passes the event's id and name, its three integer arguments, its float, its flag and the race state id at the time. The ids seen so far are listed under Race event ids. lap and finish_line are also raised as events of their own. |
lap() |
Runs when the game's race logic records a completed lap (race event id 5). For the lap's time and the player it belongs to, use lap_time. |
finish_line(
integer arg1,
integer flag
) |
Runs when the game's race logic records a finish line crossing (race event id 7). Passes the record's first argument and its flag: 0 when the last lap starts, 1 when the race is finished. |
countdown(
integer count,
seconds seconds
) |
Runs when the grid countdown's whole second changes (race state 5). Passes the whole second shown (3, 2, 1; a dev-boot race counts from 5) and the exact seconds left. The green light that follows is race_start, not a countdown of 0. See Countdowns and finishing. |
timer(
string kind,
integer seconds,
seconds exact,
boolean running
) |
Runs when one of the mode countdowns the HUD shows changes its whole second, starts or stops, for the local player's copy of it. Passes the kind (countdown for the mode timer, elimination for the seconds to the next elimination, event_end for the event-end countdown, race_end for the online race-end countdown), the whole seconds left, the exact seconds left and whether the timer is running. None of these timers run in a dev-boot race. |
Players#
These events are polled from each player's component outputs once a frame while the in-game controller ticks,
and raised when a value changes. A new race takes a fresh baseline without raising anything. The
player field is the 0-based index the player class uses, and
is_local is whether the player is the local one.
| Event | Description |
|---|---|
position(
integer player,
integer position,
integer from,
boolean is_local
) |
Runs when a player's place in the field changes. Passes the player, the new place (1-based) and the previous place. Only raised from the green light on (race states 6, 7 and 8), as the order means nothing while the field forms in the intro. Where the place comes from is explained under Positions and scores. |
score(
integer player,
integer score,
integer delta,
boolean is_local
) |
Runs when a player's score changes. Passes the player, the new score and the change. Race mode awards no score, so a plain race never raises this; Survival, Air Strike, Air Revenge and Detonator do. |
player_state(
integer player,
string state,
string from,
integer position,
boolean is_local
) |
Runs when a player's state moves between waiting, racing and finished. Passes the player, the new state, the previous state and the player's place at the time. |
player_lap(
integer player,
integer lap,
integer laps,
boolean is_local
) |
Runs when a player's lap counter changes. Passes the player, the lap the player is now on (-1 until the line is first crossed) and the number of laps in the race. For the lap's time, use lap_time. |
vehicle_state(
integer player,
string state,
integer state_id,
string from,
integer from_id,
integer position,
boolean is_local
) |
Runs when a car's vehicle state changes. Passes the player, the new state's name and id, the previous state's name and id, and the player's place at the time. |
wreck(
integer player,
integer position,
number progress,
boolean is_local,
boolean crashed
) |
Runs when a car's state moves from outside crashing, wrecked and respawning into that family. This is the same transition the game's own wreck statistic counts. Passes the player, the player's place and the player's progress (the lap plus the fraction of the current one). crashed is true when the car crashed, and false when the game is only placing it back on the track: for going the wrong way, for leaving the track, or for a respot. |
respawn(
integer player,
integer position,
boolean is_local
) |
Runs when a car's state moves back out of the wrecked family. Passes the player and the player's place. |
powerplay(
integer player,
boolean is_local,
integer id,
integer index,
string name,
number x,
number y,
number z,
boolean scripted,
integer trigger,
integer position
) |
Runs when a Power Play fires: a player's button, the AI, or a script's fire. Passes the player who fired and the player's place, and the Power Play: its index in ss.powerplays, its name, the game's id for it and its position (zeros if it keeps none). scripted is true for a fire from a script; trigger is passed only then, and player and position are nil if the script fired it as nobody's. The Power Plays the game fires by itself, and who was hit, are not covered yet. |
checkpoint(
integer player,
integer checkpoint,
integer splits,
integer lap,
seconds lap_time,
seconds sector,
seconds race_time,
integer position,
boolean is_local
) |
Runs when a car's fraction of the lap first passes checkpoint / splits on a lap. Passes the player, the split reached (1 to splits - 1), the splits per lap in effect, the lap, the running lap time at the crossing, the seconds since the previous split (or since the line for the first), the race clock and the player's place. Raised once per split per lap, only on laps that count, and good to one frame. See Checkpoints and lap times. |
lap_time(
integer player,
integer lap,
integer laps,
seconds time,
seconds race_time,
seconds best,
boolean is_best,
boolean is_local
) |
Runs when the Laps component closes a lap. Passes the player, the lap just completed (1-based), the number of laps in the race, the lap's exact time on the race clock, the race clock when the lap closed, the player's best lap (nil until the best-lap record is valid) and whether this lap is the new best. |
player_finished(
integer player,
integer position,
seconds race_time,
integer lap,
integer laps,
integer score,
seconds best_lap,
string reason,
boolean is_local
) |
Runs when the game applies one of the mode's end rules to a car. Passes the player, the player's place at that moment, the race clock, the lap and the number of laps, the score, the best lap, and the reason: laps, race_over, eliminated, countdown or ended. player_state moves to finished a tick later; race_finish is the local player's own state machine. A dev-boot race has every end rule off, so nobody finishes there. The reasons are explained under Finishing. |
Race event ids#
The ids of the game's own race events, as race_event reports them.
| Type | Field | Description |
|---|---|---|
| integer | 4 |
controller_start: once per race, when the in-game controller is created. |
| integer | 5 |
lap: a lap completed. |
| integer | 6 |
lap_progress: progress along the lap, in f1. |
| integer | 7 |
finish_line: the line crossed; flag is 0 when the last lap begins and 1 when the race is finished. |
| integer | 0xa |
mode_tick: the mode's tick, with the frame time in f1. |
| integer | 0xb |
player_stuck: the game decided a player is stuck. |