Skip to main content
The Phichain format is the native chart format for the Phichain toolchain. It provides the most comprehensive feature set and is the recommended format for chart creation.

File Structure

Phichain charts are JSON files with the following top-level structure:
{
  "format": 5,
  "offset": 0.0,
  "bpm_list": [
    {
      "beat": [0, 0, 1],
      "bpm": 120.0
    }
  ],
  "lines": [
    // Line objects
  ]
}

Field Reference

PhichainChart

The root object representing a complete chart.
format
integer
required
Format version number. Current version is 5. Used for automatic migration of older charts.
offset
number
required
Audio offset in milliseconds. Positive values delay the chart, negative values advance it.
"offset": -50.0  // Chart starts 50ms earlier
bpm_list
array
required
List of BPM change points. Must have at least one entry at beat 0.Each BPM point contains:
  • beat: Beat position as [bar, numerator, denominator]
  • bpm: Tempo in beats per minute
"bpm_list": [
  { "beat": [0, 0, 1], "bpm": 120.0 },
  { "beat": [8, 0, 1], "bpm": 140.0 }
]
lines
array
required
Array of SerializedLine objects (judgment lines).

SerializedLine

Represents a judgment line with its notes, events, and child lines.
name
string
default:"Unnamed Line"
Display name for the line in the editor.
notes
array
required
Array of Note objects attached to this line.
events
array
required
Array of LineEvent objects controlling line behavior.
Every line must have events for all five event types: x, y, rotation, opacity, and speed.
children
array
default:"[]"
Array of child SerializedLine objects. Child lines move relative to their parent.
curve_note_tracks
array
default:"[]"
Array of CurveNoteTrack objects for slide note paths.

Note

Represents a single note on a judgment line.
{
  "kind": {
    "tap": null
  },
  "above": true,
  "beat": [4, 0, 1],
  "x": 0.0,
  "speed": 1.0
}
kind
object
required
Note type. One of:
  • {"tap": null} - Standard tap note
  • {"drag": null} - Drag note (doesn’t break combo if missed)
  • {"hold": {"hold_beat": [0, 3, 4]}} - Hold note with duration
  • {"flick": null} - Flick note
// Hold note lasting 3/4 beat
"kind": {
  "hold": {
    "hold_beat": [0, 3, 4]
  }
}
above
boolean
required
Whether the note appears above (true) or below (false) the judgment line.
beat
array
required
Note timing as [bar, numerator, denominator].Examples:
  • [0, 0, 1] - Beat 0 (start)
  • [4, 0, 1] - Beat 4 (bar 4)
  • [2, 1, 2] - Beat 2.5 (bar 2 + 1/2)
  • [0, 3, 16] - Beat 3/16
x
number
required
Horizontal position relative to the line center. Measured in pixels from the coordinate origin.Range: Typically -675 to 675 (half of canvas width 1350)
speed
number
required
Note approach speed multiplier. 1.0 is standard speed.

LineEvent

Controls line properties over time.
{
  "kind": "x",
  "start_beat": [0, 0, 1],
  "end_beat": [4, 0, 1],
  "value": {
    "transition": {
      "start": 0.0,
      "end": 100.0,
      "easing": "ease_out_cubic"
    }
  }
}
kind
string
required
Event type:
  • "x" - Horizontal position (pixels)
  • "y" - Vertical position (pixels)
  • "rotation" - Rotation angle (degrees)
  • "opacity" - Opacity (0-255)
  • "speed" - Note approach speed multiplier
start_beat
array
required
Event start time as beat array.
end_beat
array
required
Event end time as beat array.
value
object
required
Event value. Either:Transition (value changes over time):
{
  "transition": {
    "start": 0.0,
    "end": 100.0,
    "easing": "linear"
  }
}
Constant (value stays fixed):
{
  "constant": 255.0
}

Easing Functions

Phichain supports the full range of easing functions:
"easing": "linear"
See the easing function documentation for the complete list.

Complete Example

Here’s a minimal but complete Phichain chart:
{
  "format": 5,
  "offset": 0.0,
  "bpm_list": [
    {
      "beat": [0, 0, 1],
      "bpm": 140.0
    }
  ],
  "lines": [
    {
      "name": "Main Line",
      "notes": [
        {
          "kind": { "tap": null },
          "above": true,
          "beat": [0, 0, 1],
          "x": 0.0,
          "speed": 1.0
        },
        {
          "kind": {
            "hold": {
              "hold_beat": [0, 1, 2]
            }
          },
          "above": true,
          "beat": [2, 0, 1],
          "x": 100.0,
          "speed": 1.0
        }
      ],
      "events": [
        {
          "kind": "x",
          "start_beat": [0, 0, 1],
          "end_beat": [100, 0, 1],
          "value": { "constant": 0.0 }
        },
        {
          "kind": "y",
          "start_beat": [0, 0, 1],
          "end_beat": [100, 0, 1],
          "value": { "constant": 0.0 }
        },
        {
          "kind": "rotation",
          "start_beat": [0, 0, 1],
          "end_beat": [4, 0, 1],
          "value": {
            "transition": {
              "start": 0.0,
              "end": 360.0,
              "easing": "ease_in_out_cubic"
            }
          }
        },
        {
          "kind": "opacity",
          "start_beat": [0, 0, 1],
          "end_beat": [100, 0, 1],
          "value": { "constant": 255.0 }
        },
        {
          "kind": "speed",
          "start_beat": [0, 0, 1],
          "end_beat": [100, 0, 1],
          "value": { "constant": 1.0 }
        }
      ],
      "children": [],
      "curve_note_tracks": []
    }
  ]
}

Advantages

Full Feature Set

Supports all Phichain features including child lines, curve notes, and complex easing.

Version Migration

Automatic migration from older format versions preserves compatibility.

Human Readable

JSON structure is easy to read, edit, and version control.

Type Safe

Rust structs provide compile-time validation of chart structure.

Schema Validation

The Phichain format is defined by Rust structs with serde serialization:
use phichain_chart::serialization::PhichainChart;

let chart: PhichainChart = serde_json::from_str(&json_string)?;
Source definition: phichain-chart/src/serialization.rs
The format version is automatically checked during deserialization. Older versions are migrated to the current version.

Next Steps

BPM and Timing

Learn about beat representation and timing

Editor Guide

Create charts in Phichain Editor