Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
f9f94b8
fixed parsing reaction conditions without parentheses (#842)
blakewatson Dec 30, 2025
28da537
Fix spell data regressions and omissions (#844)
eepMoody Jan 1, 2026
5b09d94
Convert distance fields to integer (#845)
eepMoody Jan 1, 2026
6b69faa
fixed bugs in srd-2024 CreatureAction data (closes #847) (#849)
calumbell Jan 4, 2026
8ae4a3b
fixed markdown errors in Creature spellcasting traits/actions (#855)
calumbell Jan 8, 2026
9013dc4
updated srd-2014 dragon breath weapon recharge data (closes #848) (#853)
calumbell Jan 8, 2026
90ecff3
removed prepended asterisks from toh/tdcs FeatBenefit 'desc' fields (…
calumbell Jan 8, 2026
3cc5267
fixed bugs in srd-2024 spell markdown (closes #857)
calumbell Jan 12, 2026
a558d7a
updated monster conversion script to scrap input md for bonus actions…
calumbell Jan 13, 2026
dc66a72
added missing srd-2024 creature reactions
calumbell Jan 13, 2026
242dad3
removed Mithral and Adamantine Hide Armor from srd-2014 dataset (clos…
calumbell Jan 14, 2026
00937ec
bugfix: added missing dash to bfrd mechanist starting equipment markdown
calumbell Jan 17, 2026
65ea3b3
added 2024 champion subclass data to ClassFeatureItem.json
calumbell Feb 2, 2026
9cf57c6
added srd-2024 College of Lore data to ClassFeatureItem.json
calumbell Feb 3, 2026
309f882
replaced casting_times of 'bonus_action' w/ 'bonus-action' as per mod…
calumbell Feb 8, 2026
838aa2a
wrote exclude_fields_mixin (and mvd mixins to own dir)
calumbell Feb 10, 2026
e344cc3
added ExcludeFieldsMixin to model viewsets
calumbell Feb 11, 2026
e80320d
added missing srd-2024 dragon attack data to CreatureAttackAction
calumbell Feb 12, 2026
881fb5b
removed /manifest from url, updated test cases to reflect rmvl
calumbell Feb 13, 2026
44b86a5
rmv'd ManifestViewSet
calumbell Feb 13, 2026
ae6b2b7
removed ManifestSerializer
calumbell Feb 13, 2026
4420840
removed Manifest model
calumbell Feb 13, 2026
ad9d362
rmv'd manifest from v1 API schema
calumbell Feb 13, 2026
3eb0d7e
removed /version endpoint
calumbell Feb 14, 2026
d163be3
Merge pull request #859 from calumbell/857/srd-2024-spell-bugfixes
augustjohnson Feb 21, 2026
8e31d0d
Merge pull request #860 from calumbell/850/srd-2024-missing-reactions…
augustjohnson Feb 21, 2026
bc8b479
Merge pull request #861 from calumbell/829/rmv-hide-mithral-adamantine
augustjohnson Feb 21, 2026
afa33a7
Merge pull request #863 from calumbell/bugfix/bf-mechanist-missing-li…
augustjohnson Feb 21, 2026
763907e
Merge pull request #868 from calumbell/867/missing-srd-2024-champion-…
augustjohnson Feb 21, 2026
c155dec
Merge pull request #870 from calumbell/869/srd-2024-spell-casting-tim…
augustjohnson Feb 21, 2026
7e247c4
Merge pull request #872 from calumbell/871/excludes-mixin
augustjohnson Feb 21, 2026
b732ef4
Merge pull request #874 from calumbell/873/missing-dragon-attack-data
augustjohnson Feb 21, 2026
f329ccd
Merge pull request #875 from calumbell/733/rmv-manifest-endpoint
augustjohnson Feb 21, 2026
a2c55eb
added character creation rules from srd-2024 (#878)
calumbell Feb 21, 2026
87f5e53
Added filter on monsters for environments (#884)
stevennoto Feb 26, 2026
170ceb2
fixed typo in srd-2024 Adult Green Dragon spellcasting action (#891)
calumbell Apr 5, 2026
189d3b2
[BUGFIX] Fixed data errors on `/v2/rulesets/srd_combat-sequence` (#893)
calumbell Apr 5, 2026
ee91aee
added missing ClassFeatureItem for Fighter two extra attacks action (…
calumbell Apr 5, 2026
7a15f4c
removed server/vector_index.pkl from repo (#883)
calumbell Apr 5, 2026
f8df1fd
removed leading slashes on Image file_urls (#886)
calumbell Apr 5, 2026
cccaf78
[CI/CD] Upgrade Github Action versions to Node 24 compatable versions…
calumbell Apr 5, 2026
a0194df
Feature: split V2 Item model into Item and MagicItem models (#889)
calumbell Apr 5, 2026
e74da6b
[BUGFIX] `GameContentSerializer` now inherits from `ModelSerializer` …
calumbell Apr 5, 2026
849abf6
Bugfix: seperated mixed up V1/V2 endpoints (#890)
calumbell Apr 5, 2026
cbfdb60
[BUGFIX] Fixed EagerLoadingMixin early return error (#898)
calumbell Apr 5, 2026
80fc3a2
Bump django from 5.2.1 to 5.2.12 (#904)
dependabot[bot] Apr 6, 2026
45d4a9e
Bump requests from 2.32.3 to 2.33.0 (#905)
dependabot[bot] Apr 10, 2026
e498bf9
Bump urllib3 from 2.4.0 to 2.6.3 (#906)
dependabot[bot] Apr 10, 2026
bf01719
Bump django from 5.2.12 to 5.2.13 (#908)
dependabot[bot] Apr 10, 2026
31aa4ea
fixed bug in srd-2014 skeleton resistances/immunities (#907)
calumbell Apr 12, 2026
205152b
fixed markdown bugs in srd-2014 brass dragons (#912)
calumbell Apr 12, 2026
158f358
updated srd-2024 goliath giant ancestry markdown: added missing list …
calumbell Apr 12, 2026
68ae9cb
consolidated CRs into single 'challenge_rating' field (#910)
calumbell Apr 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build_and_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
echo "DOCKER_IMAGE_TAG=staging" >> $GITHUB_ENV
fi
- name: Build and push
uses: docker/build-push-action@v4
uses: docker/build-push-action@v7
with:
push: true
tags: eepmoody/open5e-api:${{ env.DOCKER_IMAGE_TAG }}
Expand All @@ -35,7 +35,7 @@ jobs:
needs: build
steps:
- name: Check out repository code
uses: actions/checkout@v3
uses: actions/checkout@v6
- name: Install jq tool
run: |
sudo apt-get update
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/clear_cache.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v6

- name: Make script executable
run: chmod +x scripts/clear_cloudflare_cache.sh
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/pr_validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ jobs:
run-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.11'
cache: pipenv
Expand All @@ -37,7 +37,7 @@ jobs:
- name: Sanitize branch name
run: echo "BRANCH_NAME=$(echo ${GITHUB_REF##*/} | tr '/' '-')" >> $GITHUB_ENV
- name: Build Docker image
uses: docker/build-push-action@v4
uses: docker/build-push-action@v7
with:
push: false
tags: open5e-api:${{ env.BRANCH_NAME }}
4 changes: 2 additions & 2 deletions .github/workflows/rdme-openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ jobs:
rdme-openapi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.11"

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v6

- name: Set up Python
uses: actions/setup-python@v3
uses: actions/setup-python@v6
with:
python-version: '3.11'

Expand All @@ -24,7 +24,7 @@ jobs:
working-directory: ${{ github.workspace }}

- name: Upload release asset
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v6
with:
name: codebase

Expand Down
274 changes: 156 additions & 118 deletions Pipfile.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ pipenv run python manage.py spectacular --color --file openapi-schema.yml` to bu
```

# Contributing
See [contribution guide](CONTRIBUTING.md).
See [contribution guide](.github/CONTRIBUTING.md).
# Tests

Tests are located in the `api/tests` directory. These should be run before pushing new changes to the main repository. These tests require that the api is [running](##run) at `http://localhost:8000`.
Expand Down
5 changes: 5 additions & 0 deletions api/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ class Meta:


class MonsterFilter(CommonFilterSet):
environments = django_filters.CharFilter(
field_name="environments_json", lookup_expr="icontains"
)

class Meta:
model = models.Monster
fields = {
Expand All @@ -91,6 +95,7 @@ class Meta:
"hit_points": ["exact", "range", "gt", "gte", "lt", "lte"],
"armor_class": ["exact", "range", "gt", "gte", "lt", "lte"],
"type": ["iexact", "exact", "in", "icontains"],
"environments_json": ["iexact", "exact", "in", "icontains"],
"size": ["iexact", "exact", "in", "icontains"],
"page_no": ["exact", "range", "gt", "gte", "lt", "lte"],
"document__slug": [
Expand Down
16 changes: 16 additions & 0 deletions api/migrations/0003_delete_manifest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Generated by Django 5.2.9 on 2026-02-13 11:54

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('api', '0002_document_v2_related_key'),
]

operations = [
migrations.DeleteModel(
name='Manifest',
),
]
1 change: 0 additions & 1 deletion api/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""
The initialization for models for open5e's api.
"""
from .models import Manifest
from .models import Document
from .models import GameContent
from .models import CharClass
Expand Down
28 changes: 0 additions & 28 deletions api/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,6 @@
from django.template.defaultfilters import slugify
#from api_v2 import urls as urls_v2

class Manifest(models.Model):
"""A Manifest contains a hash based on the contents of a file.

This is intended for folks who process and store content from our API.
When they download content, they also download the corresponding manifest.
Periodically, they check back in to see whether any manifests have changed.
If so, then they know to re-download that source.
"""

filename = models.CharField(
max_length=255,
unique=True,
help_text='Input file name.')
type = models.CharField(
max_length=25,
help_text='Type of file (maps to a model).')
hash = models.CharField(max_length=255,
help_text='md5 hash of the file contents.')
created_at = models.DateTimeField(
auto_now_add=True,
help_text='Date that this object was added to the database.')

@staticmethod
def plural_str() -> str:
"""Return a string specifying the plural name of this model."""
return "Manifests"


class Document(models.Model):
slug = models.CharField(max_length=255, unique=True, default=uuid.uuid1)
# System Reference Document
Expand Down
6 changes: 0 additions & 6 deletions api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@
from api import models
from api import search_indexes


class ManifestSerializer(serializers.ModelSerializer):
class Meta:
model = models.Manifest
fields = ('filename', 'type', 'hash', 'created_at')

class DynamicFieldsModelSerializer(serializers.ModelSerializer):

def __init__(self, *args, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"count": 74,
"next": "http://localhost:8000/feats/?page=2",
"next": "http://localhost:8000/v1/feats/?page=2",
"previous": null,
"results": [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"count": 1618,
"next": "http://localhost:8000/magicitems/?page=2",
"next": "http://localhost:8000/v1/magicitems/?page=2",
"previous": null,
"results": [
{
Expand Down
15 changes: 7 additions & 8 deletions api/tests/approved_files/TestAPIRoot.test_root.approved.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
{
"armor": "http://localhost:8000/v2/armor/",
"backgrounds": "http://localhost:8000/v2/backgrounds/",
"armor": "http://localhost:8000/v1/armor/",
"backgrounds": "http://localhost:8000/v1/backgrounds/",
"classes": "http://localhost:8000/v1/classes/",
"conditions": "http://localhost:8000/v2/conditions/",
"documents": "http://localhost:8000/v2/documents/",
"feats": "http://localhost:8000/v2/feats/",
"conditions": "http://localhost:8000/v1/conditions/",
"documents": "http://localhost:8000/v1/documents/",
"feats": "http://localhost:8000/v1/feats/",
"magicitems": "http://localhost:8000/v1/magicitems/",
"manifest": "http://localhost:8000/v1/manifest/",
"monsters": "http://localhost:8000/v1/monsters/",
"planes": "http://localhost:8000/v1/planes/",
"races": "http://localhost:8000/v1/races/",
"sections": "http://localhost:8000/v1/sections/",
"spelllist": "http://localhost:8000/v1/spelllist/",
"spells": "http://localhost:8000/v2/spells/",
"weapons": "http://localhost:8000/v2/weapons/"
"spells": "http://localhost:8000/v1/spells/",
"weapons": "http://localhost:8000/v1/weapons/"
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
"slug": "coins"
},
{
"desc": "A typical combat encounter is a clash between two sides, a flurry of weapon swings, feints, parries, footwork, and spellcasting. The game organizes the chaos of combat into a cycle of rounds and turns. A **round** represents about 6 seconds in the game world. During a round, each participant in a battle takes a **turn**. The order of turns is determined at the beginning of a combat encounter, when everyone rolls initiative. Once everyone has taken a turn, the fight continues to the next round if neither side has defeated the other.\n\n> **Combat Step by Step** > > 1. **Determine surprise.** The GM determines whether anyone involved > in the combat encounter is surprised. > 2. **Establish positions.** The GM decides where all the characters > and monsters are located. Given the adventurers' marching order or > their stated positions in the room or other location, the GM > figures out where the adversaries are\u0336 how far away and in what > direction. > 3. **Roll initiative.** Everyone involved in the combat encounter > rolls initiative, determining the order of combatants' turns. > 4. **Take turns.** Each participant in the battle takes a turn in > initiative order. > 5. **Begin the next round.** When everyone involved in the combat has > had a turn, the round ends. Repeat step 4 until the fighting > stops.\n\n**Surprise**\n\nA band of adventurers sneaks up on a bandit camp springing from the trees to attack them. A gelatinous cube glides down a dungeon passage, unnoticed by the adventurers until the cube engulfs one of them. In these situations, one side of the battle gains surprise over the other.\n\nThe GM determines who might be surprised. If neither side tries to be stealthy, they automatically notice each other. Otherwise, the GM compares the Dexterity (Stealth) checks of anyone hiding with the passive Wisdom (Perception) score of each creature on the opposing side. Any character or monster that doesn't notice a threat is surprised at the start of the encounter.\n\nIf you're surprised, you can't move or take an action on your first turn of the combat, and you can't take a reaction until that turn ends. A member of a group can be surprised even if the other members aren't.\n\n## Initiative\n\nInitiative determines the order of turns during combat. When combat starts, every participant makes a Dexterity check to determine their place in the initiative order. The GM makes one roll for an entire group of identical creatures, so each member of the group acts at the same time.\n\nThe GM ranks the combatants in order from the one with the highest Dexterity check total to the one with the lowest. This is the order (called the initiative order) in which they act during each round. The initiative order remains the same from round to round.\n\nIf a tie occurs, the GM decides the order among tied GM-controlled creatures, and the players decide the order among their tied characters. The GM can decide the order if the tie is between a monster and a player character. Optionally, the GM can have the tied characters and monsters each roll a d20 to determine the order, highest roll going first.\n\n## Your Turn\n\nOn your turn, you can **move** a distance up to your speed and **take one action**. You decide whether to move first or take your action first. Your speed---sometimes called your walking speed---is noted on your character sheet.\n\nThe most common actions you can take are described in srd:actions-in-combat. Many class features and other abilities provide additional options for your action.\n\nsrd:movement-and-position gives the rules for your move.\n\nYou can forgo moving, taking an action, or doing anything at all on your turn. If you can't decide what to do on your turn, consider taking the Dodge or Ready action, as described in srd:actions-in-combat.\n\n### Bonus Actions\n\nVarious class features, spells, and other abilities let you take an additional action on your turn called a bonus action. The Cunning Action feature, for example, allows a rogue to take a bonus action. You can take a bonus action only when a special ability, spell, or other feature of the game states that you can do something as a bonus action. You otherwise don't have a bonus action to take.\n\n> **Sage Advice**\n\n> Actions and bonus actions can't be exchanged. If you have two abilities that require bonus actions to activate you can only use one, even if you take no other actions.\n\n> Source: [Sage Advice > Compendium](http://media.wizards.com/2015/downloads/dnd/SA_Compendium_1.01.pdf)\n\nYou can take only one bonus action on your turn, so you must choose which bonus action to use when you have more than one available.\n\nYou choose when to take a bonus action during your turn, unless the bonus action's timing is specified, and anything that deprives you of your ability to take actions also prevents you from taking a bonus action.\n\n### Other Activity on Your Turn\n\nYour turn can include a variety of flourishes that require neither your action nor your move.\n\nYou can communicate however you are able, through brief utterances and gestures, as you take your turn.\n\nYou can also interact with one object or feature of the environment for free, during either your move or your action. For example, you could open a door during your move as you stride toward a foe, or you could draw your weapon as part of the same action you use to attack.\n\nIf you want to interact with a second object, you need to use your action. Some magic items and other special objects always require an action to use, as stated in their descriptions.\n\nThe GM might require you to use an action for any of these activities when it needs special care or when it presents an unusual obstacle. For instance, the GM could reasonably expect you to use an action to open a stuck door or turn a crank to lower a drawbridge.\n\n## Reactions\n\nCertain special abilities, spells, and situations allow you to take a special action called a reaction. A reaction is an instant response to a trigger of some kind, which can occur on your turn or on someone else's. The opportunity attack <srd:opportunity-attacks> is the most common type of reaction.\n\nWhen you take a reaction, you can't take another one until the start of your next turn. If the reaction interrupts another creature's turn, that creature can continue its turn right after the reaction.",
"desc": "A typical combat encounter is a clash between two sides, a flurry of weapon swings, feints, parries, footwork, and spellcasting. The game organizes the chaos of combat into a cycle of rounds and turns. A **round** represents about 6 seconds in the game world. During a round, each participant in a battle takes a **turn**. The order of turns is determined at the beginning of a combat encounter, when everyone rolls initiative. Once everyone has taken a turn, the fight continues to the next round if neither side has defeated the other.\n\n> **Combat Step by Step** > > 1. **Determine surprise.** The GM determines whether anyone involved > in the combat encounter is surprised. > 2. **Establish positions.** The GM decides where all the characters > and monsters are located. Given the adventurers' marching order or > their stated positions in the room or other location, the GM > figures out where the adversaries are\u0336 how far away and in what > direction. > 3. **Roll initiative.** Everyone involved in the combat encounter > rolls initiative, determining the order of combatants' turns. > 4. **Take turns.** Each participant in the battle takes a turn in > initiative order. > 5. **Begin the next round.** When everyone involved in the combat has > had a turn, the round ends. Repeat step 4 until the fighting > stops.\n\n**Surprise**\n\nA band of adventurers sneaks up on a bandit camp springing from the trees to attack them. A gelatinous cube glides down a dungeon passage, unnoticed by the adventurers until the cube engulfs one of them. In these situations, one side of the battle gains surprise over the other.\n\nThe GM determines who might be surprised. If neither side tries to be stealthy, they automatically notice each other. Otherwise, the GM compares the Dexterity (Stealth) checks of anyone hiding with the passive Wisdom (Perception) score of each creature on the opposing side. Any character or monster that doesn't notice a threat is surprised at the start of the encounter.\n\nIf you're surprised, you can't move or take an action on your first turn of the combat, and you can't take a reaction until that turn ends. A member of a group can be surprised even if the other members aren't.\n\n## Initiative\n\nInitiative determines the order of turns during combat. When combat starts, every participant makes a Dexterity check to determine their place in the initiative order. The GM makes one roll for an entire group of identical creatures, so each member of the group acts at the same time.\n\nThe GM ranks the combatants in order from the one with the highest Dexterity check total to the one with the lowest. This is the order (called the initiative order) in which they act during each round. The initiative order remains the same from round to round.\n\nIf a tie occurs, the GM decides the order among tied GM-controlled creatures, and the players decide the order among their tied characters. The GM can decide the order if the tie is between a monster and a player character. Optionally, the GM can have the tied characters and monsters each roll a d20 to determine the order, highest roll going first.\n\n## Your Turn\n\nOn your turn, you can **move** a distance up to your speed and **take one action**. You decide whether to move first or take your action first. Your speed---sometimes called your walking speed---is noted on your character sheet.\n\nThe most common actions you can take are described in srd:actions-in-combat. Many class features and other abilities provide additional options for your action.\n\nsrd:movement-and-position gives the rules for your move.\n\nYou can forgo moving, taking an action, or doing anything at all on your turn. If you can't decide what to do on your turn, consider taking the Dodge or Ready action, as described in srd:actions-in-combat.\n\n### Bonus Actions\n\nVarious class features, spells, and other abilities let you take an additional action on your turn called a bonus action. The Cunning Action feature, for example, allows a rogue to take a bonus action. You can take a bonus action only when a special ability, spell, or other feature of the game states that you can do something as a bonus action. You otherwise don't have a bonus action to take.\n\n> **Sage Advice**\n\n> Actions and bonus actions can't be exchanged. If you have two abilities that require bonus actions to activate you can only use one, even if you take no other actions.\n\n> Source: [Sage Advice > Compendium](http://media.wizards.com/2015/downloads/dnd/SA_Compendium_1.01.pdf)\n\nYou can take only one bonus action on your turn, so you must choose which bonus action to use when you have more than one available.\n\nYou choose when to take a bonus action during your turn, unless the bonus action's timing is specified, and anything that deprives you of your ability to take actions also prevents you from taking a bonus action.\n\n### Other Activity on Your Turn\n\nYour turn can include a variety of flourishes that require neither your action nor your move.\n\nYou can communicate however you are able, through brief utterances and gestures, as you take your turn.\n\nYou can also interact with one object or feature of the environment for free, during either your move or your action. For example, you could open a door during your move as you stride toward a foe, or you could draw your weapon as part of the same action you use to attack.\n\nIf you want to interact with a second object, you need to use your action. Some magic items and other special objects always require an action to use, as stated in their descriptions.\n\nThe GM might require you to use an action for any of these activities when it needs special care or when it presents an unusual obstacle. For instance, the GM could reasonably expect you to use an action to open a stuck door or turn a crank to lower a drawbridge.\n\n## Reactions\n\nCertain special abilities, spells, and situations allow you to take a special action called a reaction. A reaction is an instant response to a trigger of some kind, which can occur on your turn or on someone else's. The opportunity attack is the most common type of reaction.\n\nWhen you take a reaction, you can't take another one until the start of your next turn. If the reaction interrupts another creature's turn, that creature can continue its turn right after the reaction.",
"document__license_url": "http://open5e.com/legal",
"document__slug": "wotc-srd",
"document__title": "5e Core Rules",
Expand Down
Loading
Loading