Magic in Cataclysm: Dark Days Ahead (CDDA) offers a unique and powerful way to survive the apocalypse. This guide provides a comprehensive overview of magic, spells, and enchantments, helping you understand the basics and begin your magical journey.
Spells
Spells in CDDA are actions performed by a character or item that cause an event to happen to a target. These events can range from simple actions like casting a fireball or healing, to more complex effects like granting mutations, summoning items, spawning monsters, manipulating terrain, or modifying stats. Even seemingly non-magical actions like casting Fist, Gun, or Vomit are handled by spells, demonstrating the system’s versatility. By understanding how to use JSON fields, interactions, and descriptions, anyone can create custom spells.
The Template Spell
The template spell provides a comprehensive example showcasing all available values. It serves as a reference for crafting your own spells:
{
"id": "example_template",
"type": "SPELL",
"name": "Template Spell",
"description": "This is a template to show off all the available values",
"valid_targets": [ "hostile", "ground", "self", "ally" ],
"effect": "shallow_pit",
"effect_str": "template",
"shape": "blast",
"extra_effects": [ { "id": "fireball", "hit_self": false, "max_level": 3 } ],
"affected_body_parts": [ "head", "torso", "mouth", "eyes", "arm_l", "arm_r", "hand_r", "hand_l", "leg_l", "foot_l", "foot_r" ],
"flags": [ "SILENT", "LOUD", "SOMATIC", "VERBAL", "NO_HANDS", "NO_LEGS", "SPAWN_GROUP" ],
"spell_class": "NONE",
"base_casting_time": 1000,
"final_casting_time": 100,
"casting_time_increment": -50,
"base_energy_cost": 30,
"final_energy_cost": 100,
"energy_increment": -6,
"energy_source": "MANA",
"components": [requirement_id],
"difficulty": 12,
"max_level": 10,
"get_level_formula_id": "jmath_get_level_formula",
"exp_for_level_formula_id": "jmath_exp_for_level_formula",
"magic_type": "magiclysm_default_magic",
"min_accuracy" -20,
"max_accuracy": 20,
"accuracy_increment": 1.5
"min_damage": 0,
"max_damage": 100,
"damage_increment": 2.5,
"min_aoe": 0,
"max_aoe": 5,
"aoe_increment": 0.1,
"min_range": 1,
"max_range": 10,
"range_increment": 2,
"min_dot": 0,
"max_dot": 2,
"dot_increment": 0.1,
"min_duration": 0,
"max_duration": 1000,
"duration_increment": 4,
"min_pierce": 0,
"max_pierce": 1,
"pierce_increment": 0.1,
"field_id": "fd_blood",
"field_chance": 100,
"min_field_intensity": 10,
"max_field_intensity": 10,
"field_intensity_increment": 1,
"field_intensity_variance": 0.1
"sound_type": "combat",
"sound_description": "a whoosh",
"sound_ambient": true,
"sound_id": "misc",
"sound_variant": "shockwave",
"learn_spells": { "create_atomic_light": 5, "megablast": 10 }
}
Most of these values can be set to 0 or “NONE” if they are not relevant to your spell. Note that some formulas, such as the one for spell failure chance, are non-linear.
Mandatory Fields
Several JSON fields are crucial for spells to function:
Identifier | Description |
---|---|
id |
Unique ID for the spell, used internally. Must be one continuous word, use underscores if necessary. |
type |
Indicates the JSON object is a SPELL . |
name |
Name of the spell that shows in game. |
description |
Description of the spell that shows in game. |
valid_targets |
Targets affected by the spell. Can be ally , field , ground , hostile , item , none or self . |
effect |
Hardcoded spell behaviors, essentially the spell’s “type”. |
shape |
The shape of the spell’s area of effect. |
Additional fields may be required depending on the spell effect. For example, an attack
spell needs damage_type
, min_damage
, max_damage
, min_range
, max_range
, and max_level
.
Spell Effects
The effect
field determines the spell’s behavior. Here’s a table of implemented effects:
Effect | Description |
---|---|
add_trap |
Adds a trap to the target tile. |
area_pull |
Pulls valid targets within its area of effect toward the target location. |
area_push |
Pushes valid targets within its area of effect away from the target location. |
attack |
Deals damage to valid targets within its area of effect and applies the effect specified by effect_str . |
banishment |
Kills any monster in the area of effect up to damage hp. Excess hp is taken from the caster. |
bash |
Bashes the terrain at the target. |
charm_monster |
Charms a monster that has less hp than damage() for approximately duration(). |
dash |
Dashes forward up to range and hits targets in a cone at the target. |
directed_push |
Pushes valid targets in the area of effect away from the target location, with a distance determined by damage(). |
effect_on_condition |
Runs the effect_on_condition from effect_str on all valid targets. |
emit |
Causes an emit at the target. |
explosion |
Causes an explosion centered on the target. |
flashbang |
Causes a flashbang effect centered on the target. |
fungalize |
Fungalizes the target. |
guilt |
Target gets the guilt morale as if it killed the caster. |
map |
Maps out the overmap centered on the player. |
mod_moves |
Adds damage() moves to the targets. Negative values “freeze” for that amount of time. |
morale |
Gives a morale effect to NPCs or the avatar within the area of effect. |
mutate |
Mutates the targets. |
noise |
Causes damage() amount of noise at the target. |
pain_split |
Evens out all of your limbs’ damage. |
pull_target |
Attempts to pull the target towards the caster in a straight line. |
recharge_vehicle |
Increases or decreases the battery charge of a vehicle. |
recover_energy |
Recovers an energy source equal to damage of the spell. |
remove_effect |
Removes effect_str effects from all creatures in the area of effect. |
remove_field |
Removes a effect_str field in the area of effect. |
revive |
Revives a monster like a zombie necromancer. |
revive_dormant |
Revives a dormant monster. |
short_range_teleport |
Teleports the player randomly range spaces. |
slime_split |
The slime splits into two large or normal slimes, depending on mass. |
spawn_item |
Spawns an item that will disappear at the end of its duration. |
summon |
Summons a monster or monstergroup from effect_str that will disappear at the end of its duration. |
summon_vehicle |
Summons a vehicle from effect_str that will disappear at the end of its duration. |
targeted_polymorph |
A targeted monster is permanently transformed into the monster specified by effect_str. |
ter_transform |
Transforms the field, furniture, terrain, and trap in its area of effect. |
timed_event |
Adds a timed event to the player only. |
translocate |
Opens up a window that allows the caster to choose a translocation gate to teleport to. |
upgrade |
Immediately upgrades a target monster. |
vomit |
Any creature within its area of effect will instantly vomit. |
Spell Shape
The shape
field determines how the spell’s area of effect functions:
Shape | Description |
---|---|
blast |
A circular blast centered on the impact position. |
cone |
Fires a cone with an arc equal to the area of effect in degrees. |
line |
Fires a line with a width equal to the area of effect. |
Common Fields
These JSON fields are optional but can greatly expand the spell’s behavior.
Field group | Description | Example |
---|---|---|
min_X , max_X , X_increment |
Minimum value, maximum value, and the value increase per level. | "min_damage": { "math": [ "u_skill('dodge') + u_val('intelligence')" ] }, , "min_range": 24, , "min_aoe": { "math": [ "( VAR_1 / 3 )" ] }, . |
min_damage , max_damage , damage_increment |
“Damage” value of the spell. | “min_damage”: 0, “max_damage”: 100, “damage_increment”: 5, |
min_duration , max_duration , duration_increment |
Duration of the spell effects. | “min_duration”: 100, “max_duration”: 6000, “duration_increment”: 100, |
min_range , max_range , range_increment |
Distance from the caster to the target. | “min_range”: 2, “max_range”: 10, “range_increment”: 0.5, |
min_aoe , max_aoe , aoe_increment |
Area of effect that the spell will affect. | “min_aoe”: 0, “max_aoe”: 5, “aoe_increment”: 0.1, |
min_accuracy , max_accuracy , accuracy_increment |
Accuracy of the spell. | “min_accuracy” -20, “max_accuracy”: 20, “accuracy_increment”: 1.5 |
min_dot , max_dot , dot_increment |
Damage over time. | “min_dot”: 0, “max_dot”: 2, “dot_increment”: 0.1, |
min_pierce , max_pierce , pierce_increment |
Armor “piercing”. | “min_pierce”: 0, “max_pierce”: 1, “pierce_increment”: 0.1, |
min_bash_scaling , max_bash_scaling , bash_scaling_increment |
Converts a spell with the “attack” effect’s damage into the scaling amount of terrain damage. | “min_bash_scaling”: 1.0, “max_bash_scaling”: 2.0, “bash_scaling_increment”: 0.1, |
base_casting_time , final_casting_time , casting_time_increment |
Time the caster spends when casting the spell. | “base_casting_time”: 1000, “final_casting_time”: 100, “casting_time_increment”: -50, |
base_energy_cost , final_energy_cost , energy_increment |
Amount of energy spent for cast. | “base_energy_cost”: 30, “final_energy_cost”: 100, “energy_increment”: -6, |
field_id , field_chance , min_field_intensity , max_field_intensity , field_intensity_increment , field_intensity_variance |
Spawns fields. | “field_id”: “fd_blood”, “field_chance”: 100, “min_field_intensity”: 10, “max_field_intensity”: 10, “field_intensity_increment”: 1, “field_intensity_variance”: 0.1 |
effect_str |
The “effect” the spell has. | “effect_str”: “zapped”, “effect_str”: “mon_zombie”, |
max_level |
How much you can train the spell. | “max_level”: 10, |
difficulty |
How hard it is to cast the spell. | “difficulty”: 7, |
multiple_projectiles |
Instead of shooting single spell, you will shoot multiple_projectiles amount of projectiles. |
“multiple_projectiles”: 2, |
affected_body_parts |
Body part where the attack , dot or effect_str will occur. |
“affected_body_parts”: [ “head” ] |
extra_effects |
Allows to cast a secondary spell id immediately after the primary spell. |
“extra_effects”: [ { “id”: “fireball”, “hit_self”: false, “max_level”: 3 }, { “id”: “storm_chain_1” } ] |
learn_spells |
Allow user to learn the spell id when they reach that spell level. |
“learn_spells”: { “create_atomic_light”: 5, “megablast”: 10 } |
teachable |
Whether it’s possible to teach this spell between characters. | "teachable": true |
message |
The message that will be send in the log when the spell is cast. | “message”: “You feel refreshed.” |
sound_type , sound_description , sound_ambient , sound_id , sound_variant |
Sound that will play when spell is cast. | “sound_type”: “combat”, "sound_description": "a whoosh", "sound_ambient": true, "sound_id": "misc", "sound_variant": "shockwave", |
targeted_monster_ids |
Limits the spell to target only the specified monster_id . |
“targeted_monster_ids”: [ “mon_hologram” ], |
targeted_monster_species |
Limits the spell to target only the specified monster SPECIES . |
“targeted_monster_species”: [ “ROBOT”, “CYBORG” ], |
ignored_monster_species |
The opposite of targeted_monster_species . |
“ignored_monster_species”: [ “ZOMBIE”, “NETHER” ], |
magic_type |
Optional field indicating which type of magic this spell is part of. |
Spell Flags
Flags provide additional customizations for spell effects, behavior, and limitations.
Flag | Description |
---|---|
CONCENTRATE |
Focus affects spell fail %. |
EXTRA_EFFECTS_FIRST |
The spell’s extra_effects will happen before the main spell effect. |
FRIENDLY_POLY |
The target of a targeted_polymorph spell will become friendly to the caster if the spell resolves successfully. |
HOSTILE_SUMMON |
Summon spell always spawns a hostile monster. |
HOSTILE_50 |
Summoned monster spawns friendly 50% of the time. |
IGNITE_FLAMMABLE |
If the spell area has anything flammable, a fire will be produced |
IGNORE_WALLS |
Spell’s aoe goes through walls. |
LIQUID |
Effects applied by spell will be resisted by waterproof armor if the spell targets a character’s body part. |
LOUD |
Spell makes extra noise at target. |
MAGIC_FOCUS |
Item does not interfere with hand encumbrance while spellcasting. |
MUST_HAVE_CLASS_TO_LEARN |
The spell is autolearned when you have spell_class , and removed when you lost it. |
MUTATE_TRAIT |
Overrides the mutate spell effect to use a specific trait_id instead of a category. |
NO_EXPLOSION_SFX |
The spell will not generate a visual explosion effect. |
NO_FAIL |
This spell cannot fail when cast. |
NO_HANDS |
Hands do not affect spell energy cost. |
NO_LEGS |
Legs do not affect casting time. |
NO_PROJECTILE |
The “projectile” portion of the spell phases through walls. |
NON_MAGICAL |
Ignores spell resistance when calculating damage mitigation and cannot be blocked by the NO_SPELLCASTING character flag. |
PAIN_NORESIST |
Pain altering spells can’t be resisted. |
PERCENTAGE_DAMAGE |
The spell deals damage based on the target’s current hp. |
PERMANENT |
Items or creatures spawned with this spell do not disappear and die as normal. |
PERMANENT_ALL_LEVELS |
Items spawned with this spell do not disappear even if the spell is not max level. |
POLYMORPH_GROUP |
A targeted_polymorph spell will transform the target into a random monster from the monstergroup in effect_str . |
PSIONIC |
Spells with this flag are not blocked by the NO_SPELLCASTING character flag, instead being blocked by NO_PSIONICS. |
RANDOM_AOE |
Picks random number between (min + increment) * level and max instead of normal behavior. |
RANDOM_CRITTER |
Same as RANDOM_TARGET but ignores ground. |
RANDOM_DAMAGE |
Picks random number between (min + increment) * level and max instead of normal behavior. |
RANDOM_DURATION |
Picks random number between (min + increment) * level and max instead of normal behavior. |
RANDOM_TARGET |
Forces the spell to choose a random valid target within range instead of the caster choosing the target. |
RECHARM |
charm_monster spell stacks its duration onto existing charm effect. |
SILENT |
Spell makes no noise at target. |
SOMATIC |
Arm encumbrance affects fail % and casting time (slightly). |
SPAWN_GROUP |
Spawn or summon from an item_group or monstergroup , instead of the specific IDs. |
SPAWN_WITH_DEATH_DROPS |
Allows summoned monsters to retain their usual death drops, otherwise they drop nothing. |
SPLIT_DAMAGE |
If used, instead of dealing damage to a random body part, damage would be spread evenly across entire body, unless affected_body_parts is specificed. |
SWAP_POS |
A projectile spell swaps the positions of the caster and target. |
TARGET_TELEPORT |
Teleport spell changes to maximum range target with aoe as variation around target. |
UNSAFE_TELEPORT |
Teleport spell risks killing the caster or others. |
VERBAL |
Spell makes noise at caster location, mouth encumbrance affects fail %. |
WONDER |
This drastically alters the behavior of the parent spell: The spell itself doesn’t cast, but the damage and range information are used to cast the extra_effects . |
Damage Types
These are the available damage types:
Damage type | Description |
---|---|
acid |
|
bash |
|
biological |
Internal damage such as poison. |
cold |
|
cut |
|
electric |
|
heat |
|
pure |
This damage type goes through armor altogether. |
stab |
Spell Level
Spells can change effects as they level up, affecting accuracy, area of effect, damage, damage over time, duration, pierce, and range. The min_effect
, max_effect
, and effect_increment
fields control this growth.
Learning Spells
Spells can be learned from items, spells with the learn_spells
field, and traits/mutations.
Extra Spell Effects
The extra_effects
and effect_str
fields provide additional functionality:
extra_effects
: Casts one or more spells simultaneously, enabling “chain” style casting.effect_str
: Links the main spell to a certain JSON object, such as theeffect_type
to be applied or the ID of an item to spawn.
Adding Spells to Professions and NPCs
Spells can be added to professions or NPC class definitions using the following format:
{
"id": "test_profession",
"type": "profession",
"name": "Test Professioner",
"description": "Tests professions",
"spells": [
{ "id": "summon_zombie", "level": 0 },
{ "id": "magic_missile", "level": 10 }
],
...
}
Examples
Here are some spell examples from simple to advanced:
Summon Spell
{
"type": "SPELL",
"id": "test_summon",
"name": "Summon",
"description": "Summons the creature specified in 'effect_str'",
"flags": [ "SILENT", "HOSTILE_SUMMON" ],
"valid_targets": [ "ground" ],
"min_damage": 1,
"max_damage": 1,
"min_aoe": 3,
"max_aoe": 3,
"effect": "summon",
"effect_str": "mon_test_monster",
"min_duration": 6250,
"max_duration": 6250
}
Typical Attack
{
"id": "test_attack",
"type": "SPELL",
"name": "Ranged Strike",
"description": "Deals damage to the target with 100% accuracy. Will always apply the status effect specified in 'effect_str'.",
"valid_targets": [ "ground", "hostile" ],
"effect": "attack",
"effect_str": "stunned",
"min_damage": 10,
"max_damage": 20,
"damage_increment": 1.0,
"min_range": 4,
"max_range": 4,
"base_casting_time": 500,
"min_duration": 200,
"max_duration": 300,
"duration_increment": 10,
"damage_type": "stab"
}
Consecutive Spell Casting
{
"id": "test_combo",
"type": "SPELL",
"name": "Combo Strikes",
"description": "Upon casting this spell, will also activate the spells specified on the 'extra_effects' in descending order.",
"flags": [ "SILENT", "RANDOM_DAMAGE", "RANDOM_AOE" ],
"valid_targets": [ "hostile", "ground" ],
"effect": "attack",
"effect_str": "downed",
"extra_effects": [ { "id": "test_atk1" }, { "id": "test_atk2" } ],
"min_damage": 7,
"max_damage": 14,
"damage_increment": 0.7
"min_aoe": 2,
"max_aoe": 4,
"aoe_increment": 0.2
"min_range": 10,
"max_range": 10,
"base_casting_time": 750,
"min_duration": 325,
"max_duration": 325,
"damage_type": "stab"
}
Random Spell Casting
{
"id": "test_starter_spell",
"type": "SPELL",
"name": "Starter",
"description": "Upon casting this spell, randomly selects one spell specified in 'extra_effects' to cast. The spell damage shows how many times it will randomly select from the list",
"flags": [ "SILENT", "WONDER", "RANDOM_DAMAGE" ],
"valid_targets": [ "hostile" ],
"effect": "attack",
"extra_effects": [
{ "id": "test_atk1" },
{ "id": "test_atk2" },
{ "id": "test_atk3" },
{ "id": "test_atk4" },
{ "id": "test_atk5" },
{ "id": "test_atk6" }
],
"min_damage": 3,
"max_damage": 5,
"damage_increment": 0.2
"min_range": 10,
"max_range": 10
}
Repeatedly Cast the Same Spell
{
"type": "SPELL",
"id": "test_attack_repeat",
"name": "a spell",
"description": "Upon casting this spell it will repeat the spell specified in `extra_effects` - the amount of repetitions is the interval `min_damage`-`max_damage` ",
"extra_effects": [ { "id": "test_attack" } ],
"flags": [ "SILENT", "WONDER", "RANDOM_DAMAGE" ],
"valid_targets": [ "hostile" ],
"effect": "attack",
"effect_str": "target_message",
"min_damage": 5,
"max_damage": 7,
"damage_increment": 0.2
"min_range": 10,
"max_range": 10,
"min_duration": 1,
"max_duration": 1
}
A Spell That Casts a Note on the Target and an Effect on the Caster
{
"id": "test_attack_note",
"type": "SPELL",
"name": "a note",
"description": "This spell applies a harmless status effect to notify the player about the spell that the user has cast.",
"flags": [ "SILENT" ],
"valid_targets": [ "hostile" ],
"effect": "attack",
"extra_effects": [
{ "id": "sacrifice_spell", "hit_self": true },
{ "id": "test_attack" }
],
"effect_str": "eff_test_note",
"min_aoe": 6,
"max_aoe": 6,
"min_duration": 1,
"max_duration": 1
}
Monster Spells
Refer to the “Monster special attacks – Spells” section in the game’s documentation for more information.
Custom Spell Experience Requirements
Spells may have custom formulas for their xp requirements to level by combining the get_level_formula_id
and exp_for_level_formula_id
fields.
Constant Spell Exp Requirement Example:
{
"id": "test_spell",
"type": "SPELL",
"name": "test",
"description": "constant spell experience formula.",
"valid_targets": [ "hostile" ],
"effect": "attack",
"min_damage": 1,
"max_damage": 1,
"get_level_formula_id": "magic_test_func_get_level",
"exp_for_level_formula_id": "magic_test_func_exp_for_level"
},
{
"type": "jmath_function",
"id": "magic_test_func_get_level",
"num_args": 1,
"return": "_0 / 1000"
},
{
"type": "jmath_function",
"id": "magic_test_func_exp_for_level",
"num_args": 1,
"return": "1000 * _0"
},
Magic Type
Spells may have a magic type defined. The magic type can define the experience requirements to level the spell, any flags which make the spell uncastable, and also the energy source for the spell.
Magic Type Example:
{
"id": "magic_type_test",
"type": "magic_type",
"energy_source": "MANA",
"get_level_formula_id": "magic_test_func_get_level",
"exp_for_level_formula_id": "magic_test_func_exp_for_level",
"cannot_cast_flags": "NO_SPELLCASTING",
"cannot_cast_message": "you cannot cast test spells!",
"casting_xp_formula_id": "magic_test_xp_formula",
"max_book_level": 0,
"failure_cost_percent": 1,
"failure_exp_percent": 1,
"failure_eocs": "EOC_random_mutate"
},
{
"id": "test_spell",
"type": "SPELL",
"name": "test",
"description": "a test spell.",
"valid_targets": [ "hostile" ],
"effect": "attack",
"min_damage": 1,
"max_damage": 1,
"magic_type": "magic_type_test"
}
Enchantments
Enchantments provide an additional layer of enhancements similar to effect_type
and mutation
. Enchantments are bound to “containers” such as items, mutations, bionics, and effects.
Identifier | Description |
---|---|
id |
Unique ID. |
has |
How an enchantment determines if it is in the right location. |
condition |
Determines the environment where the enchantment is active. |
hit_you_effect |
A spell that activates when you melee_attack a creature. |
hit_me_effect |
A spell that activates when you are hit by a creature. |
intermittent_activation |
Spells that activate depending on the duration. |
values |
Numbers that can be modified. |
skills |
A bonus or penalty to skills. |
emitter |
Grants the emit_id. |
modified_bodyparts |
Modifies the body plan. |
mutations |
Grants the mutation/trait ID. |
ench_effects |
Grants the effect_id. |
There are two possible syntaxes: by defining an enchantment object and then referencing the ID, or by directly defining the inline enchantment inside something.
{
"type": "enchantment",
"id": "ENCH_INVISIBILITY",
"name": { "str": "Invisibility" },
"description": "You are invisible. Just that.",
"condition": "ALWAYS",
"has": "WIELD",
"hit_you_effect": [ { "id": "AEA_FIREBALL", "hit_self": true, "once_in": 12 } ],
"hit_me_effect": [ { "id": "AEA_HEAL" } ],
"values": [ { "value": "STRENGTH", "multiply": 1.1, "add": -5 } ],
"skills": [ { "value": "computer", "add": 3 } ],
"emitter": "emit_AEP_SMOKE",
"modified_bodyparts": [ { "gain": "test_corvid_beak" }, { "lose": "torso" } ],
"mutations": [ "GILLS", "MEMBRANE", "AMPHIBIAN", "WAYFARER", "WILDSHAPE:FISH" ],
"ench_effects": [ { "effect": "invisibility", "intensity": 1 } ],
"melee_damage_bonus": [
{ "type": "bash", "add": 10 },
{ "type": "cut", "add": -3 },
{ "type": "heat", "multiply": 0.5 },
{ "type": "acid", "multiply": -0.5 },
{ "type": "necrotic", "add": 10, "multiply": 0.1 },
{ "type": "biological", "add": { "math": [ "Nemesis_iteration * -1" ] } }
],
"incoming_damage_mod": [
{ "type": "bash", "add": 10 },
{ "type": "stab", "add": -8 },
{ "type": "cut", "multiply": -0.5 },
{ "type": "bullet", "add": 1 },
{ "type": "electric", "add": { "math": [ "rand(3)