CrimsonTeamsv1.0Coming to FabPersonal $14.99 · Professional $29.99
Join the Discord

Tag-based teams & factions with dynamic attitude, plus invite-based parties that survive level travel and reconnects. Change a tag at runtime and even AI perception re-evaluates friend or foe.

Gameplay · Multiplayer · Unreal Engine 5

Teams that change mid-match, and the AI actually notices.

A replicated, tag-based team & faction system where attitude is computed live from tags, never stored. Flip a tag at runtime and every actor re-evaluates friend or foe, including AI perception, which Unreal otherwise checks once per stimulus. Invite-based parties sit on top and survive level travel and dropped connections.

Why CrimsonTeams

A complete friend-or-foe layer: replicated, GAS-aware, AI-aware, and built to change at runtime.

Tags, not numeric IDs

Teams are gameplay tags, so an actor can belong to several at once and factions nest naturally. GetTeamAttitudeBetween is the single source of truth, resolving in a fixed order: same party → Friendly; HostileToTags overlap → Hostile; shared team tag → Friendly; else Neutral.

Dynamic attitude & live re-aggro

Change a team or hostility tag at runtime and every registered agent re-evaluates. The subsystem refreshes AI perceivers with RequestStimuliListenerUpdate (no ForgetActor, last-known location preserved), so an actor that just turned hostile gets perceived without leaving and re-entering perception.

Parties that outlive the level

UCrimsonPartySubsystem lives on the GameInstance, so it outlives worlds: invite, accept, kick, promote and resize from a UCrimsonPartyMemberComponent on the PlayerState. Members are keyed by unique net id, so seamless travel keeps everyone online and a disconnect marks them offline until the grace window ends.

Built for multiplayer

Team state is server-authoritative with no client RPC: clients receive results by replication and re-fire the change delegates from OnRep, so gameplay and UI stay correct. The per-party actor is relevant to its members only, so nobody sees a roster they are not in.

Damage gating, GAS targeting & interaction gates

ShouldCauseDamageToTarget gates friendly fire in one call; MakeFilteredTargetDataFromActors filters AoE by attitude (HostileOnly, FriendlyOnly, and more) straight into a GAS target-data handle. With CrimsonCore, the Team Attitude interaction condition puts the same test on an interaction option: only allies revive, only enemies finish off.

Declared teams & team colors

Declare named teams on the Game State with a Team Creation Component, auto-assign players (override ServerChooseTeamForPlayer), and drive per-team material/Niagara parameters from a UCrimsonTeamDisplayAsset, with async observer nodes that keep nameplates and UI in sync, and faction-wide tag stacks on the team-info actor.

A closer look

Friend or foe in three steps

Add a Crimson Team Agent Component, give each actor its team and hostile tags, and ask Get Team Attitude Between. Team.Red vs Team.Blue reads Hostile; two reds read Friendly; no team reads Neutral.

  • Static nodes resolve the agent on an actor, pawn, controller or player state; no component reference needed
  • Ships no team tags of its own; you define them to match your project's factions

Parties compose with factions instead of replacing them

Tags are static faction identity; a party is consent between specific players. Because party membership is tested before every tag rule, two players from hostile factions who party up are Friendly to each other and to nobody else.

  • Project Settings hold the rules: max size, invite lifetime, leader-only invites with a suggest path for others
  • An attitude gate decides whether you may invite a neutral or hostile player
  • Member locations replicate to the party on an interval, so minimap markers and teleport-to-member work at any distance

Decoupled by design

CrimsonTeams is fully standalone. Forward ICrimsonTeamAgentInterface from your pawn or controller and any code reads team tags without knowing the component. Party events are delegates on UCrimsonPartySubsystem, and readiness is a ModularGameplay feature state you can wait on.

  • OnPartyMessage in Blueprint, OnPartyMessageNative in C++
  • The Add Teams and Add Party System actions announce Crimson.SystemReady.Teams and Crimson.SystemReady.Party

Engine AI perception needs one forward, and that part is C++

Everything in CrimsonTeams itself is Blueprint. The exception is AI Perception's affiliation filter, which asks the engine through IGenericTeamAgentInterface. That interface is not Blueprintable, so the forward to GetTeamAttitudeBetween lives in a small C++ class you reparent your Blueprint to, written once.

  • Only the perceiver needs it; the actors being looked at need nothing but the component
  • Using CrimsonCore? Its characters, NPCs, AI controllers and player state already forward it

Inspect both sides of the wire without building any UI

Tools → Crimson Teams → Teams Dev Tools opens a live PIE window with a Net Context switch for the server and every client. Join, leave and toggle hostility on agents, read the attitude matrix, diff replication and drive parties.

  • Agents lists every team component with its tags and authority badge
  • Attitude Matrix draws your whole faction graph as an N×N grid
  • Replication diffs server against client and lists only the differences
  • Console cheats cover the same ground: CycleTeam, SetTeam, PartyInvite, PartyKick, ListParties
Crimson Teams Dev Tools on the Attitude Matrix tab with the Net Context set to Server: a grid of eight agents showing Friendly, Hostile and Neutral toward each other

Technical details

Engine
UE 5.8
Tested platforms
Windows
Blueprint-ready
Yes
C++ required
No
Network replicated
Yes
Dependencies
GameplayAbilities, GameplayTags, AIModule, ModularGameplay, GameFeatures, Niagara

Frequently asked questions

Do I need C++ to use it?
Almost never. Components, tags, attitude queries, party requests, async observers, the dev-tools window and the cheats are all Blueprint-accessible, and for a Blueprint project enabling the plugin is the whole install. The one exception is exposing attitude to engine AI perception: IGenericTeamAgentInterface is not Blueprintable, so the perceiving actor needs a small C++ class that forwards GetTeamAttitudeTowards to GetTeamAttitudeBetween. It is one class, written once, and CrimsonCore's classes already do it.
Does it work in multiplayer?
Yes, that's the point. Team state is server-authoritative and replicated with no client→server RPC, so a client-side mutation is a silent no-op; clients re-fire change events from OnRep. Party requests do go through Server RPCs on the member component, and the server answers every one with an ECrimsonPartyResult. A built-in dev-tools tab diffs server vs client so you can confirm the whole thing.
Will my AI actually re-evaluate when teams change?
Yes. On any change the subsystem refreshes AI perceivers (preserving last-known location, no ForgetActor), so an actor that just turned hostile gets perceived and a new ally is ignored, without leaving and re-entering perception. This needs the one-method forward described above on the perceiving actor.
How is a party different from a team tag?
A team tag is static faction identity; a party is consent between specific players, and it is exclusive: you are in one or none. Party membership is checked before every tag rule, so partying up beats faction hostility. Parties also outlive worlds: the subsystem sits on the GameInstance and members are keyed by unique net id, so seamless travel keeps everyone online, and a hard travel or a dropped connection marks a member offline while they keep their slot until the grace window expires.
Do parties need an online subsystem?
They need valid unique net ids, which is what the roster is keyed by. A PlayerState with no valid unique net id cannot join a party; the component logs a warning after it gives up polling for one. The engine's Null online subsystem provides ids in PIE and LAN sessions, so this is only a concern for setups that run with no online subsystem at all.
Does it depend on other Crimson plugins?
No. CrimsonTeams is fully standalone and needs only engine plugins; it owns its team contract (ICrimsonTeamAgentInterface) itself. CrimsonCore, the free integration layer from the Crimson Discord, adds the Team Attitude interaction condition and pawns, controllers and a player state that already forward the interface. Without it, wire the same hooks yourself.
Does it integrate with GAS?
Yes. It gates damage by attitude and filters ability targets (hostile-only, friendly-only, …) into a GAS target-data handle for AoE. Evaluate attitude when the hit lands rather than when the ability starts: a target can change teams mid-ability, and that is the whole point of computing it live.

Build factions that react in real time

Drop in the agent component, tag your actors, and you've got replicated friend-or-foe with live AI re-aggro. Add the party member component and players can group up across travel and reconnects. Start with the Quick Start or follow the course.

Pricing

CrimsonTeams is sold on Fab under Epic’s two standard licenses. Both include the full plugin, source, and updates.

Personal$14.99For individuals & teams under $100K revenueComing to Fab. Join the Discord
Professional$29.99For companies over $100K revenueComing to Fab. Join the Discord