Skip to main content

A Python module for parsing and manipulating LiveSplit .lss files

Project description

LiveSplit LSS File Parser

A comprehensive Python module for parsing and manipulating LiveSplit .lss files. This module converts XML-based LSS files into easy-to-use Python objects, allowing for programmatic analysis and manipulation of speedrun data.

Features

  • Complete LSS File Support: Parse all elements of LSS files including metadata, attempts, segments, and timing data
  • Pydantic-Based Models: Robust data validation and serialization using Pydantic BaseModel
  • Bidirectional Conversion: Load LSS files into Python objects and save them back to LSS format
  • Type Safety: Full type annotations with automatic validation for better IDE support and code reliability
  • JSON Serialization: Built-in support for JSON export/import via Pydantic
  • Data Validation: Automatic type conversion and validation (e.g., integers to strings where needed)
  • Comprehensive API: Simple interface with just two main functions: load_lss_file() and save_lss_file()

Installation

This module requires Pydantic. Install dependencies:

pip install pydantic

Then copy the lss_parser.py file to your project directory or install it as a module.

import lss_parser

Quick Start

Loading an LSS File

import lss_parser

# Load a LiveSplit file
run = lss_parser.load_lss_file("my_speedrun.lss")

# Access basic information
print(f"Game: {run.game_name}")
print(f"Category: {run.category_name}")
print(f"Total Attempts: {run.attempt_count}")
print(f"Number of Segments: {len(run.segments)}")

Saving an LSS File

# Modify the run data
run.game_name = "Modified Game Name"
run.category_name = "Any% Modified"

# Save the modified run
lss_parser.save_lss_file(run, "modified_speedrun.lss")

Data Structure

The module provides several Pydantic models to represent LSS file structure:

Run - Main Container

  • game_name: Name of the game
  • category_name: Speedrun category
  • version: LSS file version
  • attempt_count: Total number of attempts
  • segments: List of segments (splits)
  • attempt_history: List of all attempts
  • metadata: Platform, region, and other metadata
  • auto_splitter_settings: Auto-splitter configuration

Segment - Individual Splits

  • name: Segment name
  • icon: Icon path/data
  • split_times: List of split times with different timing methods
  • best_segment_time: Best time for this segment
  • segment_history: Historical times for this segment

Attempt - Run Attempts

  • id: Unique attempt identifier
  • started: Start time/date
  • ended: End time/date
  • time: Timing data (real time, game time, pause time)

Time - Timing Information

  • real_time: Real world time
  • game_time: In-game time
  • pause_time: Paused time

Pydantic Features

The module leverages Pydantic's powerful features:

Data Validation

import lss_parser

# Automatic type conversion
time = lss_parser.Time(real_time=123)  # Converts to "123"
print(time.real_time)  # "123"

# Validation on assignment
run = lss_parser.Run(game_name="Test Game")
run.attempt_count = "42"  # Automatically converted to int

JSON Serialization

# Export to JSON
run = lss_parser.load_lss_file("speedrun.lss")
run_dict = run.model_dump()  # or run.dict() for older Pydantic versions

# Import from JSON
run_data = {...}  # JSON data
run = lss_parser.Run(**run_data)

Type Safety

# IDE support with type hints
def analyze_run(run: lss_parser.Run) -> None:
    for segment in run.segments:  # Full IDE autocomplete
        print(f"Segment: {segment.name}")
        print(f"Best time: {segment.best_segment_time.real_time}")

Usage Examples

Analyzing Speedrun Data

import lss_parser

# Load the file
run = lss_parser.load_lss_file("my_speedrun.lss")

# Find completed attempts
completed_attempts = [a for a in run.attempt_history if a.time.real_time]
print(f"Completed {len(completed_attempts)} out of {len(run.attempt_history)} attempts")

# Analyze segment times
for segment in run.segments:
    print(f"{segment.name}: Best {segment.best_segment_time.real_time or 'N/A'}")
    
# Get personal best
pb_attempts = [a for a in completed_attempts if a.time.real_time]
if pb_attempts:
    best_time = min(pb_attempts, key=lambda x: x.time.real_time)
    print(f"Personal Best: {best_time.time.real_time}")

Creating a New Run

import lss_parser

# Create a new run
new_run = lss_parser.Run(
    game_name="My Game",
    category_name="Any%"
)

# Add segments
segments = [
    lss_parser.Segment(
        name="Level 1",
        best_segment_time=lss_parser.Time(real_time="00:01:30.0000000")
    ),
    lss_parser.Segment(
        name="Level 2", 
        best_segment_time=lss_parser.Time(real_time="00:02:15.0000000")
    ),
    lss_parser.Segment(
        name="Boss",
        best_segment_time=lss_parser.Time(real_time="00:03:45.0000000")
    )
]

new_run.segments = segments

# Add metadata
new_run.metadata.platform = "PC"
new_run.metadata.region = "USA"

# Save the new run
lss_parser.save_lss_file(new_run, "new_speedrun.lss")

Modifying Existing Data

import lss_parser

# Load existing file
run = lss_parser.load_lss_file("existing_run.lss")

# Modify segment names
for segment in run.segments:
    segment.name = f"Modified {segment.name}"

# Add a new segment
new_segment = lss_parser.Segment(
    name="New Final Boss",
    best_segment_time=lss_parser.Time(real_time="00:05:00.0000000")
)
run.segments.append(new_segment)

# Update attempt count
run.attempt_count = len(run.attempt_history)

# Save changes
lss_parser.save_lss_file(run, "modified_run.lss")

API Reference

Main Functions

load_lss_file(file_path: Union[str, Path]) -> Run

Loads and parses an LSS file into a Run object.

Parameters:

  • file_path: Path to the .lss file

Returns:

  • Run object containing all parsed data

Raises:

  • FileNotFoundError: If the file doesn't exist
  • ValueError: If the file is not a valid LSS file
  • xml.etree.ElementTree.ParseError: If the XML is malformed

save_lss_file(run: Run, file_path: Union[str, Path]) -> None

Saves a Run object to an LSS file.

Parameters:

  • run: Run object to save
  • file_path: Path where to save the .lss file

Raises:

  • ValueError: If the file path is invalid

Data Models

All data models are implemented using Pydantic's BaseModel and include:

  • Type annotations with automatic validation
  • Default values where appropriate
  • Automatic data conversion and validation
  • JSON serialization/deserialization support
  • IDE support with full type hints

Error Handling

The module includes comprehensive error handling:

import lss_parser

try:
    run = lss_parser.load_lss_file("nonexistent.lss")
except FileNotFoundError:
    print("File not found!")
except ValueError as e:
    print(f"Invalid file: {e}")
except Exception as e:
    print(f"Parse error: {e}")

Testing

The module includes comprehensive tests. Run them with:

python test_parser.py

Demo

See demo.py for a comprehensive demonstration of all features:

python demo.py

File Format Support

This parser supports LiveSplit LSS files version 1.7.0 and should be compatible with other versions. The parser handles:

  • Game metadata (name, category, platform, region)
  • Attempt history with timestamps and timing data
  • Segment information with split times and history
  • Auto-splitter settings
  • Custom variables and platform-specific data

License

This module is provided as-is for educational and personal use. It is not affiliated with LiveSplit or the LiveSplit development team.

Contributing

This is a complete, self-contained module designed for parsing LSS files. Feel free to extend it for your specific needs.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lss_parser-0.1.0.tar.gz (57.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lss_parser-0.1.0-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

Details for the file lss_parser-0.1.0.tar.gz.

File metadata

  • Download URL: lss_parser-0.1.0.tar.gz
  • Upload date:
  • Size: 57.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.1

File hashes

Hashes for lss_parser-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6e8f46f1aa320a753db62f3d83cef399acde8de16ccda5f73b562ecf92f7b250
MD5 c6c080ec127d23f2e0b7ed51f5c546f2
BLAKE2b-256 95c56204b158364ecb31d324d769cad25983ff4ac451f0d4bddcb55913c560e3

See more details on using hashes here.

File details

Details for the file lss_parser-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: lss_parser-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.1

File hashes

Hashes for lss_parser-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0b9581410111356ef63347bfb9dc6c157eff5a22a4274224be86e2aef87d6e9c
MD5 bb3050f455dee8f7e0d989dc3b5ebece
BLAKE2b-256 63bd01694fb41b065103663b2f5d78fdc4304db82e65e6ffa7bcce9835d98b50

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page