Modding: Making a custom spell

From Noita Wiki
Jump to navigation Jump to search
Modding Navigation
Fundamentals
BasicsData.wakGetting startedLua ScriptingUseful Tools
Guides
AudioEnemiesEnvironments (Fog of War) • Image EmittersMaterialsPerksSpecial BehaviorsSpellsSpritesheetsSteam WorkshopUsing CMake
Components/Entities
Component DocumentationEnumsList of all tagsSpecial TagsTags SystemUpdate Order
Lua Scripting
Lua APIUtility Scripts
Other Information
Enemy Information TableMagic NumbersSound EventsSpell IDsPerk IDsMaterial IDs

It is recommended to have gone through the Modding: Basics and have a mod directory set up before delving deeper here.

You can find all the existing vanilla spell IDs listed on the page ID#Spells or in the data files data/scripts/gun/gun_actions.lua.

A Note on nomenclature

Due to Noita's many phases of development, internally spells still use a sort of "card game" terminology:

  • actions are the spells themselves, consisting of everything one spell does (projectiles, physics objects, shields, magic effects, particles, etc.)
  • cards are the "spell items" you pick up in the world and move around in your inventory and wands, and only contain a reference to the action_id

You don't usually need to care about this, but occasionally you might run into these references.

Registering your new spell

  1. Add a new file to your mod (eg. files/actions.lua), where you define all your custom spells by appending to the actions table provided by the base game Lua:
    table.insert(actions,
      {
        id                 = "MY_CUSTOM_SPELL",
        name               = "My Fancy Spell",
        description        = "Fancy spell doing fancy things",
        sprite             = "data/ui_gfx/gun_actions/air_bullet.png",
        type               = ACTION_TYPE_PROJECTILE,
        spawn_level        = "1,2",
        spawn_probability  = "1,1",
        price              = 80,
        mana               = 5,
        max_uses           = 120,  -- optional
        custom_xml_file = "data/entities/misc/custom_cards/torch_electric.xml", -- optional
        action = function()
          add_projectile("data/entities/projectiles/deck/light_bullet_air.xml")
    
          -- Examples for triggers:
          --add_projectile_trigger_hit_world("data/entities/projectiles/deck/light_bullet.xml", 1)
          --add_projectile_trigger_timer("data/entities/projectiles/deck/light_bullet.xml", 10, 1)
          --add_projectile_trigger_death("data/entities/projectiles/deck/mine.xml", 1)
        end,
      }
    )
    
    * ID must be all uppercase.
  2. Add the following line to the very beginning of your init.lua, referencing the file you just created:
    ModLuaFileAppend("data/scripts/gun/gun_actions.lua", "mods/<MY_FANCY_MOD>/files/actions.lua")
    
  3. Your new spell should now be found in the game, with mostly the default values we copied from "light air bullet".

Spawning custom spells

Now that your spell exists, you can test it by adding it to your custom wand directly, or spawning it via Lua:

-- Easiest place to test new stuff, in reality the code could be anywhere.
function OnPlayerSpawned(player)
  local x, y = EntityGetTransform(player)
  CreateItemActionEntity("MY_CUSTOM_SPELL", x+20, y)
end

Note that the function doesn't seem to print/return any errors, so be wary of typos in SPELL_ID.

Customizing your new spell

Most of the fields found in the object we inserted into actions are quite self-explanatory, but a few notes on the special cases:

  • sprite is the image of the card (ie. what you pick up from the world), not the projectile
  • type can be any of the following known valid values:
    • ACTION_TYPE_PROJECTILE
    • ACTION_TYPE_STATIC_PROJECTILE
    • ACTION_TYPE_MODIFIER
    • ACTION_TYPE_DRAW_MANY
    • ACTION_TYPE_PASSIVE
    • ACTION_TYPE_MATERIAL
    • ACTION_TYPE_UTILITY
    • ACTION_TYPE_OTHER
  • max_uses is optional, leaving it out or setting it to -1 means unlimited uses
  • action is where most of the magic happens, this function is called upon shooting and can basically do anything you can think of with Lua
    • This is where you register any projectiles you want to shoot upon using the spell (which you will have to define separately through XML)
    • This is also where you register any projectile triggers you might want (timer, hit_world, death)
    • This can also be entirely empty (see passive spells, like shields)
  • custom_xml_file is optional. Rarely needed, but super useful. This defines the XML for a custom card
    • In addition to controlling the world item, cards also work on the wand itself, attaching custom effects on them (like the electric torch)
    • Can be used to eg. make spell items physics objects, glow differently, etc.
    • If left empty, the file data/entities/misc/custom_cards/action.xml is used. You can note that the reference ItemActionComponent::action_id is empty. This is filled in silently in the background for each action.


For full list of all actions and great learning material, see data/scripts/gun/gun_actions.lua

Creating a custom projectile

See data/entities/projectiles/ for examples.

Check out Enums: RAGDOLL FX for what effects your projectile can have.

Note: The game affects some projectiles, for example Black Holes, with particular behaviours based on the Entity tags defined in the .xml file. It also searches for precise strings contained in said tags instead of checking the entire word, so for example utilizing the tag "black_hole_custom" the projectile is still recognized as one of said type.

WIP