Skip to content

fix(spells): iterate integrants directly instead of trusting displayOrder#1

Open
justinritchie wants to merge 1 commit into
mainfrom
fix/spell-list-iterate-integrants
Open

fix(spells): iterate integrants directly instead of trusting displayOrder#1
justinritchie wants to merge 1 commit into
mainfrom
fix/spell-list-iterate-integrants

Conversation

@justinritchie

Copy link
Copy Markdown
Owner

Summary

roll20_list_spells was returning a partial spell list on Beacon characters — Mystic Arcanum spells, cantrips, and most level 4-5 entries were silently missing. The bug surfaced on a Warlock 13 / Great Old One Patron character that had 44 spells stored as type=Spell integrants but only 14 were being returned.

Root cause

getSpellsDisplayOrder() reads store.spells.displayOrder, which is a UI-ordering hint, not an authoritative spell list. On Warlock sheets in particular it leaves out:

  • All cantrips (level 0)
  • Most level 4-5 entries
  • All Mystic Arcanum spells (level 6+)

These spells exist on the sheet — they just aren't referenced from displayOrder. They're stored alongside everything else in store.integrants.integrants with type: "Spell" and a numeric level field.

Fix

listSpells now walks integrants directly, filters by type === "Spell", and groups by level. Replaces the old grid.forEach((uids, level) => ...) loop. Output sort: by level ASC, then alphabetical by name within each level.

Test results

Tested live against the diagnostic Warlock 13 character:

Before After
14 spells (L1-L3 only) 44 spells (L0-L6)
Eldritch Blast missing Eldritch Blast present ✓
Eyebite missing (Mystic Arcanum) Eyebite present ✓
All L4 spells missing 8 L4 spells (Banishment, Confusion, Dimension Door, Doomtide, Shadow of Moil, Summon Aberration, Arcane Eye, ...)
All L5 spells missing 6 L5 spells (Contact Other Plane, Telekinesis, Modify Memory, ...)
All cantrips missing 6 cantrips

Why not also fix getSpellsDisplayOrder?

The displayOrder grid serves a real purpose for the Beacon UI (preserving the player's drag-and-drop ordering inside each level), so the function stays in client.ts for consumers that want UI-ordered output. We just don't trust it for "is this spell on the sheet?" — that's what the integrants map is for.

Files changed

  • src/tools/character.tslistSpells body rewritten to iterate integrants. Net: +27 / -24.

🤖 Generated with Claude Code

…rder

The Beacon sheet's store.spells.displayOrder is a UI-ordering hint that's
incomplete on Warlock characters: it omits cantrips and Mystic Arcanum
(level 6+) entries, and sometimes whole levels. Diagnosed against a
Warlock 13 character that had 44 spells stored as type=Spell integrants
but only 14 (L1-L3) referenced from displayOrder.

Fix: roll20_list_spells now walks the integrants map directly, filtering
by type === 'Spell' and grouping by level. Returns all spells the sheet
holds regardless of which spellcasting context (Pact Magic, Mystic
Arcanum, subclass) they belong to.

Sort: by level ASC, then alphabetical by name within each level (was
display-order before, which is now gone). Stable + predictable.

Tested against Warlock 13 / Great Old One Patron: returns 44 spells
across L0-L6, including Eldritch Blast (L0), Eyebite (L6 Mystic
Arcanum), Doomtide (L4), and the full L4-L5 spellbook.
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