Hierarchical Tagging can be a very useful way to organize concepts and data, and the Gameplay Tags system is the UE4 method for declaring and querying hierarchical tags. Gameplay Tags have existed in the engine for several versions, but in UE 4.15 the interface and performance were greatly improved, so now is a great time to start using them. But what are Gameplay Tags and why would you want to use them?
A Gameplay Tag is a name of the form “Family.Genus.Species.Subspecies” or just “IndividualTag”. They are implemented as an FName internally and are registered in a central dictionary for validation. The nesting of names using ‘.’ allows queries that look for exact tags, as well as queries that look for any tags that include a parent tag. For instance, if two items are tagged as “Weapon.Ranged” and “Weapon.Melee”, MatchesTag(“Weapon”) would be true for both. MatchesTagExact(“Weapon”) it would be false for both, because exact matches ignore parent tags.
Gameplay Tag Containers are sets of Gameplay Tags that can be used to query multiple tags at once. Tags will only pass Exact checks if they are added specifically, but all parent tags will be included for normal checks. If you call Container.AddTag(“Weapon.Melee”) and Container.AddTag(“Spell.Fireball”), the Container.HasTagExact() will only be true for “Weapon.Melee” and ”Spell.Fireball”, Container.HasTag() will be true for “Weapon”, “Weapon.Melee”, “Spell”, and “Spell.Fireball”.
What are Gameplay Tags useful for? First, they can be used instead of Names[a] in any cases where you want to restrict the text that can be entered by a designer to only a valid set of names, similar to a combination of a Name and an Enum. The hierarchy feature is used by games like Paragon to represent things like Damage Types that have a nested nature. For instance, “Damage.DoT.Burn” is passed along when an ability does Fire Damage Over Time. Then, you can register blueprints or native code to look for “Damage”, “Damage.DoT”, or “Damage.DoT.Fire”, and all three will go off in this specific case.
To use gameplay tags they must be registered in the central tag dictionary. So, how do you add to the dictionary? The two primary methods are using ini files, or using data tables. To set up either method, open the GameplayTags tab in the Project Settings UI. This opens the tag management UI:
To add tags using ini files, enable the “Import Tags From Config” Option. This will cause it to load tags out of GameName/Config/DefaultGameplayTags.ini as well as any ini files in GameName/Config/Tags. You should use this method if you want it to be easy for anyone on your project to add tags. Once that is done, you can add new tags by using the Add New Tag button from the tag management UI or the tag selection interface. Press the + icon next to an existing tag, or open the Add New Gameplay Tag selector:
Tags can also be added using DataTables of the type GameplayTagTableRow if you want to import an external tag list. To do this, import your DataTable and then add it to the GameplayTagTableList in the Tags settings UI. Also they can be added directly from native code using AddNativeGameplayTag during project startup.
Once tags are in the dictionary, you can manage them by searching for references, deleting, or renaming tags. These actions are accessed with the caret dropdown next to a tag in the management view. Tags can only be deleted if they were added by an ini file, and are not referenced by anything else. Renamed tags end up in the GameplayTagRedirects list, and any renamed tags will be fixed on load. Searching For References will open the Reference Viewer and show all assets using the specified tag.
To actually use tags, you need to start tagging some things. The first step is to add GameplayTag or GameplayTagContainer properties to blueprints or native types. You want to use a single GameplayTag if the thing being tagged can only ever have a single value (for instance, you could add the tag “Color.Blue” to a UI Color structure because it can’t be more than one Color at once). You want to use a container if you want to support multiple different states or values (for instance, an npc could be tagged as “Character.NPC”, “Character.Humanoid”, and “Gameplay.Important”). Once these properties have been added, you can edit them from the Blueprint Defaults view or Asset Editor:
Now that things are tagged, you can use those tags to query and filter things from your gameplay code. From C++ you can use the operations defined in GameplayTagContainer.h. Some of the important ones are MatchesTag, MatchesAny, IsValid, and GetTagName on an individual GameplayTag, and HasTag, HasAny, HasAll, AddTag, and RemoveTag on GameplayTagContainer. The Tag matching functions will match against parent tags, while the Exact variants will only match specific tags.
From Blueprints you have access to the same operations, but the Exact option is a bool passed into the matching functions.Here is a basic example of using the Make Literal Gameplay Tag node to see if the passed in Tag Container matches a tag, including parents:
There are also some more advanced node available in the GameplayTag category such as “Switch on Gameplay Tag Container” and “Compare Tag Container To Other Tag Containers”. As a note, prior to 4.15 many of these actions were still possible but using a more awkward syntax and UI.
So that’s a basic overview of how to integrate Gameplay Tags into your game. We are planning on integrating Gameplay Tags into the engine in others ways, but the current tools should provide a solid base to build on top of. Epic wouldn’t be able to ship Paragon and our other internal games without Gameplay Tags, so I hope they’ll open up some new design and programming options for your game.