Matches
Start, pause and stop matches, set their limits and read the score.
A room is always in one phase: lobby between matches, playing, goal for 5.5 seconds after a goal, and finished for 5 seconds after a win before it returns to the lobby. The simulation runs at 60 ticks per second.
Control
startGame()
room.startGame(): Promise<void>Starts a match from the lobby, or from the finished phase. It does nothing while a match is running. There is no minimum number of players. Fires onGameStart.
Returns
Promise<void>
room.onPlayerJoin = async () => {
const fielded = room
.getPlayerList()
.filter((p) => p.team !== 0);
if (
fielded.length >= 2 &&
room.getScores() === null
)
await room.startGame();
};stopGame()
room.stopGame(): Promise<void>Ends the match and returns to the lobby. Fires onGameStop.
Returns
Promise<void>
pauseGame()
room.pauseGame(paused: boolean): Promise<void>Freezes or resumes a running match; it does nothing in the lobby. Resuming starts a two-second countdown (119 ticks) before play continues. Fires onGamePause or onGameUnpause, then onGamePauseChange.
Parameters
booleanrequiredtrue to pause, false to resume.Returns
Promise<void>
room.onPlayerLeave = async (player) => {
if (player.team !== 0)
await room.pauseGame(true);
};Rules
setScoreLimit()
room.setScoreLimit(limit: number): Promise<void>Applies only between matches: during a match the call does nothing. The default is 5.
Parameters
numberrequired0 to 99. 0 means no score limit. Other integers are clamped.Returns
Promise<void>
await room.setScoreLimit(3);
await room.setTimeLimit(5);
await room.startGame();setTimeLimit()
room.setTimeLimit(minutes: number): Promise<void>Applies only between matches. The default is 5 minutes. When time runs out, the leading team wins; if the score is level, play continues until the next goal.
Parameters
numberrequired0 to 99. 0 means no time limit.Returns
Promise<void>
setKickRateLimit()
room.setKickRateLimit(min?: number, rate?: number, burst?: number): Promise<void>Limits how quickly players can kick, to curb kick spam. Every player regains one tick of recharge per tick, up to rate × burst, and needs a non-negative balance to kick. Values are clamped to their ranges. Takes effect immediately, including during a match. Fires onKickRateLimitSet with the clamped values.
Parameters
number0–255. Defaults to 2.numberrate ticks. 0–255; 0 (the default) turns the budget off.number0–100. Defaults to 0.Returns
Promise<void>
// A 6-tick cooldown, two kicks a second
// sustained, and up to three kicks saved
// for a quick exchange.
await room.setKickRateLimit(6, 30, 3);State
getScores()
room.getScores(): HostScores | nulltime is the played time in seconds and timeLimit is in seconds. See HostScores.
Returns
HostScores | nullThe score, or null in the lobby and after the room closes.
const scores = room.getScores();
if (scores) {
const minute = Math.floor(scores.time / 60);
await room.sendAnnouncement(
`${minute}' Red ${scores.red}` +
` – ${scores.blue} Blue`,
);
}getBallPosition()
room.getBallPosition(): { x: number; y: number; } | nullReturns
{ x: number; y: number; } | nullThe ball's position, or null in the lobby and after the room closes.
room.onGameTick = () => {
const ball = room.getBallPosition();
if (ball && Math.abs(ball.x) < 1)
centreTicks++;
};getState()
room.getState(): MatchStateReturns the full MatchState: phase, tick counters, limits, the kickoff team and the raw disc data. Use getScores() and the physics methods for most needs; getState() is for tools that analyse the match in detail.
Returns
MatchStateA snapshot of the whole match.
const { phase, elapsed, red, blue } =
room.getState();
console.log(
phase,
(elapsed / 60).toFixed(1),
red,
blue,
);