/** * 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). This file (Plan 03) ships 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. * * 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. */ 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) === 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) ], // === STUBS — populated by Plan 03b === // Caster stubs (Plan 03b will replace [] with full L1..L20 entries): Cleric: [], Druid: [], Witch: [], Bard: [], Sorcerer: [], Oracle: [], Champion: [], // focus-only; minimal entries // Non-caster stubs (Plan 03b confirms these stay empty): Alchemist: [], Barbarian: [], Fighter: [], Investigator: [], Monk: [], Ranger: [], Rogue: [], Swashbuckler: [], };