/** * Hand-curated spell-slot / cantrip / repertoire progression overlay. * * WHY HAND-CURATED: Foundry pf2e encodes slot tables in description prose, not machine- * readable rules (Pitfall #6 / verified 2026-04-27 against `wizard-spellcasting.json`). * NLP-parsing prose is fragile; the canonical PF2e tables fit in ~300 lines and are stable * across reprints. * * SOURCE: Archives of Nethys — Pathfinder 2e Player Core + Advanced Player's Guide * (https://2e.aonprd.com). Per-class spell-slot tables, cantrip counts, and repertoire * sizes (spontaneous casters only). * * SCOPE: 16 D-16 classes (Core + APG). Plan 03 shipped the type definitions and Wizard * fully populated as the worked example. Plan 03b appends entries for the remaining * 6 caster classes (Cleric, Druid, Witch, Bard, Sorcerer, Oracle) and the empty-array * entries for non-casters (confirmed empty per design). * * SPONTANEOUS vs PREPARED: Spontaneous casters (Bard, Sorcerer, Oracle) get * repertoireIncrement entries on level-up. Prepared casters (Cleric, Druid, Witch, Wizard) * get spellSlotIncrement only. Both get cantripIncrement at L1. * * SLOT-PROGRESSION CADENCE (all D-16 full casters share this base shape): * L1 : +2 grade-1 slots (3 for spontaneous Sorcerer/Oracle), +5 cantrips * L2 : +1 grade-1 slot * L3 : +2 grade-2 slots * L4 : +1 grade-2 slot * ... continues +2 / +1 per spell-grade through L18 (+1 grade-9) * L19: +1 grade-10 slot (Magnum Opus / capstone equivalent) * L20: no further slot increment (capstone is qualitative) * * REPERTOIRE CADENCE (spontaneous casters, Plan 03b model): * L2..L19 each grant +1 spell known (`repertoireIncrement: 1`). The recompute pipeline * in Plan 04 distributes that capacity across known spell grades; this overlay simply * tracks "new spell known this level" so the wizard can prompt the player. */ export type SpellTradition = 'ARCANE' | 'DIVINE' | 'OCCULT' | 'PRIMAL'; export interface SpellSlotOverlayEntry { level: number; spellSlotIncrement?: { tradition: SpellTradition; spellLevel: number; count: number }; cantripIncrement?: number; repertoireIncrement?: number; } /** * Each class maps to an array of overlay entries. Multiple entries per level are allowed * (e.g. L1 Wizard gets 5 cantrips AND 2 grade-1 slots — two separate entries). * Order within a level does not matter — the seed script merges them per (class, level). */ export const SPELL_SLOT_OVERLAY: Record = { // === PREPARED CASTER — WIZARD (worked example, fully populated in Plan 03) === // SOURCE: https://2e.aonprd.com/Classes.aspx?ID=12 (Wizard) — Player Core p.205 spell-slot table. Wizard: [ { level: 1, cantripIncrement: 5 }, { level: 1, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 1, count: 2 } }, { level: 2, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 1, count: 1 } }, { level: 3, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 2, count: 2 } }, { level: 4, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 2, count: 1 } }, { level: 5, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 3, count: 2 } }, { level: 6, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 3, count: 1 } }, { level: 7, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 4, count: 2 } }, { level: 8, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 4, count: 1 } }, { level: 9, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 5, count: 2 } }, { level: 10, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 5, count: 1 } }, { level: 11, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 6, count: 2 } }, { level: 12, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 6, count: 1 } }, { level: 13, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 7, count: 2 } }, { level: 14, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 7, count: 1 } }, { level: 15, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 8, count: 2 } }, { level: 16, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 8, count: 1 } }, { level: 17, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 9, count: 2 } }, { level: 18, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 9, count: 1 } }, // L19 Magnum Opus = 1 grade-10 slot per day { level: 19, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 10, count: 1 } }, // L20: no slot increment (capstone is qualitative) ], // === PREPARED CASTER — CLERIC === // SOURCE: https://2e.aonprd.com/Classes.aspx?ID=4 (Cleric) — Player Core p.119 spell-slot table. // Tradition: DIVINE. Cadence: identical to Wizard, replacing tradition. Cleric: [ { level: 1, cantripIncrement: 5 }, { level: 1, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 1, count: 2 } }, { level: 2, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 1, count: 1 } }, { level: 3, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 2, count: 2 } }, { level: 4, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 2, count: 1 } }, { level: 5, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 3, count: 2 } }, { level: 6, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 3, count: 1 } }, { level: 7, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 4, count: 2 } }, { level: 8, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 4, count: 1 } }, { level: 9, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 5, count: 2 } }, { level: 10, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 5, count: 1 } }, { level: 11, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 6, count: 2 } }, { level: 12, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 6, count: 1 } }, { level: 13, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 7, count: 2 } }, { level: 14, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 7, count: 1 } }, { level: 15, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 8, count: 2 } }, { level: 16, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 8, count: 1 } }, { level: 17, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 9, count: 2 } }, { level: 18, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 9, count: 1 } }, // L19 Miraculous Spell = 1 grade-10 slot per day { level: 19, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 10, count: 1 } }, ], // === PREPARED CASTER — DRUID === // SOURCE: https://2e.aonprd.com/Classes.aspx?ID=6 (Druid) — Player Core p.131 spell-slot table. // Tradition: PRIMAL. Cadence: identical to Wizard. Druid: [ { level: 1, cantripIncrement: 5 }, { level: 1, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 1, count: 2 } }, { level: 2, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 1, count: 1 } }, { level: 3, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 2, count: 2 } }, { level: 4, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 2, count: 1 } }, { level: 5, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 3, count: 2 } }, { level: 6, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 3, count: 1 } }, { level: 7, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 4, count: 2 } }, { level: 8, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 4, count: 1 } }, { level: 9, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 5, count: 2 } }, { level: 10, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 5, count: 1 } }, { level: 11, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 6, count: 2 } }, { level: 12, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 6, count: 1 } }, { level: 13, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 7, count: 2 } }, { level: 14, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 7, count: 1 } }, { level: 15, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 8, count: 2 } }, { level: 16, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 8, count: 1 } }, { level: 17, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 9, count: 2 } }, { level: 18, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 9, count: 1 } }, // L19 Hierophant's Power = 1 grade-10 slot per day { level: 19, spellSlotIncrement: { tradition: 'PRIMAL', spellLevel: 10, count: 1 } }, ], // === PREPARED CASTER — WITCH === // SOURCE: https://2e.aonprd.com/Classes.aspx?ID=27 (Witch) — Player Core (Witch) spell-slot table. // CAVEAT: Witch tradition depends on patron (the player picks the patron at L1 — see the // CLASS_FEATURE_OPTIONS witch-patron entries). The overlay defaults to ARCANE for slot // bookkeeping; the recompute pipeline (Plan 04) may need to remap this to the actual // patron's tradition at commit time. For Phase 1 we accept the default — the slot count // is the same regardless of tradition; only spell list / known-spell pool differs. Witch: [ { level: 1, cantripIncrement: 5 }, { level: 1, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 1, count: 2 } }, { level: 2, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 1, count: 1 } }, { level: 3, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 2, count: 2 } }, { level: 4, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 2, count: 1 } }, { level: 5, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 3, count: 2 } }, { level: 6, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 3, count: 1 } }, { level: 7, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 4, count: 2 } }, { level: 8, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 4, count: 1 } }, { level: 9, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 5, count: 2 } }, { level: 10, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 5, count: 1 } }, { level: 11, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 6, count: 2 } }, { level: 12, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 6, count: 1 } }, { level: 13, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 7, count: 2 } }, { level: 14, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 7, count: 1 } }, { level: 15, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 8, count: 2 } }, { level: 16, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 8, count: 1 } }, { level: 17, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 9, count: 2 } }, { level: 18, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 9, count: 1 } }, // L19 Patron's Truth = 1 grade-10 slot per day { level: 19, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 10, count: 1 } }, ], // === SPONTANEOUS CASTER — BARD === // SOURCE: https://2e.aonprd.com/Classes.aspx?ID=2 (Bard) — Player Core p.99 spell-slot + repertoire table. // Tradition: OCCULT (fixed by class, not by muse). // L1: 5 cantrips + 2 grade-1 slots (initial repertoire = 4 cantrips known + 2 grade-1 known). // L2..L19: each level adds 1 known spell (repertoireIncrement: 1) per the spontaneous-caster // progression. L20 is the qualitative capstone (no new slots/spells). Bard: [ { level: 1, cantripIncrement: 5 }, { level: 1, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 1, count: 2 } }, { level: 2, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 1, count: 1 } }, { level: 2, repertoireIncrement: 1 }, { level: 3, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 2, count: 2 } }, { level: 3, repertoireIncrement: 1 }, { level: 4, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 2, count: 1 } }, { level: 4, repertoireIncrement: 1 }, { level: 5, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 3, count: 2 } }, { level: 5, repertoireIncrement: 1 }, { level: 6, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 3, count: 1 } }, { level: 6, repertoireIncrement: 1 }, { level: 7, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 4, count: 2 } }, { level: 7, repertoireIncrement: 1 }, { level: 8, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 4, count: 1 } }, { level: 8, repertoireIncrement: 1 }, { level: 9, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 5, count: 2 } }, { level: 9, repertoireIncrement: 1 }, { level: 10, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 5, count: 1 } }, { level: 10, repertoireIncrement: 1 }, { level: 11, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 6, count: 2 } }, { level: 11, repertoireIncrement: 1 }, { level: 12, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 6, count: 1 } }, { level: 12, repertoireIncrement: 1 }, { level: 13, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 7, count: 2 } }, { level: 13, repertoireIncrement: 1 }, { level: 14, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 7, count: 1 } }, { level: 14, repertoireIncrement: 1 }, { level: 15, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 8, count: 2 } }, { level: 15, repertoireIncrement: 1 }, { level: 16, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 8, count: 1 } }, { level: 16, repertoireIncrement: 1 }, { level: 17, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 9, count: 2 } }, { level: 17, repertoireIncrement: 1 }, { level: 18, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 9, count: 1 } }, { level: 18, repertoireIncrement: 1 }, // L19 Magnum Opus equivalent — 1 grade-10 slot per day { level: 19, spellSlotIncrement: { tradition: 'OCCULT', spellLevel: 10, count: 1 } }, { level: 19, repertoireIncrement: 1 }, ], // === SPONTANEOUS CASTER — SORCERER === // SOURCE: https://2e.aonprd.com/Classes.aspx?ID=15 (Sorcerer) — Player Core p.193 spell-slot table. // CAVEAT: Tradition depends on bloodline (the player picks the bloodline at L1 — see the // CLASS_FEATURE_OPTIONS sorcerer-bloodline entries). The overlay defaults to ARCANE for // slot bookkeeping; recompute pipeline (Plan 04) may remap to the actual bloodline's // tradition at commit time. // L1: 5 cantrips + 3 grade-1 slots (one more than Bard/prepared casters per Sorcerer/Oracle table). // L2..L19: standard +1 / +2 cadence; repertoireIncrement: 1 each level for known-spell growth. Sorcerer: [ { level: 1, cantripIncrement: 5 }, { level: 1, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 1, count: 3 } }, { level: 2, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 1, count: 1 } }, { level: 2, repertoireIncrement: 1 }, { level: 3, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 2, count: 3 } }, { level: 3, repertoireIncrement: 1 }, { level: 4, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 2, count: 1 } }, { level: 4, repertoireIncrement: 1 }, { level: 5, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 3, count: 3 } }, { level: 5, repertoireIncrement: 1 }, { level: 6, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 3, count: 1 } }, { level: 6, repertoireIncrement: 1 }, { level: 7, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 4, count: 3 } }, { level: 7, repertoireIncrement: 1 }, { level: 8, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 4, count: 1 } }, { level: 8, repertoireIncrement: 1 }, { level: 9, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 5, count: 3 } }, { level: 9, repertoireIncrement: 1 }, { level: 10, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 5, count: 1 } }, { level: 10, repertoireIncrement: 1 }, { level: 11, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 6, count: 3 } }, { level: 11, repertoireIncrement: 1 }, { level: 12, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 6, count: 1 } }, { level: 12, repertoireIncrement: 1 }, { level: 13, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 7, count: 3 } }, { level: 13, repertoireIncrement: 1 }, { level: 14, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 7, count: 1 } }, { level: 14, repertoireIncrement: 1 }, { level: 15, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 8, count: 3 } }, { level: 15, repertoireIncrement: 1 }, { level: 16, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 8, count: 1 } }, { level: 16, repertoireIncrement: 1 }, { level: 17, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 9, count: 3 } }, { level: 17, repertoireIncrement: 1 }, { level: 18, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 9, count: 1 } }, { level: 18, repertoireIncrement: 1 }, // L19 Bloodline Paragon = 1 grade-10 slot per day { level: 19, spellSlotIncrement: { tradition: 'ARCANE', spellLevel: 10, count: 1 } }, { level: 19, repertoireIncrement: 1 }, ], // === SPONTANEOUS CASTER — ORACLE === // SOURCE: https://2e.aonprd.com/Classes.aspx?ID=12 (Oracle) — APG / Player Core 2 spell-slot table. // Tradition: DIVINE (fixed — Mystery does not change tradition). // L1: 5 cantrips + 3 grade-1 slots (matches Sorcerer pattern, not Bard). // L2..L19: standard +1 / +2 cadence; repertoireIncrement: 1 each level. Oracle: [ { level: 1, cantripIncrement: 5 }, { level: 1, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 1, count: 3 } }, { level: 2, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 1, count: 1 } }, { level: 2, repertoireIncrement: 1 }, { level: 3, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 2, count: 3 } }, { level: 3, repertoireIncrement: 1 }, { level: 4, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 2, count: 1 } }, { level: 4, repertoireIncrement: 1 }, { level: 5, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 3, count: 3 } }, { level: 5, repertoireIncrement: 1 }, { level: 6, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 3, count: 1 } }, { level: 6, repertoireIncrement: 1 }, { level: 7, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 4, count: 3 } }, { level: 7, repertoireIncrement: 1 }, { level: 8, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 4, count: 1 } }, { level: 8, repertoireIncrement: 1 }, { level: 9, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 5, count: 3 } }, { level: 9, repertoireIncrement: 1 }, { level: 10, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 5, count: 1 } }, { level: 10, repertoireIncrement: 1 }, { level: 11, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 6, count: 3 } }, { level: 11, repertoireIncrement: 1 }, { level: 12, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 6, count: 1 } }, { level: 12, repertoireIncrement: 1 }, { level: 13, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 7, count: 3 } }, { level: 13, repertoireIncrement: 1 }, { level: 14, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 7, count: 1 } }, { level: 14, repertoireIncrement: 1 }, { level: 15, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 8, count: 3 } }, { level: 15, repertoireIncrement: 1 }, { level: 16, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 8, count: 1 } }, { level: 16, repertoireIncrement: 1 }, { level: 17, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 9, count: 3 } }, { level: 17, repertoireIncrement: 1 }, { level: 18, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 9, count: 1 } }, { level: 18, repertoireIncrement: 1 }, // L19 Mystery Conduit = 1 grade-10 slot per day { level: 19, spellSlotIncrement: { tradition: 'DIVINE', spellLevel: 10, count: 1 } }, { level: 19, repertoireIncrement: 1 }, ], // === FOCUS-ONLY CASTER — CHAMPION === // Champion casts Devotion Spells via a focus pool (1-3 focus points), NOT via spell slots. // Phase 1 records minimal entries — focus-spell mechanics are handled outside the slot // table and may grow into a Plan 04 Phase 2 focus-pool tracker. Champion remains // effectively non-caster from the slot-overlay perspective; choiceOptionsRef // 'champion-cause' (set by the seed script's L1_CHOICE_MAP) routes the L1 cause pick // through ClassFeatureOption. Champion: [], // === NON-CASTERS — confirmed empty per design === // These classes have no spell-slot, cantrip, or repertoire progression. Some (Alchemist, // Investigator, Ranger) have other resource pools (alchemical-bombs / clue-pool / hunt-prey) // tracked outside this overlay. Empty arrays are required because the seed script's // `(SPELL_SLOT_OVERLAY[className] || []).filter(...)` relies on key presence to avoid // missing-key bugs. Alchemist: [], Barbarian: [], Fighter: [], Investigator: [], Monk: [], Ranger: [], Rogue: [], Swashbuckler: [], };