This file kindly provided by TheGiddyLimit for reference.
The copy system allows an existing creature to be copied, with modifications, to create a new creature.
// replace values from the copy with values specified in the root
// (N.B. these are kept in the root to ease external tooling, instead of doing e.g.:
// `name = name || _copy._set.name` we should always have basic info at the root level)
"name": "New Name",
"source": "New Source",
"page": 123,
"int": 10
"_copy": {
"name": "Name of original",
"source": "Source of original",
// modify existing properties
// key dictates the data to modify
// values can be:
// - a string operation (e.g. "remove")
// - an object operation (e.g. a "replaceTxt" operation with various options)
// - an array containing either/both of the above
"_mod": {
// apply to all text properties
// text properties are: "action", "reaction", "trait", "legendary", "variant", and "spellcasting"
"*": [
{
"mode": "replaceTxt", // replace text
"replace": "the captain",
"with": "Embric",
"flags": "i"
}
],
// alternate single-operation version
"*": {
"mode": "replaceTxt",
"replace": "the captain",
"with": "Embric",
"flags": "i"
},
// apply to _no_ properties (used for "special" operations which have their own specific implementations)
"_": {
"mode": "addSenses",
"senses": []
}
"action": [
// more on this syntax can be found later in the spec
{
"mode": "replaceArr",
"replace": "Mace",
"with": {
"name": "Staff",
"entries": [
"{@atk mw} {@hit 8} to hit, reach5 ft., ..."
]
}
}
],
"variant": "remove" // remove a property
},
// some properties are removed by default (e.g. page) since they don't make sense on modified copies
// this can be used to override that behaviour
"_preserve": {
"page": true
},
// other properties, which depend on the data type (key of the array containing the object), e.g. ...
// implementation is specific to whatever is intended to use the data
"_traits": {
"name": "Awakened",
"source": "PHB"
}
}
Essentially the same as the "_copy"
, with the information encapsulated in an "apply"
property. Here, "_root"
is used as an equivalent for values which would be held in the root for a normal copy object.
Modifiers have modes, these are:
Regex replace text.
{
"mode": "replaceTxt",
"replace": "the captain", // regex pattern to match
"with": "Embric", // text to insert as replacement
"flags": "i" // regex flags to use ("g" is always included by default)
}
Append a string to an existing string (with optional joiner), or add a new string.
{
"mode": "appendStr",
"str": "some text to append",
"joiner": ", "
}
Prepend items to an array.
{
"mode": "prependArr",
// items can be a single item (shorthand)
"items": {
"name": "Control Water",
"entries": [
"..."
]
}
}
Append items to an array.
{
"mode": "appendArr",
// items can be a single item (shorthand)
"items": {
"name": "Control Water",
"entries": [
"..."
]
}
}
Replace named items in an array. If the item does not have a name, this falls back on trying to replace string literals.
{
"mode": "replaceArr",
"replace": "Mace", // name of target to replace
// items can be an item or an array of items, or a string or array of strings
"items": {
// item to insert instead
"name": "Staff",
"entries": [
"{@atk mw} {@hit 8} to hit, reach5 ft., ..."
]
}
}
"replace"
can alternately be of the form:
{
"regex": "a*b",
"flags": "i"
}
// or
{
"replace": {
"index": 0 // replace item at index 0
}
}
Try to replaceArr
, fall back on appendArr
.
For each item, check if it exists in the target array; if not, append it to the target array.
{
"mode": "appendIfNotExistsArr",
// items can be an item or an array of items
"items": [
"charmed",
"poisoned"
]
}
Insert items into an array at the specified. Note that these are applied in order of appearance, and that indexes should not be relied upon.
{
"mode": "insertArr",
"index": 1,
// items can be an item or an array of items
"items": {
"name": "Staff",
"entries": [
"{@atk mw} {@hit 8} to hit, reach5 ft., ..."
]
}
}
Remove named or plain items from an array.
{
"mode": "removeArr",
// name/array of names of item to remove
"names": "Mace"
// alternatively, if string items are to be removed
"items": [
"fire",
"cold"
],
// optional "-f" flag to avoid throwing errors on missing items -- useful for e.g. creature traits
"force": true
}
Calculate a property, and add it to an object.
{
"mode": "calculateProp",
"prop": "stealth",
// formula gets eval'd
"formula": "let v = (<$prof_bonus$> * 2) + <$dex_mod$>; v >= 0 ? `+${v}` : `-${v}`"
}
Note that these are calculated using the current object values. The order of operations is as follows:
- (Copy original object)
- Apply root properties
- (Any other required steps, e.g.
_traits
are applied) - Sequentially apply
_mod
s, in order of appearance
Available variables are:
Var | Notes |
---|---|
prof_bonus |
Calculated from creature's CR |
dex_mod |
Add a scalar to a number or number-like property.
{
"mode": "scalarAddProp",
// "prop": "*", this affects all properties
"prop": "stealth",
"scalar": 2
}
Multiply a number or number-like property by a scalar
{
"mode": "scalarMultProp",
"prop": "average",
"scalar": 2,
"floor": true // if the resulting value should be floor'd (useful for division)
}
Add senses to a statblock. If the creature has greater range in the same senses as those that would be added, no changes are made.
{
"mode": "addSenses",
"senses": {
"type": "darkvision",
"range": 60
}
}
Add skills to a statblock. If the creature has greater skill bonuses in the same skills as those that would be added, no changes are made.
{
"mode": "addSkills",
"skills": {
"perception": 1, // "1" is "proficient"
"stealth": 2 // "2" is "expertise"
}
}
Add spells to a spell trait. Requires the creature to already be a spellcaster, and only targets the first listed trait.
{
"mode": "addSpells",
"spells": {
"0": {
"spells": [
"{@spell ray of frost}"
]
}
}
}
Replace spells in a spell trait. Requires the creature to already be a spellcaster, and only targets the first listed trait.
{
"mode": "replaceSpells",
"spells": {
"4": [
{
"replace": "{@spell banishment}",
"with":"{@spell dimension door}" // can be an array
}
]
},
"daily": {
"1e": [
{
"replace": "{@spell banishment}",
"with":"{@spell dimension door}" // can be an array
}
]
}
}
Add a scalar to @hit
tags in a statblock
{
"mode": "scalarAddHit",
"scalar": 2
}
Add a scalar to @dc
tags in a statblock
{
"mode": "scalarAddDc",
"scalar": 2
}
Set a statblock's size
to the maximum of the present value and the value provided.
{
"mode": "maxSize",
// if the creature is "H" (huge), it will be set to "L" (large).
// Otherwise, it will keep it's current size
"max": "L"
}
Multiply a creature's XP value by a scalar.
{
"mode": "scalarMultXp",
"scalar": 0.5,
"floor": true // if the resulting value should be floor'd (useful for division)
}