Stadiums and replays
Check stadium files and decode recordings without opening a room.
Both functions are exported by ball2d and ball2d/node and work without an API key or a running room.
validateStadium()
validateStadium(source: string): StadiumValidationParses the stadium exactly as a room would and throws if a room could not load it. It checks syntax, structure, geometry and the collision budget; passing means the stadium loads, not that it plays well.
Sources are limited to 256 KB, 63 discs, 1,024 vertexes, 64 planes, 16 goals and 128 joints. Unknown fields don't fail validation; each is reported in warnings, such as Unsupported stadium field: $.discs[2].bar.
Parameters
stringrequired.ball2dstadium or JSON file.Returns
StadiumValidationThe stadium name, whether it may be stored, and warnings for fields Ball2D ignores.
import { readFile } from 'node:fs/promises';
import { validateStadium } from 'ball2d/node';
const source = await readFile(
'futsal.ball2dstadium',
'utf8',
);
try {
const report = validateStadium(source);
console.log(report.name, report.warnings);
} catch (error) {
console.error(
'Stadium rejected:',
error.message,
);
}readReplay()
readReplay(blob: Blob): Promise<Replay>Decodes and verifies a recording. Recordings are binary; don't parse them as JSON.
Only recordings made with the same engine build can be read. A recording from another engine rejects with Unsupported replay engine/version, so keep the SDK version you recorded with if you need to read old files.
Parameters
BlobrequiredReturns
Promise<Replay>The decoded recording.
import { readFile } from 'node:fs/promises';
import { readReplay } from 'ball2d/node';
const bytes = await readFile('final.ball2drep');
const replay = await readReplay(
new Blob([bytes]),
);
const seconds =
(replay.end - replay.initial.tick) / 60;
console.log(
`${seconds.toFixed(1)} s,` +
` ${replay.commands.length} commands`,
);StadiumValidation
Import fromball2dball2d/node
interface StadiumValidationstringrequiredUntitled stadium when the source has none.booleanrequiredfalse only when the source sets canBeStored: false.readonly string[]required