forked from open5e/open5e
-
Notifications
You must be signed in to change notification settings - Fork 0
RFC: Schemas
Max Rothman edited this page Jun 26, 2016
·
9 revisions
roll:
num: int
die: int
mod: int
#e.g. 5d8 + 6 is num:5, die:8, mod:6
ability: "(str | dex | con | int | wis | cha)"
Below are WIP JSON schemas for spells and monsters (in YAML format because I'm lazy)
level: int
school: school
ritual: bool
components:
verbal: bool
somatic: bool
material:
required: bool
value: ({num:int, unit:str} | null)
description: str
range:
type: (self | touch | num | unlimited)
(if type: num) {num:int, unit:str}
shape: (null |
range: {num:int, unit:str}
shape: shapestr
) #(valid when type in (self, num, unlimited))
casting_time:
num: int
unit: str
ordinality: int #sorting val. #name?
(if unit: reaction)
condition: str #e.g. when an ally within x feet is hit by an attack...
(endif)
higher_levels:
text: str
levels:
int: { damage: {avg: int, roll: roll}, description: (str | null) }
#e.g. 3: {describes at 3rd lvl}
duration:
type: (num | special | concentration | instantaneous)
(if num | concentration)
#for concentration, means up to
num: int
unit: str
ordinality: int #(see above)
(endif)
text: str
summary?: str
damage:
base: {avg: int, roll: roll}
recurring: {avg: int, roll: roll}
special: [{avg: int, roll: roll, description: (str | null)}, ...]
save: {ability: ability, description: str}
- Damage and type should probably be included? That seems like a highly useful thing to use in estimating efficacy and searching for spells that have a certain effect. ("eg. I need a spell that does fire damage" or "spells that do more than 20 average damage in one hit")
- max: That's tricky because the damage is in the spell body, might be modified by the text in the body, and might be modified by
higher_levels
. Here are a few possible options:- add an extra "damage" field to the input, the writer decides what goes in there
- have a more complex damage schema that includes different damage options
- use a custom docutils role to mark up rolls, then search through the body for "damage rolls"
- ean: I took a quick pass at one that covers the vast majority of cases I've been able to find. Most spells include at most a base damage, an ongoing damage, and a different damage for a special case. If we made the latter infinite we could make it easy to expand no matter how many exceptions a spell includes. At higher levels could use the same structure as base damage but in that section. Mocked it up in the schema. Thoughts?
- max: That's tricky because the damage is in the spell body, might be modified by the text in the body, and might be modified by
- Save and type would make sense to me to include. Could maybe just have a single property of "type" that takes an array of strings.
- max: Yeah, I was thinking that too. Again, it could be a separate input field or we could use a custom role to mark up a save DC and search the body for it.
- Things not indicated: maybe markup text with roles?
- damage
- save (inc. repeat interval)
- what changes at higher levels
- shape of AoO at range (e.g. fireball) or restrictions (e.g. chain lightning)
size: size
type: type
alignment:
#multiple alignments might be possible
morality: {good:bool, neutral:bool, evil:bool}
order: {lawful:bool, neutral:bool, chaotic:bool}
text: str #e.g. “any evil”
ac:
num: int
source: [str] #e.g. natural armor, shield
hp:
num: int
roll: roll
speed:
base: int
# only base should be expected. All others are optional, always in feet.
fly: int
...
abilities:
str: {val:int, mod:int}
dex: ...
...
saves:
str: {proficient:bool, mod:int}
dex: ...
...
skills:
- {name:str, mod:int}
...
damage_resistances: [str]
damage_immunities: [str]
condition_immunities: [str] #or links?
senses:
#all optional except passive perception
passive_perception: int
truesight: int
...
languages: ??? could be [str] or something like "Common plus up to five other languages"
challenge:
num: int
xp: int
traits:
- name: str
limit: ({num:int, period:str} | null)
text: str
...
spellcasting:
source: "(innate | class | ???)"
(if source: "class")
class: str
level: int
(endif)
spells:
cantrip: [str] #or link?
1: {slots:int, spells: [str]}
2: ...
...
9: ...
multiattack:
- actions: [str, str, ...]
# These actions should correspond to `names` from `actions`
summary: str
actions:
- {name:str, text:str}
legendary_actions:
- name: str
text: str
cost: int #how many actions. 1 should not display
lair_actions:
- name: str
text: str
- Should spellcasting include a property for the source (innate, 4th level Wizard, etc.), casting attribute, and Spell save DC?
- max: 👍 definitely
- I think "type" on HP would be easier to parse if it was "dice" or "die"?
- max: how about "roll"? I feel like "type" is a little too generic - maybe "roll" for the whole property, and "die" for the size of dice to roll? I tweaked the schema with what I was thinking.
- Added an expanded "speed" property. Would be cool if it included fly, swim, etc as properties of speed so you could search for creatures with a specific movement type in typical use-cases.
- 👍 is there a set number of different types of movement? If so, I think it'd be better to always have all the keys there and if the monster doesn't have that movement type, set it to
null
. So far, the presence of optional keys is indicated by other non-optional keys in every other place, and I'd like to keep it that way to make it easier to write API clients.
- 👍 is there a set number of different types of movement? If so, I think it'd be better to always have all the keys there and if the monster doesn't have that movement type, set it to
-
should all api outputs have a links section? e.g.
ref: url rel: str #title of target page, e.g. “Charmed" text: str #text in this page, e.g. “charmed" location: path #e.g. "actions[0].text" firstchar: int lastchar: int
-
not indicated:
- attack types, damage, reach, etc. Need types? Multiattack is challenging
- traits that are actions vs traits that are passive vs other traits