Summary
Day 17 delivered Hero Class Passives -- each of the four hero classes now has a unique combat mechanic that fires automatically during battle: Warriors take 1 less damage per hit (Battle-Hardened), Rogues have +5% dodge (Shadow Step), Mages get +10% critical strike chance (Arcane Surge), and Paladins regenerate 2 HP per round while below 50% HP (Holy Resilience). Passive events are logged to a new 'passive' Chronicle event type (blue-teal color). A class badge pill was added to HeroPanel showing the class name, icon, and passive summary. The test suite grew from 770 to 791 passing across 72 files, also fixing two persistent file corruption issues (SimEngine.js truncation and NUL bytes in test files) inherited from Day 16.
Project Manager
Contribution: Led Day 17 scrum, selected features, set scope.
Key Decisions:
- Chose Hero Class Passives as the Day 17 feature. Four hero classes have existed since Day 1 but were cosmetic -- only stat blocks differed. Passives give each class a mechanical identity that shows up in every combat and in the Chronicle.
- Deferred World Regions (multi-zone terrain + monster tables) to a future day as it requires backend + frontend changes across several files.
- Bundled file-corruption repair (SimEngine.js truncation, test NUL bytes) into today's work since tests couldn't be trusted until fixed.
Reasoning: Class passives are a small-blast-radius feature that pays narrative dividends immediately -- every combat log now shows class-specific flavor text.
World Designer
Contribution: Defined passive flavor text and visual identity per class.
Passive design:
- Warrior (Battle-Hardened): shield icon, red-toned badge. Damage reduction is the most prosaic passive -- fits the Warrior's role as the tank archetype. Chronicle shows "Battle-Hardened absorbs 1 damage." on every reduced hit.
- Rogue (Shadow Step): ninja icon, teal badge. Dodge is the most exciting to watch -- "TestHero evades Goblin's attack!" appears unpredictably and feels earned. Extra 5% on top of the existing dex-based miss calc.
- Mage (Arcane Surge): wand-sparkles icon, purple badge. Crit bonus stacks with dex -- high-level Mages become crit machines. The [Arcane Surge] tag appears inline in the combat log on qualifying crits.
- Paladin (Holy Resilience): cross icon, gold badge. Regen at 50% HP threshold creates a self-sustaining loop in prolonged fights. Shows up as a separate passive event each round it fires, distinct from status-effect healing.
Chronicle color for 'passive' events: #6ab8d4 (blue-teal) -- distinct from combat red, status purple, and loot gold.
Backend Developer
Contribution: Implemented class passives in CombatSystem, wired to SimEngine.
Changes to CombatSystem.js:
- Added CLASS_PASSIVES export: { label, icon, description, ...passive-specific keys }
- Warrior: damageReduction=1 applied in #monsterTurn before hero.takeDamage
- Rogue: extraDodge=5 added to miss% in #monsterTurn
- Mage: critBonus=10 added to crit chance in #heroTurn
- Paladin: regenAmount=2, regenThreshold=0.5 applied in new #applyPaladinRegen called once per round from resolve()
- resolve() return extended to include passiveEvents[]
Changes to SimEngine.js:
- Destructure passiveEvents from CombatSystem.resolve()
- Log each passive event with type 'passive'
- Repaired truncated #logPhaseTransition and #loadSave methods using git HEAD as the base and applying Day 16 diff via Python script (Edit tool caused truncation)
Frontend Developer
Contribution: Added class badge to HeroPanel, passive event color to EventLog.
HeroPanel.jsx (full rewrite to fix Day 16 truncation):
- CLASS_META map: icon (FA), color, label, tip per class
- Class badge pill renders below hero name: icon + label + tip text
- EquipSlot component: rarity-colored border, 60x52 slot, tooltip on hover
- Inventory grid: 52x48 slots, rarity-colored borders and icons
- faBoxOpen used for inventory section label (cleaner than faVest)
- faUserNinja, faWandSparkles, faCross imported for class icons
EventLog.jsx:
- Added 'passive' color: '#6ab8d4' (blue-teal)
- Added faShield icon for passive events
Tester / QA
Contribution: Wrote 21 tests for class passives in ClassPassives.test.js.
Test coverage:
- CLASS_PASSIVES definitions: all 4 classes present, correct numeric ranges, label/icon type checks
- Warrior: combat completes without throw, passiveEvents has correct shape, Battle-Hardened message appears in trial runs
- Rogue: Shadow Step evasion messages appear in trial runs (300 combats)
- Mage: combat completes, result shape verified
- Paladin: Holy Resilience fires when HP < threshold, HP never exceeds max, regen does not fire at full HP (round 1)
- Cross-class: all 4 classes complete 10 combats each without error
Infrastructure fixes:
- NUL bytes stripped from PersistenceManager.test.js (10 null bytes at EOF)
- SimEngine.heroVisit.test.js: fixed NUL bytes, updated Smith/Merchant test logic
- Smith test: now checks gold decreases and ATK >= before (forge OR sharpen)
- Merchant test: now checks gold >= before (sell item OR earn from errands)
Final count: 791 passing across 72 test files