league-toolkit 0.2.15

Toolkit library for serializing and editing various League of Legends formats
Documentation
<div align="center">

# πŸ› οΈ League Toolkit

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

[![CI](https://img.shields.io/github/actions/workflow/status/LeagueToolkit/league-toolkit/ci.yml?style=for-the-badge&logo=github)](https://github.com/LeagueToolkit/league-toolkit/actions/workflows/ci.yml)
[![Crates.io](https://img.shields.io/crates/v/league-toolkit.svg?style=for-the-badge&logo=rust)](https://crates.io/crates/league-toolkit)
[![Docs](https://img.shields.io/docsrs/league-toolkit?style=for-the-badge&logo=docs.rs)](https://docs.rs/league-toolkit)
[![License](https://img.shields.io/crates/l/league-toolkit.svg?style=for-the-badge)](https://github.com/LeagueToolkit/league-toolkit/blob/main/LICENSE)

[Documentation](https://docs.rs/league-toolkit) β€’ [Crates.io](https://crates.io/crates/league-toolkit) β€’ [Changelog](CHANGELOG.md)

</div>

---

## ✨ 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:

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

Or use individual crates for a smaller dependency footprint:

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

---

## πŸš€ Quick Start

### Reading a WAD Archive

```rust
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

```rust
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

```rust
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

```rust
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`]https://crates.io/crates/league-toolkit | Umbrella crate (feature-gated re-exports) | β€” |
| [`ltk_wad`]https://crates.io/crates/ltk_wad | WAD archive reading/writing | `.wad.client` |
| [`ltk_texture`]https://crates.io/crates/ltk_texture | Texture decoding/encoding | `.tex`, `.dds` |
| [`ltk_mesh`]https://crates.io/crates/ltk_mesh | Skinned & static mesh parsing | `.skn`, `.scb`, `.sco` |
| [`ltk_anim`]https://crates.io/crates/ltk_anim | Skeleton & animation formats | `.skl`, `.anm` |
| [`ltk_meta`]https://crates.io/crates/ltk_meta | Property bin files | `.bin` |
| [`ltk_ritobin`]https://crates.io/crates/ltk_ritobin | Human-readable bin format | ritobin text |
| [`ltk_mapgeo`]https://crates.io/crates/ltk_mapgeo | Map environment geometry | `.mapgeo` |
| [`ltk_file`]https://crates.io/crates/ltk_file | File type detection | β€” |
| [`ltk_hash`]https://crates.io/crates/ltk_hash | Hash functions (FNV-1a, ELF) | β€” |
| [`ltk_shader`]https://crates.io/crates/ltk_shader | Shader path utilities | β€” |
| [`ltk_primitives`]https://crates.io/crates/ltk_primitives | Geometric primitives | β€” |
| [`ltk_io_ext`]https://crates.io/crates/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:

```toml
[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`:

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

---

## πŸ“– Documentation

- **[API Documentation]https://docs.rs/league-toolkit** β€” Full rustdoc reference
- **[LTK Guide]docs/LTK_GUIDE.md** β€” Comprehensive usage guide with examples

---

## πŸ› οΈ Development

**Prerequisites:** Rust stable toolchain

```bash
# 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](https://release-plz.ieni.dev/) 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:

- **Apache License, Version 2.0** ([LICENSE-APACHE]LICENSE-APACHE or <http://www.apache.org/licenses/LICENSE-2.0>)
- **MIT License** ([LICENSE-MIT]LICENSE-MIT or <http://opensource.org/licenses/MIT>)

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.

---

<div align="center">

Made with ❀️ by the [LeagueToolkit](https://github.com/LeagueToolkit) community

</div>