PH Replays
This document describes a proposal for storing replays for Project Heartbeat
Replay package
PH replays are contained within a file similar to a ZIP file with UTF-8 file namings
The structure is the following:
- root/
- replay.json
Contains basic replay information metadata, does not include the actual replay data.
- replay.phr
Contains actual replay information.
- song.json
Contains a copy of the original song.json meta file.
Replay info metadata (replay.json)
Should be a JSON file with the following structure:
- root
- song_id: String
Local ID of the song.
- song_ugc_id: String (optional)
UGC service ID of the song, if available.
- song_ugc_service: String (optional)
UGC service this song comes from (currently only “Steam Workshop”).
- song_title: String
Song title
- song_title_romanized: String
Song title (romanized version).
- difficulty: String
Difficulty (chart name) of the played song.
- user_id: String
Service ID of the player that played this replay Might be: - SteamID64 (for Steam users). - Windows/Linux user name for when Steam was not available when creating the replay.
- user_service: String
Service the player for this replay came from (should be “steam” or “local” for non logged in users).
- chart_hash: String
A SHA-1 generated from the contents of the original chart .json file.
Replay file (replay.phr)
All in little endian.
All strings are utf-8 and have their length prefixed as a uint16.
Magic number:
0x500x480x52(PHR).Version: uint8
Song ID: String
Song difficulty String
Song chart hash: String
Gamepad device count: uint8
- Gamepad device metadatas:
Device id: uint8
Device name: String
Device SDL GUID: String (may be empty)
Event count: uint32
Events
EVENT_TYPE: uint8
Value |
Name |
Description |
|---|---|---|
0 |
GAMEPAD_JOY_AXIS |
Single axis gamepad |
1 |
GAMEPAD_JOY |
Two axis gamepad |
2 |
GAMEPAD_BUTTON |
Gamepad button |
3 |
KEYBOARD_KEY |
Keyboard key |
ACTION_BITFIELD: uint8
Value |
Name |
|---|---|
0x1 |
NOTE_UP |
0x2 |
NOTE_LEFT |
0x4 |
NOTE_DOWN |
0x8 |
NOTE_RIGHT |
0x10 |
SLIDE_LEFT |
0x20 |
SLIDE_RIGHT |
0x40 |
HEART_NOTE |
Event type: EVENT_TYPE
Event game timestamp, in microseconds: int64
- Action: ACTION_BITFIELD
Main action for this event
- Actions: ACTION_BITFIELD
Actions triggered by this individual hardware press
- Pressed: uint8
Whether this is a press or release event
- Device ID: uint8_t
Device that triggered this action, will be the gamepad ID if its a gamepad event, will be 0 if its a keyboard event
- Event data:
union { double joystick_position[2]; // Second value will be 0.0 in case of single axis events uint8_t gamepad_button_idx; uint64_t keyboard_key; }