Parties
A party is a dynamic, exclusive group of players. It is not a team tag: tags are static faction identity, parties are consent between specific players. The two compose - party membership is checked before any tag rule, so two players from hostile factions who party up are Friendly to each other and to nobody else.
Where the state lives
| Piece | Lives on | Holds | Replicates |
|---|---|---|---|
UCrimsonPartySubsystem | GameInstance (server is authoritative; clients hold only the actor registry) | Party records, pending invites and suggestions, online member map, expiry timers | Never - it outlives worlds, which is why parties survive level travel |
ACrimsonPartyInfo | One actor per party, per world, spawned by the subsystem | Leader, roster (FCrimsonPartyMemberEntry: id, display name, online flag, PlayerState, join order), max size | To party members only (IsNetRelevantFor), so nobody sees a roster they are not in |
UCrimsonPartyMemberComponent | Each PlayerState | PartyId; PendingInvites, SentInvites, PendingInviteSuggestions; the Server RPC entry points | PartyId to everyone (attitude needs it on every machine); the invite lists owner-only |
How a request flows
- A client calls
Invite Playeron its member component. On the server the same call runs directly. - The component's Server RPC validates and forwards to the subsystem, which checks the rules (self, target already partied or invited, party full, leader-only, attitude gate) and mutates its record.
- The subsystem pushes the record into the party actor (roster, leader, size) and the invite lists into the affected components. Those replicate; clients fire their delegates and messages from the OnReps.
- The server answers the requester on
On Operation Resultwith theECrimsonPartyResult.
Identity, travel, and reconnects
Members are keyed by the PlayerState's unique net id, not the PlayerState object. That id is assigned right after the PlayerState begins play on a network login, so the component polls briefly until it lands, then registers with the subsystem. From then on:
| Event | What happens |
|---|---|
| Seamless travel | PlayerStates persist; the subsystem respawns the party actor in the new world when its actors initialize. Nothing goes offline |
| Hard travel / map load | Every PlayerState ends play, so every member is marked offline and the grace timer starts. The new world's PlayerStates re-register by id and are back online before anyone can act - keep Offline Member Grace Seconds above your longest load |
| Disconnect | The member stays in the roster as offline, still holding a slot, until they reconnect (instant re-attach) or the grace window ends (removed with LeaveReason = Expired). The leader can kick them early |
| Leader offline | Leadership does not move while the leader is merely offline; it moves on leave, kick, or expiry. With Only Leader Can Invite on, members can still suggest invites, which the leader sees on return |
Unique net id required
A PlayerState with no valid unique net id (no online subsystem at all) cannot join a party; the component logs a warning after it gives up polling. The engine's Null online subsystem provides ids in PIE and LAN sessions.
Invite rules
- Inviting with no party creates one, led by the inviter, at
Default Max Party Size. Invite Attitude Gatecompares the inviter's team attitude toward the target (through pawns when possessed, else PlayerStates). Friendly is always allowed; Neutral needs Friendly & Neutral or Any; Hostile needs Any.- Suggestions are gated from the leader's perspective when the leader is online, since the leader will be the inviter.
- Accepting an invite leaves the current party first. Declining, canceling, expiry, and party dissolution all resolve the invite; the inviter hears which on
On Sent Invite Resolved. - Offline members count toward the size: a slot is a slot until it expires or is kicked.
See also
- How-To: Form Parties - the recipe
- Concept: Dynamic Attitude & Multiplayer - how a membership change refreshes AI perception, exactly like a tag change