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.


Tag Sources and Organisation #

When using pre-compiled tag data, the vocabulary is organised into source files. Each source file is a text-based list of fully-qualified leaf paths, and a project can have as many as makes sense. A small game might use one. A larger project typically splits by domain, status effects in one file, ability definitions in another, world state flags in another. A third-party plugin ships its own source file and its tags merge into the same registry as the game’s own tags automatically.

Each source carries a registered flag. A registered source is merged into the runtime registry at startup and its tags are available everywhere. An unregistered source is compiled and tracked but not loaded automatically, useful when a plugin ships optional tag sets that a developer should consciously opt into rather than inherit by default.

Parent nodes don’t need to be listed explicitly. Registering Effects.Debuff.Poison is enough to ensure that Effects and Effects.Debuff exist as nodes in the hierarchy. This keeps source files focused on the actual leaf concepts your game uses rather than requiring you to maintain every level of the tree separately.


Keeping the Library Healthy #

The tag library is the shared vocabulary for everyone working on a project. Designers authoring conditions, programmers writing queries, and artists wiring up triggers are all referencing the same names. That only works well if the library is treated with care.

Organising source files by domain keeps things navigable as the vocabulary grows. Treating renames as deliberate migrations rather than casual text replacements avoids silent breakage in any data that was serialised using the old hash. And pruning deprecated tags from registered sources over time keeps the runtime vocabulary honest rather than accumulating dead entries that no longer reflect what the game actually uses.

Examples #

Coming Soon

Rate This Article!