livesplit-core provides multiple built-in renderers. All of them operate on aDocumentation 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.
LayoutState produced by calling layout.state(&timer.snapshot(), &mut image_cache). The state is a plain data snapshot — renderers consume it but never hold a reference to the live Layout or Timer.
The Rendering Pipeline
- Call
timer.snapshot()to capture the current timer state. - Call
layout.state(&snapshot, &mut image_cache)to produce aLayoutState. - Pass
LayoutStateandImageCacheto the renderer of your choice.
Software Renderer
Cargo feature:software-rendering
The software renderer rasterizes the layout entirely on the CPU using tiny-skia. It is surprisingly fast and can be considered the default rendering backend.
Output is an RGBA8 pixel buffer — 4 bytes per pixel in the order red, green, blue, alpha, each an unsigned 8-bit integer.
Rust Example
Stride and Over-Allocation
Some frameworks (e.g. OpenGL, Metal, Direct3D) over-allocate image buffers so that each row is aligned to a power-of-two boundary. For example, a 100×50 image might be backed by a 128×64 buffer. In that case:- Pass the real width (
100) and height (50) as the render dimensions. - Pass the allocated row width (
128) as thestride.
width pixels per row but advances stride pixels between rows.
C API
SVG Renderer
Cargo feature:svg-rendering
The SVG renderer produces a vector image as an SVG string. It is well suited for server-side generation and embedding in HTML documents.
SVG rendering is ideal for server-side generation and web display without a canvas element.
Rust Example
[width, height] argument is in logical units. The SVG viewBox is set to 0 0 width height.
Web Rendering (WASM)
Cargo feature:web-rendering
When targeting WebAssembly in a browser, the web renderer draws directly to an HTML <canvas> element using the browser’s 2D Canvas API. It relies on web-sys and wasm-bindgen for browser integration.
Web rendering is the recommended approach for browser-based timer UIs built with the WebAssembly target.
web-rendering feature implies wasm-web, which enables wasm-bindgen support throughout the crate (hotkeys, async, etc.).
Image Cache
ImageCache manages decoded images referenced by the layout — segment icons, game artwork, and backgrounds.
- Pass a mutable reference to the same
ImageCacheinstance to every call tolayout.state(). - The cache is also passed to the renderer so it can look up images by handle.
- When the
image-shrinkingfeature is enabled (included in the default feature set), images are automatically resized to a reasonable display size to keep memory usage low.
Custom Renderers
If none of the built-in renderers fit your target (e.g. a proprietary GPU API or a terminal UI), you can build a custom renderer by consuming theLayoutState tree directly.
LayoutState is a tree of component states. Each component’s state is a plain data struct:
| Component | State Type |
|---|---|
| Timer | TimerComponentState |
| Splits | SplitsComponentState |
| Title | TitleComponentState |
| Detailed Timer | DetailedTimerComponentState |
| Key-Value (Previous Segment, Sum of Best, etc.) | KeyValueComponentState |
| Graph | GraphComponentState |
| Text | TextComponentState |
serde::Serialize, so you can call layout.state_as_json() to get a JSON snapshot for use in any web or scripting UI: