Modding: Tags System
Fundamentals |
---|
Basics • Data.wak • Getting started • Lua Scripting • Useful Tools |
Guides |
Audio • Enemies • Environments (Fog of War) • Image Emitters • Materials • Perks • Special Behaviors • Spells • Spritesheets • Steam Workshop • Using CMake |
Components/Entities |
Component Documentation • Enums • List of all tags • Special Tags • Tags System • Update Order |
Lua Scripting |
Lua API • Utility Scripts |
Other Information |
Enemy Information Table • Magic Numbers • Sound Events • Spell IDs • Perk IDs • Material IDs |
Noita has a tag system that's used to assign tags to components and entities.
While there are some special tags, there's no preset list of tags that can exist. Instead, new tags are allocated once they are used. Tags can be invented by mods for their convenience in tracking entities and components.
Internals
For every unique tag, the game has a list of objects that have this tag. Every entity/component also knows what tags are assigned to it.
Using this data, operations like EntityGetInRadiusWithTag
and ComponentHasTag
are optimised in the engine.
For instance, with EntityGetInRadiusWithTag
the game doesn't have to check all entities to see if they are in range,
instead it checks if the given tag has been allocated, and if so only checks the entities in that tag's list.
This way the game only has to check the position of 5 entities that have this tag, and not the hundreds of entities that don't have it.
Limitations
Component and entity systems have their own instance of a tag manager. Each tag manager can only handle up to 256 unique tags.
Adding a before unseen tag to a component or entity allocates a new tag, thus reducing the amount of free tag-space in the respective tag manager.
Tags can not be deallocated. If you remove the tag from all objects, start a new run, or do a magic dance, the tag manager will still remember the tag and it will count against the 256 tag limit. Only after restarting the game will the tags be cleared from memory.
If the entity tag manager runs out of space, Noita quickly crashes.
The component tag manager is a little bit more forgiving,
it tends to keep the game running and output errors into the logger.txt
file.
Even though the game keeps running, things won't behave like intended since tags can't be assigned properly.
Modding Advice
Since tags are a limited resource that is shared with other mods and the base game, you should consider alternatives before introducing a new tag.
Mods SHOULD NOT use tags where they can be easily avoided, for example by using an entity name or Lua table instead.
Mods SHOULD NOT create new tags dynamically, for example:
-- BADBAD: This will gradually allocate more tags until the game breaks
spidey = EntityLoad("mods/mymod/spidey.xml", x, y)
EntityAddTag(spidey, "mymod_home_chunk" .. math.floor(x/100) .. "_" .. math.floor(y/100))
-- Creates:
-- mymod_home_chunk0_0
-- mymod_home_chunk1_5
-- mymod_home_chunk2_0
-- mymod_home_chunk2_3
-- ... etc ...
Mods SHOULD reuse tags from the base game when they (nearly) accomplish what they need, for example:
-- I don't need to add a fish tag, instead I use the mortal tag
function get_nearby_fish(x, y)
local mortals = EntityGetInRadiusWithTag(x, y, 200, "mortal")
local fish = {}
for _, entity in ipairs(mortals) do
if EntityGetFirstComponent(entity, "AdvancedFishAIComponent") then
table.insert(fish, entity)
end
end
return fish
end