Skip to content

RitoShark/Hematite

Repository files navigation

Hematite banner

What Hematite does

Release Rust Windows Tests Config-driven

Drop a .fantome, .wad.client, or .bin on Hematite.
It detects, repairs, and writes the file back. Auto-updates fix rules from GitHub. No recompile needed.


At a glance

For users

# Auto-detect + fix everything
hematite-cli "skin.fantome"

# Preview without writing
hematite-cli "skin.fantome" --dry-run

# Batch a whole folder
hematite-cli "C:/mods/"

# Detect only — show champion + skin
hematite-cli "skin.fantome" --check

Releases ship at github.com/RitoShark/Hematite/releases.

For devs

git clone https://github.com/RitoShark/Hematite
cd Hematite && git checkout v2
cargo build --release
cargo test --workspace      # 152 tests

Full architecture, transform framework, contribution flow → DEVELOPER.md.


What gets fixed

Symptom What Hematite does Flag
Invisible HP barAdds missing UnitHealthBarStyle--healthbar
White / chrome modelRenames TextureName/SamplerName in materials--white-model
Black or missing iconsRewrites .dds.tex when the WAD lacks the source--black-icons
Broken particle texturesRecursive .dds.tex conversion--particles
Outdated champion dataRemoves stale champion BIN entries--remove-champion-bins
Crackling / silent audioDrops BNK files with incompatible Wwise versions--remove-bnk
Animations that locked the rigRemoves problematic .anm files--remove-anm
VFX gone / wrong shapeMigrates VFX shape data to the 14.1+ layout--vfx-shape
Invisible model from bad shaderReplaces invalid shader refs with the closest valid match--fix-shaders
Orphan entries bloating the BINRemoves unreferenced CAD/AnimGraph/GearSkinUpgrade entries--validate-entries

No flags = all of the above. Pass --check to detect only.


What's new in this release

Live game detection

  • Auto-detects your League install (Riot client manifest → running processes → common paths → registry) — no flags needed
  • Deep repair without --game-wad — champion WADs resolve automatically from the detected install
  • --game-path <DIR> to point at a specific install, --no-live to opt out

Pull fixes (from the live game)

  • Gear pull — dead mGearSkinUpgrades links (a confirmed crash) are repaired by pulling the missing entry from the game; unpullable ones are safely nuked
  • CAC pull — missing ContextualActionData restored so voiceovers work
  • --restore-anm — pulls dead .anm references from the game instead of deleting them
  • Combo-bin relocation — legacy data/{champ}_skins_*.bin re-keyed to Riot's new _multi_skins_ path
  • Dead-reference ladder — dead asset refs rewritten to a live form (.dds.tex, suffix-strip) using the game's own file list

Texture lifesavers

  • Mipmap stripping for the post-2026 League regression that ate mipmapped textures
  • TEX dimension repair — rounds non-block-aligned .tex dimensions down to multiples of 4 (no more DXT-block crashes)

Smarter repathing

  • Modder-root pathsreddivinekinggaren/foo.dds style namespaces now get rewritten properly (closes an 88K-ref gap)
  • Suffix-strip fallback — handles Riot's attack1.matcha_x.anmattack1.anm rename
  • remove_prefix helper for the inverse direction

Smarter detection

  • Seed discovery — scans the WAD TOC and surfaces every champion/skin pair (jinx + jinxmine etc.) before fixes run
  • Field-scoped path rewritesreplace_string_extension now takes a regex on the field name, so HUD-only rewrites stop touching material textures

Always-up-to-date CLI

  • Force-update gate — if a critical bug ships, bumping min_cli_version in config/version.json refuses to run on old CLIs
  • --check-version to query the gate
  • --skip-version-check for CI

Deep repair

  • Seed-BIN backfill — asset-only mods (loose textures/meshes, no character BIN) now get their canonical skin{N}.bin pulled from the base game as a foundation
  • Transitive dependency closure--game-wad now follows the full dependency chain (referenced assets and .linked BINs), recursing until the mod is self-contained

We own the stack

  • Migrated off league-toolkit onto the in-house RitoShark rs_* crates (rs_bin, rs_wad, rs_tex, rs_mesh, rs_io) — isolated entirely within hematite-file, so the fix engine never noticed

Three new transform primitives let configs do more without code: transform_bytes (in-place byte ops), add_files (inject named assets from the registry), and split_entries_by_type (move objects into a sibling BIN). See DEVELOPER.md for the schema.


Quick start

# 1. Grab the binary
# → https://github.com/RitoShark/Hematite/releases/latest

# 2. Drag a mod onto it, or run from the terminal
hematite-cli "MyAwesomeSkin.fantome"

# 3. Hematite writes the fixed file next to the original:
#    MyAwesomeSkin.fixed.fantome
#
# (Same binary works as a drag-target on Windows — no terminal required.)

Supported inputs

Format What happens
.fantome / .zip Extracts every .wad.client, processes each, repacks into .fixed.fantome
.wad.client Extracts, fixes, rebuilds → .fixed.wad.client
.bin Parses, fixes, writes → .fixed.bin
Folder Recurses + processes every supported file (parallel via rayon)

Useful flags

Flag What it does
--check Detect only — prints champion / skin / issue count, doesn't touch the file
--dry-run Show what would be fixed
--json Emit machine-readable output (skips the "press enter" pause)
--repath Rename mod assets with a unique prefix so they can't collide with the base game
--game-wad <PATH> Deep repair from a specific base-game champion WAD (optional — with a detected install, deep repair runs automatically when --repath is set). Backfills the canonical skin{N}.bin for asset-only mods, then transitively resolves every referenced + linked file until the dependency chain is closed
--game-path <DIR> Point at a League install explicitly (otherwise auto-detected)
--no-live Disable all live-game features for this run
--restore-anm Pull missing .anm animations from the game instead of removing them
--pull-gear / --pull-cac / --fix-refs / --relocate-bins Select the new pull fixes individually (all run by default)
--invis-texture Inject invisible placeholders for missing texture refs after repath
-v verbose Show every fix as it's applied; -v trace for everything

Run hematite-cli --help for the complete flag list with descriptions.


See it in action

What a clean run looks like
$ hematite-cli yone-spiritblossom.fantome

[hematite] Loading hash dictionary (1.8M entries) ............. 712ms
[hematite] Seed discovery: 1 skin across 1 champion
[hematite] WAD has 1834 total entries, 14 BIN file(s)
[hematite] WAD-level fix 'TEX Dimension Fix' affected 3 files
[hematite] WAD-level fix 'DDS → TEX Texture Conversion' affected 8 files
[hematite] data/characters/yone/skins/skin7.bin
[hematite]   ✓ Missing HP Bar (1 changes)
[hematite]   ✓ White Model (TextureName) (4 changes)
[hematite] Repathing assets with prefix ".yone7_" (layout: InFolder)…
[hematite] ✓ Renamed 47 WAD entries, rewrote 213 BIN strings
[hematite] Wrote yone-spiritblossom.fixed.fantome (4.2 MB)

Done — 1 mod processed, 18 fixes applied in 1.9s.
Force-update banner in the wild

When a critical bug ships, the remote version.json bumps min_cli_version and every old CLI refuses to run until upgraded:

[BLOCKED] Hematite-CLI 0.3.0 is too old — minimum required is 0.4.0.
  Fixes BIN parser regression on patch 14.20 mods.
  Download: https://github.com/RitoShark/Hematite/releases/latest
  Pass --skip-version-check to override at your own risk.

Error: Refusing to run: CLI is older than the published minimum.

For non-blocking updates, you get a soft notice instead and the run proceeds.

Subcharacter detection

Mods that ship subchampions (Jinx + jinxmine, Annie + Tibbers, Anivia + egg) used to lose those files silently. Now you see them up front:

[hematite] Seed discovery: 2 skins across 2 champions
[hematite] WAD contains subchampion forms: jinx, jinxmine

Configure without recompiling

Every fix rule lives in config/fix_config.json. Add a rule, push to main, the next CLI run picks it up (cached for 1 hour, embedded fallback when offline).

A rule has three parts:

"my_new_fix": {
  "name": "Pretty name",
  "enabled": true,
  "severity": "medium",
  "detect": { "type": "...", "...": "..." },
  "apply":  { "type": "...", "...": "..." }
}

Detection rules cover field presence, hash existence, file-extension matches, binary header version checks, entry-type lookups, even shader validity. Transforms cover field add/rename, regex replace, file removal, in-place byte transforms, asset injection from the named registry, splitting entries into sibling BINs.

The full schema and the recipe for adding a brand-new transform action live in DEVELOPER.md.


Hash system in one paragraph

League uses 32-bit FNV-1a for class / field / path names and 64-bit xxhash for WAD asset paths. Hematite ships an LMDB containing 1.8M resolved hashes — loads in under a second, lives under %APPDATA%\RitoShark\Requirements\Hashes\, auto-downloads on first run. Falls back to the text files if LMDB is missing.


Why "Hematite"?

Hematite is the primary ore of iron. When iron oxidizes, it becomes rust. This tool is built in Rust and cleans up broken skins — the name fits.

Made by SirDexal · part of the RitoShark ecosystem
Have a question, found a bug, want to contribute? → DEVELOPER.md

footer

About

League of Legends Skin Fixer

Resources

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages