Replaces the ability score card grid in both the character sheet and
creation wizard with a proper breakdown table matching MPMB's layout:
- Sheet: "Breakdown" button opens a modal with every source labeled as a
column (Ancestry, Race, ASI, Level boost, etc.), a Manual override ±
cell per ability, and Total/Mod columns. Clicking any ability card also
opens it. Legacy characters without abilityBuild show a single Base column.
- 5e wizard: method buttons (standard/point-buy/roll/manual) remain, but
the ability grid is replaced by a table — Base column adapts to method
(select for array/roll, number field for buy/manual), Race and ASI columns
appear only when relevant, point-buy remaining shown in footer.
- PF2e wizard: replaces dropdown grid with a click-to-assign boost table —
fixed ancestry boosts shown as +2 chips, free-boost slot columns let you
click any cell to assign/unassign that slot to that ability (with source
uniqueness enforced inline).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Audited every calculation (26-agent adversarial workflow + hand-verification).
Core math was sound; fixed real bugs, closed parity gaps, and overhauled the
character-build UX. 396 -> 424 tests; lint clean; build green.
Correctness fixes:
- Heavy armor no longer applies a negative DEX penalty to AC (3 paths + default)
- 5e Exhaustion 4 (HP-max halved) implemented via deriveEffectiveMaxHp + badge
- PF2e dazzled no longer makes a creature easier to hit
- PF2e immunity 'all' zeroes all damage (was misfiled as a condition immunity)
- Director schema bounds; PF2e spell-save basis from the `basic` flag; 5e
disadvantage-only save guard; remove bogus Concentrating, add Broken/Quickened
- Fix 3 lint errors (useCloud hooks naming, useless escape, explicit any)
PF2e survival subsystem (parity with 5e death saves):
- mechanics/dying.ts (maxDying/isDead/knockOut/applyRecovery/pf2eRestDecay)
- DefensesSection knock-out + recovery-check + death UI; rest-decay in applyRest;
drained HP reduction
Character-build UX:
- Persisted abilityBuild (base + per-source contributions); sheet & wizard show
every ability source; higher-level PF2e gains L5/10/15/20 boosts
- Creation surfaces granted skills (incl. new PF2e background skill parsing)
- LevelUpModal enumerates features gained + prompts every owed choice (subclass,
feats, fighting style, ...) via collectChoices/collectFeatures/subclassPrompt
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
No-shortcuts pass on the class feature/choice engine, and PF2e brought level with 5e.
5e subclass depth (subclass.5e.ts):
- SUBCLASS_PROGRESSION_5E: per-level features for ~22 subclasses (SRD cores + popular),
and subclass-specific CHOICES — Battle Master maneuvers (3/5/7/9 by level), Arcane Archer
shots, Rune Knight runes, Way of Four Elements disciplines, Hunter's selectable features
(Hunter's Prey/Defensive Tactics/Multiattack/Superior Defense), Totem Spirit, Dragon
Ancestor. collectFeatures5e now expands the chosen subclass into its real features.
PF2e feature/choice engine (data.pf2e.ts) — full parity:
- CLASS_PROGRESSION_PF2E: signature features by level for all 24 classes.
- Universal choices generated for every class: Class feats (per-class levels incl. the
1st-level martial feat), Skill feats (even levels), General feats (3/7/11/15/19),
Ancestry feats (1/5/9/13/17), plus the 1st-level subclass (Instinct/Doctrine/Bloodline/
Racket/…) from PF2E_SUBCLASSES with options.
Engine generalized: collectChoices(system)/collectFeatures(system) dispatch 5e vs pf2e;
ClassFeaturesSection now renders for BOTH systems (pf2e subclass resolves via choices[]).
Verified in-app: PF2e Barbarian 5 → Instinct (6 options) + Class(3)/Skill(2)/General(1)/
Ancestry(2) feats = '9 to choose' + Rage/Deny Advantage; selecting Dragon Instinct resolves
and shows as a feature. 5e Fighter+Battle Master → Maneuvers (choose 3) + Combat Superiority.
352 tests green (+ pf2e & subclass suites), build OK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A character's class choices were never prompted (the user's example: a Warlock must
choose a Pact Boon + Eldritch Invocations). Now:
- CLASS_PROGRESSION_5E authors all 12 classes' features by level AND every decision point:
Fighting Style, Pact Boon, Eldritch Invocations (count grows by level), Metamagic,
Expertise, Favored Enemy/Terrain, with full option lists.
- collectChoices5e / collectFeatures5e compute, across a (multiclass) character's classes,
exactly which choices are unlocked (and how many to pick at the current level) and which
features are gained. Subclass selection (classes editor) and ASI/feat (builder/level-up)
are handled elsewhere and excluded. Unit-tested incl. the Warlock pact example.
- New 'Class Features & Choices' sheet section lists features by level and presents a picker
per unlocked choice, with a 'N to choose' badge so nothing is missed. Resolved choices
persist (character.choices, v17 migration).
Verified in-app: Fighter 3 / Warlock 5 surfaces Fighting Style (1), Pact Boon (1), Eldritch
Invocations (3) + Pact Magic feature; selecting one drops the pending count. 346 tests green
(7 new), build OK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Building a character above level 1 now grants its Ability Score Improvements. The wizard
computes the ASI count for the input level + class (4/8/12/16/19, plus Fighter's 6/14 and
Rogue's 10) and shows an allocation panel (+1 each, capped at 20, can't over-spend, gated
on Next). Folds into the final scores alongside race bonuses; the ability card shows the
'base · +race · +ASI' breakdown.
Verified: a level-8 Fighter correctly offers 3 ASIs (levels 4, 6, 8 = 6 points). Build OK,
339 tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- FeatPickerModal: browse the 104-feat compendium (PHB/XGtE/TCE) and add a real feat with
its source + description, instead of typing a name. Wired into FeatsSection (5e).
- WeaponPickerModal: pick a 5e weapon and get a ready-to-roll attack with the correct
damage dice/type and a sensible ability default (ranged/finesse → DEX, else STR).
Wired into AttacksSection (5e).
Directly addresses 'feats are missing' and 'selectable weapons are missing'. Verified
in-app (Rapier→finesse attack; Great Weapon Master + XGtE/TCE feats listed). 339 tests
green, build OK. (Subclass/background mechanical effects + higher-level auto-build are the
remaining Phase 4 depth.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Character gains a classes[] array (per-class levels + subclass); className/level become
derived mirrors (primaryClass/totalLevel/normalizeClassMirror helpers). Dexie v16
migration backfills classes[] from className/level and pulls Subclass:/Background: out
of the notes free-text (whole-line, keeping the rest).
- Correct 5e multiclass derivation (unit-tested): dnd5eMulticlassHp (first character level
= max die, rest avg+CON), dnd5eMulticlassSpellLevel, dnd5eClassesSlots (one caster uses
its own table; two+ use the PHB multiclass table; warlock pact stays separate).
- Sheet ClassesEditor (5e): add/remove classes, set subclass/level; editing auto-recomputes
the level/class mirrors and reconciles spell-slot maxes (preserving spent slots) — so
spell slots are now calculated automatically. A 'Recalc HP' button (never clobbers
hand-rolled HP silently).
- LevelUpModal is class-aware: pick which class to advance or multiclass into a new one;
applies to classes[], re-derives mirrors + combined slots. pf2e path unchanged.
- Wizard writes classes[] on creation; subclass no longer stored in notes.
Verified in-app: existing char migrated to classes[]; Fighter 3 -> +Wizard 5 = total 8,
spell slots auto-appear at 4/3/2, reconcile preserves spent, removal restores. 339 tests
green (10 multiclass), build OK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 5e skill/save proficiency shows 'Not proficient/Proficient/Expertise' instead of the
PF2e rank names (Untrained/Trained/Expert); PF2e keeps its ranks. (shared rankLabel)
- Characters can be created without a campaign: campaignId is optional ('' = unassigned),
CharactersPage no longer requires an active campaign, the wizard's campaign prop is
optional, and the sheet has a Campaign selector to attach/move later.
- New character details: appearance, personality/behaviour, alignment, and a real
background field (promoted out of notes); a Details wizard step + a Details sheet card.
- Ability step shows a clearer total + 'base · +race' breakdown.
- Point-buy verified correct (8:0..15:9 / 27, clamped 8-15, Next gated on budget).
All schema additions default-safe (characterDefaults updated). 329 tests green, build OK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
classes.json ships the SRD subclass + third-party homebrew but is missing most official
PHB/XGE archetypes. New DND5E_SUBCLASSES supplement is merged (deduped by name) ahead of
the on-disk list in the builder, surviving any classes.json regeneration. First entry:
Rogue → Mastermind. (Subclass feature mechanics remain a separate task; this adds the
selectable options.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The inline Level field silently changed only proficiency-derived stats, leaving HP and
spell slots at the old level with no signal. Adds a hint pointing to the Level Up flow,
which applies HP/slots correctly. (Auto-recompute is intentionally avoided since HP/slots
are often hand-tuned.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PF2e characters were generated with the 5e method (standard array / 27-pt point-buy /
4d6) and never applied ancestry/background/class attribute boosts, so every derived stat
was wrong. The PF2e ability step is now boost-based:
- Every score starts at 10; ancestry fixed boosts + flaw, ancestry free boost(s),
background (choose-one + free), class key ability, and 4 free boosts are applied with
the +2-below-18 / +1 rule (pf2eApplyBoosts).
- Boost data parsed from the bundled ancestry/background fields (parseAncestryBoosts,
parseBackgroundBoosts, parseFlaw). Defaults are a legal, class-favoring assignment;
same-source duplicate boosts are disabled in the pickers (PF2e doesn't allow them).
- Live ability cards show the computed scores. 5e keeps array/point-buy/manual.
Verified in-app (Dwarf Alchemist Acolyte → STR 14/DEX 12/CON 14/INT 18/WIS 12/CHA 8,
flaw + fixed boosts correct). Pure core has 8 unit tests. 5e path unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- CreationWizard: add sys.skills to the loader effect's deps (stable singleton).
- Extract NotFound to src/app/NotFound.tsx so router.tsx no longer trips
react-refresh/only-export-components.
Branch is now warning-clean (the 3 remaining eslint errors are pre-existing on master,
in files this branch does not touch).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Both cast UIs (SpellcastingSection + MyCharacterPanel) called castSpell without a level,
so it always tried the spell's base level — a warlock (only a pact slot at the pact
level) could never cast, and upcasting was impossible. New availableSlotLevels() lists
the castable levels (regular slots ≥ spell level with a charge, plus the pact level); the
UI shows a level selector and passes the chosen level. Adds a regression test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The wizard collected race/background/skill choices but applied almost none of them.
Now (5e):
- Racial ASI is parsed and folded into the final ability scores (Human +1 each, etc.);
every downstream stat (HP, AC, attacks, saves, DCs) reflects it. Shown on the
Abilities step and Review.
- Background fixed skills and racial 'proficiency in the X skill' traits are granted
as trained, on top of class picks.
- Skill step prefers the curated class table: canonical 5e skill lists (fixes the
'and Survival'/'Animal Handling' tokenization that dropped skills) and the correct
pf2e free-choice skill count (was inflated for ~13 classes).
UX:
- 'Ready-made hero' templates no longer softlock the Abilities step: scores above the
point-buy cap switch to a new Manual entry mode (1-30) instead of '-Infinity / 27'.
- Standard-array/roll assignment swaps values on collision instead of disabling them.
Parsers extracted to builder/origin.ts with unit tests; buildCharacter gains
grantedSkills. Deferred: pf2e ancestry/background/class attribute boosts (needs the
boost-based generator), subclass/class-feature/feat mechanical effects.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Confirmed accuracy defects from the audit:
- AC now scales with level + armor proficiency (10 + Dex + (level+rank) + item),
defaulting to trained; was 10 + Dex only, wrong by +3..+28.
- Weapon potency (itemBonus) applies to the attack roll ONLY, not flat damage.
- weaponAttack now reports the Multiple Attack Penalty (-5/-10, agile -4/-8) and
expands striking runes into extra weapon dice; AttacksSection surfaces MAP.
- Full-caster spell slots: 2 at the rank's unlock level, 3 thereafter (was a flat 3,
giving a level-1 caster 3 first-rank slots instead of 2).
- PF2e Refocus restores one Focus Point (recoverStep), not the whole pool.
Adds 6 regression tests. types.ts gains WeaponInput.agile/striking, WeaponResult.map,
CharacterRulesInput.acRank, RestOption.recoverStep.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Layout:
- CombatantRow: action controls (damage/AC/move/remove) grouped into one
right-aligned wrapper so they wrap together instead of scattering on narrow
widths.
- top bar: the campaign switcher now shrinks/truncates instead of overflowing
on tablet widths.
- character sheet header: stat coins go full-width grid on mobile; the name
truncates and scales down on small screens.
UX consistency:
- player Cast and resource Spend/Regain no longer fail silently — Cast shows the
reason, resource −/+ disable at their bounds.
- the AI encounter builder now catches load failures and reports them; level-up
advisor shows the human error message, not the error-kind enum.
- section headers standardized on the .smallcaps design token across 16 files
(replacing an ad-hoc uppercase class).
- player HP bar uses the shared Meter primitive.
pf2e depth: condition-effects table gains drained, dazzled, enfeebled, fatigued.
FeatCard: dropped a dead text-xl wrapper left from the emoji purge.
Left as documented (functional, off-theme, refactor-risky): the native
confirm/prompt in Settings cloud-conflict and the session-password flow.
Gate: 293 unit + 35 e2e + 2 realtime; tsc + build clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Crash fix:
- restoreBackup (file + cloud pull) now validates each row through its Zod
schema, backfilling new fields — an older backup no longer lands characters
missing feats/concentration/etc and crashing the sheet. + test.
pf2e parity (closing feature gaps vs 5e):
- +9 missing classes (Animist, Exemplar, Gunslinger, Inventor, Kineticist,
Magus, Psychic, Summoner, Thaumaturge) with data + class tips.
- the wizard now enriches pf2e classes with their caster ability, so pf2e
spellcasters get the Spells step + "Caster" tag like 5e.
- editable Perception rank and spellcasting proficiency on the pf2e sheet
(fixes wrong initiative / spell DC at higher levels); rank-10 spell slots.
- pf2e monster resistances/weaknesses/immunities now apply in combat (flat
amounts: resistance subtracts, weakness adds, 'all' matches any type). + tests.
Glyph purge (finishing the emoji→Lucide migration): replaced ~40 leftover
text-glyphs (✕ − + ✦ 🤫 ⬆ ⬇ ☑ ☐ ▶ ◀ ‹ › ★ ↻ ▸ ↑ ●) with Lucide icons across
Modal (every dialog), the sheet sections, dice, settings, player panels, world
pages, map editor, roll tray, and session UI.
Gate: 293 unit + e2e green; tsc + build clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The pf2e creator showed long, truncated run-ons where 5e shows clean, brief
overviews: classes were cut mid-word at 400 chars, backgrounds rendered the raw
Foundry "<Name> Source Core Rulebook pg. N …" citation prefix, and ancestry
summaries ended in a stray ellipsis.
- new src/features/characters/builder/overview.ts: briefOverview() strips the
Foundry citation prefix, drops a trailing ellipsis, and keeps the first clean
sentence (or a word-boundary trim — never mid-word). A no-op on already-short
text, so 5e is unchanged. Applied to pf2e class/ancestry/background overviews.
- dedupeByName(): the pf2e data carries reprints under duplicate names (94
ancestries, 612 backgrounds) which duplicated options and triggered React
duplicate-key warnings — now de-duplicated at load.
- 6 unit tests for both helpers.
Verified live: pf2e class cards now read as clean single sentences; no citation
junk; no duplicate-key warnings. Gate: 289 unit + 35 e2e + 2 realtime, build clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
P5 backend (the deferred items):
- conflict-aware cloud sync via optimistic concurrency: the server versions each
backup blob (file mtime) and rejects a push whose base version is stale (409),
so a second device can't silently overwrite a newer cloud copy. The client
tracks its last-synced version; the SyncStatusIndicator surfaces a "Sync
conflict" with one-click resolution (Use cloud / Keep this device), and the
Settings push offers the same choice.
- revocable invites: owner can rotate a campaign's invite code (kills the old
one) and remove a member (drops them + deletes their published characters).
(Skipped editor/player roles — no enforcement target in the current model.)
- image storage: deliberately deferred (live images already stream de-duped on a
separate channel; a backup blob-store is infra with no correctness gain).
P7 — subclass/feat/multiclass depth:
- feats are now first-class tracked records (name + effect text) in a Feats &
Features sheet section, not buried in notes. Dexie v15 migration.
- 5e multiclass spell-slot calculator: a pure multiclassSlots() (full ×1, half
÷2, third ÷3 → full-caster table) + a sheet control to fill the slot table for
multiclass casters. (Honest scope: tracking + slots, not per-subclass feature
automation.)
P8 — test hardening: v2-surfaces e2e (feats, multiclass calc, signals bell,
World nav) + server tests (blob versioning, invite rotation, member removal) +
multiclass unit tests.
Gate green: 283 unit + 35 e2e + 2 realtime. App + server build clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Slice-0 vertical that proves the enforcement architecture end-to-end.
- kernel: castSpell (slot consumption + concentration set/replace, upcasting,
warlock pact slots), spendResource/regainResource, rollDeathSave — pure
functions returning Partial<Character> patches. 13 unit tests.
- applyRest now ends concentration on any rest (+ test).
- character sheet SpellcastingSection: per-spell Cast button, concentration
banner with Drop, concentration markers; ResourcesSection −/+ routed through
the kernel.
- player MyCharacterPanel: castable spell list + concentration banner, so a
seated player casts and it broadcasts via the existing playerPatch flow.
- live sync: partialCharacterDiffSchema carries concentration; GM applies it;
playerCharacterSchema mirrors slots/concentration/resources (PC-only) and the
player-facing AC now respects equippedArmor. Wire round-trip test added.
Verified live: casting decrements the right slot, switching concentration logs
"Concentration on X ends", banner + Drop render. Build + 258 tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lay the foundation for full rules enforcement: a new pure, testable
mechanics kernel (src/lib/mechanics/) that derives structured, enforceable
game data from the loosely-typed compendium, plus the first user-facing
payoff (accurate armor AC + spell mechanics on the sheet).
- normalizers: spell (5e + pf2e), armor, monster defenses → typed
SpellMechanics / ArmorMechanics / DamageDefenses, with memoized derivers
wrapping the existing lazy compendium loaders (no new assets). 11 unit tests.
- character schema: spell entries snapshot concentration/save/damage at
compendium-link time; new top-level `concentration` slot and structured
`equippedArmor` (additive, defaulted). Dexie v14 migration backfills.
- AC model: baseArmorClass now consults equippedArmor (heavy = flat, medium =
Dex-capped) and falls back to the old 10+Dex formula when unarmored. Threaded
through every AC call site; armor picker added to the sheet (5e).
- compendium "Add spell to character" snapshots real mechanics via the kernel.
Backward-compatible: un-enriched spells/characters behave exactly as before.
Build + 244 unit tests green; armor→AC verified live in preview.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Replace all emoji icons (~26 instances) with Lucide icons across the app
(DashboardPage, SessionSidebar, PlayerBoards, MyCharacterPanel,
PlayerViewPage, EncounterTracker, CampaignsPage, HandoutControl,
SessionControl, CharacterSheet, EncounterTipCard, ActionGuide)
- Expose real 5e race data in wizard (ASI/vision/traits instead of stub desc);
add vision field to loadRaces5e return type
- Surface subclass descriptions after picking a subclass in the wizard
- Add per-class tips, race synergy notes, and ability/skill guidance in wizard
- New ActionGuide component: collapsible "What can I do on my turn?" in player view
- New SessionPrepCard: AI + fallback session hook generator on assistant page
- New NpcGenCard: AI + fallback quick NPC generator with "Add to campaign" action
- Inline NPC detail generator (wand button) on each NPC card in NpcsPage
- Quest hook generator button in QuestsPage header
- Condition tooltips in player party view (useConditionGlossary)
- Pass campaign.system through session snapshot so player view is system-aware
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Autosave: while signed in, a debounced full backup pushes whenever durable data
changes (useCloudAutosave watches a fingerprint of the main tables; high-churn
tables excluded). No-op signed out.
- Campaign-agnostic characters: PCs are now global — the Characters roster shows
every player character regardless of active campaign, and any PC can be added to
a fight. NPCs stay per-campaign. (charactersRepo.listAllPcs / useAllPcs; difficulty
fallback stays campaign-scoped.)
- Live "bring your own character": a joining player can push one of their own local
characters; the GM's grant inserts it into the campaign and seats them.
- Character builder: a system picker (5e / PF2e, defaults to the campaign) so creation
no longer assumes 5e; PF2e skill wording ("Trained" vs "proficient"); spell step now
explains how many to pick + that they're known spells prepared later.
230 unit + 34 e2e + 2 realtime green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Player view: a Quest log now syncs to players (snapshot += quests; broadcaster
passes campaign quests; PlayerBoards renders titles + objective checkboxes).
- AI (DeepSeek etc.): robust JSON extraction — strip code fences anywhere + a
brace-balanced scanner that ignores prose/braces in strings. Fixes "AI unavailable
(parse)" with OpenAI-compatible providers. +4 tests.
- Encounter advisor: now bidirectional — for an over-tuned (too-hard) fight it
suggests REMOVING/swapping monsters instead of only ever adding. +3 tests.
- Character share: works on iPad — native share sheet → clipboard → a copyable
link modal fallback (was a silently-failing clipboard write).
230 unit + 34 e2e + 2 realtime green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Modal: focus into the dialog ONCE on open (not on every parent re-render), and
prefer the first field over the X button — fixes focus jumping to the close
button on each keystroke in the handout composer (and every other composer).
- Campaign edit: hide the System selector entirely (it's fixed after creation).
- Combat difficulty: rate against the PCs actually in the encounter (falls back to
the roster) so adding a player updates the reading.
- Character builder: ancestry/background description is now a scrollable panel
instead of clamped to 3 lines (no longer cut off on small screens).
223 unit + key e2e green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rebuilt CreationWizard to consume the structured ruleset data (Phase 7):
- Class step: rich class cards (description, hit die, key ability, caster, playstyle
tag) + subclass picker, plus "ready-made hero" quick-start templates that prefill
class + abilities for instant play.
- Origin step: searchable ancestry/race + background pickers with descriptions (auto
speed/ancestry-HP where known).
- Abilities: key-ability hints from the chosen class. Skills: choices from class data.
- Spells step (casters only): searchable starting-spell picker → spellcasting.spells.
- Review applies derived build + data-driven saves (esp. PF2e classes).
- Updated the e2e helper + wizard spec to the new flow (class-card data-testid).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- character.portrait + mapToken.image (data URLs, Dexie v10, additive).
- src/lib/img/resize.ts: center-crop + downscale helper (160px tokens / 256px
portraits) keeping IndexedDB + wire payloads small.
- Portrait uploader on the character sheet; token icon uploader in the map token
modal (falls back to the linked character's portrait). Palette PC entries show
the portrait thumbnail.
- Tokens render the image clipped to the circle (HP ring + condition badge on top).
- Realtime: generalized the image channel to many images (map bg + token/portrait
icons), deduped by content and resent on reconnect. Player tokens/party carry an
imageId resolved from the session image cache; party panel shows portraits.
- Also: fix the encounter-picker dropdown text being clipped (drop fixed height).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Players claim a seat (GM approves) and drive their own character live —
HP/slots/resources/conditions/dice broadcast to the table — via new seat
protocol messages and per-seat ownership enforced in RoomHub. GM persists
player edits (charactersRepo.update → liveQuery → rebroadcast). Offline dev:
"Share with player" encodes a claim link (src/lib/sync/playerLink.ts) → /player
imports the character locally for full-sheet editing, bundled back as an
offlineSnapshot on seat claim for GM review.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The bare name/class/level form left new characters as shells (1 HP, all-10
abilities, no proficiencies). Now creation and level-up are guided and auto-populate.
- Hand-authored progression tables (no SRD class/slot data exists on disk):
src/lib/rules/{dnd5e,pf2e}/progression.ts — core classes' hit die/HP, key
abilities, save & perception proficiencies, trained-skill counts, caster type;
5e full/half/pact spell-slot tables, pf2e slot approximation; ASI/boost/skill
schedules.
- src/lib/rules/progression.ts: getClassDefs/getClassDef, classSkillChoices/Count,
buildCharacter() (HP from hit die + CON over levels, trained saves/skills, spell
slots + ability), planLevelUp() (HP gain, new slots, ASI/boost/skill choices),
applyIncreases/bumpRank. Pure + 12 unit tests.
- Multi-step CreationWizard (Basics → Abilities → Skills → Review) replaces the
old form; pulls PF2e ancestry HP/speed from the bestiary; review previews HP/AC/
saves/skills/slots; lands on a ready-to-play sheet.
- LevelUpModal reworked into a guided wizard: auto HP + spell slots, presents the
level's actual choices (5e ASI/feat, pf2e ability boosts + skill increase) and
applies them; keeps the strategic build-route advisor.
e2e helper drives the wizard; updated 7 specs to the new flow; new character-wizard
spec asserts a complete level-3 Wizard (HP 17, slots 4xL1 2xL2).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Level-up build-route advisor (src/features/characters/sheet/LevelUpAdvisor.tsx +
useLevelUpAdvisor): ~4 system-aware routes plus a custom one; choosing a route
expands it into concrete next-level steps. AI when configured, deterministic
fallback (src/lib/assistant/levelup.ts) otherwise. Embedded in the existing
HP-only LevelUpModal, which stays primary.
- Level-up prompts/schemas added to prompts.ts (buildRoutes/buildSteps), each
leading with the system constraint + class + next level.
- Campaign Insights section on the Assistant page renders deterministic themes,
with an optional 'ask the assistant to expand' affordance when AI is on.
levelup + prompt unit tests (4 routes both systems, system vocabulary, custom
route); e2e for the deterministic route→steps flow and the insights section.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Ability generation: standard array, point buy (27-pt, validated), 4d6kh3 roll;
AbilityGenModal with assign-from-pool + steppers (pure abilityGen lib + tests)
- Level-up flow: increment level, HP gain (average or roll hit die + CON)
- Print / save-to-PDF: print button + @media print hides app chrome and roll tray
- Plan: added Phase 11 (data-driven Assistant) to the roadmap
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Dice notation: exploding (Nd6!) and reroll-below (Nd6r2), capped + tested
- Degrees of success / roll-vs-DC (PF2e ±10 + nat 20/1 steps; 5e crit on nat 20/1)
- Global roll tray (shared store + RollTray in layout) with animated result + degree
- Roll from the character sheet: skills, saves, and attack to-hit/damage are
clickable and post to the tray + history (rollAndShow/rollCheck helpers)
- Saved roll macros per campaign (persisted) on the Dice page
10 new unit tests (notation explode/reroll, degrees), interactive-dice e2e.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Inventory + currency + encumbrance vs carrying capacity
- Class resources with correct short/long/daily rest recovery (applyRest)
- Spellcasting: slots (+pact), known/prepared spells, derived DC + attack
- Defenses: 5e death saves/inspiration/exhaustion, pf2e dying/wounded/hero points
- Derived weapon attacks + passive perception via extended RulesSystem
- Dexie v2 migration backfills new fields; debounced save flushes on pagehide
- 9 new unit tests, new character-depth e2e; all green
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>