war3parser
war3parser is a library for parsing and extracting Warcraft III map files. It extracts data from MPQ archives and parses common map formats across classic and Reforged versions — the w3i parser covers the full format ladder v8 → v33 (RoC betas through WC3 2.0).
Workspace layout
crates/
core/ # war3parser — pure parsing + shared model (no wasm-bindgen by default)
cli/ # war3parser-cli — thin CLI over core
wasm/ # war3parser-wasm — thin wasm-bindgen glue over core::model::MapSnapshot
| Crate | Depends on | Notes |
|---|---|---|
war3parser (core) |
— | pure Rust + optional serde (default); no wasm-bindgen/tsify |
war3parser-cli |
core + serde |
never pulls wasm-bindgen |
war3parser-wasm |
core + serde-wasm-bindgen |
thin parse_map / version; hand-maintained war3parser.d.ts |
Core module layout:
crates/core/src/
archive.rs # War3MapW3x — HM3W header + embedded MPQ access
formats/ # per-file parsers: w3i (v8→v33), wts, imp, mmp
model/ # portable API types: MapSnapshot, War3MapMetadata, images
reader.rs # bounds-checked little-endian ByteReader
error.rs # crate-wide Error
Shared API types (MapSnapshot, War3ImageData, ImportEntry, StringTableEntry, War3MapHeader, …) live in war3parser::model so CLI and WASM do not redefine DTOs.
Features
- Extract files from MPQ archives (by known name)
- Parse w3i map info across versions 8 → 33 (RoC betas, ROC, TFT, 1.31+, Reforged, WC3 2.0)
- Parse wts string tables (comment lines,
\n/\r\n, BOM) - Parse imp imports, minimap/preview BLP/TGA images
- Handle protected / headerless maps (no
HM3W, truncated optional w3i sections, missing listfile, inflated MPQ table counts, hash entries that wrap around the table) - Detect known third-party script modifications (
war3parser::modscan) - WASM bindings + browser playground
MPQ reader
The mpq dependency is patched to war3-archive/mpq-rust.
Upstream 0.8.1 trusts values that come straight out of the archive — block-table
indices, per-sector offsets, table counts — which map protectors deliberately
falsify, and it stops probing the hash table at the end instead of wrapping
around, so some files are unreachable by name. Each fix is a separate commit in
the fork.
Modification detection
modscan recognises injected cheat scripts from literals the injector cannot
remove, and reports how the injected menu is triggered in game. It needs only
the map at hand — no unmodified copy to diff against. parse_map exposes it as
modification; dump-metadata writes modification.json. A None result
means "no known signature matched", not "clean": a protected map whose script
cannot be read looks the same.
Usage
as a library
use War3MapMetadata;
let buffer = read.unwrap;
let mut metadata = parse.unwrap;
metadata.resolve_trigger_strings;
// Portable snapshot shared with the WASM API
let snapshot = metadata.snapshot.unwrap;
println!;
metadata.save.unwrap;
// or: War3MapMetadata::parse_snapshot(&buffer)
as a CLI
$ war3parser-cli help
A extractor and parser for Warcraft 3 map files
Usage: war3parser-cli <COMMAND>
Commands:
dump-metadata Dump metadata from a map file [aliases: d]
extract-file Extract a file from a MPQ archive and save it [aliases: x]
extract-images Extract images with *.tga and *.blp extensions [aliases: i]
convert-image Convert a *tga/blp file to png [aliases: c]
list-files List files in a MPQ archive [aliases: l]
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
as WASM
import init
from "@wesleyel/war3parser";
await ;
const meta = ;
console.log;
// Why a map failed, instead of a bare `undefined`
const result = ;
if console.warn;
// Reach into the archive directly
const script = ;
const files = ;
const injected = ;
parse_map returns:
header— HM3W presence/name/max playersmap_info— full w3i (TRIGSTR-resolved when.wtsis present)images— minimap/preview as PNG data URLsimports—war3map.impentriesstrings— sorted WTS entriesfiles—(listfile)paths when availableparse_ms— parse duration
get_map_info remains as a compatible alias of parse_map.
Web playground
Live: https://wesleyel.github.io/war3parser/
Local demo (builds WASM first):
# → http://localhost:5173/
Drop any .w3x / .w3m. Parsing is 100% in-browser; nothing is uploaded.
Static / GitHub Pages build:
The playground is Vite + React with a Real World Materials UI. CI deploys it to GitHub Pages on pushes to main (see .github/workflows/pages.yml). Enable Settings → Pages → Source: GitHub Actions once.
w3i version support
The version ladder follows War3Net, the most complete open reference:
| Version | Era | Notes |
|---|---|---|
| 8–15 | RoC beta | Legacy layouts (no save count pre-18, no subtitles pre-15) |
| 18 | ROC | Campaign background, loading screen index |
| 23–24 | early TFT | Fog, sound environment, game data set; random item tables (24) |
| 25 | TFT | Global weather |
| 26–27 | TFT patches | Trailing marker int (26–27), game build version (27) |
| 28 | 1.31 | Script language (JASS/Lua) |
| 31 | Reforged | Graphics modes, game data version, enemy priorities |
| 32–33 | WC3 2.0 | Camera zoom limits (32: default+max, 33: +min) |
| * | unknown | Future/gap versions parse with the nearest known layout |
| * | protected | 0xFF optional-section skip after forces; tolerant truncation |
Contributing
Contributions are welcome! Please submit a Pull Request or report an Issue.
License
war3parser is licensed under the MIT License. See the LICENSE file for details.