Companion to 2026_05_10_00.sql. The spawn-data migration teaches the
worldserver where Paragon characters spawn and what per-level base
stats they have; this one teaches it which weapon/armor skill lines
to grant at first character login.
Without these rows a fresh Paragon character lands in their newbie
zone with no weapon or armor proficiencies (auto-attack greys out
on anything beyond a fist) -- the universal classMask=0 rows in
playercreateinfo_skills only cover Defense, Unarmed, Cloth,
languages, Mounts, and Companion Pets.
Adds 20 rows in playercreateinfo_skills with classMask=2048 (class
12 only) for every weapon and armor proficiency:
- Weapons: Swords, Axes, Bows, Guns, Maces, 2H Swords, Dual Wield,
Staves, 2H Maces, 2H Axes, Daggers, Thrown, Crossbows,
Wands, Polearms, Fist Weapons.
- Armor: Plate Mail, Mail, Leather, Shield. (Cloth already
granted via the classMask=0 universal row.)
Idempotent: DELETE WHERE classMask=2048 then INSERT, so it replays
cleanly on a partially-seeded DB (e.g. one where a contributor hand-
patched these rows before the migration landed).
Verified locally: applies cleanly twice in a row, worldserver restart
now logs `>> Loaded 1391 Player Create Skills` (was 1371 pre-Paragon
= +20 class-12 rows) and a freshly-rolled Draenei Paragon spawns with
the full weapon/armor kit.
CLIENT-PATCHES.md troubleshooting block updated to call out the
"Paragon spawns naked / can't equip anything" failure mode and list
all three migrations in the current rebuild recipe.
Co-authored-by: Cursor <cursoragent@cursor.com>
Companion to 2026_05_09_00.sql (DBC overlay). The DBC overlay teaches
the world server that class 12 (Paragon) exists; this migration
teaches it WHERE class-12 characters spawn, what action bar they boot
with, and what per-level base stats Player::InitStatsForLevel uses.
Without these rows, contributors hit:
- Player::Create -> "invalid race/class pair (R/12) - refusing"
and the client shows "Error creating character".
- WorldServer load -> "class-12 Level-L does not have stats data!"
integrity warnings.
Tables touched (idempotent: DELETE WHERE class=12 then INSERT):
- playercreateinfo : 10 rows, every DK-eligible race spawning
in their racial newbie zone (Northshire,
Valley of Trials, Ammen Vale, ...).
NOT Acherus -- Paragon is from-level-1.
- playercreateinfo_action : 46 rows, default action bar layout
per race (attack 6603, eat 78, racial,
etc.).
- player_class_stats : 80 rows, per-level base HP/Mana/STR/AGI/
STA/INT/SPI. Curve mirrors Warrior to
level 60, Paladin-style HP inflation
past 60 to keep Paragon competitive
in Wrath content.
Tables intentionally untouched: playercreateinfo_item is empty for
class 12 (Paragon ships no per-class starting items, only racial
kit), and the mask-based playercreateinfo_skills/_cast_spell/
_spell_custom rows already cover class 12 via their classMask=0
"all classes" entries.
Verified locally: applies cleanly twice in a row (idempotent),
worldserver restart now logs `>> Loaded 72 Player Create Definitions`
(was 62 pre-Paragon = +10 races for class 12) and creates a Draenei
Paragon without rejection.
CLIENT-PATCHES.md troubleshooting block updated to merge the two
"Character Creation Failed" modes (DBC overlay missing + spawn data
missing) into a single fix recipe. Existing contributors with a
pre-built dbimport image need
`docker compose build ac-db-import ac-worldserver` before this
migration is visible to DBUpdater; fresh clones get it on first
`docker compose up`.
Co-authored-by: Cursor <cursoragent@cursor.com>
Stock Docker installs fill data/dbc/ from the vanilla 3.3.5a extract
in `ac-wotlk-client-data`, which has no class 12 in ChrClasses.dbc and
no class-12 bit on SkillRaceClassInfo.dbc. CharacterHandler.cpp's
sChrClassesStore.LookupEntry(12) returns null and the create fails
with CHAR_CREATE_FAILED ("Class (12) not found in DBC ...") before the
contributor ever sees the panel. Fixing it required hand-copying the
patched DBCs onto the named volume — undocumented, fragile, and not
portable to native installs.
DBCStores.cpp::LoadDBC merges every <table>_dbc world-DB row on top of
the on-disk DBC store (storage.LoadFromDB after storage.Load). We use
that merge layer to ship Paragon's class-12 deltas as SQL:
- chrclasses_dbc: 1 row defining class 12 (Paragon, power=Mana,
family=Warrior, expansion=2). Resolves CHAR_CREATE_FAILED.
- skillraceclassinfo_dbc: 235 rows REPLACEing stock entries with the
patched ClassMask (class-12 bit OR'd in) so baseline skills (defense,
weapon skills, etc.) are available to Paragon characters.
The new `modules/mod-paragon/data/sql/db-world/updates/2026_05_09_00.sql`
is applied automatically by AC's DBUpdater on every fresh `ac-db-import`
run (Docker) or first worldserver boot (native). End-to-end verified
locally: truncate -> docker compose up ac-db-import -> rows reappear
with hash 33B1A05 recorded in updates table.
The migration is auto-generated by
fractured-tooling/from-workspace-root/_gen_paragon_dbc_overlay_sql.py
(outside this repo per the repo-tidy policy). Re-run it whenever the
DBC bake changes.
CLIENT-PATCHES.md is rewritten so contributors no longer need the
manual DBC sync section as their primary install path. Manual overlay
is preserved as a labelled fallback for tools that read data/dbc/
directly.
Co-authored-by: Cursor <cursoragent@cursor.com>
mod-paragon Paragon_Essence.cpp:
- Broaden SkillLinesLinkedToSpell: collect every SkillLineAbility row for
an anchor spell regardless of AcquireMethod, so anchor spells whose
primary SLA uses AcquireMethod 0 (e.g. Blood Strike) correctly identify
their skill lines and let the dependent classifier do its job.
- IsSpellSkillLineCascadeDependent / RevokeUnwantedCascadeSpellsForPlayer
use the broadened helper. HandleCommit calls the post-purchase sweep
immediately so the spellbook never carries lingering cascade dependents
(Blood Presence / Forceful Deflection / Death Coil / Death Grip).
- New character_paragon_panel_spell_revoked table tracks which active
dependents we've revoked per (guid, parent) so OnPlayerLogin can
re-revoke them after AC's _LoadSkills -> learnSkillRewardedSpells
silently re-grants them.
- OnPlayerLogin opens the client SILENCE window via SendSilenceOpenForCommit
with an empty allow list and intentionally omits the matching
SendSilenceClose: the chat frame buffers CHAT_MSG_SYSTEM during the
loading screen and only flushes after PLAYER_ENTERING_WORLD, so a paired
CLOSE would shut the filter before the buffered "you have unlearned X"
toasts hit it. The addon's 8s fail-open closes the window after the flush.
- New `.paragon hat` chat command for diagnosing Honor Among Thieves
triggers (talent rank, learned spell, applied aura, proc table entry).
mod-paragon Paragon_SC.cpp:
- OnPlayerUpdate pushes server-authoritative combo points to the client
via PARAA "R CP <n>" whenever the count changes. The client-side
ComboFrame Paragon simulator listens for this and updates the target
frame, fixing HAT-generated CP not displaying (HAT's trigger casts
with a null target, which the combat-log inference path can't see).
- OnPlayerUpdate also pushes "R RUNES <cd0..cd5>" (ms remaining per
rune slot) on rune mask changes, so the client RuneFrame simulator
stays in lock-step with Spell::TakeRunePower instead of drifting
through combat-log latency.
mod-paragon SQL:
- New updates/2026_05_09_00.sql migration creates
character_paragon_panel_spell_revoked for AC's auto-DBUpdater so a
fresh checkout can stand up an existing characters DB without
manual intervention. Matching CREATE TABLE IF NOT EXISTS in
base/character_paragon_panel_learned.sql for fresh installs.
mod-paragon conf:
- New Paragon.Diag.PanelLearn flag traces every PanelLearnSpellChain
commit (chain ids, before/after spell-map sizes, side-spell
classification) for diagnosing "spell reappears on relog" bugs.
Co-authored-by: Cursor <cursoragent@cursor.com>
AzerothCore's DBUpdater scans modules/<mod>/data/sql/db-{world,characters,auth}/
(see src/server/database/Updater/UpdateFetcher.cpp). The previous
modules/mod-paragon/sql/{world,characters}/base/ layout was non-standard
and skipped by the updater, so a fresh deploy never had Paragon tables
created automatically.
Move all five SQL files into the standard layout. Files are idempotent
(CREATE TABLE IF NOT EXISTS plus a DELETE+INSERT for the cost table)
and now apply on every dbimport / worldserver start, recorded by hash
in <db>.updates so re-runs are skipped.
Update BUILD-NATIVE.md to drop the manual mysql import section, and
document the SQL layout in the mod-paragon README.
Co-authored-by: Cursor <cursoragent@cursor.com>