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.

What Are Comparisons?

A comparison is a set of target split times shown alongside the runner’s current attempt. By comparing each split as it is recorded against the corresponding comparison time, the timer can show whether the runner is ahead of or behind that target, and by how much. livesplit-core stores two categories of comparisons in a Run:
  • Custom comparisons — manually defined sets of split times, including the always-present Personal Best. These are stored directly in the run file.
  • Generated comparisons — automatically computed from the segment history by ComparisonGenerator implementations. They are recalculated after every attempt (via run.regenerate_comparisons(), which the Timer calls automatically on reset).

Built-in Comparisons

Personal Best

Module constant: comparison::personal_best::NAME = "Personal Best"
Short name: "PB"
The runner’s best complete run to date. This is the only comparison that is not auto-generated — it is stored directly as the Personal Best split times on each Segment. All other comparisons are derived from the segment history.

Best Segments

Module constant: comparison::best_segments::NAME = "Best Segments"
Short name: "Best"
The theoretically fastest possible run constructed from the fastest time ever recorded for each individual segment across all attempts. Also known as the “sum of best segments” theoretical time.

Best Split Times

Module constant: comparison::best_split_times::NAME = "Best Split Times"
Short name: "Best Split Times"
The fastest cumulative split time ever reached at each split point, regardless of whether that attempt was completed. For example, if the runner once reached the second split in record time but then died, that early time is still captured here.

Average Segments

Module constant: comparison::average_segments::NAME = "Average Segments"
Short name: "Average"
A comparison built from the arithmetic mean of all recorded segment times. Useful for measuring consistency rather than peak performance.

Median Segments

Module constant: comparison::median_segments::NAME = "Median Segments"
Short name: "Median"
A comparison built from the median of all recorded segment times. More robust than the average when the history contains outlier attempts.

Worst Segments

Module constant: comparison::worst_segments::NAME = "Worst Segments"
Short name: "Worst"
A comparison built from the slowest time ever recorded for each segment. Useful for goal-setting: any run that beats every worst-case segment time is still a completion.

Balanced PB

Module constant: comparison::balanced_pb::NAME = "Balanced PB"
Short name: "Balanced"
A comparison that has the same final time as the Personal Best, but redistributes the split times across segments according to the runner’s historical performance on the skill curve. This smooths out the unevenness of a real PB (a mediocre early split followed by an exceptional late split) and gives a fairer moment-to-moment comparison that is less likely to discourage a reset. The algorithm samples split times from the skill curve at the percentile corresponding to the Personal Best.

Latest Run

Module constant: comparison::latest_run::NAME = "Latest Run"
Short name: "Latest"
The split times from the most recently completed attempt. Useful for comparing the current run directly against the previous one.

None

Module constant: comparison::none::NAME = "None"
Short name: "None"
A special comparison that intentionally leaves all split times empty. When selected, no comparison deltas are shown. Useful when the runner wants to focus purely on their current time without any reference.

The ComparisonGenerator Trait

All generated comparisons implement the ComparisonGenerator trait:
pub trait ComparisonGenerator: Debug + Sync + Send {
    /// The name of the comparison (also used as the storage key).
    fn name(&self) -> &str;

    /// Recompute the comparison times for all segments using the segment
    /// history and attempt history.
    fn generate(&mut self, segments: &mut [Segment], attempts: &[Attempt]);
}
The generators stored in a Run are called by run.regenerate_comparisons() (and therefore by timer.reset(...)). To implement a custom generator, implement this trait and push an instance into run.comparison_generators_mut().

Switching Comparisons at Runtime

The active comparison is a property of the Timer, not the Run. It is initialised to Personal Best and can be changed at any time, even during an attempt.
use livesplit_core::comparison::best_segments;

// Advance to the next comparison in the ordered list
timer.switch_to_next_comparison();

// Go back to the previous comparison
timer.switch_to_previous_comparison();

// Jump directly to a named comparison (returns Err if it doesn't exist)
timer.set_current_comparison(best_segments::NAME).unwrap();

// Read the name of the currently active comparison
let current = timer.current_comparison();
println!("Comparing against: {}", current);
The iteration order is: all custom comparisons first (Personal Best first among them), then all generated comparisons in the order they appear in run.comparison_generators().

Race Comparisons

Comparisons whose names start with "[Race]" (the value of comparison::RACE_COMPARISON_PREFIX) are reserved for race integrations. livesplit-core enforces this: run.add_custom_comparison(name) returns AddComparisonError::NameStartsWithRace if the name begins with that prefix. Race comparisons are otherwise treated identically to other custom comparisons at the storage level — they are custom comparison entries with split times populated by the race integration at runtime.

Default Generator Set

When you create a new Run with Run::new(), the following generators are registered automatically:
Best Segments
Best Split Times
Average Segments
Median Segments
Worst Segments
Balanced PB
Latest Run
None
You can inspect the active generators with run.comparison_generators() and modify the list with run.comparison_generators_mut().

Build docs developers (and LLMs) love