Moves three derived-data maintenance handlers (--fix-zone,
--regen-collision, --build-woc) out of main.cpp into a new
cli_zone_data.{hpp,cpp} module. Distinct from cli_repair
(which fixes manifest-vs-disk drift): these rebuild derived
terrain data and clean up JSON files via load+save:
- fix-zone re-parses + re-saves every JSON sidecar to apply
load-time scrubs and save-time caps
- regen-collision rebuilds WOC for every WHM/WOT in a zone
- build-woc handles single-tile WOC generation
main.cpp shrinks by 104 lines (1,541 to 1,437).
Moves three mesh-aggregate info handlers (--info-zone-models-total,
--list-zone-meshes-detail, --info-mesh) out of main.cpp into a
new cli_mesh_info.{hpp,cpp} module. The first aggregates
WOM/WOB stats across a zone; the second tabulates per-mesh
metrics sorted by triangle count; the third dumps single-WOM
detail (bounds, version, batches, bones, animations, textures).
main.cpp shrinks by 285 lines (1,826 to 1,541). All three
preserve --json output for capacity-planning pipelines.
Moves the two basic texture-helper handlers (--gen-texture,
--add-texture-to-zone) out of main.cpp into a new
cli_texture_helpers.{hpp,cpp} module. The first synthesizes
solid hex / checker / grid PNG placeholders; the second
imports an existing PNG into a zone with optional rename and
idempotent re-run support (skip if bytes already match).
Both complement the procedural pattern generators in
cli_gen_texture (which handles the 43 named patterns).
main.cpp shrinks by 196 lines (2,022 to 1,826) and finally
drops below 2K lines.
Moves five self-discovery handlers (--list-commands,
--info-cli-stats, --info-cli-categories, --info-cli-help,
--gen-completion) out of main.cpp into a new
cli_introspect.{hpp,cpp} module. All five auto-discover
commands by parsing printUsage's stdout via tmpfile capture,
so the surface stays self-describing as new flags are added.
Useful for shell completion scripts that re-exec the binary
at completion time, IDE plugins, and 'is there a flag for X?'
search workflows. main.cpp shrinks by 276 lines (2,298 to
2,022). --validate-cli-help stays inline because it needs
direct access to the static-local kArgRequired array.
Moves the four cross-reference / content sanity-check
handlers (--check-zone-refs, --check-zone-content,
--check-project-content, --check-project-refs) out of
main.cpp into a new cli_check.{hpp,cpp} module. Each goes
deeper than --validate (which only checks open-format file
presence) — verifying that quest NPC IDs resolve to
creatures.json entries, model paths resolve to on-disk files,
spawn positions sit inside the zone's tile bounds, etc.
main.cpp shrinks by 509 lines (2,807 to 2,298). All four
preserve --json output for CI pipelines.
Moves the two batch-runner handlers (--for-each-zone,
--for-each-tile) out of main.cpp into a new
cli_for_each.{hpp,cpp} module. Both substitute `{}` with the
iterated path (find -exec convention) and shell-escape every
token before passing to std::system. Exit code is the failure
count, capped at 255 so the shell can still see it.
main.cpp shrinks by 157 lines (2,964 to 2,807).
Moves the three asset-dependency analysis handlers
(--list-zone-deps, --list-project-orphans,
--remove-project-orphans) out of main.cpp into a new
cli_deps.{hpp,cpp} module. All three surface the relationship
between content references (objects.json + WOB doodad lists)
and on-disk model files: list-deps enumerates what a zone
needs, list-orphans flips that into 'what's on disk but
unreferenced', and remove-orphans deletes the resulting set
(with --dry-run for safe previews).
main.cpp shrinks by 355 lines (3,319 to 2,964) and finally
drops below 3K. The shared 'normalize basename' rule for
matching path references stays duplicated between the list
and remove handlers — a deliberate tradeoff, with comments
flagging the sync requirement.
Moves the project-wide ADT-grid visualization handler
(--info-tilemap) out of main.cpp into a new
cli_tilemap.{hpp,cpp} module. Renders the WoW 64x64 tile
grid showing which tiles are claimed by which zones, with
collision detection (multiple zones claiming the same tile)
and per-zone glyph legend. Empty rows are skipped so the
output stays bounded for projects in one map corner.
main.cpp shrinks by 114 lines (3,433 to 3,319). --json
output mode preserved for CI pipelines.
Moves the two zone discovery / aggregation handlers
(--list-zones, --zone-stats) out of main.cpp into a new
cli_zone_list.{hpp,cpp} module. The first quickly enumerates
zones across the standard locations (custom_zones, output);
the second walks a project dir computing tile / creature /
quest / per-format byte totals with a per-zone breakdown
table — useful for content-pack release notes and capacity
planning.
main.cpp shrinks by 191 lines (3,624 to 3,433). Both --json
output modes preserved.
Moves the two Makefile-generation handlers (--gen-makefile,
--gen-project-makefile) out of main.cpp into a new
cli_makefile.{hpp,cpp} module. Both emit GNU make recipes
that rebuild every derived output (.glb / .obj / .stl / .html
/ .csv / .md) from sources via wowee_editor flags, with proper
dependency tracking so make can skip already-up-to-date
outputs. Designers can `make -j$(nproc)` to rebuild all zones
in parallel after a content edit.
main.cpp shrinks by 167 lines (3,791 to 3,624).
Moves the two manifest-drift fix handlers (--repair-zone,
--repair-project) out of main.cpp into a new cli_repair.{hpp,cpp}
module. Both auto-fix the common manifest-vs-disk
inconsistencies that accumulate when zones are hand-edited or
partially copied — adding orphan WHM tiles to the manifest,
syncing the hasCreatures flag with the actual creatures.json
content, and warning (not removing) for tiles in the manifest
without backing files. Both honor --dry-run for safe previews.
main.cpp shrinks by 155 lines (3,946 to 3,791).
Moves the two cleanup-pass handlers (--strip-zone,
--strip-project) out of main.cpp into a new
cli_strip.{hpp,cpp} module. Both remove derived outputs
(.glb / .obj / .stl / .html / .dot / .csv / .png /
ZONE.md / DEPS.md) leaving only source files. Useful before
--pack-wcp so archives don't carry redundant exports, and
before committing to git so derived blobs don't bloat
history. Both honor --dry-run for safe previews.
main.cpp shrinks by 164 lines (4,110 to 3,946).
Moves the four zone-level lifecycle handlers (--copy-zone,
--rename-zone, --remove-zone, --clear-zone-content) out of
main.cpp into a new cli_zone_mgmt.{hpp,cpp} module. All slug-
aware: copy + rename keep file names and manifest mapName in
sync so the result is self-consistent; clear-content empties
the per-feature JSONs without touching terrain.
main.cpp shrinks by 321 lines (4,431 to 4,110).
Moves the three per-tile zone-manifest handlers (--add-tile,
--remove-tile, --list-tiles) out of main.cpp into a new
cli_tiles.{hpp,cpp} module. Zones can span multiple ADT tiles;
these manage that list — add creates a fresh blank WHM/WOT
pair at the new tile, remove drops the entry + deletes
WHM/WOT/WOC files, list prints the manifest with file-presence
flags.
main.cpp shrinks by 185 lines (4,616 to 4,431).
Moves the two zone-creation handlers (--scaffold-zone,
--mvp-zone) out of main.cpp into a new cli_zone_create.{hpp,cpp}
module. Both kickstart a new authoring session by generating a
new zone directory under custom_zones/ — empty for scaffold,
populated with one of each content type (creature + object +
quest with objective + reward) for mvp. Each goes terrain +
manifest, then mvp adds the demo content positioned at the
tile center.
main.cpp shrinks by 155 lines (4,771 to 4,616).
Moves the three items.json mutation handlers (--set-item,
--copy-zone-items, --clone-item) out of main.cpp into a new
cli_items_mutate.{hpp,cpp} module. All three operate on the
same {"items": [...]} schema; --set-item supports both
id-lookup ("123") and index-lookup ("#0") with strict
"only changed fields are written" semantics, --copy-zone-items
has replace and --merge modes, --clone-item auto-assigns the
smallest unused id.
main.cpp shrinks by 316 lines (5,087 to 4,771) and finally
drops below 5K. items.json now has its full mutation surface
in one focused module instead of scattered through the
megafile.
Moves the three item-export handlers (--export-zone-items-md,
--export-project-items-md, --export-project-items-csv) out of
main.cpp into a new cli_items_export.{hpp,cpp} module. All
three render items.json data as human-readable Markdown / CSV
reports for design docs, PR descriptions, GitHub Pages, and
spreadsheet pivot-table workflows.
main.cpp shrinks by 262 lines (5,349 to 5,087).
Moves the four random-population handlers (--random-populate-zone,
--random-populate-items, --gen-random-zone, --gen-random-project)
out of main.cpp into a new cli_random.{hpp,cpp} module. All four
use the same seeded LCG so re-runs reproduce the same content;
the gen-random-* pair shells out to scaffold-zone +
random-populate-zone + random-populate-items so the simpler
single-purpose handlers stay the source of truth.
main.cpp shrinks by 439 lines (5,788 to 5,349). The inline word
lexicons (creature names, object paths, item prefixes/nouns) move
with random-populate-zone and -items into the new module.
Moves the three add-* coordinate-based append handlers
(--add-object, --add-creature, --add-item) out of main.cpp
into a new cli_add.{hpp,cpp} module. All three append a
single entry to a zone's JSON file with optional positional
args after the required ones. --add-item handles raw
nlohmann::json (no dedicated editor class) and auto-assigns
the smallest unused id when the user passes 0 / nothing.
main.cpp shrinks by 198 lines (5,986 to 5,788).
Moves the four bounds-checked remove-by-index handlers
(--remove-creature, --remove-object, --remove-quest,
--remove-item) out of main.cpp into a new
cli_remove.{hpp,cpp} module. All four share the same
load-erase-save pattern with index validation and a "what
was removed" report for audit trails. The first three use
their respective editor classes (NpcSpawner, ObjectPlacer,
QuestEditor); --remove-item walks raw nlohmann::json since
items.json doesn't have a dedicated editor class yet.
main.cpp shrinks by 145 lines (6,131 to 5,986).
Moves the three clone-* handlers (--clone-quest,
--clone-creature, --clone-object) out of main.cpp into a new
cli_clone.{hpp,cpp} module. All three deep-copy by index,
optionally rename, and (for creature/object) offset the new
copy by 5 yards along X to prevent z-fighting with the
original. Each resets the per-entity unique id so downstream
systems that dedupe by id stay consistent.
main.cpp shrinks by 184 lines (6,315 to 6,131).
Moves the two quest-reward mutation handlers
(--add-quest-reward-item, --set-quest-reward) out of main.cpp
into a new cli_quest_reward.{hpp,cpp} module. Both operate on
a quest's reward struct in zone.json: the first greedy-consumes
multiple item paths in one invocation, the second uses
order-independent flag/value pairs (--xp / --gold / --silver
/ --copper) with strict 'only changed fields are written'
semantics so partial updates don't clobber unrelated fields.
main.cpp shrinks by 114 lines (6,429 to 6,315).
Moves three contiguous quest mutation handlers (--add-quest,
--add-quest-objective, --remove-quest-objective) out of
main.cpp into a new cli_quest_objective.{hpp,cpp} module.
All three operate on a zone's quests.json with the same
QuestEditor load-edit-save flow; the objective add/remove
pair includes auto-generated description text from
type+name+count for tooltip-friendly defaults.
main.cpp shrinks by 174 lines (6,603 to 6,429). Reward and
clone-quest handlers stay inline for follow-up extractions.
Moves the three open-format world-asset inspectors
(--info-wob, --info-wot, --info-woc) out of main.cpp into a
new cli_world_info.{hpp,cpp} module. Each prints a quick
structural summary (groups / portals / chunk counts /
triangles / bounds) without paying the full deserialization
cost a viewer would.
main.cpp shrinks by 144 lines (6,926 to 6,786). The
--copy-project handler that interleaved between --info-wob
and --info-wot stays inline -- it isn't an inspector and
belongs with project-mutation operations. All --json output
modes preserved.
Moves the two audio-config audit handlers (--info-zone-audio,
--info-project-audio) out of main.cpp into a new
cli_info_audio.{hpp,cpp} module. Both surface the music /
day-ambience / night-ambience / volume settings stored in
zone.json so designers can spot zones still missing audio
assignment before a release pass.
main.cpp shrinks by 127 lines (7,053 to 6,926). Drops the
dead `label` lambda inside info-project-audio that the
unused-but-set-variable warning had been flagging. Both
--json output modes preserved.
Moves the two content-density audit handlers
(--info-zone-density, --info-project-density) out of main.cpp
into a new cli_info_density.{hpp,cpp} module. Both count
creatures/objects/quests per tile to surface sparse zones
(boring) and over-stuffed ones (frame-rate bombs); the project
variant rolls per-zone numbers into a project-wide table with
per-zone averages for content-pacing reviews.
main.cpp shrinks by 201 lines (7,254 to 7,053). Both --json
output modes preserved for balance-audit pipelines.
Moves the two water-layer audit handlers (--info-zone-water,
--info-project-water) out of main.cpp into a new
cli_info_water.{hpp,cpp} module. Both aggregate liquid data
(water/ocean/magma/slime) across MH2O chunks; the project
variant rolls per-zone counts into a project-wide total with
height range and per-type histogram.
main.cpp shrinks by 209 lines (7,463 to 7,254). Both --json
output modes preserved for capacity-planning pipelines.
Moves the two spatial-bounds info handlers (--info-zone-extents,
--info-project-extents) out of main.cpp into a new
cli_info_extents.{hpp,cpp} module. Both compute world-space XYZ
bounding boxes from manifest tile coords + per-chunk height
samples; the project variant unions every zone's box into one.
main.cpp shrinks by 232 lines (7,695 to 7,463). Both --json
output modes preserved for camera-framing pipelines.
Moves the two disk-byte audit handlers (--info-zone-bytes,
--info-project-bytes) out of main.cpp into a new
cli_info_bytes.{hpp,cpp} module. Both categorize files by
extension into open / proprietary / derived buckets — the
project-wide variant is the headline metric for tracking
the open-format migration's progress against the .m2/.wmo/
.blp/.dbc baseline.
main.cpp shrinks by 244 lines (7,939 to 7,695). Both --json
output modes preserved for machine-readable reports.
Moves the two tree-style content browser handlers
(--info-zone-tree, --info-project-tree) out of main.cpp into
a new cli_info_tree.{hpp,cpp} module. Both render
Unix-`tree`-style hierarchical views — one drilling into a
single zone (manifest, tiles, creatures, objects, quests,
files) and one giving a bird's-eye view of every zone in a
project with bake/viewer status.
main.cpp shrinks by 201 lines (8,140 to 7,939). The remaining
info-zone/-project-* pairs (bytes, extents, water, density,
audio) form the next natural extraction batch.
Moves all six world-asset interchange handlers (--export-wob-glb,
--export-wob-obj, --import-wob-obj, --export-whm-glb,
--export-whm-obj, --export-woc-obj) out of main.cpp into a new
cli_world_io.{hpp,cpp} module. WOB / WHM / WOC are our open
replacements for proprietary WMO / ADT-heightmap / ADT-collision
data; these are the bridge that lets the open formats round-trip
through Blender, MeshLab, Three.js, and the rest of the standard
3D toolchain.
main.cpp shrinks by 858 lines (8,997 to 8,140). The single-mesh
--import-obj handler stays inline for now -- it shadow-mirrors
cli_wom_io's --import-stl semantics and will move there next.
Moves the four WOM interchange-format handlers (--export-obj,
--export-glb, --export-stl, --import-stl) out of main.cpp into
a new cli_wom_io.{hpp,cpp} module. WOM is our open M2
replacement; these are the bridge that lets it round-trip
through every external 3D tool — Blender, Three.js, slicers,
CAD packages — so the open format is actually useful.
main.cpp shrinks by 467 lines (9,464 to 8,997). The five WOB
and WHM exporters (--export-wob-glb, --export-whm-glb, etc.)
remain inline for a follow-up extraction.
Moves all 4 GLB introspection handlers (--validate-glb /
--info-glb shared, --info-glb-tree, --info-glb-bytes,
--check-glb-bounds) out of main.cpp into a new
cli_glb_inspect.{hpp,cpp} module. GLB is our open replacement
for proprietary M2/WMO bake outputs, so these belong with the
other open-format tooling.
main.cpp shrinks by 657 lines (10,121 to 9,464). Every
handler preserves its --json output mode for machine-readable
reports.
Moves the four structural validators for INTEROP file formats
(--validate-stl, --validate-png, --validate-blp, --validate-jsondbc)
out of main.cpp into a new cli_validate_interop.{hpp,cpp} module.
These check files coming in/out of wowee from third-party tools,
distinct from cli_format_validate.cpp which validates the native
open formats (WOM, WOB, WOC, WHM).
main.cpp shrinks by 524 lines (10,644 to 10,121). Each validator
preserves its --json output mode for machine-readable reports.
Moves the five single-file format converters (--convert-m2,
--convert-wmo, --convert-dbc-json, --convert-json-dbc,
--convert-blp-png) out of two dedicated post-loop blocks in
main.cpp into a new cli_convert_single.{hpp,cpp} module. The
batch wrappers in cli_convert.cpp keep working — they shell
out to wowee_editor with these flags.
main.cpp shrinks by ~335 lines (10,979 → 10,644). The two
trailing for-loops were dead code after wiring the dispatcher
into the main loop, so they're gone too.
Moves the four schema-migration handlers (--migrate-wom,
--migrate-zone, --migrate-project, --migrate-jsondbc) out of
main.cpp into a new cli_migrate.{hpp,cpp} module. Same
behavior — they're idempotent in-place upgraders for older
WOM revisions and JSON DBC sidecar schemas. main.cpp shrinks
by 282 lines (11,261 → 10,979).
Moves the 3D-export bake handlers out of main.cpp:
--bake-zone-glb --bake-zone-stl --bake-zone-obj
--bake-project-obj --bake-project-stl --bake-project-glb
The STL + GLB project bakes share a combined dispatcher (one
function with internal STL-vs-GLB branching) since they walk
the same per-zone asset list and only differ in the output
emission code.
main.cpp drops 12,119 → 11,261 lines (-858). The combined-OR
opener spanning multiple lines created a parse-error fragment
in the extraction; caught + manually fixed before commit
(same pattern as the WOM info attachments/particles/sequences
extraction).
Moves the report-export handlers (md / csv / html / sha256 /
graphviz) for zone & project audits out of main.cpp:
--export-zone-summary-md --export-zone-csv
--export-zone-checksum --export-project-checksum
--validate-project-checksum --export-zone-html
--export-project-html --export-project-md
--export-quest-graph
Also moves the file-scope wowee_sha256 namespace (the SHA-256
implementation that the checksum exporters use) into the new
module's anonymous namespace — it had no other callers in
main.cpp so no cross-TU coupling needed.
main.cpp drops 13,120 → 12,119 lines (-1,001). Build error
during extraction (missing #include <unordered_set>) caught
and fixed.
Moves the four extracted-Data-tree audit handlers out of main:
--info-extract (per-extension counts + bytes)
--info-extract-tree (per-directory rollup)
--info-extract-budget (proprietary share + open-format gap)
--list-missing-sidecars (find unconverted .m2/.wmo/.blp/.dbc)
All four operate on a Blizzard-format extracted Data tree —
they audit what's there and what's missing in the migration
from proprietary formats to open ones.
main.cpp drops 13,485 → 13,120 lines (-365). Behavior verified
by re-running --info-extract on a test zone (same output).
Moves the items.json read-only inspection handlers out of
main.cpp:
--list-items --info-item
--validate-items --validate-project-items
--info-project-items
Item editing handlers (--add-item, --set-item, --remove-item,
--add-quest-reward-item) stay in main.cpp since they share
state with quest reward editing logic and would need a
broader extraction.
main.cpp drops 13,887 → 13,485 lines (-402). Behavior
verified by re-running --list-items on a non-items zone
(same error message).
Moves the NPC spawn / object placer audit + ground-snap
handlers out of main.cpp:
--snap-zone-to-ground --snap-project-to-ground
--audit-zone-spawns --audit-project-spawns
--list-zone-spawns --list-project-spawns
--diff-zone-spawns --info-spawn
All operate on creatures.json + objects.json sidecars and
the WHM terrain heightfield via WoweeTerrainLoader.
main.cpp drops 14,628 → 13,887 lines (-741). Behavior verified
by re-running --audit-zone-spawns on a test zone (PASSED with
0 issues, same as before).
Moves the file-comparison handlers out of main.cpp into their
own translation unit:
--diff-wcp --diff-zone
--diff-glb --diff-wom
--diff-wob --diff-whm
--diff-woc --diff-jsondbc
--diff-extract --diff-checksum
main.cpp drops 15,653 → 14,732 lines (-921). One build error
during extraction (missing #include for NpcSpawner /
ObjectPlacer / QuestEditor used by --diff-zone) caught by
build and fixed.
Moves the seven proprietary-data-tree handlers out of main.cpp:
--migrate-data-tree --bench-migrate-data-tree
--list-data-tree-largest --export-data-tree-md
--info-data-tree --strip-data-tree
--audit-data-tree
All operate on a Blizzard-format extracted Data tree (the .m2/
.skin/.wmo/.blp/.dbc files) — they audit, migrate, or strip
proprietary-format files in support of the open-format
migration story.
Original placement spanned two sub-blocks (12546-12892 and
13093-13417 in main.cpp) interrupted by --gen-texture and
--add-texture-to-zone in the middle. Extraction collapses
both sub-blocks into one cohesive translation unit.
main.cpp drops 16,321 → 15,653 lines (-668). Behavior verified
by re-running --info-data-tree against a missing directory.
Moves the three zone & project metadata inspection handlers
out of main.cpp:
--info-zone (single zone.json print)
--info-zone-overview (high-level zone digest)
--info-project-overview (per-zone summary table for a project)
All three load zone.json via wowee::editor::ZoneManifest.
main.cpp drops 16,564 → 16,321 lines (-243). Behavior verified
by re-running --info-zone + --info-project-overview against
existing test zones.
Moves the six WoWee Content Pack (.wcp) handlers out of
main.cpp:
--list-wcp --info-wcp
--info-pack-budget --info-pack-tree
--pack-wcp --unpack-wcp
All six defer to wowee::editor::ContentPacker for actual pack
I/O; the handlers just parse args and format output, so the
extraction has no behavioral impact on the pack format itself.
main.cpp drops 17,766 → 17,505 lines (-261). Behavior verified
by re-running --info-wcp on a missing file (same error message).
Moves the proprietary-format inspection commands out of main.cpp
into their own translation unit. Each reads a Blizzard-format
file and prints its structure:
--info-png --info-blp
--info-m2 --info-wmo
--info-adt --info-jsondbc
main.cpp drops 18,198 → 17,766 lines (-432). Behavior verified
by re-running --info-png on a generated noise texture.
Moves the four bulk format-conversion handlers out of main.cpp:
--convert-m2-batch (M2 → WOM)
--convert-wmo-batch (WMO → WOB)
--convert-blp-batch (BLP → PNG)
--convert-dbc-batch (DBC → JSON)
These all share the same pattern: walk srcDir recursively for
files of the input extension and fan out to the single-file
--convert-* counterpart via subprocess (preserving the existing
per-file logic as the source of truth, no duplication).
Single-file converters (--convert-m2, --convert-wmo, etc.) and
the --migrate-* meta-commands still live in main.cpp; they're
in dedicated argv-rescan loops that need a different extraction
approach.
main.cpp drops 18,396 → 18,198 lines (-198). Behavior verified
by re-running --convert-blp-batch with a missing directory and
confirming the same error message.
Moves the open-format validation + project-audit handlers out
of main.cpp:
--validate --validate-wom
--validate-wob --validate-woc
--validate-whm --validate-all
--validate-project --validate-project-open-only
--audit-project --bench-audit-project
--bench-validate-project
Also moves the four shared validate*Errors helpers (validateWom/
Wob/Woc/WhmErrors, ~365 lines) into the same module's anonymous
namespace — they were file-scope helpers in main.cpp used only
by these handlers, so co-locating eliminates the cross-TU
coupling.
main.cpp drops 19,446 → 18,396 lines (-1,050). Two build errors
caught during extraction (wrong include path for the WHM loader
header; missing #include for ContentPacker / std::set / std::map);
all fixed before commit.
Moves the WOM model inspection commands out of main.cpp:
--info (bare WOM summary)
--info-batches (per-batch material info)
--info-textures (texture path list)
--info-doodads (WOB doodad set / instance list)
--info-attachments ⎫ combined handler with same M2 load +
--info-particles ⎬ skin merge but different sub-array
--info-sequences ⎭ iteration
--info-bones (bone hierarchy)
--export-bones-dot (Graphviz DOT output)
main.cpp drops 20,005 → 19,446 lines (-559). Behavior verified
by running --info, --info-batches, --info-textures on a fresh
WOM. Build error during extraction (combined-or handler header
spanned 4 lines, the transform script only stripped the first;
also missing #include for WoweeBuildingLoader) caught by build
and fixed before commit.