Changing spells
Vanilla Nox stores spell configs in three different places:
- As a section in
thing.bin
file - Balance file
- Built into the engine
The engine defines a list of all supported spell IDs (e.g. SPELL_BLINK
) and the effect associated with it.
The thing.bin
then lists spells that should be enabled in the game (by ID) and additionally configures them.
Unfortunately, this configuration is quite limited.
The balance file may additionally tune per-level spell parameters, or special parameters that are unique to certain spells.
OpenNox extends this system and allows using spells.yml
file to configure new spell parameters, as well as old ones in one place.
Note: this modding feature is still in development. Not all the config options for spells are available in spells.yml
.
We will keep adding new ones in each version of OpenNox.
Generating base spells.yml
file
Since this feature is in the development, it is strongly advised to generate a fresh spells.yml
based on the latest
OpenNox version and your Nox game data.
This can be done by running OpenNox with NOX_DUMP_SPELLS=true
environment variable.
On Linux:
NOX_DUMP_SPELLS=true opennox
On Windows (via cmd.exe
):
set NOX_DUMP_SPELLS="true"
opennox.exe
This should create a spells.yml
in Nox game data directory (not OpenNox directory!).
Alternatively, you could copy the spells.yml file to your Nox game directory. Be aware that the sample file might be old and won’t list all options available in the engine.
Modifying spells.yml
Note that modifying spells.yml
currently requires OpenNox restart.
Usually, the spell section will look like this:
name: SPELL_BLINK
icon:
ind: 131860
icon_enabled:
ind: 131938
mana_cost: 10
price: 3000
flags:
- 1
- MOBS_CAN_CAST
- 128
- 1024
- CAN_COUNTER
- CANT_HOLD_CROWN
- 1048576
- CLASS_ANY
- 2147483648
phonemes: [cha, et, un]
title: thing.db:Blink
desc: thing.db:SPELL_BLINK_DESC
cast_sound: BlinkCast
---
Where:
name
- specifies spell ID to use; ifeffect
is not set, this also determines the spell effecteffect
- specifies spell ID which will control the actual effect of the spell; see adding spellsicon.ind
- the sprite index fromvideo.bag
that is used as a spell iconicon_enabled.ind
- same asicon.ind
, but for enabled spell iconmana_cost
- mana cost of the spellprice
- base spell book price; Quest uses an additional multiplier for this priceflags
- different flags that controls which category spell belongs to, what it can target, etcphonemes
- a unique list of spell phonemes/gestures that invoke this spell; see spell castingtitle
- a string ID for the spell titledesc
- a string ID for the spell descriptioncast_sound
- a sound for casing a spellon_sound
- a sound for enabling a spelloff_sound
- a sound for disabling a spell
These are the only parameters that can be originally controlled via thing.bin
, and was ported to spells.yml
.
Apart from these, OpenNox provides more options for certain spells.
For example, SPELL_MAGIC_MISSILE
has a new section:
missiles:
spread: 16
projectile: MagicMissile
vel_mult: 0.1
offset: 4
speed_rnd_min: 0.80000001
speed_rnd_max: 1.2
search_dist: 600
Here, a count
parameter is omitted, because it is usually controlled via balance file (see MagicMissileCount
).
Specifying it here will override balance data.
When a special section like missiles
this is present, all parameters in there can be controlled individually for each spell level:
missiles:
# default parameters for all levels
spread: 16
projectile: MagicMissile
vel_mult: 0.1
offset: 4
speed_rnd_min: 0.80000001
speed_rnd_max: 1.2
search_dist: 600
# per-level configs
levels:
# levels 1-3: copied from balance file
- count: 1
- count: 2
- count: 3
# level 4: same number of missiles as lvl3, but longer homing distance
- count: 3
search_dist: 800
# level 5: make it ultimate: more missiles, longer distance, faster missiles
- count: 10
speed_rnd_min: 1.0
speed_rnd_max: 2.0
search_dist: 800
Spell flags
Not all flags are completely understood at this point. So we recommend to see what flags are set for existing spells and experiment by setting/unsetting them in your mod.
Names of the spell flags provided below may change in a freshly-generated spells.yml
,
but OpenNox will still support old names as well.
Player class flags:
CLASS_ANY
- spell can be used by any magic class (Conjurer and Wizard)CLASS_WIZARD
- spell can only be used by WizardCLASS_CONJURER
- spell can only be used by Conjurer- Setting none of these flags will effectively hide the spell.
Targeting flags
TARGETED
- spell is homingAT_LOCATION
- spell can be cast at a pointCANT_TARGET_SELF
- spell cannot be targeted at the character
Cast flags:
NO_MANA
- spell doesn’t require manaNO_TRAP
- spell can’t be used in trapsINSTANT
- spell is instantDURATION
- spell is duration-basedOFFENSIVE
- spell is offensiveDEFENSIVE
- spell is defensiveCAN_COUNTER
- spell can be counteredMOBS_CAN_CAST
- mobs are allowed to use this spellCANT_HOLD_CROWN
- spell can’t be cast when holding a flag/crown/ball
Special flags
SUMMON_SPELL
- this is the base Summon Creature spellSUMMON_CREATURE
- this is Summon for a specific creatureMARK_SPELL
- this is the base Mark Location spellMARK_NUMBER
- this is Mark Location with a specific numberGOTO_MARK_SPELL
- this is the base Go To Mark spellGOTO_MARK_NUMBER
- this is Go To Mark with a specific number
There are some flags that don’t have names, which means we are not sure of its effect.
Adding new spells
Currently, adding new spells in OpenNox is not supported.
Having said that it is possible to replace unused spell slots that already exist in the game.
In spell section there’s a name
parameter that defines the slot that the spell uses
and effect
for the engine to know which effect to run.
Usually these two IDs are the same (or effect
is empty and derived from name
), but these fields can be used to replace
unused spell IDs with custom ones.
For example, there’s SPELL_PHANTOM
which doesn’t appear in the game and has no effect in the engine.
This gives us a free spell slot to use. Let’s replace it with a custom magic missiles (SPELL_MAGIC_MISSILE
) variant.
For this we need to set name: SPELL_PHANTOM
(or find existing section with it) to specify which slot we are using,
and set effect: SPELL_MAGIC_MISSILE
for the engine to know which logic to use for it. The result should look like this:
name: SPELL_PHANTOM # replacing Phantom spell slot
effect: SPELL_MAGIC_MISSILE # but effect is based on Magic Missiles
phonemes: [un, ro, do] # phonemes must be unique, so we keep ones from Phantom
# the rest is copied from Missiles and modified
icon:
ind: 18248
icon_enabled:
ind: 131967
mana_cost: 50
price: 5000
flags:
- AT_LOCATION
- MOBS_CAN_CAST
- OFFENSIVE
- CAN_COUNTER
- CANT_TARGET_SELF
- CLASS_WIZARD
- 536870912
- 1073741824
title: thing.db:MissilesOfMagic
desc: thing.db:SPELL_MAGIC_MISSILE_DESC
cast_sound: MagicMissileCast
missiles:
count: 5
spread: 30
projectile: MagicMissile
vel_mult: 0.1
offset: 4
speed_rnd_min: 0.1
speed_rnd_max: 0.3
search_dist: 800
---