Rocket League Replay Parser

Data Parsing and Analysis

A lightweight console application for parsing, analyzing, and converting Rocket Leauge replay files into a format that can be used in conjunction with a custom plugin for bakkesmod to allow a user to replay the scenario using the exact in game data for practice.

Rocket League Replay Parser preview

Built With

RustBoxCars

Goals

The core objectives driving this projects development and design

1

To parse and identify replays where a user mark was added. This would allow the identification of replays that the user intended to save for later analysis.

2

To convert replay files to a custom JSON format that can be used in conjunction with a custom plugin for bakkesmod. This plugin would allow the user to replay the scenario using the exact in game data for practice.

3

To learn the Rust programming language and explore the BoxCars library for parsing Rocket League replay files.

Key Features

1

Extremely fast parsing and analysis with low memory usage

2

Can identify replay files with user markers

3

Conversion from replay format to custom JSON that can be used in conjunction with a custom plugin

Challenges & Solutions

Challenge: Converting Quaternions

Rocket league replay files and the parsing tool used to analyze them stores rotation data in quaternions, which is incompatible with the plugin bakkesmod. This means that in order to replay the scenario using our custom plugin we need to convert the quaternions to a format that the plugin can understand.

Solution

Created a custom conversion helper method that is able to convert quaternions to a standard rotation format (pitch, yaw, roll).

Challenge: Tracking Player IDs

The way the raw data from the file is stored does not have a consistent ID for each player. The IDs are assigned when an object is created or destroyed. Each ID is re-used so in order to know what ID belongs to which player we need to track the IDs as they are created and destroyed.

Solution

Created a custom algorithm that is able to track the IDs of players as they are created and destroyed. This allows us to identify each player in the replay file even when their IDs change

Code Highlights

Quaternion To Rotation

Convert the quaternions stored in the replay file to a standard rotation format

1
fn from_quat(q: Quat) -> Self {
2
let [fwd, right, up] = [
3
Vector::new(1.0, 0.0, 0.0),
4
Vector::new(0.0, 1.0, 0.0),
5
Vector::new(0.0, 0.0, 1.0),
6
]
7
.map(|v| {
8
let mut rotated = rotate_vector_with_quat(v, q);
9
rotated.normalize();
10
rotated
11
});
12
13
let pitch = Self::angle_to_rotator_units(fwd.z.asin(), PI / 2.0, 16384.0);
14
15
let yaw = {
16
let heading = fwd.y.atan2(fwd.x);
17
Self::angle_to_rotator_units(heading, PI, 32768.0)
18
};
19
20
let roll = {
21
let vertical_reference = if up.z >= 0.0 {
22
Vector::new(0.0, 0.0, 1.0)
23
} else {
24
Vector::new(0.0, 0.0, -1.0)
25
};
26
27
let horizontal_right = {
28
let mut h = Vector::cross(fwd, vertical_reference) * -1.0;
29
h.normalize();
30
h
31
};
32
33
let roll_angle = Vector::dot(horizontal_right, right).clamp(-1.0, 1.0).acos();
34
35
let corrected_angle = match (right.z >= 0.0, up.z >= 0.0) {
36
(true, true) => -roll_angle,
37
(true, false) => -PI + roll_angle,
38
(false, false) => PI - roll_angle,
39
(false, true) => roll_angle,
40
};
41
42
Self::angle_to_rotator_units(corrected_angle, PI, 32768.0)
43
};
44
45
Rotator::new(pitch, yaw, roll)
46
}

Want to see more?