Skip to content

Onboarding

First hour on Khada, in order.

What Khada is

A 3D model viewer for League of Legends — web, iOS/Android, and Apple QuickLook. Pipeline:

CDragon / local League install

extractor (C# .NET)            — WAD → GLTF + MaterialExtras

processor (Node, tsx)          — gltfpack + texture compression + manual fixes

web / mobile / ar              — user-facing

automation (Cloudflare Worker) polls CDragon for new skins and fires the pipeline on Telegram command; ar serves USDZ for Apple QuickLook.

Monorepo

packages/
  extractor/    C# .NET CLI
  processor/    Node orchestrator
  web/          Astro + Three.js viewer
  ar/           Worker for USDZ / QuickLook
  usdz/         GLB→USDZ library
  automation/   Worker for CDragon polling + Telegram bot
  settings/     YAMLs for manual fixes, aliases, news
  docs/         this site

Package manager: pnpm@10.10.0. Full command catalog is in the root CLAUDE.md.

First-hour tours

Extract one skin

bash
cd packages/extractor
dotnet run --project LeagueConvert.CommandLine -- \
  convert-wad Zoe -o output/zoe -s -a --skins 0
  • Auto-detects a local League install (LeaguePathResolver.cs).
  • If absent, downloads the PBE WAD via CDTB — needs pip install cdtb on one of the Python interpreters WadDownloader.cs probes (prefers python3.10..12 over generic python3).
  • First run downloads hashes.game.txt and hashes.binhashes.txt from CommunityDragon.

Run the viewer

bash
pnpm run web

The Three.js engine is packages/web/src/engine/index.ts (~3500 lines). Every MaterialExtras key the extractor writes has a handler here.

Full pipeline end-to-end

bash
pnpm run processor generate-files "[1001]" --remote
# skin ID = championId * 1000 + skinIndex

Runs the extractor, post-processes with gltfpack, writes to packages/processor/output/.

Debugging a specific skin

Always fetch the CDragon bin.json first — don't start by running the extractor:

https://raw.communitydragon.org/pbe/game/data/characters/{champion}/skins/skin{skinId mod 1000}.bin.json
https://raw.communitydragon.org/pbe/game/data/characters/{champion}/animations/skin{skinId mod 1000}.bin.json

If the JSON reproduces the bug, it's a parse/mapping bug in our code. If the JSON is clean but our output isn't, the bug is downstream of parsing. Details: CDragon bin.json endpoints.

Hex hash in a material dump? Start at hashing.

Wrong tint / dark texture / red overlay? Almost always a shader profile issue — common pitfalls, especially 1 and 4.

Where to go next

Before touching…

  • Materials or shaders → read common pitfalls end to end. The ten numbered items are scar tissue, not style advice.
  • Skeletons or animations → read skeletons & animations. The two-pass track mapping and the joint-snap reparenting bake are both easy to break.
  • New file format → file formats + the relevant upstream wiki page.

When a model/texture/chroma looks wrong in the viewerdebugging the model pipeline — the toolkit (extractor CLI, bin.json, chrome-devtools-mcp, GLB Python inspection, MD5 triage) for isolating which stage broke it.

File map

Want to changeOpen first
CLI flags, entry pointLeagueConvert.CommandLine/Program.cs
WAD download / cachingLeagueConvert.CommandLine/WadDownloader.cs
Champion path resolutionLeagueConvert.CommandLine/LeaguePathResolver.cs
Hash table loading + manual overlayLeagueConvert/IO/HashTables/HashTables.cs
WAD parsingOfficialLeagueToolkit/Core/Wad/WadFile.cs + LeagueConvert/IO/WadFile/StringWad.cs
Shader param → material extrasLeagueConvert/IO/Skin/StaticMaterial.cs
GLTF exportLeagueConvert/IO/Skin/Extensions/SkinExtensions.cs
Skeleton + track mappingLeagueToolkit/IO/SkeletonFile/Skeleton.cs
Animation parsingLeagueToolkit/IO/AnimationFile/Animation.cs
Joint-snap bakeLeagueConvert/IO/Skin/Skin.cs (methods named *JointSnap*, ComputeWorldTransform, RewriteVictimTrackAsWorld)
Three.js enginepackages/web/src/engine/index.ts
Telegram bot commandspackages/automation/src/worker/index.ts
Per-skin manual overridespackages/settings/model-fixes*.yml + siblings

Poking at a WAD ad hoc without our extractor? Grab the Rust wadtools CLI.

Built for engineers and AI assistants working on Khada.