Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/LiveSplit/livesplit-core/llms.txt

Use this file to discover all available pages before exploring further.

livesplit-core can read splits files produced by a wide variety of speedrun timers. The composite parser automatically detects the format and hands off to the appropriate format-specific parser, so you typically do not need to know which format a file uses.

Supported Formats

The following formats are supported for reading:
FormatNotes
LiveSplit (.lss)Native format — also the only format supported for saving.
Face Split
Flitter
LibreSplit
Llanfair
Llanfair (Gered’s fork)
OpenSplit
Portal 2 Live Timer
Shit Split
Source Live Timer
Speedrun IGT
Splitterino
SplitterZ
Splitty
Time Split Tracker
WSplit
Only the LiveSplit .lss format is supported for saving. All other formats are read-only.

Parsing a File

Use composite::parse when the file format is unknown. It tries each parser in turn and returns the first successful result.
use livesplit_core::run::parser::composite;
use std::fs;
use std::path::Path;

// Read the raw bytes of the splits file.
let path = Path::new("splits.lss");
let data = fs::read(path).expect("Failed to read file");

// Parse the file. Passing the path allows the parser to load
// external resources (e.g. segment icons stored as separate files).
let parsed = composite::parse(&data, Some(path))
    .expect("Not a valid splits file");

// Which format was detected?
println!("Format: {}", parsed.kind);

// Extract the Run.
let run = parsed.run;
println!("Game:     {}", run.game_name());
println!("Category: {}", run.category_name());
println!("Segments: {}", run.segments().len());
The returned ParsedRun owns the Run and a kind: TimerKind value identifying the detected format.

Parsing Without a File Path

When no file system is available — for example, when receiving bytes over a network — pass None as the path. External resources (icons) will not be loaded, but the run data itself is parsed normally.
use livesplit_core::run::parser::composite;

// `data` could come from a network response, a database, or an in-memory buffer.
let parsed = composite::parse(&data, None)
    .expect("Not a valid splits file");

let run = parsed.run;

Parsing and Fixing

parse_and_fix extends the standard parse by also repairing known issues in the run data — for example, correcting decreasing split times or filling in missing information. Prefer this when loading files that users may have hand-edited or that come from older versions of a timer.
use livesplit_core::run::parser::composite;

let parsed = composite::parse_and_fix(&data, Some(path))
    .expect("Not a valid splits file");
Prefer parse_and_fix over parse when loading user-provided files. It silently corrects common data integrity issues such as decreasing segment times.

Saving a Run

Only the LiveSplit .lss format is supported for saving. Use livesplit::save_run to write any Run value, or livesplit::save_timer to save the run currently loaded in a timer (which also captures the in-progress attempt if one is active).

Save a Run directly

use livesplit_core::run::saver::livesplit;
use std::fs::File;
use std::io::BufWriter;

let file = File::create("splits.lss").expect("Failed to create file");
let mut writer = BufWriter::new(file);

livesplit::save_run(&run, livesplit::IoWrite(&mut writer))
    .expect("Failed to save splits");
IoWrite is a thin adapter that lets any io::Write implementor be used as the fmt::Write expected by the saver.

Save from a live Timer

use livesplit_core::run::saver::livesplit;
use std::fs::File;
use std::io::BufWriter;

let file = File::create("splits.lss").expect("Failed to create file");
let mut writer = BufWriter::new(file);

// save_timer captures the active attempt (if any) before writing.
livesplit::save_timer(&timer, livesplit::IoWrite(&mut writer))
    .expect("Failed to save splits");
Use save_timer rather than save_run when the timer is actively running, so that the current attempt is included in the attempt history of the saved file.

Save to a String

Because the writer accepts any fmt::Write, you can also save to an in-memory string:
use livesplit_core::run::saver::livesplit;

let mut output = String::new();
livesplit::save_run(&run, &mut output).expect("Failed to save splits");

// `output` now contains the full LSS XML.

The LSS Format

The LiveSplit splits file (.lss) is an XML-based format. A saved file includes:
  • Game name, category name, and linked layout path.
  • Run metadata: run ID, platform, region, Speedrun.com variables, and custom variables.
  • Attempt history with start/end timestamps and pause times.
  • Per-segment data: name, icon (base64-encoded), split times for each comparison, best segment time, and segment history.
  • Auto splitter settings (stored as an opaque XML blob).
The current format version written by livesplit-core is 1.8.0.

Build docs developers (and LLMs) love