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 Is a Layout?

A Layout is an ordered list of Component objects plus a set of general display settings (fonts, colours, direction, separators). It is the top-level building block for a speedrun timer UI. The layout does not render anything itself. Instead, when given a Snapshot of the timer, it produces a LayoutState — a plain, serialisable data structure that any UI framework can turn into pixels. This clean separation means livesplit-core works equally well as the backend for a desktop application, a web renderer, or an embedded display.
use livesplit_core::{Layout, Timer, localization::Lang, settings::ImageCache};

// Create a default layout (Title + Splits + Timer + Previous Segment)
let mut layout = Layout::default_layout(Lang::English);

// Take a frozen snapshot of the timer
let snapshot = timer.snapshot();

// Produce the renderable state
let mut image_cache = ImageCache::new();
let state = layout.state(&mut image_cache, &snapshot, Lang::English);
ImageCache tracks image data referenced by the state. Call image_cache.collect() periodically to free memory for images that are no longer referenced by any state.

Constructing a Layout

MethodDescription
Layout::new()Creates an empty layout with no components.
Layout::default_layout(lang)Creates a sensible default layout: Title → Splits → Timer → Previous Segment.
Layout::from_settings(layout_settings)Reconstructs a layout from a LayoutSettings value (e.g. loaded from JSON).

Adding Components

use livesplit_core::{Layout, component};

let mut layout = Layout::new();
layout.push(component::Title::new());
layout.push(component::Splits::new(Lang::English));
layout.push(component::Timer::new());
layout.push(component::SumOfBest::new());

Updating vs Calculating State

MethodDescription
layout.state(&mut image_cache, &snapshot, lang)Allocates and returns a fresh LayoutState.
layout.update_state(&mut state, &mut image_cache, &snapshot, lang)Updates an existing LayoutState in place. Prefer this in render loops to avoid repeated allocation.

Scrollable Components

Some components (e.g. Splits) support scrolling their content. Call layout.scroll_up() or layout.scroll_down() to forward a scroll event to all components that support it.

The Component Model

Each component encapsulates its own settings and internal state. When queried through a layout (or directly), it receives a &Snapshot and produces a state object — a plain data structure containing only the values needed to draw that component (strings, colours, time values, images). The state contains no references to the timer; it is entirely self-contained and can be safely passed to a rendering thread.

Available Components

Timer

Module: component::timer The primary countdown/countup clock. Displays the time of the current attempt in the currently selected timing method, formatted with configurable precision. This is the component most runners will always include.

Splits

Module: component::splits A scrollable list of all segments in the run. Each row shows the segment name, the comparison split time, and the current split time or delta. Completed segments are highlighted differently from the current split and future splits. Supports configurable column layouts.

Title

Module: component::title Displays the game name and category name from the run, along with the game icon and attempt count. Typically placed at the top of a layout.

DetailedTimer

Module: component::detailed_timer An extended timer display that shows both the overall run time and the time for the current segment, plus comparison information. Useful when the runner wants more context than the plain Timer provides.

Delta

Module: component::delta Shows the time difference (ahead or behind) between the current run and the active comparison at the current split point. Colour-coded for at-a-glance reading.

PbChance

Module: component::pb_chance Displays the estimated probability that the current attempt will result in a Personal Best, based on historical performance data.

PossibleTimeSave

Module: component::possible_time_save Shows the maximum amount of time that could theoretically be saved in the current segment compared to the runner’s Best Segment time. Helps the runner identify where the most time can be gained.

Graph

Module: component::graph A visual graph of the runner’s historical performance across attempts, or the delta over the course of the current run. Gives a quick picture of consistency and improvement trends.

SumOfBest

Module: component::sum_of_best Displays the theoretical best time calculated as the sum of all Best Segment times. Often shown at the bottom of a layout as a long-term goal.

CurrentPace

Module: component::current_pace Projects the final finish time if the runner maintains their current pace for the rest of the run. Updates live as splits are recorded.

CurrentComparison

Module: component::current_comparison Shows the name of the comparison that is currently active on the timer. Useful when the runner cycles through comparisons with a hotkey and wants to confirm which one is displayed.

PreviousSegment

Module: component::previous_segment Displays the delta for the most recently completed segment — how much faster or slower it was compared to the corresponding comparison time. Included in the default layout.

SegmentTime

Module: component::segment_time Shows the elapsed time within the current segment (i.e. time since the last split, not the cumulative run time).

TotalPlaytime

Module: component::total_playtime Shows the total time spent across all recorded attempts for this run, including incomplete ones. A useful measure of overall investment in a category.

Text

Module: component::text Displays a static or dynamically-configured string. Useful for labels, notes, or custom information surfaced from auto splitter variables.
Module: component::carousel Rotates through a list of child components, showing one at a time on a configurable interval. Useful for surfacing several stats in the space of one component.

Group

Module: component::group Groups multiple components together so they can be treated as a single unit in the layout. Useful for conditional visibility or logical organisation.

BlankSpace

Module: component::blank_space An empty spacer component that inserts configurable vertical (or horizontal) whitespace between other components.

Separator

Module: component::separator A thin horizontal (or vertical) line used to visually divide sections of a layout.

JSON Settings

Layouts are fully serialisable. You can save a layout to JSON via its LayoutSettings and reload it later:
use livesplit_core::layout::parser;

// Load a layout from a JSON reader
let layout = parser::parse(json_reader).expect("Failed to parse layout");

// Serialise the current layout settings
let settings = layout.settings(); // returns LayoutSettings
// Use serde_json::to_string(&settings) to produce JSON

Rendering

How to turn a LayoutState into pixels using the software renderer or a custom backend.

Layout API

Full API reference for Layout, LayoutState, and GeneralSettings.

Build docs developers (and LLMs) love