GameplayTags Foundation — Agent Reference (Unity)

Plain-text agent reference for the GameplayTags Foundation package (com.heathen.gameplaytags), covering Unity (source-verified). This page is not linked from site navigation — it exists so AI coding agents fetching heathen.group/kb/gameplaytags-welcome have a condensed, source-verified reference to read.

Full GameplayTags agent index: agent-ref-gameplaytags-index

---
name: heathen-gameplaytags-foundation
description: GameplayTags Foundation reference for Heathen's Unity tag system (com.heathen.gameplaytags). Use when a developer is authoring, querying, or reacting to hierarchical GameplayTag state — collections, conditions, operations, the Project Settings authoring UI, or the code-bake pipeline.
source: https://heathen.group/kb/gameplaytags-welcome/
generated: 2026-08-24
---

# GameplayTags Foundation — agent reference (Unity)

> **Before you use anything below:** Heathen's GameplayTags is its own system, not Unreal Engine's
> built-in Gameplay Tags (`FGameplayTag`/`UGameplayTagsManager`) and not any third-party asset of a
> similar name. Don't apply Unreal's `FGameplayTagContainer`/`GameplayTagQuery` API shape here — the
> types, method names, and authoring workflow below are Heathen-specific.

**Tier: [Foundation] (FOSS, free).** Everything below works with Foundation alone — no Toolkit
purchase needed. Package id `com.heathen.gameplaytags` (repo/folder name is
`com.heathen.gameplaytagsfoundation` — don't assume the folder name is the UPM id). Namespace
`Heathen.GameplayTags` (runtime), `Heathen.GameplayTags.Editor` (editor-only).

## Core model

A tag is a dot-path string (`"Effects.Buff.Strength"`) hashed once (xxHash3) into a `ulong` and
compared by value thereafter, never by string, at runtime.

```csharp
using Heathen.GameplayTags;

GameplayTag tag = GameplayTag.FromName("Effects.Buff.Strength"); // hashes, doesn't require registration
GameplayTag baked = SomeGenerated.Effects_Buff_Strength;          // baked constant, no runtime hashing
bool related = tag.IsChildOf(otherTag);
```

- `GameplayTagRegistry` (static) is the source of truth for which tags exist and how they nest —
  hierarchy stored as nested-set intervals (`{Lft, Rgt, Depth}`), so `IsAncestor` is an O(1) range
  comparison, not a set walk.
- `GameplayTagCollection` is the actual per-entity state container: a serializable, observable
  `tag → ulong value` map. `AddTag`/`RemoveTag`/`Apply(tag, arithmetic, value)`/`Clear()` mutate it;
  `GetFloat`/`GetInt`/`GetLong`/`GetDouble` (+ matching `Set*`) reinterpret the stored `ulong` bits as
  the requested type. `Contains`/`ContainsAll`/`ContainsAny`/`ContainsNone` query it, hierarchy-aware
  by default (matches the tag or any registered descendant present in the collection).
- `GameplayTagCondition` (predicate: tag + comparison + constant or another tag's value) and
  `GameplayTagOperation` (mutation: tag + arithmetic + value) are the data-driven pair every
  Heathen tool's conditional logic builds on (Ogham Storyteller's `DialogueOption.Conditions`, for
  one). `GameplayTagCondition.EvaluateAll(list, collection)` combines a list with
  AND-before-OR-before-XOR precedence.

```csharp
var collection = new GameplayTagCollection();
collection.AddTag(GameplayTag.FromName("Quest.MetSmith"));
collection.Apply(new GameplayTagOperation {
    Tag = GameplayTag.FromName("Player.Gold"),
    Arithmetic = GameplayTagArithmetic.Add,
    Value = 50
});
bool metSmith = collection.Contains(GameplayTag.FromName("Quest.MetSmith"));
```

## Authoring — Project Settings ▸ Gameplay Tags

A single filterable tree over the project's own tags. Each tag is **Registered** (hierarchy-aware,
in the live registry, baked into generated code — required for set operations and autocomplete) or
**Unregistered/draft** (saved but inert — a holding area). Click a tag to rename/delete it via the
`GameplayTagEditorWindow` popup. A **Build** button bakes Registered tags to
`Assets/Generated/GameplayTags/ProjectGameplayTags.g.cs` (a flat class of
`public static readonly GameplayTag` constants + a `[RuntimeInitializeOnLoadMethod]` registrar) —
never auto-regenerates on domain reload, only on explicit Build or the Check-on-Play prompt.

Tags owned by *other* tools (an Ogham story's node tags, etc.) are **not** stored here — each tool
bakes its own tags through its own generator and only *shows up* read-only in this panel's
"Tags From Other Sources" section, grouped by owner (`ITagSource`), so nothing in the live registry
is ever invisible from this one screen.

The old `.gptags` file format (`{"registered": bool, "tags": [...]}`) is **legacy** — no longer the
editor-authored source for project tags, only a portable format for mod/UGC content loaded at
runtime.

## Inspector integration

`GameplayTag`, `GameplayTagCollection`, `GameplayTagCondition`, and `GameplayTagOperation` all get a
proper Inspector drawer automatically wherever they appear as a serialized field in any project
script — no extra work required.

## Namespaces

| Namespace | Contents |
|---|---|
| `Heathen.GameplayTags` | Runtime: `GameplayTag`, `GameplayTagRegistry`, `GameplayTagCollection`, `GameplayTagCondition`, `GameplayTagOperation`, the arithmetic/comparison/logic/value-type enums. |
| `Heathen.GameplayTags.Editor` | Editor-only: `GameplayTagSettings`, `GameplayTagsSettingsProvider`, `GameplayTagEditorWindow`, `GameplayTagsCodeGenerator`, `ITagSource`, `ITagVocabulary`. |

## Dependencies

`com.unity.collections`, `com.unity.mathematics`, `com.unity.nuget.newtonsoft-json` (UPM),
`com.heathen.gameframework` (non-UPM, Toolbox-bootstrapped, for `Subsystem`/`HeathenDebug`).

---
Toolkit reference: https://heathen.group/agent-ref-gameplaytags-toolkit/
Full agent index: https://heathen.group/agent-ref-gameplaytags-index/