Step by Step Guide for creating a new spell - GrognardsFromHell/TemplePlus GitHub Wiki
Creating a new spell
Requirements
- Temple+
- Each spell needs a unique ID, the spell_enum
- Basic understanding in a script language
- Time
Be aware of what's possible with python and what's not
What's doable? A list what can be done via python (and is relevant for spells).
- Deal damage
- By spells
- directly
- Add Modifier to:
- Attributes
- Skills
- Saving Throws
- Combat Values
- Attack
- AC
- Damage (limited; see below)
- Damage Reduction (only add; see below)
- Damage Resistance
- Bypass DR
- Add existing Conditions
- Temporary raise caster level
- Add temporary hit points
- Heal
- Remove conditions
- Add more sneak (aka precision) damage
- Concentrating on a spell
- Dismiss a spell
And what's not doable
- Change trigger for effects (e.g. sneak attack now can hit undead)
- Get specific values from bonus_list
- Lower DR
Not tested but should be possible without problems:
- Add Spell Resistance (general)
Not tested but unlikly:
- Lower Spell Resistance
Not tested but could maybe be possible:
- Add Spell Resistance for certain spell descriptors
Not tested and no clue if it's possible:
- Shapechange
File structure
To avoid problems with other modders, please be sure to use the file extender model of temple+. Details see here.
I will refer to the spell_enum as xxxx, the spell name will be replaced by spell_name and the file extender names will be called my_spells in my naming examples. The spell name naming convention is not stringent, I will replicate it in my example.
If you do not have an overrides folder in your ToEE root installation folder, create one. The overrides folder will be the root folder for your mod.
1. Create a rules file
File location and name:
rules\spells
Spellxxxx - Spell Name.txt
The rules file contains the rules header for spells. The structure in detail:
School: [Spell School] e.g. Enchantment
Subschool: [Subschhol] e.g. Compulsion - I am unsure if this actually has a relevance in the game
Descriptor: [Spell Descriptor] e.g. Mind-Affecting
Descriptors are very important and every descriptor is listed in a single row it the spell has more than one. Example:
Descriptor: Fear
Descriptor: Mind-Affecting
Descriptor: Sonic
Assignment to base classes, the number indicates the spell level and can different from class to class. Classes that were added later on are not listed here (e.g. Assassin)
Level: Brd 2
Level: Sor 3
Level: Wiz 3
Class | Class abbreviation |
---|---|
Bard | Brd |
Druid | Drd |
Cleric | Clr |
Paladin | Pal |
Ranger | Rgr |
Sorcerer | Sor |
Wizard | Wiz |
Component: V
Component: S
Casting Time: 1 action (I used this to assign Free action if spell should be swift)
Range: [Range keyword or ft.] (see table below)
Saving Throw: Fortitude (I am unsure if this is actually used; you have to specifiy the save in the spell again)
Spell Resistance: Yes
Projectile: No
flags_Target: Range (I have not found a single spell that does not have this flag set to range)
legal targets (set to inc_ if yes and exc_ if not)
inc_flags_Target: Other
exc_flags_Target: Self
exc_flags_Target: Dead
exc_flags_Target: Non-critter
Targeting mode (see different options below)
mode_Target: Single
min_Target: 1
max_Target: 1
radius_Target: 0
ai_type modes:offensive, defensive, summon, heal_light
ai_type: ai_action_offensive
Different target modes:
Personal | Touch | Single | Mutiple Targets | Area | Cone |
---|---|---|---|---|---|
Range: Personal | Range: Touch | Range: Close | Range: Close | Range: Close or Personal (if centered on you) | Range: Specified [length of cone in ft.] |
mode_Target: Personal | mode_Target: Single | min_Target: 1 | min_Target: 1 | mode_Target: Area | mode_Target: Cone |
max_Target: 1 | max_Target: 0 | radius_Target: [radius in ft.] | flags_Target: Degrees | ||
flags_Target: Fixed-radius | |||||
radius_Target: 0 | radius_Target: 0 | radius_Target: 0 | radius_Target: [number in ft.] | radius_Target: ([number in ft.]) | radius_Target: 60 |
degrees_Target: 90 |
A special case is mode_Target: Inventory, this is used if you want to target an item in the inventory. Different range options: Close Medium Long [Number in ft.]
2. Edit the spell_enum.mes file
File location and name:
rules\spell_enum
my_spells_spell_enum.mes
This file contains:
//_spell_names_(to_the_python_interpreter)
{xxxx}Spell Name} e.g. {1050}{Sound Lance}
{5000+xxxx}{Spell Name} e.g. {6050}{Sound Lance}
{20000 + xxxx}{TAG_SPELLS_SOUND_LANCE} e.g. {21050}{TAG_SPELLS_SOUND_LANCE}
3. Edit spell.mes
File location and name:
mes\spells
my_spells_spell.mes
File structure:
// Spell System Messages
// Spell Names
{xxxx}{Spell Name} e.g. {{1}{Aid}
// Spell Descriptions
{5000+xxxx}{Spell description} e.g. {5001} Aid {[Enchantment] +1 on attack rolls and saves against fear, 1d8 temporary hit points + 1/level (max 10).}
4. Edit spell_long_descriptions.mes
It is optional but offers a more detailed description to spells. File location and name:
mes\spells
my_spells_spell_long_descriptions.mes
File structure:
{5000+xxxx} Spell Name {Description
School: [Spell School]
Casting: 1 std action [V,S]
Range: Personal
Target: You
Duration: 1 round/level, Save: None, SR: No}
5. Edit sound_spells.mes
File location and name:
sound\user_sounds
my_spells_sound_spells.mes
File structure:
// This file controls [SPELL] sounds
// * Banks of 20 sounds per spells are used from 6000 to 19999
// the bank consists of the following fields:
//
// 00 - spell begin (before cast anim)
// 01 - spell end (end of spell)
// 02 - spell effect (after cast anim)
// 03 - spell new round (spells with duration)
// 04 - spell projectile begin (only projectile spells)
// 05 - spell projectile end (only projectile spells)
// 06 - spell projectile in-flight (only projectile spells) ***not implemented yet
// 07 - spell hit (sound to play when a spell "hits")
// 08 - spell struck (sound to play if shield spell struck)
// to figure out your BASE_NUMBER, use this formula:
// BASE_NUMBER = 6000 + (20 * spell_number)
//
// where spell_number is the spell# associated with a spell (see mes/spells.mes)
// e.g. SPELL_NONE is 0 (6000), SPELL_AID is 1 (6020), SPELL_ZONE_OF_TRUTH is 541 (16820)
// [1] *[Aid]
{6020}{spells\sp_Aid_END.wav} // spell begin
{6021}{} // spell end
{6022}{spells\sp_Aid_start.wav} // spell effect
{6023}{} // spell new round
{6024}{} // spell projectile begin
{6025}{} // spell projectile end
{6026}{} // spell projectile in-flight
{6027}{} // spell hit
I highly recommend to use exisiting sound files, if you want to use custom file they are located at: sound\spells
6. Edit help file
File location and name:
mes\help
my_spells_help.tab
tab files are a bit more difficult to edit, though the spells help is pretty easy structured and I simply edit my spell help file in notepad++, no need for the protos_editor there. I do use the protos editor for every other .tab file though. The help file is a bit work and is completly optional but I think it's worth the effort. Simply take a look at the spell_compendium_help.tab.
7. Create an indicator file
File location and name:
rules\indicators
spell_name.txt
This file is only needed if you add a spell condition. This file includes the path to the buff symbol. The game will crash if you point to an indicator that does not exist!
ID_string: SPELL_NAME
effect_type: 0; 0 for buff, 1 for debuff, 2 for condition
texture_file: art\interface\player_conditions\conditions\psionic-focus.tga
help_topic: TAG_SPELLS_SPELL_NAME Links to the help topic of the spell, if you do not use a help file use TAG_ROOT
tooltip_base_text: Spell Name
For details have a look here
8. Create a buff symbol
File location and name:
art\interface\Player_Conditions\Buffs for buffs
art\interface\Player_Conditions\Ailments for debuffs
art\interface\Player_Conditions\Conditions for conditions
Spell My Spell.tga 32 bit **uncompressed**
This is higly optional, I would recommend to use an existing file. Be aware that if you compress the .tga file by accident, the game will crash!
9. Create a spell file
File location and name:
scr
Spellxxxx - Spell Name.py
I have done a seperate page for this, see here
10. Spell Condition file
File location and name:
scr\tpModifiers
sp_spell_name.py
I have done a seperate page for this, see here
11. Create a new particle effect
File location and name:
rules\partsys\
my_spells_partsys.tab
Creating spell particles is something I have not taken a deeper look into yet, if you do not need create a new effect I recommend using an existing one. As long as you do not create a new one, you do not need this file. This beind said, there is a tutorial on the Co8 forum Link
12. Test the spell
This is really important! Here are my personal steps:
- Check if spell properly expires
- Set spell duration to 1
- Start the game cast the spell and open the console
- See if the spell really expires (the expire float is triggered even if the expiry is messed up!)
- If expires properly reset spell duration
- Reopen the game, cast the spell and check if spell duration is correct (1 round and 1 min is huge difference)
- Take a rest to see if it expires properly after a rest.
- Check if the spell actually does what it should (cast it on a party member is the easiest way to do this)
- Check functionality (are buffs applied, does the spell deal damage ect.)
- Check if Debuff/Buff Symbol is in place (if applicable)
- Check if Mouseover description is there (if applicable)
- Check if the spell also works properly on an enemy I have spawned and killed quite a few gnolls in this step
- Check if spell description is properly formatted
- Check if link to help file is working
- If spell has targeting restrictions its now time to verify if they are applied This could include only evil targets, racial immunites etc.
- If spell is dismissable, check if it is dismissable
- If spell requires concentration
- Check if it's there
- Check if spell is properly dismissed and removed on all targets if concentration is broken
- If the spell interacts with other spells, check if they really interact (e.g. remove a different condition)
I hope you found this useful. Have fun creating your own spells. If you have any problems feel free to contact me in the Co8 forum.