Skip to content

DBC alignment: core structs → client-verified 1.12 schemas (48 tables)#428

Merged
MadMaxMangos merged 27 commits into
masterfrom
enhance/dbc
Jul 6, 2026
Merged

DBC alignment: core structs → client-verified 1.12 schemas (48 tables)#428
MadMaxMangos merged 27 commits into
masterfrom
enhance/dbc

Conversation

@MadMaxMangos

@MadMaxMangos MadMaxMangos commented Jul 6, 2026

Copy link
Copy Markdown
Member

DBC alignment: core structs → client-verified schemas

Aligns the core's DBC representation (DBCStructure.h) with the client-verified 1.12 DBC schemas so every active field carries its provenance name and every server-unused field is documented in place — "commented but correct" and ready to activate if ever needed. Follows the CharStartOutfit pilot (already on master).

Merge order: this PR bumps the src/modules/SD3 and src/modules/Eluna submodule pointers, so it depends on the two companion PRs landing first — mangos/ScriptDev3 and MangosServer/Eluna (both branch enhance/dbc). If those merge as merge/squash commits (changing their master tip SHA), the submodule pointers here are re-pointed to the resulting tips before this merges.

What's in here

48 core DBC tables reconciled. The bulk (46 tables) is mechanical renames + docs; the final two tables (Spell, LiquidType) needed manual adjudication and are the substance of the tail of this branch.

Part Tables Renames Documented (server-unused)
Batches 1–5 (mechanical) 46 125 404
Spell (aggressive rename to .dbd) 1 41 13
LiquidType (field-1 correctness fix) 1 1
Total 48 167 417

~1,300 consumer call-sites were updated to the new field names across the game lib, ChatCommands, the SD3 and Eluna submodules, and the playerbot module. Every one was enumerated by the compiler (a rename leaves a stale entry->OldName that won't build), so completeness is guaranteed by the build, not by grep.

Two adjudicated tables (the follow-up)

Spell — aggressive rename to build-exact 1.12 .dbd names. All 41 active SpellEntry fields now carry their Spell.dbd (BUILD 1.12.0.5595-1.12.3.6141) names (e.g. Id→ID, powerType→PowerType, SpellFamilyName→SpellClassSet, SpellFamilyFlags→SpellClassMask, EffectImplicitTargetA/B→ImplicitTargetA/B, EffectApplyAuraName→EffectAura, SpellName→Name_lang). One name-reuse collision the compiler cannot catch — EffectAmplitude(cols 94-96)→EffectAuraPeriod while EffectMultipleValue(97-99)→EffectAmplitude — was handled by snapshotting the original consumer sites before the rename and remapping each by its original column; a dedicated review lens confirmed every reused-token site reads its original column.

LiquidType — a real (latent) correctness fix. Field 1 was mis-read as an int (uint32 LiquidId) but is actually the liquid name string (proven: the real LiquidType.dbc bytes {1,7,13,19,25} are the string-block offsets of Water/Ocean/Magma/Slime/Naxxramas-Slime; the build-exact .dbd agrees). Fixed to char* Name, with the one intentional DBCfmt.h change on this branch: LiquidTypefmt "niii"→"nsii". sizeof(LiquidTypeEntry) and GetFormatRecordSize both go 16→20, so the startup size-assert still holds. The field has 0 consumers, so there is no behavioural change; the extractor sub-system reads LiquidType.dbc through its own reader (fields 0 and 3 only) and is untouched.

Why this is (essentially) zero-runtime-risk

  • A rename is compile-time only: same field, same offset, same bytes; sizeof unchanged, so the startup MANGOS_ASSERT(sizeof(T) == GetFormatRecordSize(fmt)) still holds.
  • Comment-but-correct touches only already-commented ('x') fields.
  • The only functional change is LiquidType field 1 (0 consumers, guarded by the size-assert + an in-game water check).

A branch that compiles and boots is therefore behaviourally identical to before, except the intended LiquidType.Name correction.

For reviewers — shared submodules (SD3 / Eluna) are cross-fork-safe

SD3 (mangos/ScriptDev3) and Eluna (MangosServer/Eluna) are single repositories shared by all five getMangos cores (Zero/One/Two/Three/Four). Because Zero renamed its own SpellEntry while the other cores keep the legacy names, the shared consumer code cannot use either name unconditionally. It is therefore routed through expansion-guarded accessors (extending SD3's existing GetManaCost()/GetPowerType() pattern): sc_creature.h defines SD3_Spell*() helpers that resolve per expansion — CLASSIC→the new .dbd name, TBC/WOTLK→the legacy field, CATA/MISTS→the existing GetXxx() methods — and Eluna guards its sites with ELUNA_EXPANSION == EXP_CLASSIC. So merging the SD3/Eluna enhance/dbc branches upstream leaves One/Two/Three/Four building and behaving exactly as before — each core only ever compiles its own branch. This was verified per-fork against each core's actual SpellEntry struct.

  • SD3mangos/ScriptDev3 branch enhance/dbc — SpellEntry consumers via guarded accessors (SD3_Spell*). The earlier-batch AreaTrigger id→ID and SpellRange minRange/maxRange→RangeMin/RangeMax renames — which were unguarded — are now routed the same way through SD3_AreaTriggerId / SD3_SpellRangeMin / SD3_SpellRangeMax, so every Zero-side rename that touches shared SD3 code is expansion-guarded.
  • ElunaMangosServer/Eluna branch enhance/dbc — every consumer rename guarded by #if ELUNA_EXPANSION == EXP_CLASSIC (new .dbd name) / #else (legacy token restored verbatim): SpellEntry Id, plus the earlier-batch AreaTrigger id→ID, AreaTable area_name→AreaName_lang, 8× TaxiPathNode fields, SkillLine categoryId/id, and ChrClasses/ChrRaces name→Name_lang — all of which were initially committed unguarded (Eluna is not in the mangosscript target, so those breaks were invisible until a dedicated game-target compile). All four cores' DBCStructure.h were confirmed to share the identical legacy names, so the #else branch is provably correct for One/Two/Three/Four.

Validation (all green)

  • Build: every batch and the Spell/LiquidType follow-up compile clean (mangosd links); the compiler is the consumer-completeness net.

  • Boot-assert: the deployed build boots and initializes 50 DBC data stores with no size-assert abort, then completes full server startup (spell chains, proc tables, quest/area data — all fed by the renamed SpellEntry).

  • Review: adversarial multi-lens reviews (rename-fidelity / consumer-fidelity / collision-correctness), per-finding verified — 0 surviving findings on the Zero side; a dedicated per-fork pass verified the cross-fork accessor branches against every other core's real struct.

  • Cross-fork compile proof (real other-fork builds): the SD3 and Eluna enhance/dbc branches were dropped into real One/TBC, Two/WotLK and Three/Cata checkouts and compiled:

    • SD3mangosscript on all three: every SpellEntry / AreaTrigger / SpellRange cross-fork guard site compiled to 0 errors, including Cata's distinct accessor branches (GetManaCost() method, powerType/rangeIndex data members, and the consumer sites correctly routing around the Cata-fenced SD3_SpellEffect* accessors). mangosscript.lib links cleanly on all three (and on Classic).
    • Elunagame on all three: CreatureHooks, ServerHooks and Methods (which pulls in the guarded GlobalMethods/PlayerMethods/UnitMethods headers) all recompiled and game.lib linked with 0 errors — exercising the #else legacy branch under EXP_TBC, EXP_WOTLK and EXP_CATA. The Cata build additionally compiles the string-field sites against Cata's DBCString (char const* const*) representation, confirming the [locale] indexing holds there too. (Four/MoP uses the identical DBCString and legacy names — statically confirmed, not build-cloned.)

    This upgrades the cross-fork guarantee from static struct analysis to real compiles on three other forks.

  • In-game smoke: character create + cross-zone run + class trainer + vendor (earlier); plus .learn all_myclass (exercises SpellClassSet/SpellClassMask class-family filtering) and self-cast spells/auras — no issues.

Bonus: fixes a cross-core regression this sweep uncovered

The cross-fork compile sweep surfaced an unrelated, recent regression in SD3 master (commit 005a340f, 2026-06-21): boss_shade_of_aran and boss_deathbringer_saurfang had been changed to #if !defined(MISTS) m_creature->powerType #else GetPowerType(), which assumes every core except MoP carries a Creature::powerType data member. Only Classic does — so mangosscript fails to compile on TBC/WotLK/Cata ('powerType' is not a member of 'Creature'). The bundled SD3 branch drops the guard for plain m_creature->GetPowerType() (present on all cores; behaviourally identical), which is what the code was before the regression and what every fork-pinned SD3 pointer still uses. With this, mangosscript links on TBC/WotLK/Cata (and Classic/MoP are unchanged). It rides along as a one-commit cross-core fix, clearly separated from the DBC-alignment commits.

Deferred / noted (not fixed here)

  • EffectDicePerLevel (cols 70-72) reads float in the core struct+fmt but the .dbd declares int32. Server boots (both 4 bytes) and the field name is unchanged; flagged as a candidate type-fix for a separate follow-up (a type change is out of scope for a rename PR).

This change is Reviewable

MadMaxMangos and others added 24 commits July 3, 2026 10:51
…rrect docs)

Model race/class/sex/outfit as four uint8 fields (was one packed uint32),
fmt 'dbbbb...' so file offsets match the 152-byte record, drop the phantom
Unknown1-3, and update the single Player.cpp consumer to match on the three
identity bytes. sizeof == GetFormatRecordSize == 52 (startup assert).
Renames (struct field -> client-verified provenance name), consumers updated:
BankBagSlotPrices price->Price; TaxiNodes name->Name_lang;
SpellCastTimes CastTime->Base; ItemClass name->ClassName_lang;
CreatureSpellData spellId->SpellId; CinematicSequences Id->ID;
QuestSort id->ID; Talent DependsOnSpell->RequiredSpellID;
ItemRandomProperties enchant_id->Enchantment; CharStartOutfit ItemId->ItemID;
DurabilityCosts Itemlvl->ID, multiplier->WeaponSubClassCost.
Builds clean (mangosd links); server-unused fields documented (comment-but-correct).
Renames (struct field -> client-verified provenance name; ~131 consumers updated):
LiquidType Id->ID SpellId->SpellID; CreatureDisplayInfo Displayid->ID scale->CreatureModelScale;
GameObjectDisplayInfo Displayid->ID filename->ModelName; SpellShapeshiftForm flags1->Flags creatureType->CreatureType;
TalentTab TalentTabID->ID tabpage->OrderIndex; EmotesText Id->ID textid->EmoteID;
SpellRange minRange->RangeMin maxRange->RangeMax; ChatChannels ChannelID->ID flags->Flags pattern->Name_lang;
SkillLine id->ID categoryId->CategoryID name->DisplayName_lang;
ChrClasses ClassID->ID powerType->DisplayPower name->Name_lang spellfamily->SpellClassSet;
Map map_type->InstanceType (incl. inline helpers) name->MapName_lang linked_zone->AreaTableID multimap_id->LoadingScreenID.
LiquidType.Name deferred (type-contested). Builds clean (mangosd links); server-unused fields documented.
Aligns DBCStructure.h field names + docs to the client-verified schema
(reconciliation.json worklist) for 11 tables:
  AreaTrigger, SkillRaceClassInfo, WMOAreaTable, ItemSet, WorldMapArea,
  SpellItemEnchantment, Faction, ChrRaces, FactionTemplate, CreatureFamily,
  TaxiPathNode.

66 struct-field renames + comment-but-correct docs on server-unused fields.
Renames are compile-time only: same offset/bytes, sizeof unchanged, so the
startup sizeof==GetFormatRecordSize assert still holds; DBCfmt.h untouched.
287 consumer sites across 37 game/playerbot files updated (compiler-verified
complete: mangosd links clean). Submodule pointers advanced for the SD3
(AreaTrigger id->ID) and Eluna consumer fixes, each committed on its own
enhance/dbc branch in its own repo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sed) + consumers

Final batch of the DBC field-name alignment campaign.
- AreaTable (8 renames): mapid/zone/exploreFlag/flags/area_level/area_name/team/LiquidTypeOverride
  -> ContinentID/ParentAreaID/AreaBit/Flags/ExplorationLevel/AreaName_lang/FactionGroupMask/LiquidTypeID_3
  + 9 document-unused fields (SoundProviderPref/AmbienceID/ZoneMusic/... /LiquidTypeID_0..2).
- SkillLineAbility (11 renames): id/skillId/spellId/racemask/classmask/req_skill_value/
  forward_spellid/learnOnGetSkill/max_value/min_value/reqtrainpoints
  -> ID/SkillLine/Spell/RaceMask/ClassMask/MinSkillLineRank/SupercededBySpell/AcquireMethod/
     TrivialSkillLineRankHigh/TrivialSkillLineRankLow/ReqTrainPoints + 4 document-unused.
- 129 consumer sites fixed across 30 game/playerbot files + 1 Eluna (submodule pointer bumped).
Renames + comment-but-correct docs only; no type/width/DBCfmt change. sizeof unchanged
(AreaTable 96B, SkillLineAbility 44B) so the boot size-assert still holds. Builds clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Compiler-driven consumer fan-out for the SpellEntry struct rename (Task 2):
- ~1100 member accesses across game lib + Bots + ChatCommands renamed to the
  build-exact 1.12 .dbd names (Id->ID, EffectApplyAuraName->EffectAura,
  SpellFamilyName->SpellClassSet, SpellFamilyFlags->SpellClassMask,
  EffectImplicitTargetA/B->ImplicitTargetA/B, SpellName->Name_lang, etc.).
- Header PCH-unblock: SpellAuras.h/Spell.h/GridNotifiersImpl.h/SpellMgr.h +
  Bots/ItemVisitors.h inline accessors.
- Explicit EffectAmplitude/EffectMultipleValue collision remap (name-swap by
  column the compiler cannot catch): original EffectAmplitude sites ->
  EffectAuraPeriod, original EffectMultipleValue sites -> EffectAmplitude.
- Submodule consumer companions committed on their own enhance/dbc branches
  (SD3, Eluna); parent tracks the pointers.

Builds clean (mangosd links). No runtime change (pure member renames).
Submodule consumer renames now route through expansion guards so merging the
SD3/Eluna enhance/dbc branches upstream keeps One/Two/Three/Four building
unchanged. SD3 4e6b444, Eluna 2d9a9a3.
…s-fork safe)

SD3 8f5b6ff wraps the campaign's earlier AreaTrigger id->ID and SpellRange
min/max->RangeMin/RangeMax renames in expansion-guarded accessors
(SD3_AreaTriggerId / SD3_SpellRangeMin / SD3_SpellRangeMax), matching the
Spell/Eluna guard pattern so the SD3 enhance/dbc branch stays upstream-safe
for One/Two/Three/Four. Verified by a real One/TBC mangosscript compile: all
DBC-rename cross-fork breaks resolved (only a pre-existing powerType base-drift
in a Karazhan script remains, unrelated to DBC alignment). SD3 8f5b6ff,
Eluna 2d9a9a3 (unchanged).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Eluna cc67c39 wraps the previously-unguarded AreaTrigger/AreaTable/
TaxiPathNode/SkillLine/ChrClasses/ChrRaces consumer renames in
ELUNA_EXPANSION==EXP_CLASSIC guards (legacy token restored verbatim in
#else), so merging the Eluna enhance/dbc branch upstream keeps One/Two/
Three/Four building. Verified by real game-target compiles on One (TBC) and
Two (WotLK): both recompiled CreatureHooks/ServerHooks/Methods and linked
game.lib with 0 errors. SD3 8f5b6ff (unchanged), Eluna 2d9a9a3 -> cc67c39.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
SD3 7d62a5b drops the `#if !defined(MISTS) m_creature->powerType #else
GetPowerType()` guard (a master 005a340f regression that breaks TBC/WotLK/
Cata, which lack the Creature powerType data member) for plain GetPowerType()
at boss_shade_of_aran + boss_deathbringer_saurfang. Verified by real
mangosscript compiles: One/TBC + Two/WotLK + Three/Cata all now link with 0
errors (previously 1-2 powerType errors, no link). Surfaced by this branch's
cross-fork sweep; unrelated to the DBC alignment. SD3 8f5b6ff -> 7d62a5b,
Eluna cc67c39 (unchanged).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
master advanced 4 commits during review (waypoint smoothing fix, pets-on-boats,
no-emote-when-casting, and the [Decomp][Player] extraction of SpellCooldownMgr
+ PetMgr from Player.cpp). Only Player.cpp textually conflicted: master removed
the AddSpellAndCategoryCooldowns / cooldown block (extracted to SpellCooldownMgr)
while this branch had renamed its SpellEntry consumers - resolved by taking
master's side (the block moved out). The other 6 overlapping files auto-merged.

Follow-up commit renames the SpellEntry consumers in the newly-extracted
SpellCooldownMgr/PetMgr files (compiler-driven), which still use the pre-rename
.dbd field names.
@codacy-production

codacy-production Bot commented Jul 6, 2026

Copy link
Copy Markdown

Not up to standards ⛔

🔴 Issues 50 medium

Alerts:
⚠ 50 issues (≤ 0 issues of at least minor severity)

Results:
50 new issues

Category Results
UnusedCode 50 medium

View in Codacy

🟢 Metrics 0 complexity · -1 duplication

Metric Results
Complexity 0
Duplication -1

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

MadMaxMangos and others added 2 commits July 6, 2026 15:20
master's [Decomp][Player] (bfaf638) extracted the spell-cooldown code out of
Player.cpp into src/game/Object/SpellCooldownMgr.cpp AFTER this branch had
renamed the SpellEntry consumers - so the extracted file still read the
pre-rename spellInfo->Id at 6 sites. Renamed them to spellInfo->ID
(SpellEntry::Id -> ID). PetMgr uses no renamed SpellEntry fields.

Post-merge validation: full mangosd build links clean (game.lib + mangosd.exe,
0 errors); SpellCooldownMgr.cpp and PetMgr.cpp now compiled into the build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The companion SD3 and Eluna PRs were squash-merged to their masters, so
re-point from the (now-redundant) feature-branch tips to the canonical
master commits:
  SD3   7d62a5b (enhance/dbc) -> 052bd57 (mangos/ScriptDev3 master, PR #97)
  Eluna cc67c39 (enhance/dbc) -> f7a6e59 (MangosServer/Eluna master, PR #2)
Both squash commits were verified tree-identical to the feature-branch tips.
@AppVeyorBot

Copy link
Copy Markdown

…lete 154-table map)

Adds src/game/Server/DBCStructure_reference.h — inert, build-exact reference
structs for the 103 client 1.12 DBC tables the core does not model, plus a
catalogue of all 154 (ACTIVE in DBCStructure.h vs DOC here). Generated from the
client-verified schemas by CoreAlign/tools/gen_reference.py: every field carries
its .dbd name/type and a [dbd-only] flag where the schema is dbd-inferred rather
than decomp-confirmed. The header is NOT #included by any TU (zero build cost);
activating a table = move its struct into DBCStructure.h + add its fmt + a loader.
So the core now carries a complete map of every 1.12 client DBC.

Verified: valid C++ (MSVC cl /Zs, all 103 structs, 0 errors) and adversarially
checked struct-vs-schema across all 103 (coverage/types/names/confidence flags).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@MadMaxMangos MadMaxMangos merged commit 480f0bb into master Jul 6, 2026
6 of 8 checks passed
@MadMaxMangos MadMaxMangos deleted the enhance/dbc branch July 6, 2026 15:32
MadMaxMangos added a commit that referenced this pull request Jul 6, 2026
…#429)

Post-#428 review follow-up (antz): the build-exact rename made some members
read generically (e.g. SpellName -> Name_lang), so a `git grep` for the old
mangos field name no longer found the field. Append a `(was <legacyName>)`
breadcrumb to each renamed active member's comment so the old name stays
greppable and the field remains easy to hunt down a year from now.

Comment-only, no code change: 117 fields across 30 structs, every one a pure
trailing-comment append (verified: 0 declaration/type/name edits). The legacy
names are generated from the campaign's authoritative rename maps
(reconciliation.json + spell-rename-map.json) and every one was validated as a
real pre-#428 active member. Pure case reformats (findable by case-insensitive
grep) are intentionally skipped.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants