Documentation
¶
Index ¶
- Constants
- type LobbyComponent
- func (l *LobbyComponent) AddPlayerToTeam(playerID, teamID string) bool
- func (l *LobbyComponent) AddTeam(team Team) bool
- func (c LobbyComponent) AppendWire(b []byte) []byte
- func (c LobbyComponent) FromProto(p *pbcomponent.LobbyComponent) LobbyComponent
- func (l *LobbyComponent) GetAllPlayerIDs() []string
- func (l *LobbyComponent) GetTeam(teamID string) *Team
- func (l *LobbyComponent) HasPlayer(playerID string) bool
- func (l *LobbyComponent) IsLeader(playerID string) bool
- func (c LobbyComponent) MarshalWire() []byte
- func (l *LobbyComponent) MovePlayerToTeam(playerID, oldTeamID, newTeamID string) bool
- func (LobbyComponent) Name() string
- func (l *LobbyComponent) Players() []string
- func (c LobbyComponent) ProtoDescriptor() protoreflect.MessageDescriptor
- func (l *LobbyComponent) RemovePlayerFromTeam(playerID, teamID string) bool
- func (c LobbyComponent) SizeWire() int
- func (l *LobbyComponent) TeamList() []Team
- func (c LobbyComponent) ToProto() *pbcomponent.LobbyComponent
- func (c LobbyComponent) UnmarshalWire(data []byte) (any, error)
- type PlayerComponent
- func (c PlayerComponent) AppendWire(b []byte) []byte
- func (c PlayerComponent) FromProto(p *pbcomponent.PlayerComponent) PlayerComponent
- func (c PlayerComponent) MarshalWire() []byte
- func (PlayerComponent) Name() string
- func (c PlayerComponent) ProtoDescriptor() protoreflect.MessageDescriptor
- func (c PlayerComponent) SizeWire() int
- func (c PlayerComponent) ToProto() *pbcomponent.PlayerComponent
- func (c PlayerComponent) UnmarshalWire(data []byte) (any, error)
- type Session
- type SessionState
- type ShardAddress
- type Team
- type TeamConfig
Constants ¶
const ( // MaxLobbyPlayers bounds the whole-lobby roster, across all teams. MaxLobbyPlayers = 16 // MaxLobbyTeams bounds how many teams a preset may declare for one lobby. MaxLobbyTeams = 4 )
Structural ceilings for the lobby roster. These are storage bounds, not game rules: the game rule is Team.MaxPlayers, which comes from the preset and stays configurable per deployment. A lobby cannot exceed these no matter what a preset asks for, because component data has to be fixed-size — a slice field would make a component copy alias the live world.
Raising either is safe for existing snapshots: the generated decoder writes what arrives and zeroes the rest. Lowering one is survivable but lossy — the decoder caps the array writes yet copies PlayerCount and TeamCount verbatim, so a snapshot from a larger build restores a count the array cannot satisfy. Reads go through livePlayers/liveTeams, which clamp, and the first mutation writes the clamped value back. Treat these as a floor that only moves up.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type LobbyComponent ¶
type LobbyComponent struct {
// ID is the unique identifier for the lobby.
ID string `json:"id"`
// LeaderID is the player who controls the lobby.
LeaderID string `json:"leader_id"`
// PlayerIDs is the lobby-wide roster. Only the first PlayerCount entries are live; the rest are
// zero. Reads go through Players() rather than ranging the array. Order is meaningful: leader
// succession takes the first entry, so removals shift the tail down rather than swapping.
PlayerIDs [MaxLobbyPlayers]string `json:"player_ids"`
PlayerCount int `json:"player_count"`
// Teams holds the lobby's team configuration and live per-team counts. Only the first TeamCount
// entries are live.
Teams [MaxLobbyTeams]Team `json:"teams"`
TeamCount int `json:"team_count"`
// InviteCode is the code for others to join.
InviteCode string `json:"invite_code"`
// GameWorld is the target game shard address.
GameWorld ShardAddress `json:"game_world"`
// Session is the current session state.
Session Session `json:"session"`
// CreatedAt is the Unix timestamp when the lobby was created.
CreatedAt int64 `json:"created_at"`
}
LobbyComponent represents a lobby where players gather. Following rampage-backend pattern: Name() uses value receiver for ecs.Component interface, helper methods use pointer receivers. This may change based on best practices.
func (*LobbyComponent) AddPlayerToTeam ¶
func (l *LobbyComponent) AddPlayerToTeam(playerID, teamID string) bool
AddPlayerToTeam records a player in the roster and charges them to a team. Returns false if the player is already here, the roster is at MaxLobbyPlayers, the team does not exist, or the team is at its configured capacity. Note: This only updates lobby membership. PlayerComponent must be created separately.
func (*LobbyComponent) AddTeam ¶
func (l *LobbyComponent) AddTeam(team Team) bool
AddTeam appends a team. Returns false if the lobby already holds MaxLobbyTeams.
func (LobbyComponent) AppendWire ¶ added in v0.16.9
func (c LobbyComponent) AppendWire(b []byte) []byte
func (LobbyComponent) FromProto ¶ added in v0.15.0
func (c LobbyComponent) FromProto(p *pbcomponent.LobbyComponent) LobbyComponent
func (*LobbyComponent) GetAllPlayerIDs ¶
func (l *LobbyComponent) GetAllPlayerIDs() []string
GetAllPlayerIDs returns all player IDs in the lobby.
func (*LobbyComponent) GetTeam ¶
func (l *LobbyComponent) GetTeam(teamID string) *Team
GetTeam returns a team by ID, or nil.
func (*LobbyComponent) HasPlayer ¶
func (l *LobbyComponent) HasPlayer(playerID string) bool
HasPlayer returns true if the player is in this lobby.
func (*LobbyComponent) IsLeader ¶
func (l *LobbyComponent) IsLeader(playerID string) bool
IsLeader returns true if the player is the lobby leader.
func (LobbyComponent) MarshalWire ¶ added in v0.15.0
func (c LobbyComponent) MarshalWire() []byte
func (*LobbyComponent) MovePlayerToTeam ¶
func (l *LobbyComponent) MovePlayerToTeam(playerID, oldTeamID, newTeamID string) bool
MovePlayerToTeam moves a player between teams. The roster is unchanged — only the per-team counts and the caller's PlayerComponent.TeamID move. Returns false if the player is not in this lobby, the target team does not exist, or the target is full.
func (LobbyComponent) Name ¶
func (LobbyComponent) Name() string
Name returns the component name for ECS registration.
func (*LobbyComponent) Players ¶ added in v0.16.5
func (l *LobbyComponent) Players() []string
func (LobbyComponent) ProtoDescriptor ¶ added in v0.16.4
func (c LobbyComponent) ProtoDescriptor() protoreflect.MessageDescriptor
func (*LobbyComponent) RemovePlayerFromTeam ¶
func (l *LobbyComponent) RemovePlayerFromTeam(playerID, teamID string) bool
RemovePlayerFromTeam drops a player from the roster and uncharges their team. Note: This only updates lobby membership. PlayerComponent must be deleted separately.
func (LobbyComponent) SizeWire ¶ added in v0.16.9
func (c LobbyComponent) SizeWire() int
func (*LobbyComponent) TeamList ¶ added in v0.16.5
func (l *LobbyComponent) TeamList() []Team
TeamList returns the lobby's live teams.
Exported because the clamp has to be reachable from outside this package: iterating TeamCount directly indexes past Teams when a snapshot restores a count from a build with a larger MaxLobbyTeams, and the entries between the live count and the raw one are zero Teams whose MaxPlayers of 0 reads as unlimited — a phantom team with an empty ID that accepts players.
func (LobbyComponent) ToProto ¶ added in v0.15.0
func (c LobbyComponent) ToProto() *pbcomponent.LobbyComponent
func (LobbyComponent) UnmarshalWire ¶ added in v0.15.0
func (c LobbyComponent) UnmarshalWire(data []byte) (any, error)
type PlayerComponent ¶
type PlayerComponent struct {
PlayerID string `json:"player_id"`
LobbyID string `json:"lobby_id"`
// TeamID is the authoritative record of which team this player is on. The lobby's roster tracks
// membership of the lobby; which team a player belongs to lives here and nowhere else.
TeamID string `json:"team_id"`
IsReady bool `json:"is_ready"`
// PassthroughData is client-authored JSON the plugin never reads. It relays the blob between
// clients unchanged, so it is carried as text rather than decoded — see Session.PassthroughData.
PassthroughData string `json:"passthrough_data,omitempty"`
JoinedAt int64 `json:"joined_at"` // Unix timestamp when player joined
}
PlayerComponent represents a player entity in a lobby. Players are created when joining a lobby and deleted when leaving.
func (PlayerComponent) AppendWire ¶ added in v0.16.9
func (c PlayerComponent) AppendWire(b []byte) []byte
func (PlayerComponent) FromProto ¶ added in v0.15.0
func (c PlayerComponent) FromProto(p *pbcomponent.PlayerComponent) PlayerComponent
func (PlayerComponent) MarshalWire ¶ added in v0.15.0
func (c PlayerComponent) MarshalWire() []byte
func (PlayerComponent) Name ¶
func (PlayerComponent) Name() string
Name returns the component name for ECS registration.
func (PlayerComponent) ProtoDescriptor ¶ added in v0.16.4
func (c PlayerComponent) ProtoDescriptor() protoreflect.MessageDescriptor
func (PlayerComponent) SizeWire ¶ added in v0.16.9
func (c PlayerComponent) SizeWire() int
func (PlayerComponent) ToProto ¶ added in v0.15.0
func (c PlayerComponent) ToProto() *pbcomponent.PlayerComponent
func (PlayerComponent) UnmarshalWire ¶ added in v0.15.0
func (c PlayerComponent) UnmarshalWire(data []byte) (any, error)
type Session ¶
type Session struct {
State SessionState `json:"state"`
// PassthroughData is client-authored JSON that the lobby relays between clients without ever
// reading a key from it. Carried as text, not a decoded map: decoding would buy nothing (no code
// here indexes it) and a map in a component makes a copy alias the stored value. Validity is the
// client's business — proto rejects non-UTF-8 at the boundary, which is the only guarantee the
// shard needs.
PassthroughData string `json:"passthrough_data,omitempty"`
// PendingRequestID holds the StartSessionCommand RequestID while the
// lobby waits in SessionStateAwaitingAllocation for an external shard
// assignment. Empty in other states.
PendingRequestID string `json:"pending_request_id,omitempty"`
// PendingStartedAt records the unix timestamp (seconds) at which the
// lobby entered SessionStateAwaitingAllocation. Used by timeout
// enforcement. Zero in other states.
PendingStartedAt int64 `json:"pending_started_at,omitempty"`
}
Session represents the current session state of a lobby.
func (Session) AppendWire ¶ added in v0.16.9
func (Session) FromProto ¶ added in v0.15.0
func (c Session) FromProto(p *pbcomponent.Session) Session
func (Session) ToProto ¶ added in v0.15.0
func (c Session) ToProto() *pbcomponent.Session
type SessionState ¶
type SessionState string
SessionState represents the current state of a lobby session.
const ( SessionStateIdle SessionState = "idle" // Lobby is waiting, not in a session SessionStateAwaitingAllocation SessionState = "awaiting_allocation" // Lobby is awaiting external shard assignment SessionStateInSession SessionState = "in_session" // Lobby is currently in a game session )
type ShardAddress ¶ added in v0.15.0
ShardAddress mirrors cardinal.OtherWorld for wire types (commands, events, components). A wire type can't carry cardinal.OtherWorld directly — it's cross-module to the generator, which would block. The fields are identical, so the two convert with a plain Go struct cast: cardinal.OtherWorld(a) and back.
TODO(cross-module): this mirror duplicates cardinal.OtherWorld. Since the wire is proto, the cleaner long-term fix is to import world-engine's committed other_world.proto instead of mirroring — deferred, the import path (per-module type→proto manifest + buf staging) is high effort. See sdkgen.go.
func (ShardAddress) AppendWire ¶ added in v0.16.9
func (c ShardAddress) AppendWire(b []byte) []byte
func (ShardAddress) FromProto ¶ added in v0.15.0
func (c ShardAddress) FromProto(p *pbcomponent.ShardAddress) ShardAddress
func (ShardAddress) SizeWire ¶ added in v0.16.9
func (c ShardAddress) SizeWire() int
func (ShardAddress) ToProto ¶ added in v0.15.0
func (c ShardAddress) ToProto() *pbcomponent.ShardAddress
type Team ¶
type Team struct {
// TeamID is the stable identifier used to reference this team in all
// commands and events. Server-assigned at lobby creation from the
// preset registry and immutable afterward.
TeamID string `json:"team_id"`
// MaxPlayers is the game rule from the preset. MaxPlayers <= 0 means unlimited, which still
// cannot exceed MaxLobbyPlayers.
MaxPlayers int `json:"max_players"`
PlayerCount int `json:"player_count"`
}
Team is a team within a lobby: its identity, its capacity rule, and how many players are currently charged to it. It holds no roster — the lobby owns one roster for all teams, and a player's team is PlayerComponent.TeamID. PlayerCount exists so the capacity check stays O(1) without walking either.
func (Team) AppendWire ¶ added in v0.16.9
func (Team) ToProto ¶ added in v0.15.0
func (c Team) ToProto() *pbcomponent.Team
type TeamConfig ¶
TeamConfig is a creation-time team specification used inside a lobby preset. Server operators declare presets in lobby.Config.LobbyPresets; clients choose a preset by name on CreateLobbyCommand. MaxPlayers <= 0 means unlimited.