Skip to content

Dat‐Info design notes

Dominic Slee edited this page Sep 16, 2025 · 4 revisions

Motivation

The main questions the tool can answer are:

  1. Which track is the file about? It isn't mentioned in the file
  2. Is the replay legitimate? Does it pass the start, checkpoint1, checkpoint2 and finish?
  3. What is the checkpoint 2 time? Only Start/CP1/Finish are recorded.

Answering these questions from the *.dat file

1.The data we can extract from the replay *.dat file

1.1 The header

The first few bytes of the dat file has some timings:

function getTimingDataFromHeader(hexData: string, endNameAddr: number): TimingDataFromHeader {
  // for FM Matt 54.35
  // 63.78 (total recording time)
  // 6.41  (cross start + start delay)
  // 26.65 (checkpoint 1 total time)
  // 60.76 (total time to finish)
  return {
    totalRecordingTimeMs: 10 * parseLittleEndian16(hexData.slice(8, 12)),
    crossStartPlusStartDelayMs: 10 * parseLittleEndian16(hexData.slice(endNameAddr + 2, endNameAddr + 6)),
    checkpoint1TotalMs: 10 * parseLittleEndian16(hexData.slice(endNameAddr + 10, endNameAddr + 14)),
    totalTimeToFinishMs: 10 * parseLittleEndian16(hexData.slice(endNameAddr + 18, endNameAddr + 22)),
  };
}

Notable that the checkpoint 2 crossing time is not recorded in the header.

1.2 Position data

It also has the position data for every 0.01s, so for a recording of 60.76s, there are 6076 coordinate blocks.

2. The data we can extract from the levels

Using the level data, for example Data/Levels/Alpine/Tracks/Easy/Day/Level_Data.txt, we can extract the following objects

  • Player_Start_Location: A point where the player starts
  • Start_Point: A bounded plane that starts the timer (a circle of radius 90m)
  • Check_Point_1: A bounded plane that marks checkpoint 1 (a circle of radius 90m)
  • Check_Point_2: A bounded plane that marks checkpoint 2 (a circle of radius 90m)
  • Finish_Point: A bounded plane that marks the finish line, stopping the timer (a circle of radius 90m)

Notes:

  • uniform_scale has no impact on the radius of 90, for example, check the finish (Finish_Point) of Alpine Easy.
  • The loc of the objects do not match their definitions in Level_Data.txt when it is actually rendered, because the game moves the object down to match the ground.

A clear example of loc not being the actual coordinates is Alpine Medium:

Check_Point_1 {
  uniform_scale        = 1;
  loc                  = {608.411,-465.376,654.901};
  level_inclusion_mask = -1;
  offset               = {0,0,0};
  quat                 = {0.996218,{0,0.0868903,0}};
  melt_height          = 0;
};

Using Cheat Engine, the in game x,y,z coordinates are:

["xxx_Point_74", [608.411011, -551.169128, 654.901001]],

Mainly, the y-value changed (Level_Data.txt is -465.376, real value is -551.169128) , the x and z values are minor rounding errors.

The Start_Point has y of -817 and the Finish_Point has y of 315, so a smaller value of y means that Check_Point_1 was moved up to match the ground level.

Special cases

For the 9 main tracks, the starting position can differentiate them, with the exception of

  • Alpine Easy/Medium/Hard
  • Forest Medium/Hard

For Alpine Easy/Medium/Hard, we can compare when the coordinate data crosses checkpoint 1, with the reported checkpoint 1 time.

Using circleTool/ to generate the checkpoint 1 circles:

The data is accurate to ±0.01s, and the checkpoint circles do not intersect, and the player can't travel between them within 0.02s.

The problem we are avoiding is, if the data reports:

  • 18.01 for checkpoint 1 time
  • the coordinate data crosses AM checkpoint 1 in 18.00
  • the coordinate data crosses AE checkpoint 1 in 18.02

It would be ambiguous between AE and AM, but the player can not go this fast without cheating [calculation for km/h required].

A second special case is Oleg M's run of Village Medium v2, which is identical to Village Medium except for an added checkpoint 2. Checking if the coordinate data crosses checkpoint 2 can identify that this is v2 run.

Determining TrackName of a dat file

The scoring is:

  1. The player starts within 2m of any Player_Start_Location
  2. The first cross of any Start_Point is within ±0.01s of the reported time
  3. The first cross of any Check_Point_1 is within ±0.01s of the reported time
  4. The first cross of any Finish_Point is within ±0.01s of the reported time
  5. A cross of any Check_Point_2 exists with all of these true:
    • After the first cross of any Start_Point, if it exists
    • After the first cross of any Check_Point_1, if it exists
    • Before the first cross of any Finish_Point, if it exists

Each of these is one point. If one track scores more than all the others, it is considered a match (with the exception of FM/FH).

The CP2 split borrows the logic from point 5.

A replay is only valid if it scores the max amount of points, which is 5 points.

Future problems

  • Is it possible to extract key presses from the replay file? It may need to be figured out from the animations

Timing data explanation (FM 54.35)

Here is the header:

image

Offset Value Explanation
0x04 ea18 6378 (63.78s): Total recording time
0x18 4d61747400 Matt, terminated by 00
0x19 + len(name) 8102 641 (6.41s): cross start + start delay
0x19 + len(name) + 0x4 690a 2665 (26.65s): Checkpoint 1 total time
0x19 + len(name) + 0x8 bc17 6076 (60.76s): Total time to finish

The "Lag before start" is 3.01s, which based on coordinate data, not from the header.