Site Tools


tutorial:how-to-create-a-new-spell-in-ds3

How To Create New Spells In DS3

Authors: JeNoVaViRuS

Tools

  • Witchy
  • Smithbox
  • hkxpack-souls (v0.3)
  • DS Anim Studio
  • paint.net
  • Notepad++

This tutorial will show how to add a spell from scratch but we will be using an existing animation (you can use your own one that you created instead). You normally have a cast and a fire animation for a spell and we will only use one but still cover how to implement both. Be aware that you should invest time to create a proper and fitting sfx for your spell or be prepared to have a mediocre one.

All text that is within quotation marks is meant to be literal so it's already existing exactly like this or meant to be like this. The file names sometimes include the sub-folder (in the game folder) at the start of its name so you can easily find them. Always create/have a backup ready of the original files. You should always use ModEngine 2/3 and copy the files into the mod folder.

Parts of the game that need to be modified to create a spell

Add new params, bullet, attack

The spell needs to be created as a usable magic item and as an item (goods) to be found.

Param editor → Magic

  1. Duplicate an existing spell.
  2. The SortId determines how the spell is sorted in the attunement menu.
  3. The iconId references the icon on a sheet in “menu/01_common-tpf.dcx” OR “menu/menu_knowledge_0XXXX.dcx” where XXXX is the id.
  4. Each entry has the 3 sfx param fields “CastSfx1”, “CastSfx2” and “CastSfx3”. Normally you only set the first one since you start showing a special effect when casting starts. Feel free to add other ones.
  5. Each spell has a “refType” field which determines the animation ID. Use the next free ID “51” or pick one from the existing ones.
  6. Set the bullets in refId fields. You can go to the ID of an existing one, duplicate it and change it.

Optionally you can set a replacement status type for a stat like INT or FTH.
Then you can set the threshold at which amount it should pick another spell when executing this spell. You add its ID into the replacement Magic ID field below.
This way you can let the spell execute in another way depending on a stat of the player.

Param editor → Bullet

  1. The IDs for bullets have the same as the spell but with a prefix “1”. Set an “sfxIDBullet” ID so your projectile has a visible special effect, same for “sdxIdHit” when your spell hits something.
  2. The duration(life) is the max lifetime of the bullet after which it stops existing.
  3. The other fields are mostly self explanatory.
  4. With “hitBulletId” you can set another bullet which fires after your first one hits (fitting for wave or AOE spells).

Param editor → AtkParam_PC

  1. Duplicate an existing attack from another spell
  2. Then set this atkBullet_Id to your bullet so your spell (bullet) deals damage. The attacks normally have the same IDs as the bullets.

Param editor → EquipParamGoods

  1. Duplicate an existing spell.
  2. Set the exact same ID as the Magic ID.


Add new text

Text editor → Goods

  1. Duplicate an existing entry and change the ID to the same as the Magic param ID.
  2. Set your summary and description for your spell. This sets the name and other fields in the inventory.

Text editor → Spells

  1. Duplicate an existing entry and change the ID to the same as the Magic param ID.
  2. Set your summary and description for your spell. This sets the name while it is equipped and in the attunement menu.


Add an icon

  1. Unpack “menu/01_common.tpf.dcx” with Witchy
  2. If you aren't good with texture editing I recommend using an LLM (AI) like Copilot, provide a clean spell page and some spells that use it (as .png) and describe what you want your spell page to look like. Results are alright most of the time.
  3. Edit “MENU_Icon_04000.dds” with e.g. Paint.net (the IDs on the picture are mapped out from left to right and top to bottom so you can identify them by looking at existing spells and their icons)
  4. If you got a generated spell image you need to open it in Paint.net, use the magic wand to mark the background and then remove it (delete key). Then some manual editing to clean it up. Then you can import it as a new plain and then merge it.
  5. Repack with Witchy
  6. Duplicate an existing file from “menu/knowledge” e.g. “menu_knowledge_04117.tpf.dcx”
  7. Change the folder name, the file within and the Witchy xml content to fit your spell ID from the params
  8. Edit the .dds file itself to fit your new spell.
  9. Repack with Witchy


Add new sfx

  1. Unpack “sfx/frpg_sfxbnd_commoneffects_effect.ffxbnd.dcx” with Witchy
  2. Duplicate an existing .fxr file and rename it accordingly to the CastSfx1 ID you set in the params.
  3. Edit it manually or use CCCode's JavaScript library
  4. Repack with Witchy


Animations

These are the ID ranges in a000 for magic:

  • 40000: right hand cast
  • 40300: right hand fire
  • 42000: left hand cast
  • 42300: left hand fire

As you can see left hand animation is offset by 2000 and fire animation by 300.

DS Anim Studio:

  1. open c0000.anibnd.dcx
  2. Select a tae entry e.g. a000_42051 (last existing left hand cast)
  3. “Edit” → “Duplicate”
  4. “Edit” → “Edit current animation properties” and rename it to the next ID as well as the hkt
  5. Repeat the process for the magic throw animation e.g. e.g. a000_42351
  6. Optional: If you ony want to split an existing animation into two you can do: “Edit” → “Import from animation ID” and pick the one.
  7. Optional: If you want your own animation that you created you need to unpack the “chr/c0000.anibnd.dcx” and replace the new anim files.
  8. Pick a spell with similar conditions (remeber to pick the CAST not the throw) e.g. lightning spear or emit force and copy&paste all tae events into your anim ID
  9. The event “CastHighlightedMagic” 64 has a “RefType” field (not to be confused with the “refType” field from the params) which references the magic param “refIdX” fields and uses those bullets.
  10. Now you need to sort out what you don't need:
    • PlaySound: There are often a lot of sounds included and it will take time to pick a fitting one. Take a look at “PlaySound_CenterBody[128] with SoundType 5 or 8.
    • SpawnFFX: Those event are there so you can see vfx (you should at minimum have 114 to spawn the spells castsfx1 field)
    • Jumptable: enabling and diabling what the character can do (maybe you want to disable movement or enable cancelling the animation with rolling).
      • Jumptable: CAREFUL! The order from top to bottom is important! If you put “91” (disable dash) below 89 (completely disable movement) it will activate walking again.
      • Correct order is: 91,7,97,89,97 then the cancel event with their “category” first so e.g. 87 and then 25,26.
    • AllowVerticalTorsoAim: you can set the angle possible
    • ActivateJumpTableEarly: the animation is faster (used to speed it up with Dex)
    • Invoke Rumble Cam: so the screen shakes
    • Invoke Behaviour for something extra


Add Spell in HKS

First download the decompiled versions of “common_define.hks” and “c0000.hks”. You need to edit them and then put them into the “action/script” folder.

In “common_define.hks” you need to add your custom variable e.g. “MAGIC_REQUEST_CUSTOM_SPELL” like this:

MAGIC_REQUEST_CUSTOM_SPELL = 51

“51” is the next free ID. This is also the “refType” ID that you need to set in the “Magic” params.

Also add the variable (as name) to the “AttackMagicIndex” array if it is an attack. This is normally on line 165 right below the “magic request” section.

In “c0000.hks” there is an “ExecMagic” function on line 2207.

Example: After line 2326 which is:

  elseif magic_type == 50 then
      magic_index = MAGIC_REQUEST_FAN
	

we add our own entry:

  elseif magic_type == 51 then
      magic_index = MAGIC_REQUEST_CUSTOM_SPELL

The “magic_type” ID is the “refType” ID. The “magic_index” is an ID that gets applied to “IndexMagicType”.


Add Spell in HKX

Warning: “hkxpack-souls” can write out of memory bounds. Backup the original into another folder. Use a Windows VM and a hex editor (e.g. “ImHex”) and after converting it back from .xml to .hkx you need to do a compare between the original and your new version - if they start to differ at a specific point which is NOT your new entries you need to reboot and convert it from .xml to .hkx again until it doesn't appear. Otherwise your savegame and all other players who use the file will not be able to load a savegame like 50% of the time. Doesn't occur on all systems.

  1. Unpack “chr/c0000.behbnd.dcx” with Witchy
  2. Then convert “chr\c0000-behbnd-dcx\Behaviors\c0000.hkx” with “hkxpack-souls”
  3. Open the resulting c0000.xml with Notepad++

Every object has a unique name #XXXX
There are hkobjects for every possible state to cast magic from. Those “hkbManualSelectorGenerator” lists are:

#7921: MagicLaunchLeft_Selector
#8056: MagicLaunchLeftSA_Selector
#8276: MagicFireLeft_Selector

#10638: MagicLaunchLeft_Upper_Selector
#10700: MagicLaunchLeftSA_Upper_Selector
#10797: MagicFireLeft_Upper_Selector

#8447: MagicLaunchRight_Selector
#8585: MagicLaunchRightSA_Selector
#8803: MagicFireRight_Selector

#10866: MagicLaunchRight_Upper_Selector
#10930: MagicLaunchRightSA_Upper_Selector
#11028: MagicFireRight_Upper_Selector

Launch means charging up the spell.
Fire means throwing the spell.
Upper means it only uses the upper body to perform the spell.

Their 'hkparam name=“generators”' variable holds a list of all IDs of the spells (their objects are normally right below). The order of those IDs determines how the game picks the corresponding animation.
So e.g. “refType=4” picks the 5th ID from that list and plays it because the index starts at 0.

Below every “hkbManualSelectorGenerator” you need to create a new “CustomManualSelectorGenerator” and a “hkbClipGenerator”. You only need to do this for the first 3 left/right, you simply refer to the #IDs that you already created within the last 3. The next free name/ID for objects is: #12802

Example:

  1. You pick “MagicLaunchLeft_Selector” and search for it in the c0000.xml.
  2. This is #7921. So you scroll down and see a list in <hkparam name=“generators” numelements=“51”>
  3. The first one is #7923 which is the “CustomManualSelectorGenerator” and in its <hkparam name=“generators” numelements=“1”> it references #7924.
  4. So for your new spell you copy #7923 and #7924 and paste it at the end after #8054. Now you change the IDs (name attribute in both hkobject on the their first line) to the next free ones: #12802 and #12803
  5. Then for the first one you set a UNIQUE name: <hkparam name=“name”>YourSpell_CMSG</hkparam> (for e.g. “MagicLaunchLeftSA_Selector” it would be “YourSpellLeftSA_Selector”
  6. And for its animID you set your new ID: <hkparam name=“animId”>42052</hkparam>
  7. Also within the <hkparam name=“generators” numelements=“1”> you set the new ID of your second object #12803 (so it references it)
  8. Then for the second one you set a UNIQUE name: <hkparam name=“name”>a000_042052_hkx_AutoSet_02</hkparam>
  9. And for its animationName you set your new ID: <hkparam name=“animationName”>a000_042052</hkparam>
  10. Then in #7921 you set the first ID #12802 in the list <hkparam name=“generators” numelements=“51”> AND you also need to change the amount of numelements to 52.

Now repeat that for each other Selector. There you set other consecutive IDs (they need to be unique).

Optional (split the animation): set a crop time if you have only one animation:
For the “Launch” entries you set:
cropStartAmountLocalTime = 0.0
cropEndAmountLocalTime = <end where your animation uses a windup in seconds e.g. 0.24>

For the “Fire” entries you set:
cropStartAmountLocalTime = <end where your animation uses a windup in seconds e.g. 0.24>
cropEndAmountLocalTime = 0.0

Optional: Instead of splitting an animation you can set the idle anim ID a000_000000 for the “fire” Selectors.

Optional:
playbackSpeed = the speed of your animation in % meaning 1.0 (default) is 100%, so 1.5 is 150%
enforcedDuration = speeds up your animation so that it completes in that amount of time in seconds
startTime = starts the animation AND TAE at this time in % (so 0 - 1 meaning at 1.0 it would complete instantly and at 0.5 it starts in the middle) so this SKIPS tae events that exist before the time it would start

  • Then convert “chr\c0000-behbnd-dcx\Behaviors\c0000.xml” back with “hkxpack-souls” (see Warning at the start of this paragraph)
  • Then repack “chr/c0000-behbnd-dcx/” with Witchy.


Add the spell to the world

  • place the item in the world so it can be picked up: go to “Maps” → “Parts: Objects” → duplicate an entry of a item drop object, go to “Events: Treasure” → duplicate the last entry, set your new object from the step before as the “Treausre Object”, set the item lot ID in params - create an item lot that refers to a “good”, check or uncheck “is in chest” and “is hidden” depending if you are placing it in a chest or just let it lie around
  • let an npc sell the item: Go to “Params”→ “Shops” and add / duplicate an entry within the range, change the values accordingly
  • make the spell available as a covenant reward
tutorial/how-to-create-a-new-spell-in-ds3.txt · Last modified: by jenovavirus