Reference
Routines
The routine class handles coroutines. A coroutine is a function that can hand control back to the game in the middle of its own flow and be resumed later, so a sequence that waits on the game can be written top to bottom instead of as a handler per step. The functions that wait can only be used from within a routine, and pass control back to the game until the routine resumes.
Static members#
These elements are static to the class itself and can be accessed like so:
local r = ss.routine(function() ss.wait(3) end)Static functions#
| Function | Return Values | Description |
|---|---|---|
ss.routine(
function f,
vararg args
) |
routine routine | Creates a new routine and runs it at once, up to its first wait. Additional arguments are passed to the function f. |
ss.routine(
string name,
function f,
vararg args
) |
routine routine | Creates a new routine with a name, which is shown in the log when the routine errors, and runs it at once. |
ss.wait(seconds seconds) |
nil | Exits the current routine, resuming it on the first frame tick after the given number of seconds. |
ss.wait_frames(integer frames) |
nil | Exits the current routine, resuming it on the first frame tick after the given number of frames. |
ss.wait_until(function f) |
nil | Exits the current routine, resuming it on the first frame tick on which f() returns true. An error in f ends the routine. |
ss.wait_event(string name) |
table ev | Exits the current routine, resuming it when the given event fires, after the event's handlers have run. Returns the event's payload. |
ss.wait_signal(string name) |
any values | Exits the current routine, resuming it when ss.signal is called with the given name. Returns the arguments ss.signal was given. |
ss.signal(
string name,
vararg args
) |
integer woken | Signals all routines that are waiting for the given name via ss.wait_signal, passing them the arguments. Returns the number of routines woken. Usable from a handler, a timer or another routine. |
ss.routines.count |
integer count | The number of the mod's routines that are live. |
ss.routines.all() |
table of routine routines | Returns a table of references to all of the mod's live routines. |
ss.routines.stop_all() |
nil | Stops all of the mod's live routines. |
A wait outside a routine results in an error. The waits are driven from the frame tick, in every app state, so a routine keeps waiting and resuming through the menus and after the race it was started in has ended.
Instance members#
Instance members must be accessed through a reference to a specific routine object.
local r = ss.routine(function() ss.wait(10) end)
ss.log(r.waiting)
r:stop()Instance Methods#
| Function | Return Values | Description |
|---|---|---|
stop() |
nil | Abandons the routine where it waits, preventing it from resuming. |
Instance Fields#
| Type | Field | Read-only? | Description |
|---|---|---|---|
| boolean | running |
Yes | Returns true while the routine has not finished, errored or been stopped. |
| boolean | done |
Yes | Returns true once the routine's function has returned. |
| string | error |
Yes | The error that ended the routine, with its traceback. nil if no error ended it. |
| string | waiting |
Yes | What the routine is waiting on: time, frames, until, event or signal. nil while the routine is not waiting. |
| string | name |
Yes | The name the routine was started with. nil if none was given. |
Errors and the race#
An error inside a routine ends it and is reported like a handler's error, with the traceback; the other routines
keep running. A routine lives in its mod's state, not in the race: it is not stopped when a race ends, and a
routine that resumes from a long wait may find the cars gone. Check
ss.race.state or
ss.vehicle.valid after a wait that could have outlasted the
race, or start the routine from a race_start handler and stop it from a race_end
handler.
Example#
local run
ss.on("race_start", function()
run = ss.routine("brake test", function()
ss.wait(5)
local ai = ss.vehicles[1]
if not ai then return end
ai.input = { throttle = 0, brake = 1 } -- an AI car brakes to a stop
ss.wait_until(function() return not ai.valid or ai.speed < 1 end)
if ai.valid then ai.input = nil end -- and drives off again
end)
end)
ss.on("race_end", function()
if run then run:stop(); run = nil end
end)