Closes the WSEA open-format loop with --export-wsea-json /
--import-wsea-json, mirroring the JSON pairs added for
every other novel binary format. All 25 binary formats
added since WOL now have full JSON round-trip authoring.
Each event round-trips all 11 scalar fields. Two enum-typed
fields emit dual int + name forms:
• holidayKind (combat / collection / racial / anniversary /
fishing / cosmetic / world-event)
• factionGroup (both / alliance / horde)
Verified byte-identical round-trip on the yearly preset
(4 holidays — Hallow's End / Brewfest / Lunar Festival /
Winter's Veil — with full WTKN tokenIdReward cross-refs
preserved through the JSON layer).
Adds 2 flags (623 documented total now).
Closes the WTIT open-format loop with --export-wtit-json /
--import-wtit-json, mirroring the JSON pairs added for
every other novel binary format. All 24 binary formats
added since WOL now have full JSON round-trip authoring.
Each title round-trips all 8 scalar fields (titleId, name,
nameMale, nameFemale, iconPath, prefix, category, sortOrder).
Two enum-typed fields emit dual int + name forms:
• category (achievement/pvp/raid/class/event/profession/...)
• prefix (1=prefix vs 0=suffix display position)
Verified byte-identical round-trip on the PvP preset
(28-title Honor System ladder with full Alliance + Horde
rank coverage preserved through the JSON layer).
Adds 2 flags (616 documented total now).
85th procedural texture: gear-cog wheel pattern tiled per
cell. Three concentric radii define the gear:
• hub (rNorm < 0.20) — center axle hole, kept as bg
• inner (rNorm < 0.65) — gap floor between teeth
• outer (rNorm < 0.92) — tooth tip
Teeth alternate around the gear via a per-tooth phase
calculation: theta is mapped into a tooth period of
2*pi/teeth, with the first half of each period rendering
as a tooth (effective radius = outer) and the second half
rendering as a gap (effective radius = inner).
Useful for: engineering crafting backdrops, mechanical
door textures, gnomish / goblin themed gear icons,
factory / forge tile sets, clockwork-themed dungeons,
steampunk faction insignia, machinery damage states.
Distinct from --gen-texture-rings (concentric circles only,
no teeth). The first procedural texture in the catalogue
that exercises a per-tooth periodic offset rather than a
fixed angular fold.
Novel open replacement for Blizzard's CharTitles.dbc + the
AzerothCore-style character_title SQL table. The 30th open
format added to the editor.
Defines the player-display titles awarded for completing
achievements ("the Versatile"), reaching PvP ranks
("Sergeant Major" / "Stone Guard"), participating in raids
("Champion of the Naaru"), levelling a profession ("Master
Locksmith"), or seasonal events ("Brewmaster", "the
Hallowed").
Closes a long-standing gap: WACH.entry.titleReward has been
a free-form string since batch 116 with no formal catalog
to resolve against. WTIT systematizes those strings into a
real catalog — the runtime resolves WACH.titleReward to a
WTIT entry by name, then displays the titleId in the player
title selector.
Cross-references:
WACH.entry.titleReward (string) ~= WTIT.entry.name
(string match — runtime
resolves achievement-
granted titles by
looking up matching WTIT
entry by name)
Format:
• magic "WTIT", version 1, little-endian
• per title: titleId / name / nameMale / nameFemale /
iconPath / prefix (suffix vs prefix display) /
category / sortOrder
Enums:
• Category (8): Achievement / Pvp / Raid / ClassTitle /
Event / Profession / Lore / Custom
API: WoweeTitleLoader::save / load / exists +
WoweeTitle::findById / findByName.
Three preset emitters showcase typical title catalogs:
• makeStarter — 4 titles (Versatile / Sergeant /
Champion / Hallowed) covering 4
categories
• makePvp — 28-title classic Honor System ladder
(14 Alliance ranks Private->Grand
Marshal + 14 Horde ranks Scout->High
Warlord)
• makeAchievement — 8 achievement titles including "the
Versatile" matching WACH.makeMeta's
achievement 250 titleReward + capstone
profession titles
CLI added (5 flags, 608 documented total now):
--gen-titles / --gen-titles-pvp / --gen-titles-achievement
--info-wtit / --validate-wtit
Validator catches: titleId=0 + duplicates, empty name,
unknown category, gender variants set on only one side
(causes mixed-gender display when the runtime falls back to
canonical for the unset side).
Closes the WTRG open-format loop with --export-wtrg-json /
--import-wtrg-json, mirroring the JSON pairs added for
every other novel binary format. All 23 binary formats
added since WOL now have full JSON round-trip authoring.
Each trigger round-trips:
• triggerId / mapId / areaId / name / minLevel
• center / boxDims / dest as 3-element JSON arrays
• shape (dual int + name) / kind (dual int + name)
• radius / actionTarget / destOrientation
• requiredQuestId / requiredItemId
Verified byte-identical round-trip on the dungeon preset
(3 triggers including the box-shaped Deadmines portal with
WIT key gate (itemId=5200) and full destination + facing
preserved through the JSON layer).
Adds 2 flags (603 documented total now).
Novel open replacement for Blizzard's AreaTrigger.dbc +
AreaTriggerTeleport.dbc + the AzerothCore-style
areatrigger_template / areatrigger_teleport SQL tables.
The 29th open format added to the editor.
Defines proximity-based event zones — when a player enters
a defined region (box or sphere), the runtime fires the
trigger's action: teleport to another map, award
exploration XP for a quest, run a server script, gate an
instance entrance behind a key item, mark a PvP boundary,
or simply display a "Discovered: {area name}" banner.
Cross-references with previously-added formats — every
trigger field has a real format target:
WTRG.entry.mapId / areaId -> WMS.map.mapId / WMS.area.areaId
WTRG.actionTarget (Teleport) -> WMS.mapId
WTRG.actionTarget (QuestExploration) -> WQT.questId
WTRG.requiredQuestId -> WQT.entry.questId
WTRG.requiredItemId -> WIT.entry.itemId (key)
Format:
• magic "WTRG", version 1, little-endian
• per trigger: triggerId / mapId / areaId / name /
center vec3 / shape / kind / boxDims vec3 / radius /
actionTarget / dest vec3 / destOrientation /
requiredQuestId / requiredItemId / minLevel
Enums:
• Shape (2): Box / Sphere
• Kind (7): Teleport / QuestExploration / Script /
InstanceEntrance / AreaName / CombatStartZone /
Waypoint
API: WoweeTriggerLoader::save / load / exists / findById.
Three preset emitters showcase common trigger shapes:
• makeStarter — area-name + quest-exploration with
cross-ref to WQT 100 ("Investigate the
Camp")
• makeDungeon — outdoor area-name + portal-style
InstanceEntrance with Deadmines key
gate (WIT itemId 5200, matches
WLCK.makeDungeon's Boss Vault Seal) +
interior exit teleport back outdoors
• makeFlightPath — 2 sphere waypoints near flight masters
so the runtime can auto-open the
flight UI on proximity (matches WTAX
starter node positions)
CLI added (5 flags, 601 documented total now):
--gen-triggers / --gen-triggers-dungeon / --gen-triggers-flightpath
--info-wtrg / --validate-wtrg
Validator catches: triggerId=0 + duplicates, unknown shape /
kind, non-finite center, sphere with radius<=0, box with
all-zero half-extents, teleport / instance with dest=(0,0,0)
(silently does nothing — usually a typo), QuestExploration
without an actionTarget questId.
Closes the WTKN open-format loop with --export-wtkn-json /
--import-wtkn-json, mirroring the JSON pairs added for
every other novel binary format. All 22 binary formats
added since WOL now have full JSON round-trip authoring.
Each token round-trips all 8 scalar fields (tokenId, name,
description, iconPath, category, maxBalance, weeklyCap,
flags). Two enum-typed fields (category and flags) emit
dual int + name forms.
The flag bitset emits string-array form so a hand-author
can write ["hidden", "resets"] instead of having to
remember that HiddenUntilEarned|ResetsOnLogout = 0xC.
Verified byte-identical round-trip on the PvP preset
(8 tokens: Honor + Arena + 6 BG marks of honor with
maxBalance + weeklyCap + flags all preserved).
Adds 2 flags (596 documented total now).
Closes the WCHC open-format loop with --export-wchc-json /
--import-wchc-json, mirroring the JSON pairs added for
every other novel binary format. All 21 binary formats
added since WOL now have full JSON round-trip authoring.
Three top-level arrays mirror the binary layout:
• classes[] — id / name / icon / powerType (dual int +
name) / displayPower / baseHP+power scaling /
factionAvailability bitmask
• races[] — id / name / icon / factionId (dual int +
name) / male+female displayId / 5 base
stats / starting map+zone / language+mount
spell IDs
• outfits[] — classId+raceId+gender (dual int + name) +
items array (each: itemId + displaySlot)
Verified byte-identical round-trip on the starter preset
(2 classes / 2 races / 4 outfits with full WIT itemId
cross-references preserved through the JSON layer).
Adds 2 flags (594 documented total now).
Closes the WMS open-format loop with --export-wms-json /
--import-wms-json, mirroring the JSON pairs added for
every other novel binary format. All 20 binary formats
added since WOL now have full JSON round-trip authoring.
Two top-level arrays mirror the binary layout:
• maps[] — mapId / name / shortName / mapType (dual int +
name) / expansionId (dual int + name) / maxPlayers
• areas[] — areaId / mapId / parentAreaId / name /
minLevel..maxLevel / factionGroup (dual int +
name) / explorationXP / ambienceSoundId
Three enum-typed fields (mapType, expansionId, factionGroup)
emit dual int + name forms — a hand-author can write
"continent" / "wotlk" / "alliance" instead of remembering
the integer values.
Verified byte-identical round-trip on the classic preset
(3 maps including Deadmines instance, 6 areas with full
parent-chain hierarchy + WSND ambient cross-refs preserved).
Adds 2 flags (587 documented total now).
Closes the WTAL open-format loop with --export-wtal-json /
--import-wtal-json, mirroring the JSON pairs added for
every other novel binary format. All 19 binary formats
added since WOL now have full JSON round-trip authoring.
Each tree round-trips:
• treeId, name, iconPath, requiredClassMask
• talents[] with talentId / row / col / maxRank /
prereqTalentId+Rank / rankSpellIds[5] (always emitted
as a 5-element array, zero-padded for unused ranks)
The fixed-size rankSpellIds array round-trips exactly
even when most slots are zero — preserves binary layout
parity for downstream consumers expecting fixed-stride
talent records.
Verified byte-identical round-trip on the warrior preset
(3 trees, 11 talents with prereq chains and capstone WSPL
spell references intact).
Adds 2 flags (580 documented total now).
Novel open replacement for Blizzard's Map.dbc + AreaTable.dbc
+ the AzerothCore-style world_zone SQL tables. The 26th open
format added to the editor.
Defines two related kinds of locator in one catalog:
• Maps — top-level worlds (continents / instances / raids /
battlegrounds / arenas) with a friendly name,
type, expansion tag, and player-count cap.
• Areas — sub-zones within maps with friendly names, parent-
area chain, recommended level range, faction-
territory marker (alliance / horde / contested /
both), exploration XP, and an ambient-sound
cross-reference into WSND.
The runtime uses Areas for minimap labels, location strings
under the player frame, "Discover Sub-zone" XP gains, and
ambient-music selection on zone entry.
Cross-references with previously-added formats:
WMS.area.ambienceSoundId -> WSND.entry.soundId
WMS.area.parentAreaId -> WMS.area.areaId (intra-format
sub-zone hierarchy)
WSPN entries are tied to WMS.area boundaries by
world position (no direct ID — the runtime resolves
position -> area at lookup time)
Format:
• magic "WMSX", version 1, little-endian
• maps[] (each): mapId / name / shortName / mapType /
expansionId / maxPlayers
• areas[] (each): areaId / mapId / parentAreaId / name /
minLevel..maxLevel / factionGroup / explorationXP /
ambienceSoundId
Enums:
• MapType (5): Continent / Instance / Raid / Battleground / Arena
• ExpansionId (5): Classic / Tbc / Wotlk / Cata / Mop
• FactionGroup: Both / Alliance / Horde / Contested
(PvP-flagging zone)
API: WoweeMapsLoader::save / load / exists +
WoweeMaps::findMap / findArea.
Three preset emitters showcase the catalog shape:
• makeStarter — 1 continent + 3 areas with parent chain
(Goldshire is a sub-zone of Elwynn Forest)
• makeClassic — 2 continents + Deadmines instance + 6
areas (Stormwind/Elwynn/Goldshire/Westfall/
Duskwood/Teldrassil/Deadmines) with WSND
ambient-sound refs
• makeBgArena — Alterac Valley (40-player BG) + Nagrand
Arena (5v5 with maxPlayers=10)
CLI added (5 flags, 578 documented total now):
--gen-maps / --gen-maps-classic / --gen-maps-bgarena
--info-wms / --validate-wms
Validator catches: empty map name, unknown mapType / expansion,
BG/Arena with maxPlayers=0 (no participant cap), area ids=0
+ duplicates, empty area name, maxLevel < minLevel, areas
referencing non-existent maps, parentAreaId chains crossing
maps (sub-zones must be on the same world), self-parent.
Closes the WTAX open-format loop with --export-wtax-json /
--import-wtax-json, mirroring the JSON pairs added for
every other novel binary format. All 18 binary formats
added since WOL now have full JSON round-trip authoring.
Two top-level arrays mirror the binary layout:
• nodes[] — nodeId / mapId / name / iconPath / position[3] /
factionAlliance + factionHorde restrictions
• paths[] — pathId / fromNodeId / toNodeId / moneyCostCopper /
waypoints[] each with position[3] + delaySec
Vec3 fields become 3-element JSON arrays for natural
hand-edit. The intra-format graph (paths reference nodeIds)
round-trips exactly so the catalog's connectivity is
preserved.
Verified byte-identical round-trip on the continent preset
(6 nodes + 8 paths covering hub-and-spoke + 3 perimeter
shortcuts, 16 total waypoints).
Adds 2 flags (573 documented total now).
Novel open replacement for Blizzard's TalentTab.dbc +
Talent.dbc + the AzerothCore-style talent_progression SQL
tables. The 25th open format added to the editor.
Defines class talent specialization trees: per-class set
of named tabs (Arms / Fury / Protection for warrior, Fire
/ Frost / Arcane for mage), each with talents arranged in
a row/column grid, each talent having up to 5 ranks and
an optional prerequisite chain.
Cross-references with previously-added formats:
WTAL.talent.prereqTalentId -> WTAL.talent.talentId
(intra-format chain)
WTAL.talent.rankSpellIds[] -> WSPL.entry.spellId
(spell granted at each rank)
Format:
• magic "WTAL", version 1, little-endian
• per tree: treeId / name / iconPath / requiredClassMask /
talents[] (row, col, maxRank, prereqTalentId+rank,
rankSpellIds[5] zero-padded for unused ranks)
Enums:
• ClassMask: bit positions match canonical CharClasses.dbc
classIds — Warrior / Paladin / Hunter / Rogue / Priest /
DK / Shaman / Mage / Warlock / Druid
API: WoweeTalentLoader::save / load / exists +
WoweeTalent::findTree / findTalent (global lookup across
all trees in the catalog).
Three preset emitters showcase tree shapes:
• makeStarter — 1 small tree (3-talent vertical chain)
• makeWarrior — 3 trees (Arms 4 / Fury 4 / Protection 3)
with WSPL cross-refs at capstones
(Mortal Strike -> WSPL 12294, Battle Shout
-> WSPL 6673, Thunder Clap -> WSPL 6343)
• makeMage — 3 trees (Arcane / Fire / Frost) with
capstones referencing Frostbolt 116 /
Fireball 133 / Blink 1953 from WSPL
CLI added (5 flags, 571 documented total now):
--gen-talents / --gen-talents-warrior / --gen-talents-mage
--info-wtal / --validate-wtal
Validator catches: tree+talent ids=0 or duplicates, empty
tree name, requiredClassMask=0 (every class would see this
tree — usually a typo), maxRank not in 1..5, talent listing
itself as prerequisite, prereqTalentId pointing at a
talent that doesn't exist in this catalog (intra-format
cross-reference resolution), prereqRank=0 or > the prereq
talent's maxRank (catches off-by-one references), gaps in
rankSpellIds progression (rank N has spell but rank N-1
doesn't — usually a typo).
The validator caught a real authoring bug in the makeMage /
makeWarrior presets during smoke testing — initial check
was comparing prereqRank against the WRONG talent's maxRank
(this talent's rather than the prereq's). Fixed in the same
commit by hoisting the check into the cross-reference
resolution pass where the prereq talent is in hand.
Closes the WGSP open-format loop with --export-wgsp-json /
--import-wgsp-json, mirroring the JSON pairs added for
every other novel binary format. All 17 binary formats
added since WOL now have full JSON round-trip authoring.
Each menu round-trips:
• menuId, titleText
• options[] with optionId / text / kind (dual int + name) /
actionTarget / requiredFlags (dual int + flag-string array) /
moneyCostCopper
The kindName field makes it obvious that a hand-edited
"vendor" / "trainer" / "submenu" string maps to the right
internal value without needing to know that vendor=2 and
submenu=1.
Verified byte-identical round-trip on the innkeeper preset
(2 menus, 7 options including Submenu cross-references that
must stay byte-stable to preserve the inter-menu graph).
Adds 2 flags (566 documented total now).
Novel open replacement for Blizzard's TaxiNodes.dbc +
TaxiPath.dbc + TaxiPathNode.dbc. The 24th open format
added to the editor.
Defines the flight-master network: a set of named nodes
(positions on the world map) plus the paths between them
(sequences of waypoints with per-segment delay and a
per-path gold cost). The same file holds both node and
path lists — flat arrays keyed by id, with intra-format
references from path.fromNodeId / toNodeId to node.nodeId.
Cross-references:
WCRT.entry (with FlightMaster npcFlag) ~= WTAX.nodeId
(matched by world
position; flight
master NPCs stand
at their nodes)
WTAX.path.fromNodeId / toNodeId -> WTAX.entry.nodeId
(intra-format graph)
Format:
• magic "WTAX", version 1, little-endian
• nodes (each): nodeId / mapId / name / iconPath /
position / faction restrictions
• paths (each): pathId / from+toNodeId / moneyCostCopper /
waypoints[] each with position + per-waypoint delaySec
API: WoweeTaxiLoader::save / load / exists +
WoweeTaxi::findNode / findPath / findPathBetween.
Three preset emitters showcase different graph shapes:
• makeStarter — 2 nodes + 2 paths (round-trip)
• makeRegion — 4 nodes at a 500m square + 4-path
directed ring (NW->NE->SE->SW->NW)
• makeContinent — 6 nodes hub-spoke + 3 perimeter
shortcuts; intermediate waypoints
climb to altitude 120m for visual
arc effect
CLI added (5 flags, 564 documented total now):
--gen-taxi / --gen-taxi-region / --gen-taxi-continent
--info-wtax / --validate-wtax
Validator catches: nodeId/pathId=0 + duplicates, empty node
name, non-finite positions, fromNodeId == toNodeId
(self-loop path), path references to non-existent nodes
(intra-format cross-reference resolution), negative
waypoint delays.
91st procedural mesh: a wide flat base block with a tall
narrow monolith standing on top. Reads as a small carved
standing-stone marker.
Distinct from existing ritual-prop primitives:
• --gen-mesh-altar — table-shaped, has flat top
• --gen-mesh-shrine — multi-tier with cap
• --gen-mesh-tombstone — narrower, curved-top silhouette
• --gen-mesh-pillar — round column, no base block
• --gen-mesh-statue — has figure on top
Useful for: druid groves (boundary markers), witch shrines,
ancient ruins (pre-civilization monuments), graveyard
boundary stones, faction territory markers, Stonehenge-style
ring formations (use 4-8 instances around a center point).
48 verts / 24 tris from two simple boxes — minimal vertex
budget, suitable for placing in dense clusters.
Novel open replacement for AzerothCore-style gossip_menu +
gossip_menu_option + npc_text SQL tables PLUS the Blizzard
NpcText.dbc family. The 23rd open format added to the
editor.
An NPC's dialogue tree: a menu of options the player can
pick from when right-clicking the NPC. Each option may
bridge to another menu, trigger a vendor / trainer
interaction, offer a quest, etc. The simplified per-option
model (kind + actionTarget + flags + moneyCost) covers the
common cases without needing separate npc_text condition
tables.
Closes a major cross-format gap: WCRT.entry.gossipId has
existed since batch 116 (when WCRT was added) but pointed
to a format that didn't exist yet. The innkeeper preset's
menuId=4001 deliberately matches WCRT's Bartleby NPC so
the demo content stack can wire WCRT.gossipId = 4001 once
that field is plumbed through the runtime.
Cross-references:
WCRT.entry.gossipId -> WGSP.entry.menuId
WGSP.option.actionTarget (Submenu) -> WGSP.entry.menuId
WGSP.option.actionTarget (Vendor / Trainer)
-> WTRN.entry.npcId
WGSP.option.actionTarget (Quest) -> WQT.entry.questId
Format:
• magic "WGSP", version 1, little-endian
• per menu: menuId / titleText + options[]
• per option: optionId / text / kind / actionTarget /
requiredFlags / moneyCostCopper
Enums:
• OptionKind (13): Close / Submenu / Vendor / Trainer /
Quest / Tabard / Banker / Innkeeper /
FlightMaster / TextOnly / Script /
Battlemaster / Auctioneer
• OptionFlags: AllianceOnly / HordeOnly / Coinpouch /
QuestGated / Closes
API: WoweeGossipLoader::save / load / exists / findById;
presets makeStarter (1 menu with vendor + trainer + close),
makeInnkeeper (2-menu tree: main menu 4001 with hearth /
vendor / flight / submenu options + lore submenu 4002 that
links back), makeQuestGiver (1 menu with 2 quest options
referencing WQT 1 and 100, plus a paid respec script
exercising the Coinpouch flag with a 10g cost).
CLI added (5 flags, 558 documented total now):
--gen-gossip / --gen-gossip-innkeeper / --gen-gossip-questgiver
--info-wgsp / --validate-wgsp
Validator catches: menuId=0 + duplicates, empty title /
options, unknown option kind, empty option text, Submenu
options pointing at non-existent menuIds (intra-format
cross-reference resolution), Coinpouch flag without
moneyCost (misleading UI), AllianceOnly+HordeOnly conflict.
Closes the WTRN open-format loop with --export-wtrn-json /
--import-wtrn-json, mirroring the JSON pairs added for
every other novel binary format. All 16 binary formats
added since WOL now have full JSON round-trip authoring.
Each NPC round-trips:
• npcId, kindMask (dual int + kindList string array),
greeting
• spells[]: spellId / cost / requiredSkill+rank / minLevel
• items[]: itemId / stockCount / restockSec /
extendedCost / moneyCostCopper
The stockCount field has special handling — the sentinel
0xFFFFFFFF value emits as the string "unlimited" instead of
the raw integer, since 4294967295 reads as a magic-number
typo in hand-edit JSON. The importer accepts either form.
Verified byte-identical round-trip on the starter preset
(innkeeper 4001 with 1 spell + 3 items, exercising both
unlimited-stock and finite-stock-with-restock cases).
Adds 2 flags (553 documented total now).
Novel open replacement for AzerothCore-style npc_trainer +
npc_vendor SQL tables PLUS the Blizzard TrainerSpells.dbc
family. The 22nd open format added to the editor.
Unifies trainer spell lists and vendor item inventories
into one per-NPC entry. A creature flagged Trainer or
Vendor in WCRT references a WTRN entry that lists what they
teach / sell. The same NPC can be both — kindMask is a
bitmask covering the Trainer (0x01) and Vendor (0x02) kinds.
This format closes a major cross-format gap: WCRT.npcFlags
already had Vendor / Trainer bits, but until now there was
no format defining what a vendor sells or what a trainer
teaches. Now an NPC marked Vendor in WCRT has a real
inventory, and an NPC marked Trainer has a real spell list.
Cross-references — every WTRN field has a real format target:
WTRN.entry.npcId -> WCRT.entry.creatureId
WTRN.spell.spellId -> WSPL.entry.spellId
WTRN.spell.requiredSkillId -> WSKL.entry.skillId
WTRN.item.itemId -> WIT.entry.itemId
Format:
• magic "WTRN", version 1, little-endian
• per NPC: npcId / kindMask / greeting + spells[] + items[]
• per spell offer: spellId / moneyCostCopper /
requiredSkillId / requiredSkillRank / requiredLevel
• per item offer: itemId / stockCount (0xFFFFFFFF =
unlimited) / restockSec / extendedCost / moneyCostCopper
(0 = inherit from WIT.buyPrice)
API: WoweeTrainerLoader::save / load / exists / findByNpc;
presets makeStarter (innkeeper 4001 as both trainer +
vendor: teaches First Aid + sells starter items),
makeMageTrainer (NPC 4003 teaches the WSPL mage spells
at scaling cost), makeWeaponVendor (NPC 4002 sells WIT
weapons with mixed unlimited/finite stock + restock timers).
CLI added (5 flags, 551 documented total now):
--gen-trainers / --gen-trainers-mage / --gen-trainers-weapons
--info-wtrn / --validate-wtrn
Validator catches: npcId=0 + duplicates, kindMask=0 (NPC
offers nothing), Trainer flag without spells, Vendor flag
without items, spells/items present without the matching
kind bit (silently ignored at runtime), spellId=0 / itemId=0
in offers, finite stock with restockSec=0 (single-fill —
usually intentional but worth surfacing).
The 3 presets deliberately use npcIds matching WCRT village
merchants (4001/4002/4003) so the demo content stack is
self-consistent: WCRT 4001 has the Vendor + Trainer flag,
and WTRN 4001 actually defines what they sell and teach.
Closes the WACH open-format loop with --export-wach-json /
--import-wach-json, mirroring the JSON pairs added for
every other novel binary format. All 15 binary formats
added since WOL now have full JSON round-trip authoring.
Each achievement round-trips:
• 11 scalar fields (id, categoryId, name, description,
icon, titleReward, points, minLevel, faction, flags)
• criteria array with full per-criterion fields
Three enum-typed fields emit dual int + name forms so a
hand-author can use either:
• criterion.kind (kill/quest/loot/level/rep/cast/skill/visit/meta)
• faction (both/alliance/horde)
• flags (hidden/server-first/realm-first/tracking/...)
Verified byte-identical round-trip on the meta preset (4
achievements, 6 criteria including the 3 CompleteAchievement
criteria that wire the meta-achievement to its prerequisites).
Adds 2 flags (546 documented total now).
Closes the WSPL open-format loop with --export-wspl-json /
--import-wspl-json, mirroring the JSON pairs added for
every other novel binary format. All 14 binary formats
added since WOL now have full JSON round-trip authoring.
Each spell round-trips all 18 scalar fields. Four enum-typed
fields emit dual int + name forms so a hand-author can use
either:
• school (physical / holy / fire / nature / frost / shadow / arcane)
• targetType (self / single / cone / aoe-self / line / ground)
• effectKind (damage / heal / buff / debuff / teleport / summon / dispel)
• flags (passive / channeled / ranged / aoe / friendly / hostile / ...)
The flags bitset emits string-array form so a hand-author
can write ["hostile", "aoe"] instead of having to remember
that HostileOnly|AreaOfEffect = 0x110.
Verified byte-identical round-trip on the mage preset (4
spells covering frost / fire / arcane schools and damage /
buff / teleport effects, full flag and effect-value coverage).
Adds 2 flags (544 documented total now).
Novel open replacement for Blizzard's Achievement.dbc +
AchievementCriteria.dbc + AchievementCategory.dbc + the
AzerothCore-style character_achievement /
character_achievement_progress SQL tables. The 21st open
format added to the editor.
Each achievement carries display metadata (name, description,
icon, points, faction restriction) plus a list of criteria
the player must satisfy. Criteria mirror the WQT objective
model (kind + targetId + quantity), so the runtime can
reuse the same progress-tracking machinery for both quests
and achievements.
Cross-references with previously-added formats — every
criterion kind has a real format target:
WACH.criteria.targetId (kind=KillCreature) -> WCRT.creatureId
WACH.criteria.targetId (kind=CompleteQuest) -> WQT.questId
WACH.criteria.targetId (kind=LootItem) -> WIT.itemId
WACH.criteria.targetId (kind=CastSpell) -> WSPL.spellId
WACH.criteria.targetId (kind=ReachSkillLevel) -> WSKL.skillId
WACH.criteria.targetId (kind=EarnReputation) -> WFAC.factionId
WACH.criteria.targetId (kind=CompleteAchievement) -> WACH.achievementId
(meta-achievements)
Format:
• magic "WACH", version 1, little-endian
• per achievement: id / categoryId / name / description /
iconPath / titleReward / points / minLevel / faction /
flags / criteria[]
• per criterion: criteriaId / kind / targetId / quantity /
description
Enums:
• CriteriaKind (9): KillCreature / CompleteQuest / LootItem /
ReachLevel / EarnReputation / CastSpell /
ReachSkillLevel / VisitArea /
CompleteAchievement
• Faction: Both / Alliance / Horde
• Flags: HiddenUntilEarned / ServerFirst / RealmFirst /
Tracking / Counter / Account
API: WoweeAchievementLoader::save / load / exists /
findById; presets makeStarter (3 simple kill/quest/level
demos), makeBandit (3 with WCRT/WGOT/WQT cross-refs),
makeMeta (3 base + 1 meta-achievement granting "the
Versatile" title, exercising CompleteAchievement criterion
kind that lets achievements depend on other achievements).
CLI added (5 flags, 542 documented total now):
--gen-achievements / --gen-achievements-bandit / --gen-achievements-meta
--info-wach / --validate-wach
Validator catches: achievementId=0 + duplicates, empty name,
faction out of range, no criteria (achievement can never
be earned), criterion quantity=0, unknown criterion kind,
targetId=0 on criterion kinds that need a real resource
reference (everything except ReachLevel which uses the
quantity field for the level number).
The bandit preset's cross-references close the gameplay
graph end-to-end: kill 50 creatureId=1000 (matches WCRT/
WSPN/WLOT bandit), loot objectId=2000 (matches WGOT bandit
strongbox), complete questId=1 (matches WQT Bandit Trouble).
The meta preset closes a separate loop: 3 sub-achievements
covering Mining (skillId=186), Lockpicking (skillId=633),
and Frostbolt cast count (spellId=116) — each pointing at
a real WSKL/WSPL entry that already exists in the demo
content stack.
Closes the WSKL open-format loop with --export-wskl-json /
--import-wskl-json, mirroring the JSON pairs added for
every other novel binary format. All 13 binary formats
added since WOL now have full JSON round-trip authoring.
Each skill round-trips all 8 scalar fields (skillId, name,
description, categoryId, canTrain, maxRank, rankPerLevel,
iconPath). The categoryId emits dual int + name forms so a
hand-author can write "profession" / "weapon" / "language"
instead of the int values.
Verified byte-identical round-trip on the professions
preset (12 entries: 9 primary + 3 secondary professions
with full canonical SkillLine IDs preserved).
Adds 2 flags (537 documented total now).
Closes the WLCK open-format loop with --export-wlck-json /
--import-wlck-json, mirroring the JSON pairs added for
every other novel binary format. All 12 binary formats
added since WOL now have full JSON round-trip authoring.
Each lock round-trips:
• lockId, name, flags
• all 5 channel slots (even unused ones, kind=None)
• each channel: kind (dual int + name) + skillRequired +
targetId
The flag bitset emits string-array form so a hand-author
can write ["destruct"] instead of having to remember that
DestructOnOpen = 0x01. Channel kindName makes the difference
between item / lockpick / spell / damage obvious without
needing to know the int values.
Verified byte-identical round-trip on the dungeon preset
(3 locks: light lockpick + steel chest with dual key/pick
channels + boss-key seal with destruct flag).
Adds 2 flags (530 documented total now).
Closes the WFAC open-format loop with --export-wfac-json /
--import-wfac-json, mirroring the JSON pairs added for
every other novel binary format. All 11 binary formats
added since WOL now have full JSON round-trip authoring.
Each faction round-trips:
• 13 scalar fields (id, parent, name, description, flags,
7 ascending threshold values, baseReputation)
• enemies[] and friends[] as JSON int arrays for trivial
hand-edit
• reputationFlags as dual int + string-array form
(e.g. ["visible", "header"])
The 7 reputation thresholds round-trip exactly even though
they have non-default values in some presets — the
importer uses the canonical Hostile/Friendly/etc enum
values as defaults so a hand-author can omit the standard
thresholds and only specify custom ones.
Verified byte-identical round-trip on the alliance preset
(5 factions: Alliance header + 3 cities with reciprocal
friend lists + Defias enemy). Adds 2 flags (523 documented
total now).
Novel open replacement for Blizzard's Lock.dbc. The 18th
open format added to the editor. Closes the cross-reference
gap from WGOT.entry.lockId — until now that field pointed
to a format that didn't exist yet.
A lock is a multi-channel security check. Each lock has up
to 5 independent channels; a player can open the lock by
satisfying ANY ONE channel:
• Item — requires a specific key item (WIT cross-ref)
• Lockpick — requires the lockpicking skill at minimum rank
(rogue / engineering profession)
• Spell — requires casting a specific spell
• Damage — can be forced open with attack damage
Cross-references with previously-added formats:
WGOT.entry.lockId -> WLCK.entry.lockId
WLCK.channel.targetId (Item) -> WIT.entry.itemId
WLCK.channel.targetId (Lockpick) -> future WSKL skillId
WLCK.channel.targetId (Spell) -> future WSPL spellId
The starter and dungeon presets' lockIds (1 and 2)
deliberately match WGOT.makeDungeon's iron-door lockId=1
and bandit-strongbox lockId=2, so the demo content stack
already wires together: WSPN spawn -> WGOT object template
-> WLCK lock template -> WIT key items.
Format:
• magic "WLCK", version 1, little-endian
• per lock: lockId / name / flags / 5 fixed channel slots
• per channel: kind / skillRequired / targetId
• all 5 slots written even when unused (kind=None +
zeroed fields), keeping the per-entry size constant for
fast random access
Enums:
• ChannelKind: None / Item / Lockpick / Spell / Damage
• Flags: DestructOnOpen / RespawnOnKey / TrapOnFail
API: WoweeLockLoader::save / load / exists / findById;
presets makeStarter (Iron Door + Wooden Chest), makeDungeon
(matches WGOT cross-references; light/heavy lockpicks +
boss-key-only seal), makeProfessions (4-tier rogue lockpick
progression at ranks 1/100/175/250).
CLI added (5 flags, 521 documented total now):
--gen-locks / --gen-locks-dungeon / --gen-locks-professions
--info-wlck / --validate-wlck
Validator catches: lockId=0 + duplicates, all-None channels
(lock can never open), Item/Spell/Lockpick channels with
targetId=0 (no resource referenced), unknown channel kind,
skillRequired set on non-Lockpick channel (silently ignored
at runtime — flag as warning).
Closes the WGOT open-format loop with --export-wgot-json /
--import-wgot-json, mirroring the JSON pairs added for
every other novel binary format. All 10 binary formats
added since WOL now have full JSON round-trip authoring.
Each game object round-trips all 13 scalar fields plus
dual int + name forms for typeId (16 enum values) and the
flags bitset.
The flag bitset emits string-array form so a hand-author
can write ["despawn"] instead of having to remember that
Despawn = 0x08. typeName makes "door/chest/herb-node/..."
obvious without needing to know typeId=11 means HerbNode.
Verified byte-identical round-trip on the dungeon preset
(5 objects: door + button + 2 chests + trap with full
WLOT cross-references and lockId fields preserved).
Adds 2 flags (516 documented total now).
Novel open replacement for Blizzard's Faction.dbc +
FactionTemplate.dbc + the AzerothCore-style
reputation_reward / reputation_spillover SQL tables. The
17th open format added to the editor.
Combines the "displayable Faction" (player-facing name +
reputation thresholds for friendly/honored/revered/exalted)
with the "FactionTemplate matrix" (which factions are
hostile to which) into one entry. The runtime walks the
catalog to answer two questions:
• "Will faction A attack faction B on sight?" -> enemy list
• "What rep tier is the player with X?" -> thresholds
Cross-references with previously-added formats:
WCRT.entry.factionId -> WFAC.entry.factionId
WFAC.entry.parentFactionId -> WFAC.entry.factionId
WFAC.entry.enemies[] -> WFAC.entry.factionId
WFAC.entry.friends[] -> WFAC.entry.factionId
The starter preset's factionId 35 (Friendly) and 14
(Hostile) deliberately match the WCRT preset defaults, so
the demo content stack is consistent: WCRT.makeBandit's
factionId=14 has a real entry in WFAC.makeStarter that
declares it hostile to friendly NPCs (35) and players (1).
Format:
• magic "WFAC", version 1, little-endian
• per faction: factionId / parentFactionId / name /
description / reputationFlags / baseReputation /
7 ascending tier thresholds (hostile..exalted) /
enemies[] / friends[]
Enums:
• ReputationFlags: VisibleOnTab / AtWarDefault / Hidden /
NoReputation / IsHeader (group label)
• Tier (canonical): Hated / Hostile / Unfriendly /
Neutral / Friendly / Honored /
Revered / Exalted
API: WoweeFactionLoader::save / load / exists / findById +
WoweeFaction::isHostile(a, b); presets makeStarter (3-faction
demo matching WCRT defaults), makeAlliance (header +
Stormwind / Darnassus / Ironforge with reciprocal friend
lists + Defias enemy), makeWildlife (4 beast factions, each
hostile to player but ignoring other beasts).
CLI added (5 flags, 514 documented total now):
--gen-factions / --gen-factions-alliance / --gen-factions-wildlife
--info-wfac / --validate-wfac
Validator catches: factionId=0 + duplicates, empty name,
threshold ordering violations (hostile must be < unfriendly
< neutral < ... < exalted), self-listed as enemy or friend,
faction in both enemies and friends (incoherent).
Closes the WQT open-format loop with --export-wqt-json /
--import-wqt-json, mirroring the WOL/WOW/WOMX/WSND/WSPN/
WIT/WLOT/WCRT JSON pairs. All 9 binary formats added since
WOL now have full JSON round-trip authoring.
Each quest round-trips:
• 13 scalar fields (id, level range, masks, chain links,
giver/turnin, xp + money reward, flags)
• 3 string fields (title, objective, description)
• objectives array with dual int + name kindName
• rewardItems array with dual int + name pickFlagsList
The flag bitset emits string-array form so a hand-author can
write ["daily", "repeatable", "auto-accept"] instead of
having to remember the bit math. The objective kindName
makes "visit/collect/kill" obvious without needing to know
that kind=3 means VisitArea.
Verified byte-identical round-trip on the 3-quest chain
preset (full feature exercise: prev/next chain links,
mixed objective kinds, AutoComplete bridge quest, player-
choice rewards). Adds 2 flags (509 documented total now).
Closes the WCRT open-format loop with --export-wcrt-json /
--import-wcrt-json, mirroring the WOL/WOW/WOMX/WSND/WSPN/
WIT/WLOT JSON pairs. All 8 binary formats added since WOL
now have full JSON round-trip authoring.
Each creature template round-trips all 22 scalar fields.
Three enum-typed fields emit dual int + name forms so a
hand-author can use either:
• typeId (humanoid / beast / dragon / ...)
• familyId (wolf / cat / bear / ... — for beasts)
• npcFlags (vendor / quest / trainer / innkeeper / ...)
• aiFlags (passive / aggressive / flee / call-help / no-leash)
Both flag bitsets emit string-array forms so a hand-author
can write ["vendor", "innkeeper", "repair"] instead of
having to remember that those bits combine to 0x91.
Verified byte-identical round-trip on the merchants preset
(3 NPCs covering innkeeper / smith / alchemist with mixed
flag combinations). Adds 2 flags (502 documented total now).
Closes the WLOT open-format loop with --export-wlot-json /
--import-wlot-json, mirroring the WOL/WOW/WOMX/WSND/WSPN/WIT
JSON pairs. All 7 binary formats added since WOL now have
full JSON round-trip authoring.
Each loot table round-trips:
• table-level: creatureId, flags (int + flagsList strings),
dropCount, money min/max (copper)
• per-drop: itemId, chancePercent (float),
minQty / maxQty, flags (int + flagsList)
Both flag fields emit dual int + named string-array forms.
A hand-author can write ["quest", "always"] instead of
having to remember that QuestRequired|AlwaysDrop = 5.
Verified byte-identical round-trip on the boss preset
(6 drops including the QuestRequired+AlwaysDrop combo on
the guaranteed quest item, group-only epic at 5%, mass-loot
trade goods at 90%).
Adds 2 flags (495 documented total now).
Closes the WIT open-format loop with --export-wit-json /
--import-wit-json, mirroring the WOL/WOW/WOMX/WSND/WSPN
JSON pairs. All 6 binary formats added since WOL now have
full JSON round-trip authoring.
Each entry round-trips all 18 scalar fields plus the
variable-length stats array. Three enum-typed fields emit
dual int + name forms so a hand-author can use either:
• quality (poor..heirloom)
• itemClass (consumable / weapon / armor / quest / ...)
• inventoryType (head, chest, weapon-1h, ...)
Stats round-trip with both type int + typeName string so
"strength: 5" reads more naturally than "type=4, value=5"
in hand-edit JSON.
Verified byte-identical round-trip on the makeWeapons
preset (5 items spanning common -> legendary, both 1H and
2H slots, full damage / speed / stat coverage). Adds 2
flags (488 documented total now).
Novel open replacement for AzerothCore-style
creature_loot_template / gameobject_loot_template SQL
tables. The 13th open format added to the editor.
Pairs naturally with the WIT item catalog from the
preceding commit: each loot drop's itemId references an
entry in a WIT file, so a content pack ships both the
item definitions and the loot tables that reference them.
The runtime composes WIT + WLOT + WSPN to drive the full
"creature dies, drops items" flow without any SQL.
Format:
• magic "WLOT", version 1, little-endian
• per table: creatureId / flags / dropCount /
moneyMin..Max / itemDropCount + drops[]
• per drop: itemId / chancePercent (float, 0..100) /
minQty / maxQty / drop_flags
Table flags: QuestOnly, GroupOnly, Pickpocket
Drop flags: QuestRequired, GroupRollOnly, AlwaysDrop
dropCount is the slot budget — how many distinct drops
to roll per kill. Each item drop is rolled independently
against its chancePercent (so dropCount=2 with 4 candidate
drops at varying chances gives the classic "up to 2 distinct
items per kill" behavior). Drops with the AlwaysDrop flag
bypass the slot budget — used for guaranteed quest items.
API: WoweeLootLoader::save / load / exists /
findByCreatureId; presets makeStarter (1 table, 1 drop),
makeBandit (4 candidates, dropCount=2, matches the camp
spawns from WSPN at creatureId=1000), makeBoss (6 candidates
including guaranteed quest item via AlwaysDrop and a
group-only epic at 5%).
CLI added (5 flags, 486 documented total now):
--gen-loot / --gen-loot-bandit / --gen-loot-boss
--info-wlot / --validate-wlot
Validator catches: creatureId=0, duplicates, chance not in
0..100, NaN chance, money min > max, minQty > maxQty,
dropCount=0 with non-empty drops list (silent dead config).
All 3 presets save / load / re-validate clean. The bandit
table's creatureId=1000 deliberately matches WSPN's
makeCamp creatureId so the open-format demo content pack
already has working cross-references.
84th procedural texture: 6-fold symmetric snowflake stamp
tiled per cell. Built by computing polar (r, theta) from
the cell center and folding theta into a [0, pi/6] wedge,
so a single arm-shape definition replicates 12 times via
mirror + 60-degree rotation.
Each arm is a thin sliver (sin-based perpendicular distance
test) thickened at two perpendicular knobs at r = 0.40 and
0.70 of the cell-half radius — the knobs provide the
classic "branched ice crystal" silhouette without needing
a separate per-arm subdivision pass.
A small filled center dot anchors the motif at small cell
sizes where the knobs vanish.
Useful for: arctic / winter zones, frost spell effects,
frost-mage themed gear icons, holiday-event decoration,
crystal-shrine backdrops, snowstorm overlays.
Distinct from --gen-texture-snow (random tiny dots, not a
patterned crystal) and --gen-texture-frost (spider-web
crackle, not radial). The first 6-fold-symmetric texture in
the catalogue.
Closes the WSPN open-format loop with --export-wspn-json /
--import-wspn-json, mirroring the WOL/WOW/WOMX/WSND JSON
pairs from earlier batches. All 5 binary formats added in
recent batches now have full JSON round-trip authoring.
Each entry round-trips all 12 fields:
kind (int + kindName string), entryId, position[3],
rotation[3], scale, flags (int + flagsList string array),
respawnSec, factionId, questIdRequired, wanderRadius,
label.
Vector fields are emitted as 3-element arrays for natural
JSON layout. Both kind and flags are emitted in dual form
(int + named) so a hand-author can write the named string
forms and skip the integer boilerplate. Missing optional
fields fall back to WoweeSpawns::Entry defaults.
Verified byte-identical round-trip on the village preset
(12 entries: 6 creature + 2 object + 4 doodad). The
position vec3 round-trips through floats with no precision
loss for the typical small-coordinate test cases.
Adds 2 flags (475 kArgRequired entries total).
Novel open replacement for AzerothCore-style scattered
creature_template / gameobject SQL spawn tables PLUS the
ADT MDDF / MODF doodad-placement chunks. The 11th open
format, and the first that covers the live world-content
side (atmosphere + sounds + spawns now form the runtime
"what fills this zone" picture).
A WSPN file holds all spawn points for a zone in a single
table, with kind discriminating creature vs game object
vs static doodad. The same format powers:
• server runtime — knows what NPCs / objects to spawn
• editor — draws spawn markers
• renderer — reads the doodad subset directly to
draw static props without going
through a server roundtrip
Format:
• magic "WSPN", version 1, little-endian
• per entry: kind / entryId / position(3f) / rotation(3f)
/ scale / flags / respawnSec / factionId /
questIdRequired / wanderRadius / label
Flags packed: disabled (0x01), event-only (0x02),
quest-phased (0x04). Reserved bits for future per-entry
encoding extensions.
API: WoweeSpawnsLoader::save / load / exists; presets
makeStarter (1 each kind), makeCamp (4-bandit ring +
chest + 2 tents), makeVillage (6 NPCs + 2 signs + 4
corner trees).
CLI added (5 flags, 473 documented total now):
--gen-spawns / --gen-spawns-camp / --gen-spawns-village
--info-wspn / --validate-wspn
Validator catches: out-of-range kind, NaN/inf coords,
non-positive scale, doodad with non-zero respawn (static
prop misuse), creature with respawn=0 (won't respawn after
kill), entryId=0 (orphan reference).
All 3 presets save / load / re-validate clean. Doodad and
game-object entries explicitly set wanderRadius=0 so the
generated catalogs are noise-free.
Tavern back-of-house / cookhouse scene composite. Pairs
naturally with --gen-tavern-pack (front-of-house common
room) for a complete inn setup.
Emits 7 .wom files into outDir:
• stove — pot-bellied cookfire stove
• cauldron — large hanging pot
• prep-table — flat work surface
• stool — cook's seat
• barrel — water / ale / flour storage
• mug — drink ready for the inn customer
• mortar — herb / spice grinding tool
This is the 11th themed pack (camp, blacksmith, village,
temple, graveyard, garden, dock, tavern, mining, arena,
kitchen). Notable for being the first pack that uses the
two recently-added drinking-vessel + alchemy primitives
(mug from batch 111, mortar-pestle from batch 113), proving
out the "build small primitives, then compose into themed
packs" workflow.
All 7 emitted primitives pass --validate-wom on first
generation. 468 kArgRequired entries total.
Closes the WSND open-format loop with --export-wsnd-json /
--import-wsnd-json, mirroring the WOL/WOW/WOMX JSON pairs
from earlier batches.
Each entry round-trips all 9 fields:
soundId, kind (int + kindName string), flags (int +
flagsList string array), volume, minDistance, maxDistance,
filePath, label.
Both kind and flags are emitted in dual form (int + named):
• kind : 2,
kindName : "ambient",
• flags : 3,
flagsList: ["loop", "3d"]
The importer accepts either form per field, so a hand-author
can write only the named string forms and skip the integer
boilerplate. Missing optional fields fall back to
WoweeSound::Entry defaults.
Verified byte-identical round-trip on the tavern preset
(5 entries with mixed flags and 3D distances).
Adds 2 flags (467 kArgRequired entries total). All 4 binary
formats added in recent batches now have full JSON round-trip:
WOL, WOW, WOMX, WSND.