subtr-actor
July 9, 2026 ยท View on GitHub
WebAssembly bindings for subtr-actor, a Rocket League replay processing library.
This package mirrors the Python binding at a JavaScript/TypeScript-friendly boundary: pass replay bytes in, get structured data or ndarray-like output back.
Related npm packages:
@rlrml/subtr-actor: low-level WebAssembly bindings@rlrml/player: replay player package built on top of these bindings@rlrml/stats-player: stats-focused replay viewer UI built on top of the player package
Installation
npm install @rlrml/subtr-actor
Runtime Support
The published npm package is the web-target ESM build produced by wasm-pack. It is the right fit for browsers and bundlers.
If you need a Node-specific build from the repository, build it yourself with:
npm --prefix js install
npm --prefix js run build:nodejs
That generates js/pkg-node/.
Usage
Browser / bundler
import init, {
get_column_headers,
get_ndarray_with_info,
get_replay_frames_data,
get_replay_info,
get_replay_meta,
validate_replay,
} from "@rlrml/subtr-actor";
await init();
const replayData = new Uint8Array(
await fetch("/example.replay").then((response) => response.arrayBuffer()),
);
const validation = validate_replay(replayData);
if (!validation.valid) {
throw new Error(validation.error ?? "Replay is not valid");
}
const info = get_replay_info(replayData);
const headers = get_column_headers(
["BallRigidBody", "SecondsRemaining"],
["PlayerRigidBody", "PlayerBoost", "PlayerAnyJump"],
);
const ndarrayResult = get_ndarray_with_info(
replayData,
["BallRigidBody", "SecondsRemaining"],
["PlayerRigidBody", "PlayerBoost", "PlayerAnyJump"],
10.0,
);
const metadata = get_replay_meta(replayData);
const frameData = get_replay_frames_data(replayData);
console.log(info);
console.log(headers.player_headers.slice(0, 5));
console.log(ndarrayResult.shape);
console.log(metadata.replay_meta.player_stats.length);
console.log(frameData.meta.map_name);
API Surface
validate_replay(data: Uint8Array)
Validate that replay bytes can be parsed successfully.
Return shape:
{ valid: true, message: "Replay is valid" }
or:
{ valid: false, error: "..." }
get_replay_info(data: Uint8Array)
Return lightweight replay metadata including version numbers and property counts.
parse_replay(data: Uint8Array)
Parse raw replay bytes and return the full replay structure as plain JS data.
get_ndarray_with_info(data, globalFeatureAdders?, playerFeatureAdders?, fps?)
Return numerical replay data suitable for analysis or ML.
Defaults:
- global features:
["BallRigidBody"] - player features:
["PlayerRigidBody", "PlayerBoost", "PlayerAnyJump"] - FPS:
10.0
Return shape:
{
metadata: {
replay_meta: { /* replay metadata */ },
column_headers: {
global_headers: string[],
player_headers: string[],
},
},
array_data: number[][],
shape: number[],
}
get_replay_meta(data, globalFeatureAdders?, playerFeatureAdders?)
Return replay metadata plus column headers without building the full ndarray.
get_column_headers(globalFeatureAdders?, playerFeatureAdders?)
Return only the ndarray header layout for a given feature configuration.
get_replay_frames_data(data)
Return structured frame-by-frame data from ReplayDataCollector. This path does not do FPS resampling.
Common Feature Names
See the subtr-actor ndarray docs for the full list.
Common global features:
"BallRigidBody""CurrentTime""SecondsRemaining"
Common player features:
"PlayerRigidBody""PlayerBallDistance""PlayerBoost""PlayerAnyJump""PlayerJump""PlayerDodgeRefreshed""PlayerEvent:touch"
"PlayerBoost" is exposed in raw replay units (0-255), not percentage.
Analysis-backed player event indicators use "PlayerEvent:<event_name>" and
emit 1 for a sampled frame when that player has a new event, otherwise 0.
Building from Source
Requirements:
- Rust toolchain
wasm-packjustnpm
Repository-local bundler build:
just build-js
Publishable web build from js/package.json:
npm --prefix js install
npm --prefix js run build
Other package targets:
npm --prefix js run build:nodejs
npm --prefix js run build:bundler
Tests:
npm --prefix js test
Local packages built on top of these bindings:
@rlrml/player/js/player: reusable replay player library with imperative playback and camera APIs.@rlrml/stats-player/js/stat-evaluation-player: stats-focused replay viewer package with timeline overlays and per-module stat panels.
The mechanics evaluation player was moved to the sibling subtr-actor-mechanics
project because it is tied to mechanics-specific datasets and review workflows.
Publishing Notes
This binding depends on the workspace crate via:
[dependencies.subtr-actor]
path = ".."
version = "1.2.0"
That keeps local development wired to the workspace crate while still pinning the published crate version. Use just bump <version> to update the versions together.
License
MIT