Team Registration & Info Actors
"Membership" (an agent's tags) and "declared teams" (named teams with cosmetics and a registry) are separate layers. Basic attitude needs only the first; the second adds display assets, player auto-assignment, faction-wide tag stacks, and a queryable registry.
The pieces
| Type | Role |
|---|---|
UCrimsonTeamCreationComponent | On the Game State (server). Spawns the configured team-info actors, assigns players (ServerChooseTeamForPlayer), and supports runtime AddTeams / RemoveTeams |
ACrimsonTeamInfoBase | Abstract AInfo. Holds the team FGameplayTag + a FCrimsonTagStackContainer of faction tag stacks; registers with the subsystem on BeginPlay |
ACrimsonTeamPublicInfo | Replicated to all clients; carries the UCrimsonTeamDisplayAsset reference |
ACrimsonTeamPrivateInfo | Server/owner-scoped; for team-internal state you don't broadcast to opponents |
UCrimsonTeamSubsystem | World subsystem registry. Resolves agents, gates damage, exposes faction tag stacks, and drives the dynamic-attitude refresh |
Registration is automatic
Team-info actors register/unregister themselves in
BeginPlay/EndPlay. Never call RegisterTeamInfo / UnregisterTeamInfo yourself.Faction tag stacks
Team-wide flags and buffs (zone control, global modifiers) live as tag stacks on the team-info actor, mutated through the subsystem and shared by every member of the faction.
const FGameplayTag RedTeam = FGameplayTag::RequestGameplayTag(FName("Team.Red"));const FGameplayTag ZoneCaptured = FGameplayTag::RequestGameplayTag(FName("Team.Buff.ZoneCaptured"));UCrimsonTeamSubsystem* TS = GetWorld()->GetSubsystem<UCrimsonTeamSubsystem>();TS->AddTeamTagStack(RedTeam, ZoneCaptured, 1); // serverconst int32 N = TS->GetTeamTagStackCount(RedTeam, ZoneCaptured);const bool bHas = TS->TeamHasTag(RedTeam, ZoneCaptured);