Files
healer-man/docs/CHARACTER_STAT_RULESETS_2026-10-03.md
T

7.4 KiB

Character stat rulesets

Character origin and character stat rules are independent. RoM characters can select Native RoM or WoW compatibility from the main menu. WoW characters retain WoW rules.

Saved profiles

  • Existing saved profiles without a valid statRuleset normalize to "wow". This preserves the pre-existing RoM compatibility calculations, including their hybrid base-stat behavior.
  • Newly created RoM profiles explicitly select "rom"; newly created WoW profiles select "wow".
  • The selector updates only the selected character. Inventory, equipment, progression, class pairing, learned skills, bindings, loadouts, and dungeon checkpoints remain attached to that profile.
  • Switching is restricted to the main menu and blocked while a character remains active, a live enemy is engaged, or an online group activity is live. The combat check uses the installed dungeon runtime bridge so the main menu does not eagerly import combat catalogs. A failed storage write reports failure and retains the saved choice. A failed migration write still leaves the existing roster readable and retries on a subsequent read.
  • Cloud saves retain the profile field because the client and server persist complete profile objects.

src/game/characterStatRuleset.ts owns normalization. src/app/accountRepository.ts owns profile migration and persistence; src/app/shellStore.ts owns the switch action; src/ui/MainMenuScreen.tsx owns the selector and controller actions.

Native calculation and shared combat

Native inputs must retain their source meaning. Wisdom is RoM MND. Physical and magical attack, defense, damage, and combat points are distinct source channels. Native hit/critical/dodge points must never enter WoW rating-to-percent conversions.

Native derived calculations are sourced from the local RuneWaker RoleAttr.cpp and player vocation/race/sex/fixed-argument database records. Secondary-class activation at level 10 and treating the secondary level as the main level remain simulator policies.

src/game/romNativeStats.ts owns derivation and source-unit modifier re-derivation. romNativeStatsTypes.ts keeps native points and multiplicative rates separate. scripts/runewaker-pipeline/export-rom-native-stat-rules.mjs owns src/game/generated/romNativeStatRules.generated.json and the compact romNativeGearCurves.generated.json; runtime code does not import the full reference item catalog. The existing romStats.ts/base-growth path remains available for legacy compatibility.

Equipped native items carry ItemStats.romNative. Their common WoW projection is not counted again. Foreign items without that payload bridge only direct Strength, Stamina, Intellect, Agility, and flat health/mana under an explicit simulator policy. Spirit does not become Wisdom; WoW armor, attack/spell power, weapons, and ratings do not become native channels. The five existing source-reference heirloom classes supply native gear curves; other classes retain the direct-stat fallback until native gear profiles are sourced. Reference item selection and intermediate-level interpolation remain synthetic simulator policies.

The existing dungeon combat resolver remains a shared simulator. Adapting a verified native stat into a common combat field does not establish that the WoW damage, hit, armor, or critical formulas reproduce RoM combat. Native healing inputs alone also do not certify every RoM healing spell's amount, rank, or coefficient.

The explicit common adapter uses native ATK as attack/ranged attack power, MDMG as spell power, and DEF as armor. Physical mitigation uses the existing shared WoW armor curve. MATK, MDEF, DMG, native recovery values, and hit/critical/dodge/parry points remain source-semantic sidecar/display fields; native point values are not converted into common percentages. Native common hit/critical/avoidance percentages start at zero. Existing primary resource types and regeneration policy remain part of the shared dungeon simulation; native MP derivation also supplies supported secondary mana pools. The Equipment panel identifies the shared combat boundary, labels point fields explicitly, and shows active native aura effects for its selected owner. Shared HUD counters display whole HP/MP values while their accessible maxima and runtime pools retain source precision.

Player FIX record 303001 sets DmgAtkArg and MDmgMAtkArg to zero, so this source version derives DMG/MDMG from flat gear channels rather than ATK/MATK. Its Dmg_HealArg is 0.5. Wisdom/MND, MDMG, MPow, HealPowerRate, HealPoint, and target heal-modifier inputs now have explicit source channels. Per-spell OrgPower, rank/skill-level evaluation, timing, flags, and the complete native healing consumer remain separate work. These local RuneWaker records do not certify current-CoA formulas or balance.

The character, party member, and combat actor retain their own ruleset. No global party or dungeon setting chooses every participant's stat system. This provides a foundation for future mixed parties; matchmaking and cross-game balance certification are outside this change.

Compatibility evidence

src/game/generated/characterStatRulesetCompatibility.json freezes 18 pre-change stat outputs across WoW characters and legacy RoM builds, including gear, modifiers, race, level, and secondary-class cases. src/game/characterStatRulesetCompatibility.test.ts checks both omitted rulesets and explicit WoW compatibility against those outputs. This fixture is a simulator regression baseline, not native RoM source data.

Validation

  • 219 focused tests passed across 22 files, with four existing IndexedDB skips: the final 21-file selection passed 211 tests, and the independent native runtime suite passed eight. The source/gear worker's 30-test selection overlaps these totals.
  • The runtime suite covers per-owner mode, primary and secondary Mana mirrors, level-10 secondary activation, Wisdom/Holy Blessing and GM-buff cap removal, periodic/channel source amounts, native party autoattacks, and exclusion of foreign WoW attack/critical/hit/haste ratings.
  • Ready-five passed seven Vitest and twenty Python checks. Avatar validation passed 47 tests across ten files.
  • The final full 8 GB TypeScript/Vite production build passed, including prebuild asset audits, compression, and release-bundle verification. A subsequent TypeScript project check also passed after the final test edits.
  • Exact-final-dist Edge QA passed through scripts/playtest-stat-rulesets.cjs, using an isolated temporary offline account. New-profile defaults, synthetic legacy migration, independent saved choices, build/checkpoint preservation, both dungeon modes, switching locks, native panel tabs, and desktop/390-pixel layouts passed. Roster and both dungeon screenshots show character bodies and held starter staffs. There were no page errors or application-resource response errors; the optional favicon returned 404.
  • Browser evidence: playtest-artifacts/stat-rulesets/results.json and its ten referenced screenshots. The checked chunks were index-CGkT8hBz.js, combatStore-CVXgxk1Z.js, and PartyFrames-BeW5_TCA.js. Synthetic engaged-mob and online-activity fixtures verify the menu guards, not a real multiplayer session.
  • Final npm run release:check passed for 157 changed paths, including untracked files and concurrent unrelated work. Final documentation and owned vault notes satisfy text-file hygiene.
  • No full repository suite, all-class balance sweep, RoM readiness promotion, matchmaking, or deployment was performed.