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.

This quickstart walks you through the native Rust API. If you want to use livesplit-core from C, Swift, Python, JavaScript, or another language, see the Bindings Overview instead. By the end of this guide you will have a fully functional in-memory timer that you can start, split, pause, reset, and read time values from.
1

Add livesplit-core to your Cargo.toml

Open your project’s Cargo.toml and add livesplit-core as a dependency:
Cargo.toml
[dependencies]
livesplit-core = "0.13.0"
Run cargo build once to download and compile the crate and its dependencies.
2

Create a Run with segments

A Run stores everything about a particular game and category: the game name, category name, and an ordered list of Segment objects. Each segment represents one split point.
use livesplit_core::{Run, Segment, Timer, TimerPhase};

let mut run = Run::new();
run.set_game_name("Super Mario Odyssey");
run.set_category_name("Any%");
run.push_segment(Segment::new("Cap Kingdom"));
run.push_segment(Segment::new("Cascade Kingdom"));
run.push_segment(Segment::new("Sand Kingdom"));
You can add as many segments as you need. The timer will track your time through each one in order.
3

Create a Timer

Pass the Run to Timer::new. This will fail with CreationError::EmptyRun if the run has no segments, so always add at least one segment first.
let mut timer = Timer::new(run).expect("Run must have at least one segment");
At this point the timer is in the TimerPhase::NotRunning state and is ready to begin an attempt.
4

Control the Timer

All mutating operations return a Result. In most cases you can safely .unwrap() them during development; in production you may want to inspect the error to understand why an operation was rejected (e.g. calling split() when the timer is not running).
// Start the attempt
timer.start().unwrap();
assert_eq!(timer.current_phase(), TimerPhase::Running);

// Record a split
timer.split().unwrap();

// Skip a split if needed
timer.skip_split().unwrap();

// Undo the last split
timer.undo_split().unwrap();

// Pause and resume
timer.pause().unwrap();
timer.resume().unwrap();

// Reset (pass true to save the attempt to history)
timer.reset(true).unwrap();
MethodDescription
start()Begins a new attempt.
split()Completes the current segment and advances to the next.
skip_split()Skips the current segment without recording a time.
undo_split()Goes back to the previous segment.
pause()Pauses Real Time accumulation.
resume()Resumes a paused timer.
reset(save)Ends the attempt; true stores it in history.
5

Read the Current Time

To observe the timer without mutating it, take a Snapshot. The snapshot captures the exact instant it was created and gives you a frozen, consistent view of the timer state — safe to read from any thread.
let snapshot = timer.snapshot();
let current_time = snapshot.current_time();
println!("Real Time: {:?}", current_time.real_time);
println!("Game Time: {:?}", current_time.game_time);
current_time() returns a Time with two optional fields:
  • real_time — wall-clock elapsed time; always tracked.
  • game_time — elapsed time as reported by the game; None until your auto splitter or application calls set_game_time.
Instead of constructing a Run manually, you can load an existing LiveSplit .lss file (or any of the 15+ other supported formats) using the built-in parsers. See Parsing Splits Files for details.

Explore Further

Timer Concepts

Deep-dive into timer phases, timing methods, and SharedTimer.

Parsing Splits Files

Load .lss and 15+ other split formats from disk or a byte slice.

Build docs developers (and LLMs) love