Skip to content

Commit 18eb06d

Browse files
committed
Changed groups-and-tagsets.md.
1 parent c900c87 commit 18eb06d

1 file changed

Lines changed: 4 additions & 18 deletions

File tree

docs/advanced/groups-and-tagsets.md

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Groups are the foundation of Trecs' performance model:
4444
The tags you pass to `AddEntity<...>()` are a **filter**, not a label. Trecs picks the registered group whose tag set contains every tag you passed:
4545

4646
- One group matches → that's the target.
47-
- Several match, but one matches your tags *exactly* that one wins. (This is how partitioned templates let you target either side of a presence/absence partition by omitting the partition tag.)
47+
- Several match → if one of them has *only* your tags and no extras, that one wins. (This is how partitioned templates let you target either side of a presence/absence partition by omitting the partition tag.)
4848
- Otherwise → the call throws as ambiguous.
4949

5050
```csharp
@@ -54,28 +54,14 @@ accessor.AddEntity<GameTags.Player>();
5454
// → {Player, Character}. Only this group contains Player.
5555
5656
accessor.AddEntity<GameTags.Enemy, GameTags.Character>();
57-
// → {Enemy, Character}. Both groups contain Character, but this one matches exactly.
57+
// → {Enemy, Character}. Only this group contains Enemy.
5858
5959
accessor.AddEntity<GameTags.Character>();
60-
// → throws. Both groups contain Character and neither matches exactly.
60+
// → throws. Both groups contain Character, and neither has Character on its own.
6161
```
6262

6363
`AddEntity<Player>()` works because `Player` narrows to one group. `AddEntity<Character>()` doesn't — `Character` alone matches both, so you have to add `Player` or `Enemy` to disambiguate.
6464

65-
## TagSet vs GroupIndex
66-
67-
Trecs exposes two first-class handles for groups:
68-
69-
| | `TagSet` | `GroupIndex` |
70-
|---|---|---|
71-
| **Role** | Stable identity for a tag combination | Runtime handle — a small array-indexable integer |
72-
| **Representation** | 32-bit stable hash of the tag GUIDs | Sequential `ushort` assigned at world build time |
73-
| **Serializable** | Yes — same value across runs | No — assignment depends on registration order |
74-
| **Typical use** | `[FromWorld(typeof(GameTags.Player))]`, `world.CountEntitiesWithTags<...>()`, save-game fields | `[ForEachEntity]` internals, group-slice iteration, `ComponentBuffer`, event callbacks |
75-
| **How you get one** | `TagSet<GameTags.Player>.Value`, `TagSet.FromTags(...)` | `worldInfo.GetSingleGroupWithTags(tagSet)`, capture from slice, event callback |
76-
77-
Rule of thumb: to **store** the handle (component, disk, across sessions), use `TagSet`. To **use** it within a frame to reach into native storage, use `GroupIndex`.
78-
7965
## GroupSlices
8066

8167
`GroupSlices()` is a low-level iteration pattern that gives direct access to component buffers per group. It bypasses the per-entity abstraction and can be more efficient for bulk operations, but requires you to manage group-level access yourself.
@@ -132,7 +118,7 @@ TagSet tags = TagSet.FromTags(Tag<GameTags.Player>.Value, Tag<GameTags.Enemy>.Va
132118
TagSet combined = playerTags.CombineWith(TagSet<GameTags.Active>.Value);
133119
```
134120

135-
`TagSet` is a stable hash, so it's safe to serialize — the same tag combination hashes to the same value across runs. Use it for save-game fields or network messages that name a group.
121+
`TagSet` is a stable hash, so it's safe to serialize — the same tag combination hashes to the same value across runs.
136122

137123
## GroupIndex
138124

0 commit comments

Comments
 (0)