From e1ba3fe1b93f73bd2c0b67ea24f7db2cff8699fc Mon Sep 17 00:00:00 2001 From: Nils Briggen Date: Mon, 8 Jun 2026 15:23:25 +0200 Subject: [PATCH] Phase 7: structured ruleset data (Open5e 5e + Foundry PF2e classes) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Scrapers scripts/fetch_open5e.ts (classes/races/backgrounds/feats, CC-BY/OGL) and fetch_foundry_pf2e.ts (25 PF2e classes, OGL/ORC) → normalized JSON in src/data/srd + public/data/pf2e/classes.json. - src/lib/ruleset/normalize.ts: pure, tested normalizers → unified RulesetClass (hit die, key abilities, saves/ranks, perception, skills, caster, subclasses, profs). - compendium loaders (loadClasses/loadRaces5e/loadBackgrounds5e) + a "Classes" tab for both systems (ClassDetail) with full stats; Bestiary stays the default category. - Data-source attribution in Settings. Feeds the Phase 5 builder. Co-Authored-By: Claude Opus 4.8 (1M context) --- e2e/compendium.spec.ts | 6 ++ public/data/pf2e/classes.json | 1 + scripts/fetch_foundry_pf2e.ts | 25 +++++ scripts/fetch_open5e.ts | 48 +++++++++ src/data/srd/backgrounds.json | 1 + src/data/srd/classes.json | 1 + src/data/srd/feats.json | 1 + src/data/srd/races.json | 1 + src/features/compendium/details.tsx | 30 ++++++ src/features/compendium/registry.tsx | 16 +++ src/features/settings/SettingsPage.tsx | 9 ++ src/lib/compendium/index.ts | 33 ++++++ src/lib/ruleset/normalize.test.ts | 55 ++++++++++ src/lib/ruleset/normalize.ts | 139 +++++++++++++++++++++++++ 14 files changed, 366 insertions(+) create mode 100644 public/data/pf2e/classes.json create mode 100644 scripts/fetch_foundry_pf2e.ts create mode 100644 scripts/fetch_open5e.ts create mode 100644 src/data/srd/backgrounds.json create mode 100644 src/data/srd/classes.json create mode 100644 src/data/srd/feats.json create mode 100644 src/data/srd/races.json create mode 100644 src/lib/ruleset/normalize.test.ts create mode 100644 src/lib/ruleset/normalize.ts diff --git a/e2e/compendium.spec.ts b/e2e/compendium.spec.ts index 805a7f7..f5cd15f 100644 --- a/e2e/compendium.spec.ts +++ b/e2e/compendium.spec.ts @@ -21,6 +21,12 @@ test('compendium: browse 5e categories, switch to PF2e, cross-link a spell', asy // Compendium → 5e categories exist (Feats is a new one) await page.getByRole('link', { name: 'Compendium' }).click(); await expect(page.getByRole('button', { name: 'Feats' })).toBeVisible(); + + // Classes category (Open5e data) lists classes with detail + await page.getByRole('button', { name: 'Classes', exact: true }).click(); + await page.getByRole('button', { name: /^Wizard/ }).first().click(); + await expect(page.getByText('Hit die')).toBeVisible(); + await expect(page.getByText(/School of Evocation/)).toBeVisible(); await page.getByRole('button', { name: 'Conditions' }).click(); await expect(page.getByText(/results/)).toBeVisible(); diff --git a/public/data/pf2e/classes.json b/public/data/pf2e/classes.json new file mode 100644 index 0000000..ca8cc12 --- /dev/null +++ b/public/data/pf2e/classes.json @@ -0,0 +1 @@ +[{"system":"pf2e","slug":"alchemist","name":"Alchemist","hitDie":8,"keyAbilities":["int"],"saves":["con","dex","wis"],"saveRanks":{"con":"Expert","dex":"Expert","wis":"Trained"},"perception":"Trained","skillCount":4,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","medium","unarmored"],"weapons":["simple","unarmed"],"description":"There's no sight more beautiful to you than a strange brew bubbling in a beaker, and you consume your ingenious elixirs with abandon. You're fascinated by uncovering the secrets of science and the natural world, and you're constantly experimenting in your lab or on the go with inventive concoctions for every eventuality. You are fearless in the face of risk, hurling explosive or toxic creations…","source":"Pathfinder Player Core 2","license":"ORC"},{"system":"pf2e","slug":"animist","name":"Animist","hitDie":8,"keyAbilities":["wis"],"saves":["con","dex","wis"],"saveRanks":{"con":"Trained","dex":"Trained","wis":"Expert"},"perception":"Trained","skillCount":3,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","medium","unarmored"],"weapons":["simple","unarmed"],"description":"You are the interlocutor between the seen and unseen, the voice that connects the mortal and the spiritual. You bond with spirits, manifesting their distinct magic and allowing their knowledge to flow through you. You may favor apparitions that grant you healing magic, others that grant you spells of destructive power, or pick and choose between different apparitions as your environment and cir…","source":"Pathfinder War of Immortals","license":"ORC"},{"system":"pf2e","slug":"barbarian","name":"Barbarian","hitDie":12,"keyAbilities":["str"],"saves":["con","dex","wis"],"saveRanks":{"con":"Expert","dex":"Trained","wis":"Expert"},"perception":"Expert","skillCount":4,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","medium","unarmored"],"weapons":["martial","simple","unarmed"],"description":"Rage consumes you in battle. You delight in wreaking havoc and using powerful weapons to carve through your enemies, relying on astonishing durability without needing complicated techniques or rigid training. Your rages draw upon a vicious instinct, which you might associate with an animal, a spirit, or some part of yourself. To many barbarians, brute force is a hammer and every problem looks l…","source":"Pathfinder Player Core 2","license":"ORC"},{"system":"pf2e","slug":"bard","name":"Bard","hitDie":8,"keyAbilities":["cha"],"saves":["con","dex","wis"],"saveRanks":{"con":"Trained","dex":"Trained","wis":"Expert"},"perception":"Expert","skillCount":6,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","unarmored"],"weapons":["martial","simple","unarmed"],"description":"You are a master of artistry, a scholar of hidden secrets, and a captivating persuader. Using powerful performances, you influence minds and elevate souls to new levels of heroics. You might use your powers to become a charismatic leader, or perhaps you might instead be a counselor, manipulator, scholar, scoundrel, or virtuoso. While your versatility leads some to consider you a beguiling ne'er…","source":"Pathfinder Player Core","license":"ORC"},{"system":"pf2e","slug":"champion","name":"Champion","hitDie":10,"keyAbilities":["dex","str"],"saves":["con","dex","wis"],"saveRanks":{"con":"Expert","dex":"Trained","wis":"Expert"},"perception":"Trained","skillCount":3,"skillChoices":[],"caster":"none","subclasses":[],"armor":["heavy","light","medium","unarmored"],"weapons":["martial","simple","unarmed"],"description":"You are an emissary of a deity, a devoted servant who has taken up a weighty mantle, and you adhere to a code that holds you apart from those around you. While champions exist for every alignment, as a champion of good, you provide certainty and hope to the innocent. You have powerful defenses that you share freely with your allies and innocent bystanders, as well as holy power you use to end t…","source":"Pathfinder Player Core 2","license":"ORC"},{"system":"pf2e","slug":"cleric","name":"Cleric","hitDie":8,"keyAbilities":["wis"],"saves":["con","dex","wis"],"saveRanks":{"con":"Trained","dex":"Trained","wis":"Expert"},"perception":"Trained","skillCount":3,"skillChoices":[],"caster":"none","subclasses":[],"armor":["unarmored"],"weapons":["simple","unarmed"],"description":"Deities work their will upon the world in infinite ways, and you serve as one of their most stalwart mortal servants. Blessed with divine magic, you live the ideals of your faith, adorn yourself with the symbols of your church, and train diligently to wield your deity's favored weapon. Your spells might protect and heal your allies, or they might punish foes and enemies of your faith, as your d…","source":"Pathfinder Player Core","license":"ORC"},{"system":"pf2e","slug":"druid","name":"Druid","hitDie":8,"keyAbilities":["wis"],"saves":["con","dex","wis"],"saveRanks":{"con":"Trained","dex":"Trained","wis":"Expert"},"perception":"Trained","skillCount":3,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","medium","unarmored"],"weapons":["simple","unarmed"],"description":"The power of nature is impossible to resist. It can bring ruin to the stoutest fortress in minutes, reducing even the mightiest works to rubble, burning them to ash, burying them beneath an avalanche of snow, or drowning them beneath the waves. It can provide endless bounty and breathtaking splendor to those who respect it—and an agonizing death to those who take it too lightly. You are one of …","source":"Pathfinder Player Core","license":"ORC"},{"system":"pf2e","slug":"exemplar","name":"Exemplar","hitDie":10,"keyAbilities":["dex","str"],"saves":["con","dex","wis"],"saveRanks":{"con":"Expert","dex":"Trained","wis":"Expert"},"perception":"Trained","skillCount":4,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","medium","unarmored"],"weapons":["martial","simple","unarmed"],"description":"As the war god died, his power rained through the many planes of creation, sparking conflict and instilling divine energy in those previously without it. Whether you were directly touched by this power, claimed it from an ancient being or artifact, or whether it awoke something long dormant in your lineage, a spark of the divine now blazes within your soul, granting you abilities, sacred weapon…","source":"Pathfinder War of Immortals","license":"ORC"},{"system":"pf2e","slug":"fighter","name":"Fighter","hitDie":10,"keyAbilities":["dex","str"],"saves":["con","dex","wis"],"saveRanks":{"con":"Expert","dex":"Expert","wis":"Trained"},"perception":"Expert","skillCount":3,"skillChoices":[],"caster":"none","subclasses":[],"armor":["heavy","light","medium","unarmored"],"weapons":["advanced","martial","simple","unarmed"],"description":"Fighting for honor, greed, loyalty, or simply the thrill of battle, you are an undisputed master of weaponry and combat techniques. You combine your actions through clever combinations of opening moves, finishing strikes, and counterattacks whenever your foes are unwise enough to drop their guard. Whether you are a knight, mercenary, sharpshooter, or blade master, you have honed your martial sk…","source":"Pathfinder Player Core","license":"ORC"},{"system":"pf2e","slug":"gunslinger","name":"Gunslinger","hitDie":8,"keyAbilities":["dex"],"saves":["con","dex","wis"],"saveRanks":{"con":"Expert","dex":"Expert","wis":"Trained"},"perception":"Expert","skillCount":3,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","medium","unarmored"],"weapons":["martial","simple","unarmed"],"description":"While some fear projectile weapons, you savor the searing flash, wild kick, and cloying smoke that accompanies a gunshot, or snap of the cable and telltale thunk of your crossbow just before your bolt finds purchase. Ready to draw a bead on an enemy at every turn, you rely on your reflexes, steady hand, and knowledge of your weapons to riddle your foes with holes. @UUID[Compendium.pf2e.journals…","source":"Pathfinder Guns & Gears","license":"ORC"},{"system":"pf2e","slug":"inventor","name":"Inventor","hitDie":8,"keyAbilities":["int"],"saves":["con","dex","wis"],"saveRanks":{"con":"Expert","dex":"Trained","wis":"Expert"},"perception":"Trained","skillCount":4,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","medium","unarmored"],"weapons":["martial","simple","unarmed"],"description":"Any tinkerer can follow a diagram to make a device, but you invent the impossible! Every strange contraption you dream up is a unique experiment pushing the edge of possibility, a mysterious machine that seems to work for only you. You're always on the verge of the next great breakthrough, and every trial and tribulation is another opportunity to test and tune. If you can dream it, you can buil…","source":"Pathfinder Guns & Gears","license":"ORC"},{"system":"pf2e","slug":"investigator","name":"Investigator","hitDie":8,"keyAbilities":["int"],"saves":["con","dex","wis"],"saveRanks":{"con":"Trained","dex":"Expert","wis":"Expert"},"perception":"Expert","skillCount":5,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","unarmored"],"weapons":["martial","simple","unarmed"],"description":"You seek to uncover the truth, doggedly pursuing leads to reveal the plots of devious villains, discover ancient secrets, or unravel other mysteries. Your analytical mind quickly formulates solutions to complicated problems and your honed senses identify even the most obscure clues. Wielding knowledge as a weapon, you study the creatures and dangers you encounter to exploit their weaknesses. @U…","source":"Pathfinder Player Core 2","license":"ORC"},{"system":"pf2e","slug":"kineticist","name":"Kineticist","hitDie":8,"keyAbilities":["con"],"saves":["con","dex","wis"],"saveRanks":{"con":"Expert","dex":"Expert","wis":"Trained"},"perception":"Trained","skillCount":4,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","unarmored"],"weapons":["simple","unarmed"],"description":"The power of the elements flows from within you. Roaring fire pure water, fleeting air, steadfast earth, twisting wood, slicing metal. A kinetic gate inextricably tied to your body channels power directly from the elemental planes, causing elements to leap to your hand, whirl around your body, and blast foes at your whim. As your connection to the planes grows, you attain true mastery over your…","source":"Pathfinder Rage of Elements","license":"OGL"},{"system":"pf2e","slug":"magus","name":"Magus","hitDie":8,"keyAbilities":["dex","str"],"saves":["con","dex","wis"],"saveRanks":{"con":"Expert","dex":"Trained","wis":"Expert"},"perception":"Trained","skillCount":3,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","medium","unarmored"],"weapons":["martial","simple","unarmed"],"description":"Combining the physicality and technique of a warrior with the ability to cast arcane magic, you seek to perfect the art of fusing spell and strike. While the hefty tome you carry reflects hours conducting arcane research, your enemies need no reminder of your training. They recognize it as you take them down. @UUID[Compendium.pf2e.journals.JournalEntry.kzxu2dI7tFxv6Ix6.JournalEntryPage.YVoyzV9v…","source":"Pathfinder Secrets of Magic","license":"OGL"},{"system":"pf2e","slug":"monk","name":"Monk","hitDie":10,"keyAbilities":["dex","str"],"saves":["con","dex","wis"],"saveRanks":{"con":"Expert","dex":"Expert","wis":"Expert"},"perception":"Trained","skillCount":4,"skillChoices":[],"caster":"none","subclasses":[],"armor":["unarmored"],"weapons":["simple","unarmed"],"description":"The strength of your fist flows from your mind and spirit. You seek perfection-honing your body into a flawless instrument and your mind into an orderly bastion of wisdom. You're a fierce combatant renowned for martial arts skills and combat stances that grant you unique fighting moves. While the challenge of mastering many fighting styles drives you to great heights, you also enjoy meditating …","source":"Pathfinder Player Core 2","license":"ORC"},{"system":"pf2e","slug":"oracle","name":"Oracle","hitDie":8,"keyAbilities":["cha"],"saves":["con","dex","wis"],"saveRanks":{"con":"Trained","dex":"Trained","wis":"Expert"},"perception":"Trained","skillCount":4,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","unarmored"],"weapons":["simple","unarmed"],"description":"Your conduit to divine power eschews the traditional channels of prayer and servitude—you instead glean sacred truths and great mysteries embodied in overarching concepts, whether because you perceive the common ground across multiple deities or circumvent their power entirely. You explore one of these mysteries and draw upon its power to cast miraculous spells, but that power comes with a terr…","source":"Pathfinder Player Core 2","license":"ORC"},{"system":"pf2e","slug":"psychic","name":"Psychic","hitDie":6,"keyAbilities":[],"saves":["con","dex","wis"],"saveRanks":{"con":"Trained","dex":"Trained","wis":"Expert"},"perception":"Trained","skillCount":4,"skillChoices":[],"caster":"none","subclasses":[],"armor":["unarmored"],"weapons":["simple","unarmed"],"description":"The mind can perceive truths hidden to fine-tuned instruments, house more secrets than any tome, and move objects and hearts more deftly than any lever. By delving into both the conscious and subconscious aspects of your inner self, you have awoken to the might of psychic magic, allowing you to cast spells not through incantations or gestures but by the power of your will alone. While the thin …","source":"Pathfinder Dark Archive","license":"OGL"},{"system":"pf2e","slug":"ranger","name":"Ranger","hitDie":10,"keyAbilities":["dex","str"],"saves":["con","dex","wis"],"saveRanks":{"con":"Expert","dex":"Expert","wis":"Trained"},"perception":"Expert","skillCount":5,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","medium","unarmored"],"weapons":["martial","simple","unarmed"],"description":"Some rangers believe civilization wears down the soul, but still needs to be protected from wild creatures. Others say nature needs to be protected from the greedy, who wish to tame its beauty and plunder its treasures. You could champion either goal, or both. You might be a scout, tracker, or hunter of fugitives or beasts, haunting the edge of civilization or exploring the wilds. You know how …","source":"Pathfinder Player Core","license":"ORC"},{"system":"pf2e","slug":"rogue","name":"Rogue","hitDie":8,"keyAbilities":["dex"],"saves":["con","dex","wis"],"saveRanks":{"con":"Trained","dex":"Expert","wis":"Expert"},"perception":"Expert","skillCount":8,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","unarmored"],"weapons":["martial","simple","unarmed"],"description":"You are skilled and opportunistic. Using your sharp wits and quick reactions, you take advantage of your opponents' missteps and strike where it hurts most. You play a dangerous game, seeking thrills and testing your skills, and likely don't care much for any laws that happen to get in your way. While the path of every rogue is unique and riddled with danger, the one thing you all share in comm…","source":"Pathfinder Player Core","license":"ORC"},{"system":"pf2e","slug":"sorcerer","name":"Sorcerer","hitDie":6,"keyAbilities":["cha"],"saves":["con","dex","wis"],"saveRanks":{"con":"Trained","dex":"Trained","wis":"Expert"},"perception":"Trained","skillCount":2,"skillChoices":[],"caster":"none","subclasses":[],"armor":["unarmored"],"weapons":["simple","unarmed"],"description":"You didn't choose to become a spellcaster-you were born one. There's magic in your blood, whether a divinity touched one of your ancestors, a forebear communed with a primal creature, or a powerful occult ritual influenced your line. Self-reflection and study allow you to refine your inherent magical skills and unlock new, more powerful abilities. The power in your blood carries a risk, however…","source":"Pathfinder Player Core 2","license":"ORC"},{"system":"pf2e","slug":"summoner","name":"Summoner","hitDie":10,"keyAbilities":["cha"],"saves":["con","dex","wis"],"saveRanks":{"con":"Expert","dex":"Trained","wis":"Expert"},"perception":"Trained","skillCount":3,"skillChoices":[],"caster":"none","subclasses":[],"armor":["unarmored"],"weapons":["simple","unarmed"],"description":"You can magically beckon a powerful being called an eidolon to your side, serving as the mortal conduit that anchors it to the world. Whether your eidolon is a friend, a servant, or even a personal god, your connection to it marks you as extraordinary, shaping the course of your life dramatically. @UUID[Compendium.pf2e.journals.JournalEntry.kzxu2dI7tFxv6Ix6.JournalEntryPage.gA4Ud8oSUGkkLwAi]{Su…","source":"Pathfinder Secrets of Magic","license":"OGL"},{"system":"pf2e","slug":"swashbuckler","name":"Swashbuckler","hitDie":10,"keyAbilities":["dex"],"saves":["con","dex","wis"],"saveRanks":{"con":"Trained","dex":"Expert","wis":"Expert"},"perception":"Expert","skillCount":5,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","unarmored"],"weapons":["martial","simple","unarmed"],"description":"Many warriors rely on brute force, weighty armor, or cumbersome weapons. For you, battle is a dance where you move among foes with style and grace. You dart among combatants with flair and land powerful finishing moves with a flick of the wrist and a flash of the blade, all while countering attacks with elegant ripostes that keep enemies off balance. Harassing and thwarting your foes lets you c…","source":"Pathfinder Player Core 2","license":"ORC"},{"system":"pf2e","slug":"thaumaturge","name":"Thaumaturge","hitDie":8,"keyAbilities":["cha"],"saves":["con","dex","wis"],"saveRanks":{"con":"Expert","dex":"Trained","wis":"Expert"},"perception":"Expert","skillCount":7,"skillChoices":[],"caster":"none","subclasses":[],"armor":["light","medium","unarmored"],"weapons":["martial","simple","unarmed"],"description":"The world is full of the unexplainable: ancient magic, dead gods, and even stranger things. In response, you've scavenged the best parts of every magical tradition and built up a collection of esoterica—a broken holy relic here, a sprig of mistletoe there—that you can use to best any creature by exploiting their weaknesses and vulnerabilities. The mystic implement you carry is both badge and we…","source":"Pathfinder Dark Archive","license":"OGL"},{"system":"pf2e","slug":"witch","name":"Witch","hitDie":6,"keyAbilities":["int"],"saves":["con","dex","wis"],"saveRanks":{"con":"Trained","dex":"Trained","wis":"Expert"},"perception":"Trained","skillCount":3,"skillChoices":[],"caster":"none","subclasses":[],"armor":["unarmored"],"weapons":["simple","unarmed"],"description":"You command powerful magic, not through study or devotion, but as an agent for an otherworldly patron that even you don't entirely understand. This entity might be a covert divinity, a powerful fey, an ancient spirit, or any other mighty supernatural being—but its nature is likely as much a mystery to you as it is to others. Through a special familiar, your patron grants you versatile spells an…","source":"Pathfinder Player Core","license":"ORC"},{"system":"pf2e","slug":"wizard","name":"Wizard","hitDie":6,"keyAbilities":["int"],"saves":["con","dex","wis"],"saveRanks":{"con":"Trained","dex":"Trained","wis":"Expert"},"perception":"Trained","skillCount":3,"skillChoices":[],"caster":"none","subclasses":[],"armor":["unarmored"],"weapons":["simple","unarmed"],"description":"You are an eternal student of the secrets of the universe, using your mastery of magic to cast powerful spells. You treat magic like a science, cross-referencing the latest texts on practical spellcraft with ancient tomes to discover and understand arcane magic. Yet magical theory is vast, and there's no way you can study it all. Most wizards learn through formal schooling, with their curriculu…","source":"Pathfinder Player Core","license":"ORC"}] \ No newline at end of file diff --git a/scripts/fetch_foundry_pf2e.ts b/scripts/fetch_foundry_pf2e.ts new file mode 100644 index 0000000..403ccdc --- /dev/null +++ b/scripts/fetch_foundry_pf2e.ts @@ -0,0 +1,25 @@ +/* Scrape Foundry VTT pf2e class packs (OGL/ORC + Paizo Community Use) → + * normalized JSON in public/data/pf2e/classes.json. + * Run: bunx tsx scripts/fetch_foundry_pf2e.ts */ +import { writeFileSync } from 'node:fs'; +import { normalizeFoundryClass, type FoundryClass } from '../src/lib/ruleset/normalize'; + +const LIST = 'https://api.github.com/repos/foundryvtt/pf2e/contents/packs/classes?ref=master'; + +async function main() { + const res = await fetch(LIST, { headers: { 'User-Agent': 'ttrpg-manager-scraper', Accept: 'application/vnd.github+json' } }); + if (!res.ok) throw new Error(`list: ${res.status}`); + const files = (await res.json()) as { name: string; download_url: string }[]; + const classFiles = files.filter((f) => f.name.endsWith('.json')); + + const out = []; + for (const f of classFiles) { + const raw = (await (await fetch(f.download_url)).json()) as FoundryClass; + out.push(normalizeFoundryClass(f.name.replace(/\.json$/, ''), raw)); + } + out.sort((a, b) => a.name.localeCompare(b.name)); + writeFileSync('public/data/pf2e/classes.json', JSON.stringify(out)); + console.log(`pf2e: classes ${out.length} (${out.map((c) => c.name).join(', ')})`); +} + +main().catch((e) => { console.error(e); process.exit(1); }); diff --git a/scripts/fetch_open5e.ts b/scripts/fetch_open5e.ts new file mode 100644 index 0000000..3349b3c --- /dev/null +++ b/scripts/fetch_open5e.ts @@ -0,0 +1,48 @@ +/* Scrape Open5e (SRD 5.1, CC-BY-4.0 / OGL) → normalized JSON in src/data/srd/. + * Run: bunx tsx scripts/fetch_open5e.ts */ +import { writeFileSync } from 'node:fs'; +import { normalizeOpen5eClass, type Open5eClass } from '../src/lib/ruleset/normalize'; + +const BASE = 'https://api.open5e.com/v1'; + +async function all>(path: string): Promise { + let url: string | null = `${BASE}/${path}/?limit=500`; + const out: T[] = []; + while (url) { + const r = await fetch(url); + if (!r.ok) throw new Error(`${path}: ${r.status}`); + const j = (await r.json()) as { results: T[]; next: string | null }; + out.push(...j.results); + url = j.next; + } + return out; +} + +const first = (s: string | undefined): string => { + const p = (s ?? '').replace(/[#*_`>]/g, '').split('\n').map((x) => x.trim()).filter(Boolean)[0] ?? ''; + return p.length > 500 ? `${p.slice(0, 497)}…` : p; +}; + +async function main() { + const classes = (await all('classes')).map(normalizeOpen5eClass).sort((a, b) => a.name.localeCompare(b.name)); + writeFileSync('src/data/srd/classes.json', JSON.stringify(classes)); + + const races = (await all>('races')).map((r) => ({ + slug: r.slug, name: r.name, desc: first(r.desc), asi: r.asi_desc ?? '', speed: r.speed_desc ?? '', vision: r.vision ?? '', traits: first(r.traits), + })).sort((a, b) => a.name.localeCompare(b.name)); + writeFileSync('src/data/srd/races.json', JSON.stringify(races)); + + const backgrounds = (await all>('backgrounds')).map((b) => ({ + slug: b.slug, name: b.name, desc: first(b.desc), skills: b.skill_proficiencies ?? '', tools: b.tool_proficiencies ?? '', languages: b.languages ?? '', feature: b.feature ?? '', + })).sort((a, b) => a.name.localeCompare(b.name)); + writeFileSync('src/data/srd/backgrounds.json', JSON.stringify(backgrounds)); + + const feats = (await all>('feats')).map((f) => ({ + slug: f.slug, name: f.name, desc: first(f.desc), prerequisite: f.prerequisite ?? '', + })).sort((a, b) => a.name.localeCompare(b.name)); + writeFileSync('src/data/srd/feats.json', JSON.stringify(feats)); + + console.log(`5e: classes ${classes.length}, races ${races.length}, backgrounds ${backgrounds.length}, feats ${feats.length}`); +} + +main().catch((e) => { console.error(e); process.exit(1); }); diff --git a/src/data/srd/backgrounds.json b/src/data/srd/backgrounds.json new file mode 100644 index 0000000..4a42a00 --- /dev/null +++ b/src/data/srd/backgrounds.json @@ -0,0 +1 @@ +[{"slug":"acolyte","name":"Acolyte","desc":"You have spent your life in the service of a temple to a specific god or pantheon of gods. You act as an intermediary between the realm of the holy and the mortal world, performing sacred rites and offering sacrifices in order to conduct worshipers into the presence of the divine. You are not necessarily a cleric-performing sacred rites is not the same thing as channeling divine power.","skills":"Insight, Religion","tools":"","languages":"Two of your choice","feature":"Shelter of the Faithful"},{"slug":"artisan","name":"Artisan","desc":"You are skilled enough in a trade to make a comfortable living and to aspire to mastery of your art. Yet here you are, ready to slog through mud and blood and danger.","skills":"Persuasion, and either Insight or History.","tools":"","languages":"","feature":"Trade Mark"},{"slug":"charlatan","name":"Charlatan","desc":"People call you a con artist, but you're really an entertainer. You make people happy—the separation of fools and villains from their money is purely a pleasant side effect.","skills":"Deception, and either Culture, Insight, or Sleight of Hand.","tools":"","languages":"","feature":"Many Identities"},{"slug":"con-artist","name":"Con Artist","desc":"You have always had a knack for getting people to see your point of view, often to their own detriment. You know how people think, what they want, and how to best use that to your advantage.","skills":"Deception, Sleight of Hand","tools":"Two of your choice","languages":"","feature":"Cover Story"},{"slug":"court-servant","name":"Court Servant","desc":"Even though you are independent now, you were once a servant to a merchant, noble, regent, or other person of high station. You are an expert in complex social dynamics and knowledgeable in the history and customs of courtly life. Work with your GM to determine whom you served and why you are no longer a servant: did your master or masters retire and no longer require servants, did you resign from the service of a harsh master, did the court you served fall to a neighboring empire, or did som…","skills":"History, Insight","tools":"One artisan's tools set of your choice","languages":"One of your choice","feature":"Servant's Invisibility"},{"slug":"crime-syndicate-member","name":"Crime Syndicate Member","desc":"Whether you grew up in the slum-run streets bamboozling foolish gamblers out of their fortune, or spent your youth pilfering loose coin from the pockets of less-attentive travelers, your lifestyle of deceiving-to-survive eventually drew the attention of an organized and dangerous crime syndicate. Offering protection, a modicum of kinship, and a number of useful resources to further develop your craft as a criminal, you agree to receive the syndicate’s brand and join their ranks.","skills":"Deception, plus your choice of one between Sleight of Hand or Stealth.","tools":"Your choice of one from Thieves’ Tools, Forgery Kit, or Disguise Kit.","languages":"Thieves’ Cant","feature":"A Favor In Turn"},{"slug":"criminal","name":"Criminal","desc":"As a career criminal you were acquainted with murderers, thieves, and those who hunt them. Your new career as an adventurer is, relatively speaking, an honest trade.","skills":"Stealth, and either Deception or Intimidation.","tools":"","languages":"","feature":"Thieves' Cant"},{"slug":"desert-runner","name":"Desert Runner","desc":"You grew up in the desert. As a nomad, you moved from place to place, following the caravan trails. Your upbringing makes you more than just accustomed to desert living—you thrive there. Your family has lived in the desert for centuries, and you know more about desert survival than life in the towns and cities.","skills":"Perception, Survival","tools":"Herbalist kit","languages":"One of your choice","feature":"Nomad"},{"slug":"destined","name":"Destined","desc":"Duty is a complicated, tangled affair, be it filial, political, or civil. Sometimes, there's wealth and intrigue involved, but more often than not, there's also obligation and responsibility. You are a person with just such a responsibility. This could involve a noble title, an arranged marriage, a family business you're expected to administer, or an inherited civil office. You promised to fulfill this responsibility, you are desperately trying to avoid this duty, or you might even be seeking…","skills":"History, Insight","tools":"No additional tool proficiencies","languages":"One of your choice","feature":"Reputation of Opportunity"},{"slug":"diplomat","name":"Diplomat","desc":"You have always found harmonious solutions to conflict. You might have started mediating family conflicts as a child. When you were old enough to recognize aggression, you sought to defuse it. You often resolved disputes among neighbors, arriving at a fair middle ground satisfactory to all parties.","skills":"Insight, Persuasion","tools":"No additional tool proficiencies","languages":"Two of your choice","feature":"A Friend in Every Port"},{"slug":"elemental-warden","name":"Elemental Warden","desc":"Away from the complex political struggles of the massive cities, you’ve instead been raised to revere and uphold the protection of the natural world, while policing, bending, and guiding the elemental powers that either foster life or destroy it. Living among smaller bands of tribal societies means you have stronger ties to your neigh- bors than most, and the protection of this way of life is of cardinal importance. Each elemental warden is tethered to one of the four elemental tribes and the…","skills":"Nature, plus your choice of one between Arcana or Survival.","tools":"Herbalism Kit","languages":"One of your choice.","feature":"Elemental Harmony"},{"slug":"entertainer","name":"Entertainer","desc":"You're a performer who knows how to dazzle a crowd, an artist but also a professional: you never forget to pass the hat after a show.","skills":"Performance, and either Acrobatics, Culture, or Persuasion.","tools":"","languages":"","feature":"Pay the Piper"},{"slug":"exile","name":"Exile","desc":"Your homeland is barred to you and you wander strange lands. You will never be mistaken for a local but you find ready acceptance among other adventurers, many of which are as rootless as you are.","skills":"Survival, and either History or Performance.","tools":"","languages":"","feature":"Fellow Traveler"},{"slug":"farmer","name":"Farmer","desc":"You were raised a farmer, an occupation where the money is short and the work days are long. You've become an adventurer, a career where the money is plentiful but your days—if you're not careful—may be all too short.","skills":"Nature, and either Animal Handling or Survival.","tools":"","languages":"","feature":"Bit and Bridle"},{"slug":"fate-touched","name":"Fate-Touched","desc":"Many lives and many souls find their ways through the patterns of fate and destiny, their threads following the path meant for them, oblivious and eager to be a part of the woven essence of history meant for them. Some souls, however, glide forth with mysterious influence, their threads bending the weave around them, toward them, unknowingly guiding history itself wherever they walk. Events both magnificent and catastrophic tend to follow such individuals. These souls often become great ruler…","skills":"","tools":"","languages":"","feature":"Fortune’s Grace"},{"slug":"folk-hero","name":"Folk Hero","desc":"You were born to a commoner family, but some event earned you fame. You're admired locally, and tales of your deeds have reached the far corners of the world.","skills":"Survival, and either Animal Handling or Nature.","tools":"","languages":"","feature":"Local Fame"},{"slug":"forest-dweller","name":"Forest Dweller","desc":"You are a creature of the forest, born and reared under a canopy of green. You expected to live all your days in the forest, at one with the green things of the world, until an unforeseen occurrence, traumatic or transformative, drove you from your familiar home and into the larger world. Civilization is strange to you, the open sky unfamiliar, and the bizarre ways of the so-called civilized world run counter to the truths of the natural world.","skills":"Nature, Survival","tools":"Woodcarver's tools, Herbalism kit","languages":"Sylvan","feature":"Forester"},{"slug":"former-adventurer","name":"Former Adventurer","desc":"As you belted on your weapons and hoisted the pack onto your back, you never thought you'd become an adventurer again. But the heroic call couldn't be ignored. You've tried this once before—perhaps it showered you in wealth and glory or perhaps it ended with sorrow and regret. No one ever said adventuring came with a guarantee of success.","skills":"Perception, Survival","tools":"No additional tool proficiencies","languages":"One of your choice","feature":"Old Friends and Enemies"},{"slug":"freebooter","name":"Freebooter","desc":"You sailed the seas as a freebooter, part of a pirate crew. You should come up with a name for your former ship and its captain, as well as its hunting ground and the type of ships you preyed on. Did you sail under the flag of a bloodthirsty captain, raiding coastal communities and putting everyone to the sword? Or were you part of a group of former slaves turned pirates, who battle to end the vile slave trade? Whatever ship you sailed on, you feel at home on board a seafaring vessel, and you…","skills":"Athletics, Survival","tools":"Navigator's tools, vehicles (water)","languages":"No additional languages","feature":"A Friendly Face in Every Port"},{"slug":"gambler","name":"Gambler","desc":"You haven't met your match at dice or cards. A career of high stakes and daring escapades has taught you when to play close to the chest and when to risk it all—but you haven't yet learned when to walk away.","skills":"Deception, and either Insight or Sleight of Hand.","tools":"","languages":"","feature":"Lady Luck"},{"slug":"gamekeeper","name":"Gamekeeper","desc":"You are at home in natural environments, chasing prey or directing less skilled hunters in the best ways to track game through the brush. You know the requirements for encouraging a herd to grow, and you know what sustainable harvesting from a herd involves. You can train a hunting beast to recognize an owner and perform a half-dozen commands, given the time. You also know the etiquette for engaging nobility or other members of the upper classes, as they regularly seek your services, and you …","skills":"Animal Handling, Persuasion","tools":"Leatherworker's tools","languages":"One of your choice","feature":"Confirmed Guildmember"},{"slug":"guildmember","name":"Guildmember","desc":"It never hurts to be part of a team, and when you're part of a guild opportunities knock at your door.","skills":"Two of your choice.","tools":"","languages":"","feature":"Guild Business"},{"slug":"hermit","name":"Hermit","desc":"You lived for years alone in a remote shrine, cave, monastery, or elsewhere away from the world. Among your daily tasks you had lots of time for introspection.","skills":"Religion, and either Medicine or Survival.","tools":"","languages":"","feature":"Inner Voice"},{"slug":"innkeeper","name":"Innkeeper","desc":"You spent some time as an innkeeper, tavern keeper, or perhaps a bartender. It might have been in a small crossroads town, a fishing community, a fine caravanserai, or a large cosmopolitan community. You did it all; preparing food, tracking supplies, tapping kegs, and everything in between. All the while, you listened to the adventurers plan their quests, heard their tales, saw their amazing trophies, marveled at their terrible scars, and eyed their full purses. You watched them come and go, …","skills":"Insight plus one of your choice from among Intimidation or Persuasion","tools":"No additional tool proficiencies","languages":"Two of your choice","feature":"I Know Someone"},{"slug":"lyceum-student","name":"Lyceum Student","desc":"You most likely came up through money or a family of social prestige somewhere in the world, as tuition at a lyceum is not inexpensive. Your interests and pursuits have brought you to the glittering halls of a place of learning, soaking in all and every lesson you can to better make your mark on the world (or at least you should be, but every class has its slackers). However, the call to adventure threatens to pull you from your studies, and now the challenge of balancing your education with …","skills":"Your choice of two from among Arcana, History, and Persuasion.","tools":"","languages":"Two of your choice","feature":"Student Privilege"},{"slug":"marauder","name":"Marauder","desc":"You were a member of an outlaw band. You might have been part of a troop of cutthroat bandits, or a resistance movement battling a tyrant, or a pirate fleet. You lived outside of settled lands, and your name was a terror to rich travelers.","skills":"Survival, and either Intimidation or Stealth.","tools":"","languages":"","feature":"Secret Ways"},{"slug":"mercenary-company-scion","name":"Mercenary Company Scion","desc":"You descend from a famous line of free company veterans, and your first memory is playing among the tents, training yards, and war rooms of one campaign or another. Adored or perhaps ignored by your parents, you spent your formative years learning weapons and armor skills from brave captains, camp discipline from burly sergeants, and a host of virtues and vices from the common foot soldiers. You've always been told you are special and destined to glory. The weight of your family's legacy, hon…","skills":"Athletics, History","tools":"One type of gaming set, one musical instrument","languages":"One of your choice","feature":"The Family Name"},{"slug":"mercenary-recruit","name":"Mercenary Recruit","desc":"Every year, the hopeful strive to earn a place in one of the great mercenary companies. Some of these would-be heroes received training from a mercenary company but needed more training before gaining membership. Others are full members but were selected to venture abroad to gain more experience before gaining a rank. You are one of these hopeful warriors, just beginning to carve your place in the world with blade, spell, or skill.","skills":"Athletics, Persuasion","tools":"One type of gaming set","languages":"No additional languages","feature":"Theoretical Experience"},{"slug":"monstrous-adoptee","name":"Monstrous Adoptee","desc":"Songs and sagas tell of heroes who, as children, were raised by creatures most view as monsters. You were one such child. Found, taken, left, or otherwise given to your monstrous parents, you were raised as one of their own species. Life with your adopted family could not have been easy for you, but the adversity and hardships you experienced only made you stronger. Perhaps you were “rescued” from your adopted family after only a short time with them, or perhaps only now have you realized the…","skills":"Intimidation, Survival","tools":"No additional tool proficiencies","languages":"One language of your choice, typically your adopted parents' language (if any)","feature":"Abnormal Demeanor"},{"slug":"mysterious-origins","name":"Mysterious Origins","desc":"Your origins are a mystery even to you. You might recall fragments of your previous life, or you might dream of events that could be memories, but you can't be sure of what is remembered and what is imagined. You recall practical information and facts about the world and perhaps even your name, but your upbringing and life before you lost your memories now exist only in dreams or sudden flashes of familiarity.","skills":"Deception, Survival","tools":"One type of artisan's tools or one type of musical instrument","languages":"One of your choice","feature":"Unexpected Acquaintance"},{"slug":"northern-minstrel","name":"Northern Minstrel","desc":"While the tribal warriors residing in other parts of the wintry north consider you to be soft and cowardly, you know the truth: life in northern cities and mead halls is not for the faint of heart. Whether you are a larger-than-life performer hailing from one of the skaldic schools, a contemplative scholar attempting to puzzle out the mysteries of the north, or a doughty warrior hoping to stave off the bleakness of the north, you have successfully navigated alleys and stages as treacherous as…","skills":"Perception plus one of your choice from among History or Performance","tools":"One type of musical instrument","languages":"One of your choice","feature":"Northern Historian"},{"slug":"occultist","name":"Occultist","desc":"At your core, you are a believer in things others dismiss. The signs abound if you know where to look. Questions beget answers that spur further questions. The cycle is endless as you uncover layer after layer of mystery and secrets.","skills":"Arcana, Religion","tools":"Thieves' tools","languages":"Two of your choice","feature":"Strange Lore"},{"slug":"outlander","name":"Outlander","desc":"You lived far from the farms and fields of civilization. You know the beauties and the dangers of the wilderness.","skills":"Survival, and either Athletics or Intimidation.","tools":"","languages":"","feature":"Trader"},{"slug":"parfumier","name":"Parfumier","desc":"You are educated and ambitious. You spent your youth apprenticed among a city's more reputable greenhouses, laboratories, and perfumeries. There, you studied botany and chemistry and explored properties and interactions with fine crystal, rare metals, and magic. You quickly mastered the skills to identify and process rare and complex botanical and alchemical samples and the proper extractions and infusions of essential oils, pollens, and other fragrant chemical compounds—natural or otherwise.","skills":"Nature, Investigation","tools":"Alchemist's supplies, herbalism kit","languages":"No additional languages","feature":"Aromas and Odors and Airs, Oh My"},{"slug":"recovered-cultist","name":"Recovered Cultist","desc":"The rise of cults are scattered and separated, with little to no unity between the greater evils. Hidden hierarchies of power-hungry mortals corrupt and seduce, promising a sliver of the same power they had been promised when the time comes to reap their harvest.","skills":"Religion and Deception.","tools":"","languages":"One of your choice.","feature":"Wicked Awareness"},{"slug":"sage","name":"Sage","desc":"You are a seeker of the world's truths and an expert in your chosen field, with esoteric knowledge at your fingertips, or at the farthest, in a book you vaguely remember.","skills":"History, and either Arcana, Culture, Engineering, or Religion.","tools":"","languages":"","feature":"Library Privileges"},{"slug":"sailor","name":"Sailor","desc":"You're an experienced mariner with a keen weather eye and a favorite tavern in every port. Hard voyages have toughened you and the sea's power has made you humble.","skills":"Athletics, and either Acrobatics or Perception.","tools":"","languages":"","feature":"Sea Salt"},{"slug":"scoundrel","name":"Scoundrel","desc":"You were brought up in a poor neighborhood in a crowded town or city. You may have been lucky enough to have a leaky roof over your head, or perhaps you grew up sleeping in doorways or on the rooftops. Either way, you didn't have it easy, and you lived by your wits. While never a hardened criminal, you fell in with the wrong crowd, or you ended up in trouble for stealing food from an orange cart or clean clothes from a washing line. You're no stranger to the city watch in your hometown and ha…","skills":"Athletics, Sleight of Hand","tools":"One type of gaming set, thieves' tools","languages":"No additional languages","feature":"Urban Explorer"},{"slug":"sentry","name":"Sentry","desc":"In your youth, the defense of the city, the community, the caravan, or your patron was how you earned your coin. You might have been trained by an old, grizzled city watchman, or you might have been pressed into service by the local magistrate for your superior skills, size, or intellect. However you came to the role, you excelled at defending others.","skills":"Insight, Perception","tools":"One type of gaming set","languages":"One language of your choice","feature":"Comrades in Arms"},{"slug":"trader","name":"Trader","desc":"You served your apprenticeship among merchants and traders. You've traveled dusty miles and haggled under distant skies.","skills":"Persuasion, and either Culture, Deception, or Insight.","tools":"","languages":"","feature":"Supply and Demand"},{"slug":"trophy-hunter","name":"Trophy Hunter","desc":"You hunt the mightiest beasts in the harshest environments, claiming their pelts as trophies and returning them to settled lands for a profit or to decorate your abode. You likely were set on this path since birth, following your parents on safaris and learning from their actions, but you may have instead come to this path as an adult after being swept away by the thrill of dominating the natural world.","skills":"Nature, Survival","tools":"Leatherworker's tools, vehicles (land)","languages":"No additional languages","feature":"Shelter from the Storm"},{"slug":"urchin","name":"Urchin","desc":"You grew up on the streets. You know where to hide and when your puppy dog eyes will earn you a hot meal.","skills":"Sleight of Hand, and either Deception or Stealth.","tools":"","languages":"","feature":"Guttersnipe"}] \ No newline at end of file diff --git a/src/data/srd/classes.json b/src/data/srd/classes.json new file mode 100644 index 0000000..227be4b --- /dev/null +++ b/src/data/srd/classes.json @@ -0,0 +1 @@ +[{"system":"5e","slug":"barbarian","name":"Barbarian","hitDie":12,"keyAbilities":["str"],"saves":["str","con"],"skillCount":2,"skillChoices":["Animal Handling","Athletics","Intimidation","Nature","Perception","and Survival"],"caster":"none","subclasses":[{"name":"Path of the Berserker","desc":"For some barbarians, rage is a means to an end- that end being violence. The Path of the Berserker is a path of untrammeled fury, slick with blood. As you enter the berserker's rage, you thrill in the chaos of battle, heedless of your own health or well-being."},{"name":"Path of Booming Magnificence","desc":"Barbarians who walk the Path of Booming Magnificence strive to be as lions among their people: symbols of vitality, majesty, and courage. They serve at the vanguard, leading their allies at each charge and drawing their opponents' attention away from more vulnerable members of their group. As they grow more experienced, members of this path often take on roles as leaders or in other integral po…"},{"name":"Path of Hellfire","desc":"Devils have long been known to grant power to mortals as part of a pact or bargain. While this may take the form of unique magic or boons, those who follow the Path of Hellfire are gifted with command over the fires of the Lower Planes, which they channel for short periods to become powerful and furious fighting machines."},{"name":"Path of Mistwood","desc":"The first barbarians that traveled the path of mistwood were elves who expanded upon their natural gifts to become masters of the forests. Over time, members of other races who saw the need to protect and cherish the green places of the world joined and learned from them. Often these warriors haunt the woods alone, only seen when called to action by something that would despoil their home."},{"name":"Path of the Dragon","desc":"Few creatures embody the power and majesty of dragons. By walking the path of the dragon, you don't solely aspire to emulate these creatures—you seek to become one. The barbarians who follow this path often do so after surviving a dragon encounter or are raised in a culture that worships them. Dragons tend to have a mixed view of the barbarians who choose this path. Some dragons, in particular …"},{"name":"Path of the Herald","desc":"In northern lands, the savage warriors charge into battle behind chanting warrior-poets. These wise men and women collect the histories, traditions, and accumulated knowledge of the people to preserve and pass on. Barbarians who follow the Path of the Herald lead their people into battle, chanting the tribe's sagas and spurring them on to new victories while honoring the glory of the past."},{"name":"Path of the Inner Eye","desc":"The barbarians who follow the Path of the Inner Eye elevate their rage beyond anger to glimpse premonitions of the future."},{"name":"Path of Thorns","desc":"Path of Thorns barbarians use ancient techniques developed by the druids of old that enable them to grow thorns all over their body. The first barbarians of this path fought alongside these druids to defend the natural order. In the centuries since, the knowledge of these techniques has spread, allowing others access to this power."},{"name":"Path of the Juggernaut","desc":"Honed to assault the lairs of powerful threats to their way of life, or defend against armed hordes of snarling goblinoids, the juggernauts represent the finest of frontline destroyers within the primal lands and beyond."}],"armor":["Light armor","medium armor","shields"],"weapons":["Simple weapons","martial weapons"],"description":"Rage","source":"5e Core Rules","license":"http://open5e.com/legal"},{"system":"5e","slug":"bard","name":"Bard","hitDie":8,"keyAbilities":["cha"],"saves":["dex","cha"],"skillCount":2,"skillChoices":[],"caster":"cha","subclasses":[{"name":"College of Lore","desc":"Bards of the College of Lore know something about most things, collecting bits of knowledge from sources as diverse as scholarly tomes and peasant tales. Whether singing folk ballads in taverns or elaborate compositions in royal courts, these bards use their gifts to hold audiences spellbound. When the applause dies down, the audience members might find themselves questioning everything they he…"},{"name":"College of Skalds","desc":"Skalds are poets of battle, recounting the deeds of heroes and the bloody battles that shook nations. But you do more than just tell stories; a skald draws on the tales of past greatness in his own quest for glory on the battlefield. While learning the sagas of bygone years, you have also taken up a practical study of combat, allowing you to use more weapons and with greater effectiveness than …"},{"name":"College of Echoes","desc":"In the caverns beneath the surface of the world, sound works differently. Your exposure to echoes has taught you about how sound changes as it moves and encounters obstacles. Inspired by the effect caves and tunnels have on sounds, you have learned to manipulate sound with your magic, curving it and altering it as it moves. You can silence the most violent explosions, you can make whispers seem…"},{"name":"College of Investigation","desc":"Bards pick up all sorts of information as they travel the land. Some bards focus on a certain type of information, like epic poetry, love ballads, or bawdy drinking songs. Others, however, turn to the shadowy occupation of investigating crimes. These bards use their knack for gathering information to learn about criminals and vigilantes, their tactics, and their weaknesses. Some work with agent…"},{"name":"College of Shadows","desc":"Some bards are as proficient in the art of espionage as they are in poetry and song. Their primary medium is information and secrets, though they are known to slip a dagger between ribs when necessary. Masters of insight and manipulation, these bards use every tool at their disposal in pursuit of their goals, and they value knowledge above all else. The more buried a secret, the deeper they del…"},{"name":"College of Sincerity","desc":"Bards of the College of Sincerity know it is easier for someone to get what they want when they mask their true intentions behind a pleasant façade. These minstrels gain a devoted following and rarely lack for company. Some of their devotees go so far as to put themselves at the service of the bard they admire. Though members of the college can be found as traveling minstrels and adventuring tr…"},{"name":"College of Tactics","desc":"Bards of the College of Tactics are calculating strategists who scour historical records of famous battles for tricks they can use to give their own troops, and those of their patrons, an edge on the battlefield. Members of this college travel from war zone to combat site and interview the veterans of those engagements, trying to discern how the victors won the day and leveraging that informati…"},{"name":"College of the Cat","desc":"Scholars and spies, heroes and hunters: whether wooing an admirer in the bright sunlight or stalking prey under the gentle rays of the moon, bards of the College of the Cat excel at diverse skills and exhibit contrary tendencies. The adventurous spirits who favor the College of the Cat let their curiosity and natural talents get them into impossible places. Most are skilled, cunning, and viciou…"}],"armor":["Light armor"],"weapons":["Simple weapons","hand crossbows","longswords","rapiers","shortswords"],"description":"Spellcasting","source":"5e Core Rules","license":"http://open5e.com/legal"},{"system":"5e","slug":"cleric","name":"Cleric","hitDie":8,"keyAbilities":["wis"],"saves":["wis","cha"],"skillCount":2,"skillChoices":["History","Insight","Medicine","Persuasion","and Religion"],"caster":"wis","subclasses":[{"name":"Life Domain","desc":"The Life domain focuses on the vibrant positive energy-one of the fundamental forces of the universe-that sustains all life. The gods of life promote vitality and health through healing the sick and wounded, caring for those in need, and driving away the forces of death and undeath. Almost any non-evil deity can claim influence over this domain, particularly agricultural deities (such as Chaunt…"},{"name":"Demise Domain","desc":"Compare to the core book’s Death Domain"},{"name":"Mischief Domain","desc":"While most deities inspire awe with their might and power, some prefer subtler methods. Gods of the mischief domain favor cunning to advance their agendas, and they encourage this trait in the followers as well. Some deities of mischief, like Anansi and Hermes, are good natured tricksters. Some, like the impetuous Susanoo, vacillate between being helpful or hindering on a whim. Deities like Lok…"},{"name":"Storm Domain","desc":"Nothing inspires fear in mortals quite like a raging storm. This domain encompasses deities such as Enlil, Indra, Raijin, Taranis, Zeus, and Zojz. Many of these are the rulers of their respective pantheons, wielding the thunderbolt as a symbol of divine might. Most reside in the sky, but the domain also includes lords of the sea (like Donbettyr) and even the occasional chthonic fire deity (such…"},{"name":"Hunt Domain","desc":"Many terrible creatures prey on the villages, towns, and inns that dot the forests of Midgard. When such creatures become particularly aggressive or can't be dissuaded by local druids, the settlements often call on servants of gods of the hunt to solve the problem."},{"name":"Mercy Domain","desc":"Mercy can mean promoting healing instead of harm, but it can also mean ending suffering with a quick death. These often-contradictory ideals are the two sides of mercy. The tenets of deities who embody mercy promote ways to end bloody conflicts or deliver healing magics to those in need. While mercy for some may be benevolent, for others it is decidedly not so. More pragmatic mercy gods teach t…"},{"name":"Portal Domain","desc":"You have dedicated yourself to the study and protection of the doors, gateways, and rips in the boundaries between the physical world and the infinite planar multiverse. Stepping through portals is a sacred prayer and woe betide any who seek to misuse them. Domain Spells You gain domain spells at the cleric levels listed in the Portal Domain Spells table. See the Divine Domain class feature for…"},{"name":"Serpent Domain","desc":"You embody the deadly, secretive, and mesmerizing nature of serpents. Others tremble at your majesty. You practice the stealth and envenomed attacks that give serpents their dreaded reputation, but you also learn the shedding of skin that has made snakes into symbols of medicine."},{"name":"Shadow Domain","desc":"The shadow domain embraces the darkness that surrounds all things and manipulates the transitory gray that separates light from dark. Shadow domain clerics walk a subtle path, frequently changing allegiances and preferring to operate unseen."},{"name":"Vermin Domain","desc":"You exemplify the cunning, stealth, and invasiveness of vermin (rodents, scorpions, spiders, ants, and other insects). As your dedication to this domain grows in strength, you realize a simple truth: vermin are everywhere, and you are legion."},{"name":"Wind Domain","desc":"You have dedicated yourself to the service of the primordial winds. In their service, you are the gentle zephyr brushing away adversity or the vengeful storm scouring the stones from the mountainside."},{"name":"Blood Domain","desc":"The Blood domain centers around the understanding of the natural life force within one’s own physical body. The power of blood is the power of sacrifice, the balance of life and death, and the spirit’s anchor within the mortal shell. The Gods of Blood seek to tap into the connection between body and soul through divine means, exploit the hidden reserves of will within one’s own vitality, and ev…"}],"armor":["Light armor","medium armor","shields"],"weapons":["Simple weapons"],"description":"Spellcasting","source":"5e Core Rules","license":"http://open5e.com/legal"},{"system":"5e","slug":"druid","name":"Druid","hitDie":8,"keyAbilities":["wis"],"saves":["int","wis"],"skillCount":2,"skillChoices":["Arcana","Animal Handling","Insight","Medicine","Nature","Perception","Religion","and Survival"],"caster":"wis","subclasses":[{"name":"Circle of the Land","desc":"The Circle of the Land is made up of mystics and sages who safeguard ancient knowledge and rites through a vast oral tradition. These druids meet within sacred circles of trees or standing stones to whisper primal secrets in Druidic. The circle's wisest members preside as the chief priests of communities that hold to the Old Faith and serve as advisors to the rulers of those folk. As a member o…"},{"name":"Circle of the Many","desc":"Compare to the core book’s Circle of the Moon"},{"name":"Circle of Ash","desc":"Druids of the Circle of Ash believe in the power of rebirth and resurrection, both physical and spiritual. The ash they take as their namesake is the result of burning and death, but it can fertilize the soil and help bring forth new life. For these druids, ash is the ultimate symbol of the elegant cycle of life and death that is the foundation of the natural world. Some such druids even use fr…"},{"name":"Circle of Bees","desc":"Druids of the Circle of Bees are friends to all stinging insects but focus their attention on honeybees and other pollinating insects. When not adventuring, they tend hives, either created by the insects or by themselves. They tap into the horror inherent in stinging insects to protect their allies or the fields hosting their bee friends."},{"name":"Circle of Crystals","desc":"Circle of Crystals druids first arose in subterranean environments, where they helped tend giant crystal gardens, but now they can be found most anywhere with access to underground caverns or geothermal activity. These druids view crystals as a naturally occurring form of order and perfection, and they value the crystals' slow growth cycle, as it reminds them the natural world moves gradually b…"},{"name":"Circle of Sand","desc":"The Circle of Sand originally arose among the desert dunes, where druids forged an intimate connection with the sands that surrounded them. Now such circles gather anywhere with excess sand, including coastlines or badlands."},{"name":"Circle of the Green","desc":"Druids of the Circle of the Green devote themselves to the plants and green things of the world, recognizing the role of plants in giving life. By continued communion with plant life, they believe they draw nearer to what they call “The Green,” a cosmic thread that binds all plant life. Druids of this circle believe they gain their abilities by tapping into the Green, and they use this connecti…"},{"name":"Circle of the Shapeless","desc":"Druids of the Circle of the Shapeless believe that oozes, puddings, and jellies serve an important and integral role in the natural world, particularly in decomposition and in clearing detritus. Druids of this circle also admire the adaptability of these gelatinous creatures and study them to learn how to duplicate some of their abilities."},{"name":"Circle of Wind","desc":"Founded in deserts, badlands, and grasslands, where wind dominates and controls the landscape, the teachings of the Circle of Wind have spread far and wide, like a mighty storm. Druids who follow this circle's teachings embrace the mercurial winds to create several effects."}],"armor":["Light armor","medium armor","shields (druids will not wear armor or use shields made of metal)"],"weapons":["Clubs","daggers","darts","javelins","maces","quarterstaffs","scimitars","sickles","slings","spears"],"description":"Druidic","source":"5e Core Rules","license":"http://open5e.com/legal"},{"system":"5e","slug":"fighter","name":"Fighter","hitDie":10,"keyAbilities":["str"],"saves":["str","con"],"skillCount":2,"skillChoices":["Acrobatics","Animal","Handling","Athletics","History","Insight","Intimidation","Perception","and Survival"],"caster":"none","subclasses":[{"name":"Champion","desc":"The archetypal Champion focuses on the development of raw physical power honed to deadly perfection. Those who model themselves on this archetype combine rigorous training with physical excellence to deal devastating blows."},{"name":"Arcane Warrior","desc":"Most fighters train exhaustively with their preferred weapons to hone their power and reflexes. To some, this easily flows into the careful practice of magic as well. Unlike wizards, arcane warriors focus on a smaller number of spells that they commit to memory, particularly from the schools of magic that focus on protection and direct damage which are particularly useful in a combat setting. A…"},{"name":"Chaplain","desc":"Militaries and mercenary companies often contain members of various clergies among their ranks. These chaplains typically come from religious sects whose tenets promote war, healing, peace, protection, or freedom, and they tend to the emotional and physical well-being of their charges. In the eyes of your companions, you are as much a counselor and spiritual leader as you are a fellow warrior."},{"name":"Legionary","desc":"A legionary follows the techniques of close-quarters combat developed by soldiers fighting shoulder to shoulder with their allies. This style of fighting spread far and wide, finding an honored place among the armies and mercenary companies of other races. True legionaries scoff at the image of the storybook hero standing alone against impossible odds, knowing together they can face any danger …"},{"name":"Pugilist","desc":"Pugilists live by their fists, bare-knuckle warriors who do not hesitate to throw hands if the situation demands it. They know the intense, close, violent intimacy of melee, and they operate unapologetically in that space. Whether in fighting pits by the docks to make some extra coin, in the king's grand arena as champions of quarreling nobles, or in the employ of local merchants in need of see…"},{"name":"Radiant Pikeman","desc":"You were a member of an order of knights dedicated to a deity of sun and light. You know that next to your deity's favor, a soldier's greatest strength is their comrades. You wield a spear, glaive, halberd, or other polearm as a piercing ray of sunlight against your enemies."},{"name":"Timeblade","desc":"There are warriors who move so quickly that they seem to stop time, then there are those who actually alter time with their attacks. The timeblade augments physical attacks by manipulating temporal powers and eventually learns to step outside time itself."},{"name":"Tunnel Watcher","desc":"For untold ages, the dwarves have paid in blood to keep their subterranean homes safe. The keystone to the defense of the dwarven citadels are the tunnel watchers, warriors trained in the tight, uneven paths beneath the surface of the world. While the techniques of the tunnel watchers originated with the dwarves, others see the value in such specialization. Tunnel watchers can thus be found thr…"}],"armor":["All armor","shields"],"weapons":["Simple weapons","martial weapons"],"description":"Fighting Style","source":"5e Core Rules","license":"http://open5e.com/legal"},{"system":"5e","slug":"monk","name":"Monk","hitDie":8,"keyAbilities":["dex"],"saves":["str","dex"],"skillCount":2,"skillChoices":["Acrobatics","Athletics","History","Insight","Religion","and Stealth"],"caster":"none","subclasses":[{"name":"Way of the Open Hand","desc":"Monks of the Way of the Open Hand are the ultimate masters of martial arts combat, whether armed or unarmed. They learn techniques to push and trip their opponents, manipulate ki to heal damage to their bodies, and practice advanced meditation that can protect them from harm."},{"name":"Way of Shadowdancing","desc":"Monks of the shadowdancing tradition are more than just stealthy assassins; they have mastered their ki to become one with the shadows. As they continue their training, they strengthen their connection to the plane of shadow, giving them the ability to perform supernatural feats of subterfuge and jaunt through that very realm of darkness. They are known as ninjas in some regions, and they can s…"},{"name":"Way of Concordant Motion","desc":"The monks of Concordant Motion follow a tradition developed and honed by various goblin and kobold clans that favored tactics involving swarming warriors. The tradition combines tactical disciplines designed to encourage groups to work as one unit with practical strategies for enhancing allies. Where many warrior-monks view ki as a power best kept within, the Way of Concordant Motion teaches it…"},{"name":"Way of the Dragon","desc":"You have studied at a monastery devoted to dragonkind. Warriors trained in these places adapt their fighting styles to match the dragons they hold in such esteem. They are respected and feared by students of other traditions. Once they are trained, followers of this Way travel far and wide, rarely settling in one place for long."},{"name":"Way of the Humble Elephant","desc":"Like their namesake, monks of the Way of the Humble Elephant are respectful and accommodating. A large part of their training involves traveling through their home region and assisting local farmers and common folk with problems ranging from rebuilding burned homes to dispatching troublesome bandits. In areas where their Way is known, adherents are welcomed into the community and their needs ar…"},{"name":"Way of the Still Waters","desc":"Monks who follow the Way of the Still Waters are like placid mountain lakes; they are still and calm until some outside force disrupts them and forces a reaction. Many adherents live a pacifistic lifestyle and never seek conflict. When strife finds them, though, they deal with it in a swift and decisive use of power and grace."},{"name":"Way of the Tipsy Monkey","desc":"Monks who practice the Way of the Tipsy Monkey lurch and waddle across the battlefield, seeming to be too intoxicated to comport themselves. Their school of fighting is typified by its low-standing stance, periods of swaying in place punctuated with bursts of wild, staggering movement, and the disorienting manner in which they seem to never be in the place they appear to be standing."},{"name":"Way of the Unerring Arrow","desc":"The inner peace of contemplation, the artistry of focused breathing, and the calm awareness which leads to pinpoint accuracy all contribute to the Way of the Unerring Arrow. Some are dedicated soldiers, others walk the path of a wandering warrior-mendicant, but all of them hone their art of self-control, spirituality, and the martial arts, combining unarmed combat with archery. Select this trad…"},{"name":"Way of the Wildcat","desc":"Monks of the Wildcat train relentlessly to incorporate speed, acrobatics, and precision strikes to exert control over the field of battle and foes alike. They learn techniques that emulate the grace and agility of felines, including reflexively avoiding blows and bounding between opponents with ease. Embodying the Way of the Wildcat requires intense devotion, endless practice, and no small amou…"},{"name":"Way of the Cerulean Spirit","desc":"To become a Cerulean Spirit is to give one’s self to the quest for unveiling life’s mysteries, bringing light to the secrets of the dark, and guarding the most powerful and dangerous of truths from those who would seek to pervert the sanctity of civilization."}],"armor":["None"],"weapons":["Simple weapons","shortswords"],"description":"Unarmored Defense","source":"5e Core Rules","license":"http://open5e.com/legal"},{"system":"5e","slug":"paladin","name":"Paladin","hitDie":10,"keyAbilities":["str"],"saves":["wis","cha"],"skillCount":2,"skillChoices":["Athletics","Insight","Intimidation","Medicine","Persuasion","and Religion"],"caster":"cha","subclasses":[{"name":"Oath of Devotion","desc":"The Oath of Devotion binds a paladin to the loftiest ideals of justice, virtue, and order. Sometimes called cavaliers, white knights, or holy warriors, these paladins meet the ideal of the knight in shining armor, acting with honor in pursuit of justice and the greater good. They hold themselves to the highest standards of conduct, and some, for better or worse, hold the rest of the world to th…"},{"name":"Oathless Betrayer","desc":"Those who fall from the loftiest heights may reach the darkest depths. A paladin who breaks their oath and turns their back on redemption may instead pledge themselves to a dark power or cause. Sometimes known as antipaladins, such betrayers may gain abilities in a mockery of their former goodness, spreading evil where once they fought for the cause of right."},{"name":"Oath of Justice","desc":"The Oath of Justice is a commitment not to the tenets of good or evil but a holy vow sworn to uphold the laws of a nation, a city, or even a tiny village. When lawlessness threatens the peace, those who swear to uphold the Oath of Justice intervene to maintain order, for if order falls to lawlessness, it is only a matter of time before all of civilization collapses into anarchy."},{"name":"Oath of Safeguarding","desc":"Paladins who choose the Oath of Safeguarding spend their lives in service to others, conserving the people and places they vow to protect. They take missions to guard against assassination attempts, safely transport a person or group through treacherous lands, and stand as bastions for locations under attack. These paladins are no mere mercenaries, however, as they view their missions as sacred…"},{"name":"Oath of the Elements","desc":"The Oath of the Elements is taken by those paladins who have dedicated their lives to serving the awakened spirits of air, earth, fire, and water. Such paladins might also serve a genie, elemental deity, or other powerful elemental creature."},{"name":"Oath of the Guardian","desc":"A paladin who takes the Oath of the Guardian is sworn to defend the community. Taking the mantle of a guardian is a solemn vow to place the needs of the many before the needs of yourself and requires constant vigilance."},{"name":"Oath of the Hearth","desc":"Paladins who swear the Oath of the Hearth endeavor to extend the comforts of home to others, by allaying the rigors of travel or simply assuring those who grow despondent of the possibility of returning home. Ironically, paladins who follow this oath remain far from home in pursuit of their goals. Their oath reflects the welcoming warmth and light provided by the hearth, and paladins following …"},{"name":"Oath of the Plaguetouched","desc":"After suffering an attack by a darakhul, you were infected with the dreaded—and generally fatal— darakhul fever. As you felt your life draining away and the grasp of eternal undeath clenching its cold fingers around your heart, you called out to any power that would answer your prayers. You pledged that you would do anything asked of you, if only you would be spared this fate worse than death."}],"armor":["All armor","shields"],"weapons":["Simple weapons","martial weapons"],"description":"Divine Sense","source":"5e Core Rules","license":"http://open5e.com/legal"},{"system":"5e","slug":"ranger","name":"Ranger","hitDie":10,"keyAbilities":["dex"],"saves":["str","dex"],"skillCount":3,"skillChoices":["Animal Handling","Athletics","Insight","Investigation","Nature","Perception","Stealth","and Survival"],"caster":"wis","subclasses":[{"name":"Hunter","desc":"Emulating the Hunter archetype means accepting your place as a bulwark between civilization and the terrors of the wilderness. As you walk the Hunter's path, you learn specialized techniques for fighting the threats you face, from rampaging ogres and hordes of orcs to towering giants and terrifying dragons."},{"name":"Beast Trainer","desc":"People have used animals in their war efforts since time immemorial. As a beast trainer, you teach animals how to fight and survive on the battlefield. You also train them to recognize and obey your allies when you aren't able to direct them. While a beast trainer can train any type of animal, they often generate a strong bond with one species and focus their training on beasts of that type."},{"name":"Grove Warden","desc":"Fiercely protective of their territory, alseid herds form close bonds with their home forests. In return for their diligent protection, the forests offer their blessings to dedicated alseid rangers. In recent years, woodsy adventurers of other races who have earned the forests' trust also received this blessing, though their numbers are scant. These Grove Wardens can tap into the living magic o…"},{"name":"Haunted Warden","desc":"It is no secret the wilds are dangerous and that many an intrepid adventurer has met an untimely end while exploring them. Haunted wardens are rangers who have come face to face with the restless spirit of one of those lost wanderers. Somehow during the course of this meeting, the yearning phantom tethers its spirit to the warden's in order to put its unfinished business to rest. Even after its…"},{"name":"Snake Speaker","desc":"Like the serpents they adore, snake speakers are highly adaptable hunters. Snakes are common throughout the world, and people who need to travel through snake-filled jungles often retain a snake speaker guide, trusting the guide to protect them from scaly poisoners."},{"name":"Spear of the Weald","desc":"The alseid have long defended the limits of their forest homes. These warriors can make a dizzying variety of ranged and melee attacks in quick succession, using ancient magic to flash across the battlefield."},{"name":"Wasteland Strider","desc":"A barren landscape wracked by chaotic magics, crawling with strange monstrosities and twisted aberrations that warp the minds of those who lay eyes upon them … you have learned to traverse these wastes and face these creatures without flinching. You patrol its boundaries and stride unseen through its harsh landscape, evading danger and protecting those who find themselves at the mercy of the ar…"}],"armor":["Light armor","medium armor","shields"],"weapons":["Simple weapons","martial weapons"],"description":"Favored Enemy","source":"5e Core Rules","license":"http://open5e.com/legal"},{"system":"5e","slug":"rogue","name":"Rogue","hitDie":8,"keyAbilities":["dex"],"saves":["dex","int"],"skillCount":4,"skillChoices":["Acrobatics","Athletics","Deception","Insight","Intimidation","Investigation","Perception","Performance","Persuasion","Sleight of Hand","and Stealth"],"caster":"none","subclasses":[{"name":"Thief","desc":"You hone your skills in the larcenous arts. Burglars, bandits, cutpurses, and other criminals typically follow this archetype, but so do rogues who prefer to think of themselves as professional treasure seekers, explorers, delvers, and investigators. In addition to improving your agility and stealth, you learn skills useful for delving into ancient ruins, reading unfamiliar languages, and using…"},{"name":"Eldritch Trickster","desc":"A rogue is not defined merely by swift reflexes, but also by a quick mind. Some rogues are even able to pick up some magical tricks during their career to complement their mundane skills. Though they lack the power of a full fledged wizard, they can apply their magic in unexpected ways, performing feats that would leave their arcane compatriots dumbfounded. An eldritch prankster may be a tradit…"},{"name":"Cat Burglar","desc":"As a cat burglar, you've honed your ability to enter closed or restricted areas, drawing upon a tradition first developed among the catfolk, who often are innately curious and driven to learn what wonders, riches, or unusual friends and foes lie beyond their reach or just out of sight. In ages past, some allowed this inquisitiveness to guide them toward a rogue's life devoted to bridging that g…"},{"name":"Dawn Blade","desc":"Even churches and temples of deities of goodness and light have need of those willing to get their hands dirty and willing to sully their honor in service of what must be done. Dawn blades are devout rogues, drawing divine power from deities of light to strike as a sudden ray of searing sunlight in the darkness. They are often considered controversial by other adherents of their faith, yet the …"},{"name":"Sapper","desc":"You focus as much on identifying the weak points of structures as on the weak points of creatures. Sappers are deployed with the soldiery to dig trenches, build bridges, and breach defenses. When troops move into a heavily defended area, it's your job to make it happen as efficiently as possible."},{"name":"Smuggler","desc":"The transport of goods, creatures, and even people can be a lucrative business, particularly if you know how to avoid expensive import and export taxes, bridge, highway, and port tolls, and other legal requirements. Exotic poisons from far-off locales, banned or cursed magic items, and illicit drugs or bootleg liquor all fetch a high price on the black market. Thieves- guilds, pirates, and crim…"},{"name":"Soulspy","desc":"In the eternal war between good and evil, between light and darkness, between life and death, there are many types of participants on each side. Soulspies are agents of the divine who lurk in the shadows, taking a less-visible role in the fight. Occasionally, they aid other agents of their deities, but most often they locate and manage or eliminate threats to their deities that more scrupulous …"},{"name":"Underfoot","desc":"Though most rogues prefer ambushing their opponents from the shadows, erina rogues ambush their opponents from below. These Underfoot use druidic magic and their natural aptitude for burrowing to defend their forest homes. The Underfoot are an elite order of burrow warriors in every erina colony. Using a combination of guerilla attacks and druidic magic, they are a force to be reckoned with, di…"}],"armor":["Light armor"],"weapons":["Simple weapons","hand crossbows","longswords","rapiers","shortswords"],"description":"Expertise","source":"5e Core Rules","license":"http://open5e.com/legal"},{"system":"5e","slug":"sorcerer","name":"Sorcerer","hitDie":6,"keyAbilities":["cha"],"saves":["con","cha"],"skillCount":2,"skillChoices":["Arcana","Deception","Insight","Intimidation","Persuasion","and Religion"],"caster":"cha","subclasses":[{"name":"Draconic Bloodline","desc":"Your innate magic comes from draconic magic that was mingled with your blood or that of your ancestors. Most often, sorcerers with this origin trace their descent back to a mighty sorcerer of ancient times who made a bargain with a dragon or who might even have claimed a dragon parent. Some of these bloodlines are well established in the world, but most are obscure. Any given sorcerer could be …"},{"name":"Wyrd Magic","desc":"Sorcerers have a gift. Unlike wizards who have to study magic, or warlocks who must bargain for it, sorcerers have magic in their blood. However, sometimes this magic surges out of its own accord in unpredictable ways. Sorcerers with a wyrd bloodline may derive it from a powerful chaotic force, perhaps the Elemental Chaos itself. They may suffer a curse of fate, or some creature’s idea of a ble…"},{"name":"Cold-Blooded","desc":"The serpentfolk slithered across the surface of the world in the primordial times before the warmblooded races became dominant. They worked their will upon the land and ocean and created works to show their mastery of the magical arts. Their artistry did not end with the landscape. They also experimented on any warm-blooded creatures they captured until they had warped and molded the creatures …"},{"name":"Hungering","desc":"Your innate magic comes from a deep, primal source of hunger and craving. Perhaps your line was cursed for its greed by a god of plenty or generosity. Perhaps one of your forebears was marked by the hungering undead. Sorcerers with this origin have an unyielding appetite for arcana and go to nearly any length to satiate their desire to increase their magical power."},{"name":"Resonant Body","desc":"You are a conduit for the power that exists in sounds and vibrations, your body a living tuning fork capable of emitting, focusing, muting, and transmuting sound and sonic forms of magic. Perhaps you endured overexposure to transmutation magic, arcane thunder, or the ear-splitting cries of an androsphinx, bukavac (see Tome of Beasts), or avalanche screamer (see Tome of Beasts 2). Maybe you can …"},{"name":"Rifthopper","desc":"Rifthoppers are the living embodiment of wanderlust. The yearn to travel and witness unseen vistas burns in them and manifests in their ability to move nearly at the speed of thought. The origin of the rifthoppers' powers remains a mystery, as they refuse to stay in one place long enough to be studied extensively. Given the lack of empirical evidence, many scholars have hypothesized that riftho…"},{"name":"Spore Sorcery","desc":"One of the most omnipresent elements in the atmosphere is practically invisible and often ignored: spores. Plants of all varieties, fungal sentient life forms like mushroomfolk, and even animals emit these tiny pieces of life. You've always had an affinity for the natural world, and your innate magic is carried within the power of these omnipresent spores."},{"name":"Wastelander","desc":"Eldritch power and residual magical energy left over from a horrific arcane war is drawn to you as a lodestone is drawn to iron. Perhaps this attraction is due to a pact one of your ancestors made with an ancient eldritch horror. Perhaps it is an unfortunate twist of circumstance. Regardless, your physiology is in a constant state of transformation as a result of your condition. Some sorcerers …"},{"name":"Runechild","desc":"The weave and flow of magic is mysterious and feared by many. Many study the nature of the arcane in hopes of learning to harness it, while sorcerers carry innate talent to sculpt and wield the errant strands of power that shape the world. Some sorcerers occasionally find their body itself becomes a conduit for such energies, their flesh collecting and storing remnants of their magic in the for…"}],"armor":["None"],"weapons":["Daggers","darts","slings","quarterstaffs","light crossbows"],"description":"Spellcasting","source":"5e Core Rules","license":"http://open5e.com/legal"},{"system":"5e","slug":"warlock","name":"Warlock","hitDie":8,"keyAbilities":["cha"],"saves":["wis","cha"],"skillCount":2,"skillChoices":["Arcana","Deception","History","Intimidation","Investigation","Nature","and Religion"],"caster":"cha","subclasses":[{"name":"The Fiend","desc":"You have made a pact with a fiend from the lower planes of existence, a being whose aims are evil, even if you strive against those aims. Such beings desire the corruption or destruction of all things, ultimately including you. Fiends powerful enough to forge a pact include demon lords such as Demogorgon, Orcus, Fraz'Urb-luu, and Baphomet; archdevils such as Asmodeus, Dispater, Mephistopheles, …"},{"name":"The Ancient Fey Court","desc":"Compare to the core book’s Pact of the Archfey"},{"name":"The Great Elder Thing","desc":"Your patron, if you can call it that, is an alien mind from a far realm beyond the multiverse as we know it. Not evil per se, its motives are incomprehensible to the understanding of mortals. It might see you as a tool to further these strange aims, bidding you on seemingly unconnected but always unsettling errands. Or, you might tap into its unspeakable power without so much as gaining the not…"},{"name":"Ancient Dragons","desc":"You have made a pact with one or more ancient dragons or a dragon god. You wield a measure of their control over the elements and have insight into their deep mysteries. As your power and connection to your patron or patrons grows, you take on more draconic features, even sprouting scales and wings."},{"name":"Animal Lords","desc":"While humanoids have vast pantheons and divine figures of every stripe, the animals of the world have much simpler forms of faith. Among each species there is always one paragon that embodies the animal spirit in a humanoid form, the better to speak to others and represent the animals in the fey courts and the Upper Planes. These timeless entities are connected to every animal of the kind they …"},{"name":"Hunter in Darkness","desc":"The Hunter in Darkness is an entity that sees all creatures as prey and enjoys instilling fear in its prey. It prefers intelligent prey over mere beasts, as their fear tastes so much sweeter. Hunters who display impressive prowess for hunting pique its interest. The Hunter in Darkness often bestows its power on such individuals to spread fear further than the Hunter can by itself."},{"name":"Old Wood","desc":"You have made a pact with the ancient intelligence of a primeval forest. Before the rise of human civilization, before the time of the elves, before even the dragons, there were the forests. Empires rise and fall around them, but the forests remain as a testament to nature's endurance."},{"name":"Primordial","desc":"Some who search for power settle on lesser gods or demon lords, others delve into deeper mysteries until they touch elder entities. These great entities build worlds, crafting mountains and species as if sculpting clay, or annihilate them utterly. Embodying creation, destruction, and the land itself, your patron is an ancient power beyond mortal understanding."},{"name":"Wyrdweaver","desc":"Your patron is probability itself, the personified wellspring of chance as embodied by chosen deities, entities, and eldritch beings across the planes. By binding yourself to the Wyrdweaver, you live by the roll of the dice and the flip of the coin, delighting in the randomness of life and the thrill of new experiences. You might find yourself driven to invade a lich's keep to ask it about its …"}],"armor":["Light armor"],"weapons":["Simple weapons"],"description":"Otherworldly Patron","source":"5e Core Rules","license":"http://open5e.com/legal"},{"system":"5e","slug":"wizard","name":"Wizard","hitDie":6,"keyAbilities":["int"],"saves":["int","wis"],"skillCount":2,"skillChoices":["Arcana","History","Insight","Investigation","Medicine","and Religion"],"caster":"int","subclasses":[{"name":"School of Evocation","desc":"You focus your study on magic that creates powerful elemental effects such as bitter cold, searing flame, rolling thunder, crackling lightning, and burning acid. Some evokers find employment in military forces, serving as artillery to blast enemy armies from afar. Others use their spectacular power to protect the weak, while some seek their own gain as bandits, adventurers, or aspiring tyrants."},{"name":"School of Divining and Soothsaying","desc":"Divination is said to be the oldest of the magical arts as it defends against mortals’ greatest fear: that of the unknown. Necromancy, pyromancy, geomancy, all come from manteia, different methods of seeing that which cannot be seen by normal means. So, whether you are reading tea leaves or interpreting charred scapula bones, your magic allows you to perceive things beyond the normal boundaries…"},{"name":"School of Illusions and Phantasms","desc":"An illusionist calls forth phantom images and sounds from the plane of shadow to deceive the minds of the unwary. They can create the appearance of an object where none is, and they can also hide real creatures and objects from sight. They can dazzle and disorient with flashes of color, or call forth a target’s deepest inner fears. Practitioners of illusions and phantasms are often some of the …"},{"name":"School of Necrotic Arts","desc":"Compare to the core book’s school of Necromancy"},{"name":"Cantrip Adept","desc":"It's easy to dismiss the humble cantrip as nothing more than an unsophisticated spell practiced by hedge wizards that proper mages need not focus on. But clever and cautious wizards sometimes specialize in such spells because while other mages fret when they're depleted of arcane resources, Cantrip Adepts hardly even notice … and at their command, the cantrips are not so humble."},{"name":"Courser Mage","desc":"A tradition more focused on stalking prey than reading dozens of books, courser mages generally choose more subtle spells that aid in finding or hiding from their enemies. They learn to imbue their arrows with spell energy to deliver more deadly shots."},{"name":"Familiar Master","desc":"Each wizard has a strong connection with their familiar, but some mages eschew specializing in a school of magic in favor of forming a powerful bond with a familiar. This bond allows the two to work in tandem in ways that few arcane practitioners could even dream of. Those who encounter such a familiar never look at a rodent or bird the same way again."},{"name":"Gravebinding","desc":"While most wizards who desire power over the dead focus their efforts on necromancy, there are other, rarer, paths one can choose. Gravebinders focus their efforts on safeguarding tombs and graveyards to ensure the dead remain at rest and the living remain safe from the dead. When undead rise to prey upon the living, a gravebinder hunts downs the abominations and returns them to their eternal s…"},{"name":"School of Liminality","desc":"Liminal spaces are spaces on the boundary, at the edge between what's real and what's unreal. A liminal space can be neither here nor there, and yet be both here and there at the same time. Stories of liminal spaces are common across cultures, though their true nature often isn't recognized by the uninitiated: the stranger who appears suddenly at a lonely crossroads, the troll that snatches at …"},{"name":"Spellsmith","desc":"Some wizards pride themselves on being spell artisans, carefully sculpting the magical energy of spells like smiths sculpt iron. Focusing on the artistry inherent in spellcasting, these wizards learn to tap the magical energy of spells and manipulate that energy to amplify or modify spells like no other arcane practitioners."}],"armor":["None"],"weapons":["Daggers","darts","slings","quarterstaffs","light crossbows"],"description":"Spellcasting","source":"5e Core Rules","license":"http://open5e.com/legal"}] \ No newline at end of file diff --git a/src/data/srd/feats.json b/src/data/srd/feats.json new file mode 100644 index 0000000..3d4501b --- /dev/null +++ b/src/data/srd/feats.json @@ -0,0 +1 @@ +[{"slug":"ace-driver","name":"Ace Driver","desc":"You are a virtuoso of driving and piloting vehicles, able to push them beyond their normal limits and maneuver them with fluid grace through hazardous situations. You gain the following benefits:","prerequisite":"Prerequisite: Proficiency with a type of vehicle"},{"slug":"athletic","name":"Athletic","desc":"Your enhanced physical training grants you the following benefits:","prerequisite":""},{"slug":"attentive","name":"Attentive","desc":"Always aware of your surroundings, you gain the following benefits:","prerequisite":""},{"slug":"battle-caster","name":"Battle Caster","desc":"You're comfortable casting, even in the chaos of battle.","prerequisite":"Requires the ability to cast at least one spell of 1st-level or higher"},{"slug":"boundless-reserves","name":"Boundless Reserves","desc":"You have learned to harness your inner vitality to replenish your ki. You gain the following benefits:","prerequisite":"*Wisdom 13 or higher and the Ki class feature*"},{"slug":"brutal-attack","name":"Brutal Attack","desc":"After making a melee attack, you may reroll any weapon damage and choose the better result. This feat can be used no more than once per turn.","prerequisite":""},{"slug":"bull-rush","name":"Bull Rush","desc":"Your headlong rush devastates your foes.","prerequisite":""},{"slug":"combat-thievery","name":"Combat Thievery","desc":"You know how to trade blows for more than inflicting harm.","prerequisite":""},{"slug":"covert-training","name":"Covert Training","desc":"You have absorbed some of the lessons of the world of spies, criminals, and others who operate in the shadows. You gain the following benefits:","prerequisite":""},{"slug":"crafting-expert","name":"Crafting Expert","desc":"You have devoted time to studying and practicing the art of crafting, gaining the following benefits:","prerequisite":""},{"slug":"crossbow-expertise","name":"Crossbow Expertise","desc":"Crossbows are lethal in your hands.","prerequisite":""},{"slug":"deadeye","name":"Deadeye","desc":"Your natural talent or skill makes you lethal with a ranged weapon.","prerequisite":"Prerequisite: 8th level or higher"},{"slug":"deflector","name":"Deflector","desc":"Your lightning reflexes make you hard to hit.","prerequisite":"Prerequisite: Dexterity 13 or higher"},{"slug":"destinys-call","name":"Destiny's Call","desc":"You are more in tune with the nature of who you truly are and what you can become.","prerequisite":""},{"slug":"diehard","name":"Diehard","desc":"You are difficult to wear down and kill. You gain the following benefits:","prerequisite":"*Constitution 13 or higher*"},{"slug":"dual-wielding-expert","name":"Dual-Wielding Expert","desc":"You are a whirlwind of steel.","prerequisite":""},{"slug":"dungeoneer","name":"Dungeoneer","desc":"You've honed your senses to subterranean danger and opportunity.","prerequisite":""},{"slug":"empathic","name":"Empathic","desc":"You have a heightened awareness of the feelings and motivations of those around you.","prerequisite":""},{"slug":"fear-breaker","name":"Fear Breaker","desc":"You have a habit of snatching victory from the jaws of defeat. You gain the following benefits:","prerequisite":""},{"slug":"floriographer","name":"Floriographer","desc":"You have studied the secret language of Floriography. You gain the following benefits:","prerequisite":"*Proficiency in one of the following skills: Arcana, History, or Nature*"},{"slug":"forest-denizen","name":"Forest Denizen","desc":"You are familiar with the ways of the forest. You gain the following benefits:","prerequisite":"*N/A*"},{"slug":"fortunate","name":"Fortunate","desc":"Be it the gods, fate, or dumb luck, something is looking out for you.","prerequisite":""},{"slug":"friend-of-the-forest","name":"Friend of the Forest","desc":"After spending some time in forests, you have attuned yourself to the ways of the woods and the creatures in it.","prerequisite":"*N/A*"},{"slug":"giant-foe","name":"Giant Foe","desc":"Your experience fighting giants, such as ogres, trolls, and frost giants, has taught you how to avoid their deadliest blows and how to wield mighty weapons to better combat them. You gain the following benefits:","prerequisite":"*A Small or smaller race*"},{"slug":"grappler","name":"Grappler","desc":"You've developed the skills necessary to hold your own in close-quarters grappling. You gain the following benefits:","prerequisite":"Prerequisite: Strength 13 or higher"},{"slug":"guarded-warrior","name":"Guarded Warrior","desc":"You punish foes that try to target your allies.","prerequisite":""},{"slug":"hardy-adventurer","name":"Hardy Adventurer","desc":"You can endure punishment that would break lesser beings.","prerequisite":""},{"slug":"harrier","name":"Harrier","desc":"You have learned to maximize the strategic impact of your misty step. You appear in a flash and, while your foe is disoriented, attack with deadly precision. You gain the following benefits:","prerequisite":"*The Shadow Traveler shadow fey trait or the ability to cast the* misty step *spell*"},{"slug":"heavily-outfitted","name":"Heavily Outfitted","desc":"You have learned to fight in heavy armor","prerequisite":"Requires proficiency with medium armor"},{"slug":"heavy-armor-expertise","name":"Heavy Armor Expertise","desc":"Plate and chain are your fortress.","prerequisite":"Requires proficiency with heavy armor"},{"slug":"heraldic-training","name":"Heraldic Training","desc":"You have studied the specialized techniques used by the divine agents known as heralds. You gain the following benefits:","prerequisite":""},{"slug":"idealistic-leader","name":"Idealistic Leader","desc":"The strength of your principles inspires others to follow you with impressive dedication that makes up for whatever your stronghold lacks. You gain the following benefits:","prerequisite":""},{"slug":"inner-resilience","name":"Inner Resilience","desc":"Your internal discipline gives you access to a small pool of ki points. You gain the following benefits:","prerequisite":"*Wisdom 13 or higher*"},{"slug":"intuitive","name":"Intuitive","desc":"You've trained your powers of observation to nearly superhuman levels.","prerequisite":""},{"slug":"keen-intellect","name":"Keen Intellect","desc":"Your mind is a formidable weapon.","prerequisite":""},{"slug":"lightly-outfitted","name":"Lightly Outfitted","desc":"You've learned to fight in light armor.","prerequisite":""},{"slug":"linguistics-expert","name":"Linguistics Expert","desc":"Your gift for languages borders on the supernatural.","prerequisite":""},{"slug":"martial-scholar","name":"Martial Scholar","desc":"You have taken the time to learn some advanced combat techniques. You gain the following benefits:","prerequisite":"Prerequisite: Proficiency with at least one martial weapon"},{"slug":"medium-armor-expert","name":"Medium Armor Expert","desc":"Medium armor is like a second skin for you.","prerequisite":"Requires proficiency with medium armor."},{"slug":"moderately-outfitted","name":"Moderately Outfitted","desc":"","prerequisite":"Requires proficiency with light armor"},{"slug":"monster-hunter","name":"Monster Hunter","desc":"You are a peerless slayer of beasts most foul. You gain the following benefits:","prerequisite":"Prerequisite: Proficiency with Survival, 8th level or higher"},{"slug":"mounted-warrior","name":"Mounted Warrior","desc":"You fight as if you were born to the saddle.","prerequisite":""},{"slug":"mystical-talent","name":"Mystical Talent","desc":"You've learned to channel the spark of magic in you.","prerequisite":""},{"slug":"natural-warrior","name":"Natural Warrior","desc":"The urge to fight runs hot in your veins and you take to battle naturally. You gain the following benefits:","prerequisite":""},{"slug":"part-of-the-pack","name":"Part of the Pack","desc":"Wolves are never seen to be far from your side and consider you to be a packmate. You gain the following benefits:","prerequisite":"*Proficiency in the Animal Handling skill*"},{"slug":"physician","name":"Physician","desc":"Your mastery of mundane healing arts borders on the mystical.","prerequisite":""},{"slug":"polearm-savant","name":"Polearm Savant","desc":"You've honed fighting with hafted weapons, including glaives, halberds, pikes, quarterstaffs, or any other similar weapons.","prerequisite":""},{"slug":"power-caster","name":"Power Caster","desc":"","prerequisite":"Requires the ability to cast one spell"},{"slug":"powerful-attacker","name":"Powerful Attacker","desc":"You reap a bloody harvest with a two-handed weapon.","prerequisite":""},{"slug":"primordial-caster","name":"Primordial Caster","desc":"Your blood seethes with elemental power.","prerequisite":"Requires the ability to cast one spell."},{"slug":"rallying-speaker","name":"Rallying Speaker","desc":"Your words can set even the coldest hearts ablaze.","prerequisite":"Requires Charisma 13"},{"slug":"rapid-drinker","name":"Rapid Drinker","desc":"Through a lifestyle of hard, competitive drinking, you’ve learned how to quaff drinks at an incredibly accelerated pace. You gain the following benefits:","prerequisite":"*N/A*"},{"slug":"resonant-bond","name":"Resonant Bond","desc":"You lose resonance with an item if another creature attunes to it or gains resonance with it. You can also voluntarily end the resonance by focusing on the item during a short rest, or during a long rest if the item is not in your possession.","prerequisite":"You're able to form a greater bond with magic items. During a short rest, you can focus on a non-consumable magic item and create a unique bond with it called resonance. You can have resonance with only one item at a time. Attempting to resonate with another item fails until you end the resonance with your current item. When you resonate with an item, you gain the following benefits:"},{"slug":"rimecaster","name":"Rimecaster","desc":"You are from an area with a cold climate and have learned to adapt your magic to reflect your heritage. You gain the following benefits:","prerequisite":"*A race or background from a cold climate and the ability to cast at least one spell*"},{"slug":"rite-master","name":"Rite Master","desc":"You have delved into ancient mysteries.","prerequisite":"Requires intelligence or Wisdom 13 or higher"},{"slug":"shield-focus","name":"Shield Focus","desc":"A shield is a nearly impassable barrier in your hands.","prerequisite":""},{"slug":"skillful","name":"Skillful","desc":"Your versatility makes you an asset in nearly any situation.","prerequisite":""},{"slug":"skirmisher","name":"Skirmisher","desc":"You are as swift and elusive as the wind.","prerequisite":""},{"slug":"sorcerous-vigor","name":"Sorcerous Vigor","desc":"When your magical reserves are low, you can call on your lifeforce to fuel your magic.","prerequisite":"*Charisma 13 or higher and the Sorcery Points class feature*"},{"slug":"spellbreaker","name":"Spellbreaker","desc":"You are a terrifying foe to enemy spellcasters.","prerequisite":""},{"slug":"stalker","name":"Stalker","desc":"You are an expert at hunting prey. You are never more at home than when on a hunt, and your quarry rarely escapes you. You gain the following benefits:","prerequisite":"*N/A*"},{"slug":"stalwart","name":"Stalwart","desc":"You can quickly recover from injuries that leave lesser creatures broken.","prerequisite":""},{"slug":"stealth-expert","name":"Stealth Expert","desc":"The shadows embrace you as if you were born to them.","prerequisite":"Requires Dexterity 13 or higher"},{"slug":"street-fighter","name":"Street Fighter","desc":"You've left a trail of broken opponents in the back alleys and barrooms of your home.","prerequisite":""},{"slug":"stunning-sniper","name":"Stunning Sniper","desc":"You have mastered the use of ranged weapons to cripple your target from a distance.","prerequisite":"*Proficiency with a ranged weapon*"},{"slug":"surgical-combatant","name":"Surgical Combatant","desc":"Your knowledge of anatomy and physiology is a boon to your allies and a bane to your foes. You gain the following benefits:","prerequisite":""},{"slug":"survivor","name":"Survivor","desc":"You use every last ounce of energy to survive, even in the worst of circumstances.","prerequisite":""},{"slug":"swift-combatant","name":"Swift Combatant","desc":"You are naturally quick and use that to your advantage in battle. You gain the following benefits:","prerequisite":"Prerequisite: 8th level or higher"},{"slug":"tactical-support","name":"Tactical Support","desc":"Your tactical expertise gives your allies an edge in combat.","prerequisite":""},{"slug":"tenacious","name":"Tenacious","desc":"","prerequisite":"Choose an attribute and raise it by 1, up to the attribute cap of 20, and become proficient with saving throws using the selected attribute."},{"slug":"thespian","name":"Thespian","desc":"Your mastery of the dramatic arts is useful both on and off the stage.","prerequisite":""},{"slug":"weapons-specialist","name":"Weapons Specialist","desc":"Nearly any weapon is lethal in your hands.","prerequisite":""},{"slug":"well-heeled","name":"Well-Heeled","desc":"You can maneuver effortlessly through the corridors of power and prestige. You gain the following benefits:","prerequisite":"Prerequisite: Prestige rating of 2 or higher"},{"slug":"woodcraft-training","name":"Woodcraft Training","desc":"You have learned to survive in the wilds, a useful skill for almost any adventurer. You gain the following benefits:","prerequisite":""}] \ No newline at end of file diff --git a/src/data/srd/races.json b/src/data/srd/races.json new file mode 100644 index 0000000..cf95c20 --- /dev/null +++ b/src/data/srd/races.json @@ -0,0 +1 @@ +[{"slug":"alseid","name":"Alseid","desc":"Alseid Traits","asi":"***Ability Score Increase.*** Your Dexterity score increases by 2, and your Wisdom score increases by 1.","speed":"***Speed.*** Alseid are fast for their size, with a base walking speed of 40 feet.","vision":"***Darkvision.*** Accustomed to the limited light beneath the forest canopy, you have superior vision in dark and dim conditions. You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Alseid Weapon Training. You have proficiency with spears and shortbows."},{"slug":"catfolk","name":"Catfolk","desc":"Catfolk Traits","asi":"***Ability Score Increase.*** Your Dexterity score increases by 2.","speed":"***Speed.*** Your base walking speed is 30 feet.","vision":"***Darkvision.*** You have a cat's keen senses, especially in the dark. You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Cat's Claws. Your sharp claws can cut with ease. Your claws are natural melee weapons, which you can use to make unarmed strikes. When you hit with a claw, your claw deals slashing damage equal to 1d4 + your Strength modifier, instead of the bludgeoning damage normal for an unarmed strike."},{"slug":"darakhul","name":"Darakhul","desc":"Darakhul Traits","asi":"***Ability Score Increase.*** Your Constitution score increases by 1.","speed":"***Speed.*** Your base walking speed is determined by your Heritage Subrace.","vision":"***Darkvision.*** You can see in dim light within 60 feet as though it were bright light and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Hunger for Flesh. You must consume 1 pound of raw meat each day or suffer the effects of starvation. If you go 24 hours without such a meal, you gain one level of exhaustion. While you have any levels of exhaustion from this trait, you can't regain hit points or remove levels of exhaustion until you spend at least 1 hour consuming 10 pounds of raw meat."},{"slug":"derro","name":"Derro","desc":"Derro Traits","asi":"***Ability Score Increase.*** Your Dexterity score increases by 2.","speed":"***Speed.*** Derro are fast for their size. Your base walking speed is 30 feet.","vision":"***Superior Darkvision.*** Accustomed to life underground, you can see in dim light within 120 feet of you as if it were bright light, and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Eldritch Resilience. You have advantage on Constitution saving throws against spells."},{"slug":"dragonborn","name":"Dragonborn","desc":"Dragonborn Traits","asi":"**_Ability Score Increase._** Your Strength score increases by 2, and your Charisma score increases by 1.","speed":"**_Speed._** Your base walking speed is 30 feet.","vision":"","traits":"Draconic Ancestry"},{"slug":"drow","name":"Drow","desc":"Drow Traits","asi":"***Ability Score Increase.*** Your Intelligence score increases by 2.","speed":"***Speed.*** Your base walking speed is 30 feet.","vision":"***Superior Darkvision.*** Accustomed to life in the darkest depths of the world, you can see in dim light within 120 feet of you as if it were bright light, and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Fey Ancestry. You have advantage on saving throws against being charmed, and magic can't put you to sleep."},{"slug":"dwarf","name":"Dwarf","desc":"Dwarf Traits","asi":"**_Ability Score Increase._** Your Constitution score increases by 2.","speed":"**_Speed._** Your base walking speed is 25 feet. Your speed is not reduced by wearing heavy armor.","vision":"**_Darkvision._** Accustomed to life underground, you have superior vision in dark and dim conditions. You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Dwarven Resilience. You have advantage on saving throws against poison, and you have resistance against poison damage."},{"slug":"elf","name":"Elf","desc":"Elf Traits","asi":"**_Ability Score Increase._** Your Dexterity score increases by 2.","speed":"**_Speed._** Your base walking speed is 30 feet.","vision":"**_Darkvision._** Accustomed to twilit forests and the night sky, you have superior vision in dark and dim conditions. You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Keen Senses. You have proficiency in the Perception skill."},{"slug":"erina","name":"Erina","desc":"Erina Traits","asi":"***Ability Score Increase.*** Your Dexterity score increases by 2, and you can choose to increase either your Wisdom or Charisma score by 1.","speed":"***Speed.*** Your base walking speed is 25 feet.","vision":"***Darkvision.*** Accustomed to life in the dark burrows of your people, you have superior vision in dark and dim conditions. You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Hardy. The erina diet of snakes and venomous insects has made them hardy. You have advantage on saving throws against poison, and you have resistance against poison damage."},{"slug":"gearforged","name":"Gearforged","desc":"Gearforged Traits","asi":"***Ability Score Increase.*** Two different ability scores of your choice increase by 1.","speed":"***Speed.*** Your base walking speed is determined by your Race Chassis.","vision":"","traits":"Construct Resilience. Your body is constructed, which frees you from some of the limits of fleshand- blood creatures. You have resistance to poison damage, you are immune to disease, and you have advantage on saving throws against being poisoned."},{"slug":"gnome","name":"Gnome","desc":"Gnome Traits","asi":"**_Ability Score Increase._** Your Intelligence score increases by 2.","speed":"**_Speed._** Your base walking speed is 25 feet.","vision":"**_Darkvision._** Accustomed to life underground, you have superior vision in dark and dim conditions. You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Gnome Cunning. You have advantage on all Intelligence, Wisdom, and Charisma saving throws against magic."},{"slug":"half-elf","name":"Half-Elf","desc":"Half-Elf Traits","asi":"**_Ability Score Increase._** Your Charisma score increases by 2, and two other ability scores of your choice increase by 1.","speed":"**_Speed._** Your base walking speed is 30 feet.","vision":"**_Darkvision._** Thanks to your elf blood, you have superior vision in dark and dim conditions. You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Fey Ancestry. You have advantage on saving throws against being charmed, and magic can't put you to sleep."},{"slug":"half-orc","name":"Half-Orc","desc":"Half-Orc Traits","asi":"**_Ability Score Increase._** Your Strength score increases by 2, and your Constitution score increases by 1.","speed":"**_Speed._** Your base walking speed is 30 feet.","vision":"**_Darkvision._** Thanks to your orc blood, you have superior vision in dark and dim conditions. You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Menacing. You gain proficiency in the Intimidation skill."},{"slug":"halfling","name":"Halfling","desc":"Halfling Traits","asi":"**_Ability Score Increase._** Your Dexterity score increases by 2.","speed":"**_Speed._** Your base walking speed is 25 feet.","vision":"","traits":"Lucky. When you roll a 1 on the d20 for an attack roll, ability check, or saving throw, you can reroll the die and must use the new roll."},{"slug":"human","name":"Human","desc":"Human Traits","asi":"**_Ability Score Increase._** Your ability scores each increase by 1.","speed":"**_Speed._** Your base walking speed is 30 feet.","vision":"","traits":""},{"slug":"minotaur","name":"Minotaur","desc":"Your minotaur character has certain characteristics in common with all other minotaurs.","asi":"***Ability Score Increase.*** Your Strength score increases by 2, and your Constitution score increases by 1.","speed":"***Speed.*** Your base walking speed is 30 feet.","vision":"***Darkvision.*** You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Natural Attacks. Your horns are sturdy and sharp. Your horns are a natural melee weapon, which you can use to make unarmed strikes. When you hit with your horns, they deal piercing damage equal to 1d6 + your Strength modifier, instead of the bludgeoning damage normal for an unarmed strike."},{"slug":"mushroomfolk","name":"Mushroomfolk","desc":"Your mushroomfolk character has characteristics in common with all other mushroomfolk.","asi":"***Ability Score Increase.*** Your Wisdom score increases by 2.","speed":"***Speed.*** Your base walking speed is 30 feet.","vision":"***Darkvision.*** Accustomed to life underground, you can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Fungoid Form. You are a humanoid, though the fungal nature of your body and your unique diet of decayed vegetable and animal matter marks you with some plant-like characteristics. You have advantage on saving throws against poison, and you have resistance to poison damage. In addition, you are immune to disease."},{"slug":"satarre","name":"Satarre","desc":"Your satarre heritage is apparent in a variety of traits you share with other satarre.","asi":"***Ability Score Increase.*** Your Constitution score increases by 2, and your Intelligence score increases by 1.","speed":"***Speed.*** Your base walking speed is 30 feet.","vision":"***Darkvision.*** Thanks to your dark planar parentage, you have superior vision in darkness. You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"A Friend to Death. You have resistance to necrotic damage."},{"slug":"shade","name":"Shade","desc":"Your shade character has a number of traits that arise from being a shade as well as a few drawn from life.","asi":"***Ability Score Increase.*** Your Charisma score increases by 1, and one other ability score of your choice increases by 1. Choose one ability score that is increased by your Living Origin or by one of its subraces. That ability score increases by 1.","speed":"***Speed.*** Your speed is determined by your Living Origin.","vision":"***Darkvision.*** Your existence beyond death makes you at home in the dark. You can see in dim light within 60 feet of you as if it were bright light and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Ghostly Flesh. Starting at 3rd level, you can use your action to dissolve your physical body into the ephemeral stuff of spirits. You become translucent and devoid of color, and the air around you grows cold. Your transformation lasts for 1 minute or until you end it as a bonus action. During it, you have a flying speed of 30 feet with the ability to hover, and you have resistance to bludgeoning, piercing, and slashing damage from nonmagical attacks that aren't made with silvered weapons. In …"},{"slug":"tiefling","name":"Tiefling","desc":"Tiefling Traits","asi":"**_Ability Score Increase._** Your Intelligence score increases by 1, and your Charisma score increases by 2.","speed":"**_Speed._** Your base walking speed is 30 feet.","vision":"**_Darkvision._** Thanks to your infernal heritage, you have superior vision in dark and dim conditions. You can see in dim light within 60 feet of you as if it were bright light, and in darkness as if it were dim light. You can't discern color in darkness, only shades of gray.","traits":"Hellish Resistance. You have resistance to fire damage."}] \ No newline at end of file diff --git a/src/features/compendium/details.tsx b/src/features/compendium/details.tsx index 700e3f6..dd89768 100644 --- a/src/features/compendium/details.tsx +++ b/src/features/compendium/details.tsx @@ -7,6 +7,36 @@ import type { Condition5e, CompendiumEntry, } from '@/lib/compendium/types'; +import type { RulesetClass } from '@/lib/ruleset/normalize'; + +const cap = (s: string): string => (s ? s.charAt(0).toUpperCase() + s.slice(1) : s); + +function ClassRow({ label, value }: { label: string; value: string }) { + return
{label}{value}
; +} + +export function ClassDetail({ c }: { c: RulesetClass }) { + return ( +
+ {c.description &&

{c.description}

} + + {c.keyAbilities.length > 0 && } + {c.saves.length > 0 && (c.saveRanks?.[s] ? `${cap(s)} (${c.saveRanks[s]})` : cap(s))).join(', ')} />} + {c.perception && } + + {c.caster !== 'none' && } + {c.weapons.length > 0 && } + {c.armor.length > 0 && } + {c.subclasses.length > 0 && ( +
+
{c.system === 'pf2e' ? 'Options' : 'Subclasses'}
+
    {c.subclasses.slice(0, 16).map((s) =>
  • {s.name}
  • )}
+
+ )} +

Source: {c.source}{c.license ? ` · ${c.license}` : ''}

+
+ ); +} function Header({ title, subtitle }: { title: string; subtitle?: string | undefined }) { return ( diff --git a/src/features/compendium/registry.tsx b/src/features/compendium/registry.tsx index 8274aca..5da4dd4 100644 --- a/src/features/compendium/registry.tsx +++ b/src/features/compendium/registry.tsx @@ -10,9 +10,11 @@ import { loadArmor5e, loadFeats5e, loadConditions5e, + loadClasses, loadPf2e, crLabel, } from '@/lib/compendium'; +import type { RulesetClass } from '@/lib/ruleset/normalize'; import { MonsterDetail } from './MonsterDetail'; import { Spell5eDetail, @@ -22,6 +24,7 @@ import { Feat5eDetail, Condition5eDetail, Pf2eDetail, + ClassDetail, } from './details'; export type Entry = CompendiumEntry; @@ -141,6 +144,17 @@ function pf2eCategory(id: string, label: string, file: string, opts: { level?: b }; } +function classCategory(system: SystemId): CategoryDef { + return { + id: `${system}-classes`, system, label: 'Classes', + load: () => loadClasses(system) as unknown as Promise, + searchKeys: ['name'], + meta: (e) => { const c = e as unknown as RulesetClass; return c.system === 'pf2e' ? `${c.hitDie} HP` : `d${c.hitDie}`; }, + detail: (e) => , + filters: [], + }; +} + export const CATEGORIES: CategoryDef[] = [ // ---------- D&D 5e ---------- { @@ -164,6 +178,7 @@ export const CATEGORIES: CategoryDef[] = [ { key: 'crMax', label: 'Max CR', kind: 'lte', get: (e) => e.cr as number, options: (d) => numericOptions(d, (e) => e.cr, (n) => `CR ≤ ${crNum(n)}`) }, ], }, + classCategory('5e'), { id: '5e-spells', system: '5e', label: 'Spells', linkAs: 'spell', load: () => loadSpells() as unknown as Promise, @@ -235,6 +250,7 @@ export const CATEGORIES: CategoryDef[] = [ ...(e.level !== undefined ? { level: Number(e.level) } : {}), }), }, + classCategory('pf2e'), pf2eCategory('spells', 'Spells', 'spells', { linkAs: 'spell' }), pf2eCategory('feats', 'Feats', 'feats'), pf2eCategory('equipment', 'Equipment', 'equipment', { linkAs: 'item' }), diff --git a/src/features/settings/SettingsPage.tsx b/src/features/settings/SettingsPage.tsx index 768a4fa..d5ff615 100644 --- a/src/features/settings/SettingsPage.tsx +++ b/src/features/settings/SettingsPage.tsx @@ -67,6 +67,15 @@ export function SettingsPage() { +
+

Data sources & licenses

+
    +
  • D&D 5e — SRD content via Open5e (OGL 1.0a / CC-BY-4.0).
  • +
  • Pathfinder 2e — content from the Foundry VTT pf2e project & Archives of Nethys (OGL / ORC / Paizo Community Use).
  • +
  • Map import follows the Universal VTT (.dd2vtt) format used by Dungeondraft, Foundry & others.
  • +
+
+

Danger zone

Permanently delete all campaigns and data on this device.

diff --git a/src/lib/compendium/index.ts b/src/lib/compendium/index.ts index 7989d9c..3792d9e 100644 --- a/src/lib/compendium/index.ts +++ b/src/lib/compendium/index.ts @@ -1,3 +1,5 @@ +import type { SystemId } from '@/lib/rules'; +import type { RulesetClass } from '@/lib/ruleset/normalize'; import type { Monster, Spell, @@ -78,6 +80,37 @@ export async function loadConditions5e(): Promise { return cache.get('c5e') as Condition5e[]; } +// ---- Structured ruleset classes (Open5e + Foundry pf2e; feed builder + compendium) ---- +export async function loadClasses(system: SystemId): Promise { + const key = `classes:${system}`; + if (!cache.has(key)) { + if (system === '5e') { + const mod = await import('@/data/srd/classes.json'); + cache.set(key, mod.default as unknown as RulesetClass[]); + } else { + const res = await fetch(`${import.meta.env.BASE_URL}data/pf2e/classes.json`); + cache.set(key, (res.ok ? await res.json() : []) as RulesetClass[]); + } + } + return cache.get(key) as RulesetClass[]; +} + +export async function loadRaces5e(): Promise<{ slug: string; name: string; desc: string; asi: string; speed: string; traits: string }[]> { + if (!cache.has('races5e')) { + const mod = await import('@/data/srd/races.json'); + cache.set('races5e', mod.default as unknown[]); + } + return cache.get('races5e') as { slug: string; name: string; desc: string; asi: string; speed: string; traits: string }[]; +} + +export async function loadBackgrounds5e(): Promise<{ slug: string; name: string; desc: string; skills: string; feature: string }[]> { + if (!cache.has('bg5e')) { + const mod = await import('@/data/srd/backgrounds.json'); + cache.set('bg5e', mod.default as unknown[]); + } + return cache.get('bg5e') as { slug: string; name: string; desc: string; skills: string; feature: string }[]; +} + // ---- PF2e categories (static assets fetched at runtime; large files) ---- const pf2eCache = new Map(); diff --git a/src/lib/ruleset/normalize.test.ts b/src/lib/ruleset/normalize.test.ts new file mode 100644 index 0000000..0ecd911 --- /dev/null +++ b/src/lib/ruleset/normalize.test.ts @@ -0,0 +1,55 @@ +import { describe, it, expect } from 'vitest'; +import { normalizeOpen5eClass, normalizeFoundryClass } from './normalize'; + +describe('normalizeOpen5eClass', () => { + it('parses hit die, saves, skill choices, caster and subclasses', () => { + const c = normalizeOpen5eClass({ + name: 'Wizard', slug: 'wizard', desc: '### Arcane\n\nMasters of magic.', + hit_dice: '1d6', prof_armor: 'None', prof_weapons: 'Daggers, darts, slings', + prof_saving_throws: 'Intelligence, Wisdom', + prof_skills: 'Choose two from Arcana, History, Insight, Investigation, Medicine, and Religion', + spellcasting_ability: 'Intelligence', + archetypes: [{ name: 'School of Evocation', desc: 'Boom.' }], + document__title: 'Systems Reference Document', document__license_url: 'https://...', + }); + expect(c.hitDie).toBe(6); + expect(c.keyAbilities).toEqual(['int']); + expect(c.saves).toEqual(['int', 'wis']); + expect(c.skillCount).toBe(2); + expect(c.skillChoices).toContain('Arcana'); + expect(c.caster).toBe('int'); + expect(c.subclasses[0]!.name).toBe('School of Evocation'); + expect(c.system).toBe('5e'); + }); + + it('defaults caster to none when not a spellcaster', () => { + const c = normalizeOpen5eClass({ name: 'Fighter', slug: 'fighter', hit_dice: '1d10', prof_saving_throws: 'Strength, Constitution', prof_skills: 'Choose two from Acrobatics, Athletics' }); + expect(c.caster).toBe('none'); + expect(c.keyAbilities).toEqual(['str']); + }); +}); + +describe('normalizeFoundryClass', () => { + it('maps PF2e hp/key ability/saves/proficiencies to ranks', () => { + const c = normalizeFoundryClass('fighter', { + name: 'Fighter', + system: { + hp: 10, keyAbility: { value: ['dex', 'str'] }, perception: 2, + savingThrows: { fortitude: 2, reflex: 2, will: 1 }, + trainedSkills: { value: [], additional: 3 }, + attacks: { simple: 2, martial: 2, advanced: 1, unarmed: 2, other: { name: '', rank: 0 } }, + defenses: { unarmored: 1, light: 1, medium: 1, heavy: 1 }, + description: { value: '

A master of arms.

' }, + publication: { title: 'Pathfinder Player Core', license: 'ORC' }, + }, + }); + expect(c.system).toBe('pf2e'); + expect(c.hitDie).toBe(10); + expect(c.keyAbilities).toEqual(['dex', 'str']); + expect(c.saveRanks).toEqual({ con: 'Expert', dex: 'Expert', wis: 'Trained' }); + expect(c.perception).toBe('Expert'); + expect(c.skillCount).toBe(3); + expect(c.weapons).toEqual(expect.arrayContaining(['martial', 'simple'])); + expect(c.description).toBe('A master of arms.'); + }); +}); diff --git a/src/lib/ruleset/normalize.ts b/src/lib/ruleset/normalize.ts new file mode 100644 index 0000000..c1a8a06 --- /dev/null +++ b/src/lib/ruleset/normalize.ts @@ -0,0 +1,139 @@ +/** Pure normalizers turning Open5e (5e) and Foundry PF2e raw records into our + * unified RulesetClass shape. Used by the scrapers (scripts/) and unit tests. */ + +export interface RulesetClass { + system: '5e' | 'pf2e'; + slug: string; + name: string; + /** 5e: hit-die size (e.g. 12). PF2e: HP gained per level (e.g. 10). */ + hitDie: number; + keyAbilities: string[]; + /** abilities that start proficient/trained (lowercase keys) */ + saves: string[]; + /** PF2e initial save ranks by ability */ + saveRanks?: Record; + perception?: string; + skillCount: number; + skillChoices: string[]; + /** spellcasting ability ('int'/'wis'/'cha') or 'none' */ + caster: string; + subclasses: { name: string; desc?: string }[]; + armor: string[]; + weapons: string[]; + description: string; + source: string; + license?: string; +} + +const ABBR: Record = { + strength: 'str', dexterity: 'dex', constitution: 'con', + intelligence: 'int', wisdom: 'wis', charisma: 'cha', +}; +const NUM_WORD: Record = { one: 1, two: 2, three: 3, four: 4, five: 5, six: 6 }; +const RANKS = ['Untrained', 'Trained', 'Expert', 'Master', 'Legendary']; + +/** 5e classes don't expose a "key ability"; this is the conventional primary. */ +const DND_KEY: Record = { + barbarian: 'str', bard: 'cha', cleric: 'wis', druid: 'wis', fighter: 'str', monk: 'dex', + paladin: 'str', ranger: 'dex', rogue: 'dex', sorcerer: 'cha', warlock: 'cha', wizard: 'int', +}; + +function stripMd(s: string): string { + return (s || '').replace(/[#*_`>]/g, '').replace(/\r/g, '').trim(); +} +function firstParagraph(s: string): string { + const p = stripMd(s).split('\n').map((x) => x.trim()).filter(Boolean)[0] ?? ''; + return p.length > 400 ? `${p.slice(0, 397)}…` : p; +} +function abilList(s: string | undefined): string[] { + return (s ?? '').split(/[,&]| and /).map((x) => ABBR[x.trim().toLowerCase()]).filter(Boolean) as string[]; +} + +export interface Open5eClass { + name: string; slug: string; desc?: string; hit_dice?: string; + prof_armor?: string; prof_weapons?: string; prof_saving_throws?: string; prof_skills?: string; + spellcasting_ability?: string; archetypes?: { name: string; desc?: string }[]; + document__title?: string; document__license_url?: string; +} + +export function normalizeOpen5eClass(c: Open5eClass): RulesetClass { + const hitDie = Number(/d(\d+)/.exec(c.hit_dice ?? '')?.[1]) || 8; + // "Choose two from Acrobatics, Athletics, …" + const skillsRaw = c.prof_skills ?? ''; + const countWord = /choose (\w+)/i.exec(skillsRaw)?.[1]?.toLowerCase() ?? ''; + const skillCount = NUM_WORD[countWord] ?? 2; + const fromPart = /from (.+)$/is.exec(skillsRaw)?.[1] ?? ''; + const skillChoices = fromPart.split(',').map((s) => stripMd(s).replace(/\.$/, '').trim()).filter(Boolean).slice(0, 18); + const caster = ABBR[(c.spellcasting_ability ?? '').trim().toLowerCase()] ?? 'none'; + return { + system: '5e', + slug: c.slug, + name: c.name, + hitDie, + keyAbilities: DND_KEY[c.slug] ? [DND_KEY[c.slug]!] : [], + saves: abilList(c.prof_saving_throws), + skillCount, + skillChoices, + caster, + subclasses: (c.archetypes ?? []).map((a) => ({ name: a.name, ...(a.desc ? { desc: firstParagraph(a.desc) } : {}) })), + armor: (c.prof_armor ?? '').split(',').map((x) => x.trim()).filter(Boolean), + weapons: (c.prof_weapons ?? '').split(',').map((x) => x.trim()).filter(Boolean), + description: firstParagraph(c.desc ?? ''), + source: c.document__title ?? 'Open5e', + ...(c.document__license_url ? { license: c.document__license_url } : {}), + }; +} + +export interface FoundryClass { + name: string; + system?: { + hp?: number; + keyAbility?: { value?: string[] }; + perception?: number; + savingThrows?: { fortitude?: number; reflex?: number; will?: number }; + trainedSkills?: { value?: string[]; additional?: number }; + attacks?: Record; + defenses?: Record; + description?: { value?: string }; + publication?: { title?: string; license?: string }; + }; +} + +const PF2E_SAVE_ABIL: Record = { fortitude: 'con', reflex: 'dex', will: 'wis' }; + +export function normalizeFoundryClass(slug: string, c: FoundryClass): RulesetClass { + const s = c.system ?? {}; + const saveRanks: Record = {}; + const saves: string[] = []; + for (const [k, abil] of Object.entries(PF2E_SAVE_ABIL)) { + const n = (s.savingThrows as Record | undefined)?.[k] ?? 0; + if (n > 0) { saveRanks[abil] = RANKS[Math.min(4, n)]!; saves.push(abil); } + } + const weaponProfs = Object.entries(s.attacks ?? {}) + .filter(([k, v]) => k !== 'other' && (typeof v === 'number' ? v : v?.rank ?? 0) > 0) + .map(([k]) => k); + const armorProfs = Object.entries(s.defenses ?? {}).filter(([, v]) => (v ?? 0) > 0).map(([k]) => k); + return { + system: 'pf2e', + slug, + name: c.name, + hitDie: s.hp ?? 8, + keyAbilities: s.keyAbility?.value ?? [], + saves, + saveRanks, + ...(s.perception !== undefined ? { perception: RANKS[Math.min(4, s.perception)]! } : {}), + skillCount: (s.trainedSkills?.additional ?? 0) + (s.trainedSkills?.value?.length ?? 0), + skillChoices: [], + caster: 'none', + subclasses: [], + armor: armorProfs, + weapons: weaponProfs, + description: firstParagraph(stripHtml(s.description?.value ?? '')), + source: s.publication?.title ?? 'Pathfinder 2e (Foundry VTT)', + license: s.publication?.license ?? 'OGL/ORC', + }; +} + +function stripHtml(s: string): string { + return (s || '').replace(/<[^>]+>/g, ' ').replace(/&[a-z]+;/g, ' ').replace(/\s+/g, ' ').trim(); +}