league-toolkit 0.2.14

Toolkit library for serializing and editing various League of Legends formats
Documentation

πŸ› οΈ League Toolkit

Rust library for parsing, editing, and writing League of Legends file formats

CI Crates.io Docs License

Documentation β€’ Crates.io β€’ Changelog


✨ Features

  • πŸ“¦ WAD Archives β€” Read and write .wad.client asset containers
  • 🎨 Textures β€” Decode/encode .tex and .dds formats
  • 🧍 Meshes β€” Parse skinned (.skn) and static (.scb/.sco) meshes
  • 🦴 Animation β€” Load skeletons (.skl) and animations (.anm)
  • πŸ“‹ Property Bins β€” Read/write .bin configuration files
  • πŸ—ΊοΈ Map Geometry β€” Parse .mapgeo environment assets
  • πŸ”§ Modular β€” Use individual crates or the umbrella crate

πŸ“¦ Installation

Add the umbrella crate to your project:

[dependencies]
league-toolkit = { version = "0.2", features = ["wad", "mesh", "texture"] }

Or use individual crates for a smaller dependency footprint:

[dependencies]
ltk_wad = "0.2"
ltk_texture = "0.4"
ltk_mesh = "0.3"

πŸš€ Quick Start

Reading a WAD Archive

use std::fs::File;
use ltk_wad::Wad;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let file = File::open("assets.wad.client")?;
    let mut wad = Wad::mount(file)?;
    
    println!("Archive contains {} files", wad.chunks().len());
    
    // Decode a specific chunk
    let (mut decoder, chunks) = wad.decode();
    for chunk in chunks.values().take(5) {
        let data = decoder.load_chunk_decompressed(chunk)?;
        println!("Chunk {:016x}: {} bytes", chunk.path_hash(), data.len());
    }
    
    Ok(())
}

Decoding a Texture

use ltk_texture::Tex;
use std::io::Cursor;

let tex = Tex::from_reader(&mut cursor)?;
let surface = tex.decode_mipmap(0)?;
let image = surface.into_rgba_image()?;
image.save("output.png")?;

Parsing a Skinned Mesh

use ltk_mesh::SkinnedMesh;
use std::fs::File;

let mesh = SkinnedMesh::from_reader(&mut File::open("champion.skn")?)?;
println!("Vertices: {}", mesh.vertex_buffer().vertex_count());
println!("Submeshes: {}", mesh.ranges().len());

Working with Property Bins

use ltk_meta::{BinTree, BinTreeObject, value::*};

// Read
let tree = BinTree::from_reader(&mut file)?;
for (hash, object) in &tree.objects {
    println!("Object 0x{:08x}", hash);
}

// Create
let tree = BinTree::builder()
    .dependency("shared/data.bin")
    .object(
        BinTreeObject::builder(0x12345678, 0xABCDEF00)
            .property(0x1111, I32Value(42))
            .build()
    )
    .build();

πŸ“š Crates

Crate Description Formats
league-toolkit Umbrella crate (feature-gated re-exports) β€”
ltk_wad WAD archive reading/writing .wad.client
ltk_texture Texture decoding/encoding .tex, .dds
ltk_mesh Skinned & static mesh parsing .skn, .scb, .sco
ltk_anim Skeleton & animation formats .skl, .anm
ltk_meta Property bin files .bin
ltk_ritobin Human-readable bin format ritobin text
ltk_mapgeo Map environment geometry .mapgeo
ltk_file File type detection β€”
ltk_hash Hash functions (FNV-1a, ELF) β€”
ltk_shader Shader path utilities β€”
ltk_primitives Geometric primitives β€”
ltk_io_ext I/O extensions (internal) β€”

Each crate lives under crates/<name>.


βš™οΈ Feature Flags

The league-toolkit umbrella crate uses feature flags to control which subsystems are included:

Feature Enables Default
anim ltk_anim βœ…
file ltk_file βœ…
mesh ltk_mesh βœ…
meta ltk_meta βœ…
primitives ltk_primitives βœ…
texture ltk_texture βœ…
wad ltk_wad βœ…
hash ltk_hash βœ…
serde Serde support (where available) ❌

For a minimal build, disable defaults and opt-in selectively:

[dependencies]
league-toolkit = { version = "0.2", default-features = false, features = ["wad"] }

Texture Encoding with intel-tex

BC1/BC3 texture encoding requires the optional intel-tex feature on ltk_texture:

[dependencies]
league-toolkit = { version = "0.2", features = ["texture"] }
ltk_texture = { version = "0.4", features = ["intel-tex"] }

πŸ“– Documentation


πŸ› οΈ Development

Prerequisites: Rust stable toolchain

# Build all crates
cargo build

# Run tests
cargo test

# Build documentation
cargo doc --open

Project Structure

league-toolkit/
β”œβ”€β”€ crates/
β”‚   β”œβ”€β”€ league-toolkit/    # Umbrella crate
β”‚   β”œβ”€β”€ ltk_wad/           # WAD archives
β”‚   β”œβ”€β”€ ltk_texture/       # Textures
β”‚   β”œβ”€β”€ ltk_mesh/          # Meshes
β”‚   β”œβ”€β”€ ltk_anim/          # Animation
β”‚   β”œβ”€β”€ ltk_meta/          # Property bins
β”‚   β”œβ”€β”€ ltk_ritobin/       # Ritobin text format
β”‚   β”œβ”€β”€ ltk_mapgeo/        # Map geometry
β”‚   β”œβ”€β”€ ltk_file/          # File detection
β”‚   β”œβ”€β”€ ltk_hash/          # Hashing
β”‚   β”œβ”€β”€ ltk_shader/        # Shader utilities
β”‚   β”œβ”€β”€ ltk_primitives/    # Primitives
β”‚   └── ltk_io_ext/        # I/O extensions
└── docs/
    └── LTK_GUIDE.md       # Usage guide

πŸ“‹ Releasing

This repository uses Release-plz for automated versioning and publishing:

  1. Pushes to main trigger Release-plz to open a release PR
  2. Merging the release PR publishes updated crates to crates.io

πŸ“„ License

Licensed under either of:

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


Made with ❀️ by the LeagueToolkit community