The .bytes file format is a binary format used for storing chart data in a certain rhythm games with Unity-based engines. This format is a derivative of the .pt format and contains timing information, note data, tempo changes, and references to audio samples (officially called instruments).
The file consists of several sections in the following order:
[File Header] [Instruments] [Tracks...] [Header]
Note that the [Header] could be anywhere in-between. But it is typically located at the end of file.
All multi-byte integers are stored in little-endian format.
| Type | Size | Description |
|---|---|---|
int32 |
4 bytes | 32-bit signed integer |
uint32 |
4 bytes | 32-bit unsigned integer |
uint16 |
2 bytes | 16-bit unsigned integer |
float |
4 bytes | 32-bit IEEE 754 floating point |
byte |
1 byte | 8-bit unsigned integer |
sbyte |
1 byte | 8-bit signed integer |
bool |
1 byte | Boolean value (0 = false, non-zero = true) |
string[N] |
N bytes | UTF-8 encoded string, null-terminated, padded to N bytes |
ticks |
4 bytes | The smallest musical time-division unit, stored as a 32-bit unsigned integer (uint32) unless otherwise noted.The number of ticks per measure is music-specific but it has universal maximum value of 192 in common rhythm games. For example, in a 4/4 bar with 192 ticks per measure, each quarter-note beat is 48 ticks (192 ÷ 4). |
Position: 0x00
Size: 8 bytes
| Offset | Type | Description |
|---|---|---|
| 0x00 | int32 |
File format version |
| 0x04 | uint32 |
Offset of music header |
Position: 0x08
Size: Variable (67 bytes per instrument)
Each instrument reference contains:
| Offset | Type | Description |
|---|---|---|
| +0 | uint16 |
Instrument ID (Typically start from 0) |
| +2 | bool |
Stream flag Determine whether the audio music file will be play as a stream as opposed to one-shot. Usually set to true for audio sample with long duration to reduce large memory usage of the cost of small cpu cycles. |
| +3 | string[64] |
Audio filename (UTF-8, null-terminated) |
Instrument ID
Position: After instruments
Size: Variable
Each track represents one Lane (also known as Channel), such as the individual note lanes that players interact with.
This should not be confused with event types (which is closer concept to Channel, like BPM changes or volume changes). While some rhythm game formats use "channel" and "lane" interchangeably, in this particular .bytes format, tracks (lanes) and event types (channels) are two distinct concepts.
For an instance: BPM change in Lane #6 mixed with normal notes. This is usually is not possible in other format since BPM change most of the time has their own lane/channel.
Each track contains a header followed by events:
Position: At the beginning of each track Size: 74 bytes
| Offset | Type | Description |
|---|---|---|
| +0 | uint16 |
Track ID |
| +2 | string[64] |
Track name (UTF-8, null-terminated) |
| +66 | int32 |
Track data length in bytes |
| +70 | int32 |
Number of events in track |
Each event is exactly 13 bytes:
| Offset | Type | Description |
|---|---|---|
| +0 | int32 |
Event position in ticks |
| +4 | byte |
Event type |
| +5 | byte[8] |
Event-specific data |
Events are identified by a single byte type field:
| Value | Name | Description |
|---|---|---|
| 0 | Start | Initial event for initial track |
| 1 | Note | Note/background sample |
| 2 | Volume | Volume change |
| 3 | Bpm | Tempo change |
| 4 | Beat | Time signature change |
| Offset | Type | Description |
|---|---|---|
| +0 | uint16 |
Instrument ID (ins) |
| +2 | byte |
Velocity (vel) |
| +3 | byte |
Pan position (pan) |
| +4 | byte |
Note type (attr) |
| +5 | uint16 |
Length (Dur) |
| +7 | byte |
Unused |
| Value | Name | Description |
|---|---|---|
| 0x00 | Note | Either Normal or Hold note |
| Value | Name | Description |
|---|---|---|
| 0x00 | Normal/Drag | Normal note or drag note. If the NoteType is 0x00 and the Length is not 0 (typically 6) then it is considered as a Drag note. |
| 0x05 | StartChain | Start of a chain sequence |
| 0x06 | EndChain | End of a chain sequence |
| 0x0A | StartRepeat | Start of a repeat sequence |
| 0x0B | EndRepeat | End of a repeat sequence |
| 0x0C | Hold | Hold note |
| Offset | Type | Description |
|---|---|---|
| +0 | byte |
New Volume value |
| +1-7 | byte |
Unused |
| Offset | Type | Description |
|---|---|---|
| +0 | float |
New BPM value |
| +4-7 | byte |
Unused |
| Offset | Type | Description |
|---|---|---|
| +0 | int32 |
Beats per measure |
| +4-7 | byte |
Unused |
Position: As specified by header pointer
Size: 32 bytes
| Offset | Type | Description |
|---|---|---|
| +0 | uint16 |
Number of instrument references |
| +2 | uint16 |
Number of tracks |
| +4 | uint16 |
Ticks per measure (typically 192) |
| +6 | float |
Default tempo (BPM) |
| +10 | int32 |
Total ticks in song |
| +14 | float |
Play duration (ticks) |
| +18 | int32 |
Last event tick |
| +22 | int32 |
Total event count across all tracks |