Skip to content

Report level gains as events and add LearnSpell for spell-book growth - #37

Merged
mmacy merged 1 commit into
mainfrom
level-up-advancement
Jul 30, 2026
Merged

Report level gains as events and add LearnSpell for spell-book growth#37
mmacy merged 1 commit into
mainfrom
level-up-advancement

Conversation

@mmacy

@mmacy mmacy commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Levels have always happened silently: every XP award surface discarded XpAwardResult.level_up, so the only level signal on the wire was level_after buried in the XP line — no hit points, no title, no moment. And a leveled arcane caster had no in-session path to the new spell their widened book allows: add_spell_to_book existed but no command wrapped it, so any front end calling it directly would bypass the command log and break replay.

  • CharacterLeveledUpEvent (session.level.gained, player visibility): fires immediately after the member's own XpAwardedEvent whenever an award crosses a threshold, on all three award surfaces (end-of-adventure, immediate timing, referee AwardXP) — routed through one _xp_award_events helper so the ordering is structural. Carries level_before/level_after, hp_gained, hp_roll (None past name level), con_applied, and the class's level title (None past the printed list).
  • LearnSpell command (town + exploring, no time cost): drives add_spell_to_book through the command loop so book growth is validated, logged, and replayed like everything else. Emits the existing SpellBookUpdatedEvent; no new rejection codes.
  • open_book_capacity (per-spell-level open book slots, zero-floored for over-capacity drained books, () for non-arcane) — add_spell_to_book's capacity check now consults it, giving front ends the same rule for rendering learnable picks. Plus level_title for the IndexError-guarded title lookup.

Golden: phase5_milestone.json regenerated — the diff is exactly one inserted leveled_up event (the thief's level 2, Footpad, +4 hp), its transcript line, and the engine_version stamp catching up to 1.4.0. No dice value, stream state, checkpoint, or command-log byte moved; all other goldens byte-identical.

Verification: 1644 passed / 58 skipped; ruff format --check clean and ruff check at exact parity with main; mkdocs build (strict) green, which proves the message-template and command-docstring gates accept the additions.

https://claude.ai/code/session_01TW7yQtphaXFdex8ZutgDLd

An XP award that crossed a level threshold was invisible as a moment: the
gain surfaced only as level_after on the XP award event, so a front end had
no event to announce the level on and no hit-point or title facts to
announce it with. Every apply_xp call site in the session (the
end-of-adventure award, the immediate timing, and the referee's AwardXP)
now reports through one module helper, _xp_award_events, which emits the
member's XpAwardedEvent and, when the award leveled them, a
CharacterLeveledUpEvent (session.level.gained, player visibility)
immediately after it — levels before and after, hp gained, the raw hit die
roll (None past name level), whether CON applied, and the class's level
title at the new level via the new level_title helper.

Leveling also opens spell-book capacity with no in-session way to use it,
so LearnSpell drives the core add_spell_to_book through the command loop:
town and exploring, zero game time, the existing SpellBookUpdatedEvent, no
new rejection codes. The capacity rule itself moves into one home,
open_book_capacity (row capacity minus spells held, floored at zero, () for
non-arcane classes), which add_spell_to_book now consults with behavior
unchanged.

The phase5_milestone golden regenerates because the milestone's return
award now reports the thief's level gain: the diff is exactly one inserted
leveled_up event and its transcript line (plus the engine_version stamp of
the producing engine moving 1.3.0 -> 1.4.0); no dice roll or other value
changed anywhere — the level-up hp draw already existed. The hoard and NPC
goldens regenerated byte-identical.

Claude-Session: https://claude.ai/code/session_01TW7yQtphaXFdex8ZutgDLd
@mmacy
mmacy merged commit 41953a8 into main Jul 30, 2026
5 checks passed
@mmacy
mmacy deleted the level-up-advancement branch July 30, 2026 14:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant