Tag Library

GameplayTag doesn’t need a library to work. Hand the system any string at any point and it will compute a consistent, high-performance integer identifier for it immediately. Two parts of your codebase referencing "Effects.Debuff.Poison" will independently arrive at exactly the same ID, with no shared setup, no initialization order to manage, and no performance penalty for the conversion. The hash function is the contract, and it holds everywhere.

This matters because it means tags are usable in any context, including fully dynamic or data-driven ones where you can’t predict the vocabulary in advance. A modding system, a runtime-configured event, a tag arriving over the network, all produce valid and consistent GameplayTag values the moment you compute them from their string.

So what is the tag library for?


What the Registry Enables #

The registry is what the system consults when it needs to understand relationships between tags. When a query asks whether a collection contains anything beneath Effects.Debuff, the registry is where the system looks to find out which tag IDs count as descendants of that path. Without that information, hierarchy-aware queries can’t work, because the hash of Effects.Debuff.Poison has no inherent mathematical relationship to the hash of Effects.Debuff. The connection has to be established explicitly.

Everything else in the system that goes beyond simple identity checks depends on the registry in the same way. Ancestor and descendant queries, broad containment checks that match a whole family of tags, name lookups that recover a human-readable path from an ID, all of these draw from the registry’s relationship map.

If your use of tags stays within simple exact-match operations, put this tag in this collection, does this collection contain exactly this tag, you don’t need to register anything. Once you reach for the hierarchy, you do.


Populating the Registry #

The registry can be populated in two ways and they can be combined freely.

The first is pre-compiled tag data. You define your tag vocabulary in a source file, a simple list of the leaf paths your project intends to use. This gets processed at build time into an efficient compiled form, the kind that loads cleanly at startup without any string parsing. The hierarchy relationships are baked in, so the registry can populate itself from that compiled data almost immediately. This is the right choice for any tags that are fixed parts of your game design, because it keeps startup fast and makes all those tags available to editor tooling like pickers, validators, and debug views.

The second is runtime registration. Any tag path can be registered at any point during execution. The system walks the path, registers every node in the hierarchy, and establishes all the ancestor relationships automatically, just as if that path had been in a source file. This is the right choice for tags that aren’t known at build time, content from a mod, tags defined in a downloaded data pack, paths generated from player input or external configuration.

The two approaches interoperate without friction. Pre-compiled tags and runtime-registered tags live in the same registry and work together in all queries. A condition that was authored against a compiled tag will correctly evaluate against a runtime-registered descendant of that tag.


Examples #

Work In Progress

Rate This Article!