Modding: Tags System

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

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