Skip to main content

dnd5e-character-builder

Build, level up and check D&D 2024 (SRD 5.2.1) character sheets in Python.

A sheet written by a person or a model is free text: "Rogue (Arcane Trickster)", "Shield — level 1, prepared". This library reads it against the rules, lists every problem at once, writes in the numbers the rules derive, and says what the character may still pick now or at the next level. It sits on nat20's rules engine and SRD corpus; nat20 decides whether a build is constructible and derives its HP, AC, saves and slots. This library adds the parts of a sheet nat20 takes as given: class spell lists, prepared and cantrip counts, wizard spellbooks, feat slots, choice counts, skills and ability-score generation.

pip install dnd5e-character-builder

Python 3.14 or later.

Use

from dnd5e_character_builder import Feat, Sheet, check, fill, level_up, options

sheet = Sheet.model_validate({
    'name': 'Ana',
    'species': 'Human',
    'class': 'Fighter',
    'level': 4,
    'subclass': 'Champion',
    'background': 'Soldier',
    'abilities': {'str': 17, 'dex': 15, 'con': 14, 'int': 8, 'wis': 12, 'cha': 10},
    'skills': ['Athletics', 'Intimidation', 'Perception', 'Survival', 'Acrobatics'],
    'feats': ['Savage Attacker', 'Alert', Feat(name='Grappler', level=4)],
    'choices': ['Defense'],
    'inventory': ['Chain Mail', 'Longsword', 'Shield'],
})

sheet = fill(sheet)            # max_hp, ac, saving_throws and spell_slots from nat20
for issue in check(sheet):     # every problem at once
    print(issue.severity, issue.code, issue.message)

options(sheet)                 # every pick at this level (subclass, feature choices, feat slots, skills, spells) and what fills it
level_up(sheet, 5)             # what level 5 gives automatically and which picks it makes due

level_up and options report; neither changes the sheet. Write the picks, then run fill and check.

build_spec(sheet) and derive(sheet) give nat20's CharacterBuildSpec and DerivedSheet for a sheet, for hosts that run nat20 combat.

The sheet

Field Holds
species, class, subclass, background Names as written. A subclass in parentheses after the class is read too.
A background the content does not know is a custom one: +2/+1 or +1/+1/+1 to any abilities, any two skills and any one origin feat.
level 1-20, one class.
abilities Final scores by str ... cha.
skills, expertise Skill names; "Stealth (expertise)" in skills also counts as Expertise.
feats Feat(name, level). level is the class level whose Ability Score Improvement the feat took; leave it None for an origin feat. A bare string is a feat with no level.
choices Class, subclass and species options by name: "Archery", "Agonizing Blast", "Protector".
spells Cantrips known and spells prepared.
spellbook A wizard's level 1+ spells.
magic_initiate One record per Magic Initiate: list, ability, two cantrips, one level 1 spell.
max_hp, ac, spell_slots, saving_throws The sheet's numbers; fill replaces them.

Issues

Each Issue has a stable code, a severity (error breaks the rules, warning is likely wrong, info is a note), the sheet field, a message and a detail dict.

Code Severity Meaning
build.rejected error nat20 cannot construct the build; its reason is in detail.reason
class.unknown, class.multiclass error No class the content knows, or more than one (multiclass is not supported yet)
species.unknown, species.missing error
subclass.unknown, subclass.missing error Not in the content, or none chosen at the subclass level
feat.unknown error Not in the content
feat.no_slot error Nothing gives this feat: no Ability Score Improvement at that level, the slot is taken, or an origin feat beyond the background's and species'
feat.level_missing info A feat in an Ability Score Improvement without the level it was taken at; it is checked against the first free one
feat.slot_empty warning An Ability Score Improvement level with no feat recorded
feat.missing warning The background's feat (a custom background's chosen origin feat) is not on the sheet
abilities.not_buildable warning Not the standard array or a 27-point buy plus the background's increase and the Ability Score Improvements taken
abilities.over_cap error Above 20 (30 with an Epic Boon)
saves.mismatch error / warning Not the class's saving throws (warning when the sheet lists none)
skills.unknown error Not a skill
skills.too_many, skills.too_few warning More or fewer than background, class, species, subclass and feats give
skills.granted_missing warning A skill given outright is not on the sheet
expertise.too_many, expertise.not_proficient error
choice.unknown, choice.too_many error Not an option this build has, or more picks than its level allows
choice.missing warning Picks still due
spell.unknown error Not in the content
spell.not_on_list error Not on the class list and nothing else grants it
spell.too_many_cantrips, spell.too_many_prepared error Over the class table; granted spells do not count
spell.above_slot error Prepared above the highest spell slot
spellbook.missing, spellbook.not_wizard_spell error Prepared but not in the book; a book entry that is not a level 1+ wizard spell
spellbook.too_few warning Fewer than 6 + 2 per level after the first
magic_initiate.not_on_list, magic_initiate.too_many error
magic_initiate.unrecorded info A Magic Initiate whose picks are not recorded
max_hp.mismatch, ac.mismatch, spell_slots.mismatch warning The sheet's number differs from the derived one
numbers.unchecked info HP, AC and slots not compared because something the derivation needs is unknown

Spells a character has without preparing them do not count against the class table: species and subclass grants, spells a feature's own text grants ("You always have the Hunter's Mark spell prepared"), the Circle of the Land table the sheet matches best, Mystic Arcanum, Magic Initiate, and the College of Lore's Magical Discoveries.

Homebrew

load_content(*paths) layers YAML or JSON files (or folders of them) over the SRD; pass the result as content= to any call. A file holds nat20-schema entries and this library's tables:

subclasses: [...]        # nat20 schema; also classes, species, backgrounds, feats, features, spells
spell_lists:             # class -> spell level -> spells added to its list; a name with no entry is known by name and level
  wizard: {1: [Chromatic Orb], 2: [Dragon's Breath]}
subclass_spells:         # always-prepared spells by class level
  oath-of-glory: {3: [Guiding Bolt, Heroism], 5: [Enhance Ability, Magic Weapon]}
subclass_spell_choices:  # one table per option, as Circle of the Land
  circle-of-the-reef: {shallows: {3: [Fog Cloud, Water Breathing]}}
class_tables:            # cantrips and prepared per level, 20 each; a casting subclass also names progression and spell_list
  eldritch-knight: {cantrips: [...], prepared: [...], progression: third, spell_list: wizard}
aliases:
  subclasses: {glory: oath-of-glory}

A path may also be a mapping of the same shape. load_content(loader=...) builds on your own nat20 AssetLoader instead of nat20's bundled corpus.

Loading refuses anything the library could not check, with a ContentError naming it: a spellcasting class without a table or spell list, a subclass with a Spellcasting feature and no table, a subclass whose spells feature grants no spells, a spell listed at the wrong level, an alias to nothing. Entries without nat20 provenance get a placeholder one so they pass nat20's schema.

Limits

Single class only; see BACKLOG.md for the rest.

Data and attribution

  • Rules engine and SRD corpus: nat20 (dnd5e-engine, dnd5e-srd-data), MIT.
  • Class spell lists and the Cantrips and Prepared Spells columns: 5e-SRD-Spells.json and 5e-SRD-Levels.json from 5e-database (src/2024/en, commit 6f6299e), MIT, vendored unchanged in src/dnd5e_character_builder/data/5e-database with its licence. Two columns are corrected from the SRD in data/srd.yaml.
  • This work includes material from the System Reference Document 5.2.1 ("SRD 5.2.1") by Wizards of the Coast LLC, available at https://www.dndbeyond.com/srd. The SRD 5.2.1 is licensed under the Creative Commons Attribution 4.0 International License, available at https://creativecommons.org/licenses/by/4.0/legalcode.

This library's code is MIT; see LICENSE.

Develop

uv sync
uv run ruff format --check src tests && uv run ruff check src tests && uv run mypy src tests && uv run pytest

Release

Bump version in pyproject.toml, commit, then git tag v<version> && git push origin v<version>. The release.yml workflow runs the checks and publishes to PyPI through Trusted Publishing.

Metadata

Release files for dnd5e-character-builder 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dnd5e-character-builder 0.1.0
File Size Uploaded Provenance Actions
dnd5e_character_builder-0.1.0.tar.gz 135.7 kB With provenance Details for dnd5e_character_builder-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for dnd5e-character-builder 0.1.0
File Interpreter ABI Platform Actions
dnd5e_character_builder-0.1.0-py3-none-any.whl Python 3 none any Details for dnd5e_character_builder-0.1.0-py3-none-any.whl

Total release size: 276.9 kB

Release files / dnd5e_character_builder-0.1.0.tar.gz

Download URL dnd5e_character_builder-0.1.0.tar.gz
Size 135.7 kB
Tags Source
SHA-256 checksum
How to use checksums
dfacd124c039f4b1a135c12bed7ded20097b50a864d6ef3888a9c5274da5e75b
BLAKE2b-256 checksum
How to use checksums
36bf1a8e2a1e46de0d19cceead19edb86df9a425fb9e8051e7b63abad10cee3c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

Release files / dnd5e_character_builder-0.1.0-py3-none-any.whl

Download URL dnd5e_character_builder-0.1.0-py3-none-any.whl
Size 141.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
23758558b6667b2eed0d37dfcf27fb997f5cbe686d7e52b7230e1b8481d0b1c0
BLAKE2b-256 checksum
How to use checksums
45d44c736e189aec3dc7127fcd4a71fafc4e1e9f4915fd73fa923df523b7bfbd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

Security for dnd5e-character-builder 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for dnd5e_character_builder-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page