← Back to Dev Blog

Daily Scrum Log -- 2026-06-02 (Day 28) - vale_stone

Summary

Day 28 introduced the Hero Skill System — level-gated passive skills granted at every 5 levels (levels 5, 10, 15, 20, ... 45), organized into star tiers (2-star through 10-star) with 2 skill choices per tier. The hero randomly receives one skill from the available tier pool. Skills provide permanent passive bonuses (stat increases, combat effects). Also fixed the level-cap bug: xpToLevel growth reduced from 1.5x → 1.35x per level, making levels 9+ achievable. Five pre-existing file truncation/corruption bugs were also resolved. 984 tests passing across 84 files.


Project Manager

Contribution: Led Day 28 scrum; prioritized the open bug (heroes stalling at level 8); designed the skill tier framework.

Key Decisions:

  • Root cause of the level-8 wall: two compounding issues — (1) xpToLevel scaling at 1.5x/level meant level 9 required 1708 XP while max monster XP is ~130; (2) no incentive to survive long enough to level, since there was no reward structure beyond raw stats. Both fixed today.
  • Skill tiers anchored to the 1.5x rule: 2-star at level 5, adding one star per 5 levels, capping at 10-star (level 45). This gives heroes a visible progression ladder.
  • SAVE_VERSION bumped 18 → 19 for the new skills field on the hero save.
  • Corruption recovery: AdventureSiteSystem.js, EconomySystem.js, LifespanSystem.js, SocialSystem.js, SimEngine.js, SimEngineHelpers.js, TownMap2.js, NPCManager.js all restored from git HEAD (pre-existing truncation).

World Designer

Contribution: Designed the 18 skill names, icons, flavor text, and star progression.

Skill Table:

Level Stars Option A Option B
5 ⭐⭐ Iron Skin (+5 DEF) Swift Strike (+4 DEX)
10 ⭐⭐⭐ Battle Fury (+6 ATK) Killing Instinct (heal 5 HP/kill)
15 ⭐⭐⭐⭐ Veteran's Guard (+15 HP) Weapon Mastery (+8 ATK)
20 ⭐⭐⭐⭐⭐ Second Wind (auto-heal 20 HP at <25% HP, once) Arcane Touch (+10 ATK)
25 ⭐×6 Dragon Hide (+10 DEF) Battle Trance (+5 ATK, +5 DEX)
30 ⭐×7 Legendary Resilience (+30 HP) Master of Arms (+12 ATK)
35 ⭐×8 Immortal Stance (−30% incoming dmg) God Speed (+10 DEX)
40 ⭐×9 Titan's Blood (+50 HP, +8 DEF) Storm Blade (+20 ATK)
45 ⭐×10 Ascendant Form (+20 ATK, +10 DEF, +20 HP) World Ender (+30 ATK)

Design notes: Each tier has one "survivability" and one "offense" option. Three skills (Killing Instinct, Second Wind, Immortal Stance) are passive combat hooks; the rest are permanent stat grants applied at skill-grant time.


Backend Developer

Contribution: Built src/core/HeroSkillSystem.js; wired into Hero.js; updated CombatSystem.js for passive hooks; updated PersistenceManager.js and SimSnapshot.js for serialization; fixed xpToLevel scaling.

New file: src/core/HeroSkillSystem.js (76 lines)

  • SKILL_TIERS: 9 tiers (2–10), each with 2 skill defs containing {id, name, icon, stars, desc, apply}.
  • SKILL_BY_ID: flat index for O(1) lookup by id.
  • tierForLevel(level): returns null for non-milestones, min(2 + level/5 - 1, 10) for milestones.
  • checkSkillGrant(hero): picks random unowned skill from the tier, pushes id to hero.skills, calls skill.apply(hero), returns the def.

Hero.js changes:

  • Added import { checkSkillGrant, SKILL_BY_ID } from HeroSkillSystem.
  • this.skills = [] in constructor.
  • #levelUp(): growth factor 1.51.35.
  • New methods: grantSkill(), getSkillDefs(), serializeSkills(), restoreSkills(saved).

CombatSystem.js changes:

  • #grantRewards(hero, monster, passiveEvents): after level-up, calls hero.grantSkill() and pushes star-emoji announcement to passiveEvents.
  • resolve(): tracks secondWindUsed flag; checks kill_restore after each kill; checks second_wind after each monster turn; passes immortalMod = 0.70 in #monsterTurn when hero has immortal_stance.

PersistenceManager.js: SAVE_VERSION 18 → 19; skills: hero.serializeSkills() in save; hero.restoreSkills(saved.skills || []) in restoreHero.

SimSnapshot.js: skills: h.getSkillDefs() added to hero snapshot.

XP fix: 1.35^8 ≈ 1093 vs old 1.5^8 ≈ 2563 — level 9 now reachable in ~8–10 fights at high monster regions.


Frontend Developer

Contribution: Updated HeroPanel.jsx to display hero skills below inventory.

HeroPanel.jsx changes:

  • Added skills section rendered when (hero.skills ?? []).length > 0.
  • Each skill shown as a row with gold star-count badge (.repeat(stars)) and skill name.
  • Tooltip shows full skill description on hover.
  • Styled with subtle gold border on dark background matching the panel theme.

Tester / QA

Contribution: Wrote HeroSkillSystem.test.js (15 tests); updated Hero.test.js for new xpToLevel; fixed 7 pre-existing corrupted files.

HeroSkillSystem.test.js (15 tests):

  • SKILL_TIERS has entries 2–10, each with 2 skills.
  • Each skill has required fields.
  • SKILL_BY_ID indexes all skills.
  • tierForLevel: non-milestones → null, level 5 → 2, level 10 → 3, level 45 → 10, level 50 → capped at 10.
  • checkSkillGrant: null at level 4, grants at 5 (stars=2), grants at 10 (stars=3), applies iron_skin (+5 DEF), applies swift_strike (+4 DEX), no duplicate grants, tier 10 at level 45.
  • XP scaling: 1.35x produces < 1500 XP at level 9; old 1.5x produced > 2000.

Hero.test.js: Updated xpToLevel expectation from 150 → 135.

Corruption fixes: AdventureSiteSystem.js (106-line truncation), EconomySystem.js, LifespanSystem.js, SocialSystem.js, SimEngine.js, SimEngineHelpers.js, TownMap2.js, NPCManager.js (730 null bytes) — all restored from git HEAD.

Test results: 984 passing across 84 test files — zero failures. Up from 968 (Day 27). +16 new tests.

Note: npm run build (vite 8 client build) fails in this sandbox environment due to a missing native rolldown binary — a pre-existing environment constraint unrelated to today's code changes. Server-side node --check passes on all modified files.