lobby

package
v0.18.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2026 License: LGPL-3.0 Imports: 3 Imported by: 0

README

Lobby Plugin

A flexible lobby/party system for Cardinal worlds, handling player grouping and session management. Implemented as a Cardinal plugin.

Regenerating the wire code

The wire.gen.go files are generated by world sdk generate. From the world-engine repo root:

world sdk generate ./pkg/plugin/lobby \
  --go-out ./pkg/plugin/lobby/gen

Requires Docker (the generator runs protoc/buf in a container). Rerun after changing any command/component/event struct in this plugin.

--proto-out ./pkg/plugin/lobby/proto is optional. The generator compiles the schema in a temp dir, so nothing in the build reads a persisted copy. Add the flag when you want to read the wire contract directly — what a field became, or whether a type fell back to opaque JSON.

Quick Start

import (
    "github.com/argus-labs/world-engine/pkg/cardinal"
    "github.com/argus-labs/world-engine/pkg/lobby"
)

func main() {
    w, _ := cardinal.NewWorld(cardinal.WorldOptions{...})

    w.RegisterPlugin(lobby.NewPlugin(lobby.Config{
        LobbyWorld: cardinal.OtherWorld{
            Region:       "us-west",
            Organization: "myorg",
            Project:      "myproject",
            ShardID:      "lobby-shard-1",
        },
    }))

    w.StartGame()
}

Overview

  • PvE: Lobby acts as a persistent party that plays games together
  • PvP: Lobby acts as a temporary session where multiple teams gather

Message Categories

The lobby package uses 4 message categories:

1. Command (Client ↔ Shard)

Client sends a command to the shard. Shard processes it and returns a result to the sender.

Command Request Fields Response Fields
CreateLobby Teams []TeamConfig, GameWorld, PlayerPassthroughData?, SessionPassthroughData? IsSuccess, Message, Lobby
JoinLobby InviteCode, TeamName?, PlayerPassthroughData? IsSuccess, Message, Lobby
JoinTeam TeamName IsSuccess, Message
LeaveLobby - IsSuccess, Message
SetReady IsReady IsSuccess, Message
KickPlayer TargetPlayerID IsSuccess, Message
TransferLeader TargetPlayerID IsSuccess, Message
StartSession - IsSuccess, Message
GenerateInviteCode - IsSuccess, Message, InviteCode
UpdateSessionPassthrough PassthroughData IsSuccess, Message
UpdatePlayerPassthrough PassthroughData IsSuccess, Message
Heartbeat - - (no response)

All commands include RequestID for request/response correlation (except Heartbeat).

2. Event (Shard → All Clients, broadcast)

Shard broadcasts state changes to all subscribed clients.

Event Fields Description
LobbyCreatedEvent LobbyID, LeaderID, InviteCode Lobby created
PlayerJoinedEvent LobbyID, TeamName, Player (PlayerState) Player joined
PlayerLeftEvent LobbyID, PlayerID Player left
PlayerKickedEvent LobbyID, PlayerID, KickerID Player kicked
PlayerReadyEvent LobbyID, PlayerID, IsReady Ready status changed
PlayerChangedTeamEvent LobbyID, PlayerID, OldTeamName, NewTeamName Player changed team
LeaderChangedEvent LobbyID, OldLeaderID, NewLeaderID Leadership transferred
SessionStartedEvent LobbyID Session started
SessionEndedEvent LobbyID Session ended
SessionAwaitingAllocationEvent LobbyID Session is pending shard assignment; orchestrators listen for this
InviteCodeGeneratedEvent LobbyID, InviteCode New code generated
LobbyDeletedEvent LobbyID Lobby deleted (empty)
PlayerTimedOutEvent LobbyID, PlayerID Player removed due to missed heartbeats
SessionPassthroughUpdatedEvent Lobby Session passthrough data updated
PlayerPassthroughUpdatedEvent Lobby, PlayerID Player passthrough data updated
3. CrossShardCommand (Shard → Shard)

One shard sends a command to another shard.

Command Direction Fields Description
NotifySessionStartCommand Lobby → Game Lobby, LobbyWorld Notify game shard to start session
NotifySessionEndCommand Game → Lobby LobbyID Notify lobby shard to end session
AssignShardCommand Orchestrator → Lobby LobbyID, RequestID, GameWorld, Reason Complete a pending session-start by assigning a game shard (see Shard Assignment)
4. CrossShardResult (Shard → Shard, response)

Shard sends a response back to the originating shard.

Currently not needed. CrossShardCommands in this package don't require responses.

Data Structures

Lobby
Lobby
- ID string              // Unique identifier
- LeaderID string        // Player who controls the lobby
- Teams []Team           // List of teams
- InviteCode string      // Code for others to join
- GameWorld OtherWorld   // Target game shard address
- Session Session        // Current session state
- CreatedAt int64        // Unix timestamp
Team
Team
- TeamID string          // Unique team identifier
- Name string            // Team display name
- Players []PlayerState  // Players in team
- MaxPlayers int         // Max players (0 = unlimited)
PlayerState
PlayerState
- PlayerID string                 // Player identifier
- IsReady bool                    // Ready status
- PassthroughData map[string]any  // Forwarded to game shard
- JoinedAt int64                  // Unix timestamp when player joined
Session
Session
- State SessionState                   // idle | awaiting_allocation | in_session
- PassthroughData map[string]any       // Forwarded to game shard
- PendingRequestID string              // StartSessionCommand RequestID while awaiting_allocation
- PendingStartedAt int64               // Unix seconds at which awaiting_allocation began

Configuration

Option Description Default
LobbyWorld This lobby shard's address (for game shard to send NotifySessionEndCommand back) required
Provider Custom provider (optional, default provided) DefaultProvider
HeartbeatTimeout Seconds before a player is removed for not sending heartbeats. Clients should send heartbeats more frequently (e.g., every timeout/3 seconds). 30
AssignmentAuthority Accident-prevention filter for AssignShardCommand — dropped when cmd.Persona differs. Not authentication. cmd.Persona is not signature-verified at this layer, so a forged client command still passes if it matches. Real auth (NATS ACLs, gateway auth) must live above the plugin. empty
MaxAllocationTimeout Max seconds a lobby may sit in awaiting_allocation before the plugin fails the pending request. <= 0 disables timeout enforcement. 0 (disabled)

Cross-Shard Communication

When StartSessionCommand succeeds, NotifySessionStartCommand is sent to game shard:

type NotifySessionStartCommand struct {
    LobbyID    string             // The lobby whose session is starting
    LobbyWorld lobby.ShardAddress // For NotifySessionEndCommand callback
}

Game shard should:

  1. Register NotifySessionStartCommand and a system that handles it
  2. Run the game
  3. Send NotifySessionEndCommand back to lobby when game ends
// In game shard
w.RegisterCommand[lobby.NotifySessionStartCommand]()
w.RegisterSystem(&GameSessionSystem{})

type GameSessionSystem struct{}

func (*GameSessionSystem) Run(w *cardinal.World) {
    for cmd := range w.Commands[lobby.NotifySessionStartCommand]() {
        payload := cmd.Payload
        // payload.LobbyID identifies the lobby
        // payload.LobbyWorld for sending NotifySessionEndCommand back

        // When game ends:
        w.SendToShard(cardinal.OtherWorld(payload.LobbyWorld), lobby.NotifySessionEndCommand{
            LobbyID: payload.LobbyID,
        })
    }
}

Custom Provider

Override invite code generation:

type MyProvider struct {
    lobby.DefaultProvider
}

func (p MyProvider) GenerateInviteCode(l *lobby.Component) string {
    return generateMyCustomCode(8)
}

w.RegisterPlugin(lobby.NewPlugin(lobby.Config{
    LobbyWorld: cardinal.OtherWorld{...},
    Provider:   MyProvider{},
}))

Default: Hash(LobbyID + Timestamp) -> 6-char uppercase alphanumeric (excludes confusing chars: 0, O, I, L, 1).

Lifecycle

CreateLobby -> idle -> (players join, ready up) -> StartSession -> awaiting_allocation
                                                                         │
                                                                         v
                                                                  AssignShardCommand
                                                                         │
                                                                         v
                                                                     in_session
                                                                         │
                                                                         v
                                                                    EndSession
                                                                         │
                                                                         v
                                                                       idle
                                                          (players can start again)

StartSession does not commit the session directly — the lobby enters awaiting_allocation and emits SessionAwaitingAllocationEvent. An external orchestrator (another system running in the same shard) picks a game shard and sends AssignShardCommand back to complete the start.

Shard Assignment

When a StartSessionCommand is accepted, the plugin does not pick a game shard itself. Instead it transitions the lobby to awaiting_allocation and waits for an orchestrator to send AssignShardCommand. This lets consumers plug in any assignment strategy (static, round-robin, probe + claim, external matchmaker, etc.) without the lobby plugin knowing anything about the game.

⚠ If you enable this plugin, you MUST register an orchestrator

Every StartSessionCommand parks the lobby in awaiting_allocation and waits for AssignShardCommand. Without an orchestrator registered in the same shard, sessions never start and clients sit waiting until MaxAllocationTimeout expires (or forever, if unset). There is no implicit default behavior and no startup detection — the plugin cannot tell whether an orchestrator exists.

Always set MaxAllocationTimeout to a reasonable value (e.g., 30–60 seconds). This is your only safety net: if the orchestrator is missing or broken, the timeout fails the pending session and returns the lobby to idle instead of hanging forever.

The orchestrator is just a normal system

An orchestrator is not a special plugin or interface. It is a regular system registered in the same lobby shard.

Copy-paste template

Drop this into your lobby shard. Change the five REPLACE: markers and you're running. The rest is boilerplate — the system shape stays the same regardless of how fancy your assignment logic becomes.

Heads up: this minimal template has no in-flight tracking. It iterates every pending lobby each tick and sends AssignShardCommand unconditionally. The plugin's one-shot RequestID check rejects duplicates, but you'll see WARN logs for every redundant send until the lobby leaves awaiting_allocation. That's fine for the first smoke test or a one-server deployment; for anything real, track in-flight assignments — see the pool-based example below for the pattern (a PendingProbe-style component destroyed after the first send).

package main

import (
    "github.com/argus-labs/world-engine/pkg/cardinal"
    "github.com/argus-labs/world-engine/pkg/lobby"
)

type AssignerSystem struct{}

type lobbyRow struct {
    Lobby lobby.Component
}

func (*AssignerSystem) Run(w *cardinal.World) {
    // REPLACE: your lobby shard's own address.
    self := cardinal.OtherWorld{
        Region:       "us-west", // REPLACE
        Organization: "myorg",   // REPLACE
        Project:      "mygame",  // REPLACE
        ShardID:      "lobby",   // REPLACE
    }

    for refs := range w.Contains[lobbyRow]().Iter() {
        lob := refs.Get[lobby.Component]()
        if lob.Session.State != lobby.SessionStateAwaitingAllocation {
            continue
        }
        w.SendToShard(self, lobby.AssignShardCommand{
            LobbyID:   lob.ID,
            RequestID: lob.Session.PendingRequestID,
            GameWorld: cardinal.OtherWorld{
                Region:       "us-west", // REPLACE
                Organization: "myorg",   // REPLACE
                Project:      "mygame",  // REPLACE
                ShardID:      "game-shard-1", // REPLACE: pick your target shard
            },
        })
    }
}

Wire it up in main.go alongside the plugin:

w.RegisterPlugin(lobby.NewPlugin(lobby.Config{...}))
w.RegisterSystem(&AssignerSystem{})

That's it. Every StartSessionCommand now routes to the shard you named. To get smarter behavior (round-robin, probe-based idle selection, external matchmaker), replace the hardcoded ShardID with whatever selection logic you want — the command shape stays identical.

Minimum requirements for the orchestrator

All three fields are required for the command to be accepted:

Field Value Why
LobbyID lob.ID (from the Lobby entity) Tells the plugin which pending lobby this assignment is for.
RequestID lob.Session.PendingRequestID (echoed verbatim) Plugin rejects stale or mismatched assignments. Never generate your own — always read it from the lobby.
GameWorld cardinal.OtherWorld with at minimum a non-empty ShardID The full address of the game shard for this session. Empty ShardID = failure (regardless of Reason); Reason is only used as the failure message.
Example: pool-based orchestrator (probe + claim)

A realistic deployment with multiple game shards needs dynamic assignment. The shape below probes a pool of game shards, claims the first idle one, and releases claims when the session ends. This is a pattern only — adapt it to your own shard naming, pool sizing, and failure handling.

Components (two, both orchestrator-owned):

type ShardClaim struct {
    LobbyID   string  // which lobby owns the claim
    ShardID   string  // which game shard is bound
    ClaimedAt int64   // unix seconds
}
func (ShardClaim) Name() string { return "shard_claim" }

type PendingProbe struct {
    LobbyID   string  // lobby we've already fanned out probes for
    StartedAt int64
}
func (PendingProbe) Name() string { return "pending_probe" }

Custom commands for the game-shard round trip:

// Lobby → game shard: "are you idle?"
type CheckAvailabilityCommand struct {
    LobbyID       string
    SendbackWorld cardinal.OtherWorld // where to reply
}
func (CheckAvailabilityCommand) Name() string { return "check_availability" }

// Game shard → lobby: "here's my state"
type AvailabilityResponseCommand struct {
    LobbyID   string
    ShardID   string
    Idle      bool
    SessionID string  // empty if Idle
    StartedAt int64
}
func (AvailabilityResponseCommand) Name() string { return "availability_response" }

Three systems working together:

  1. ProbeOnSessionAwaitingAllocationSystem — scans lobbies; for each in awaiting_allocation with no PendingProbe yet, creates a PendingProbe entity and fans out CheckAvailabilityCommand to every shard in the pool (e.g., game-shard-1 .. game-shard-N).

  2. HandleAvailabilityResponseSystem — consumes AvailabilityResponseCommand. For each Idle=true response whose lobby is still pending and whose shard isn't already claimed: create a ShardClaim entity, destroy the PendingProbe, send lobby.AssignShardCommand{LobbyID, RequestID, GameWorld} to the lobby shard itself.

  3. ReleaseOnSessionEndSystem — scans the lobby table each tick; drops ShardClaim entities whose lobby is no longer in_session (session ended, cancelled, or lobby destroyed) and drops PendingProbe entities whose lobby left awaiting_allocation.

Game-shard side: a single responder system handles CheckAvailabilityCommand and replies with AvailabilityResponseCommand to SendbackWorld, reading idle state from whatever singleton the game uses to track its active session.

Why it's this many pieces: Cardinal's only inter-shard primitive is async SendCommand. Asking a shard "are you idle?" therefore requires a command out, a command back, and state to correlate them across ticks. Simpler orchestrators (static, round-robin) skip the probe entirely — see the minimal example above.

Orchestrator contract

Send AssignShardCommand to the lobby shard's own address with:

  • LobbyID — the lobby awaiting allocation
  • RequestID — echoed from lob.Session.PendingRequestID (the plugin rejects mismatches to guard against stale / duplicate commands)
  • GameWorld — the chosen game shard's full address, or empty ShardID (+ Reason) to fail the start

The plugin's handler validates the RequestID, checks cmd.Persona against AssignmentAuthority if configured, and rejects anything that doesn't match. On success it writes GameWorld onto lobby.GameWorld, transitions to in_session, dispatches NotifySessionStartCommand, and emits the final StartSessionResult.

Timing contract

Because assignment is asynchronous, StartSessionResult is emitted several ticks after the StartSessionCommand arrives (orchestrator round-trip + decision). Clients should not set short timeouts on StartSessionResult — treat session start as a matchmaking-style wait.

Key Behaviors

  • Invite code persists on leader transfer/leave (no auto-regeneration)
  • Leader-only actions: kick, transfer, start session, regenerate code
  • Ready check: All players (including leader) must be ready to start
  • Session lock: No join/team-change during in_session (leave is always allowed)
  • Auto-reset: After session ends, all players reset to not-ready
  • Auto-delete: Lobby deleted when last player leaves
  • Per-lobby game shard: Each lobby specifies its target game shard via GameWorld

Heartbeat System

The lobby package includes a heartbeat mechanism to detect and remove disconnected players. It uses a deadline-based (lease) approach where clients must continuously renew their presence.

How It Works
  1. Clients send HeartbeatCommand periodically (e.g., every HeartbeatTimeout/3 seconds)
  2. Server stores a deadline for each player: deadline = now + HeartbeatTimeout
  3. On each heartbeat, the deadline is extended: deadline = now + HeartbeatTimeout
  4. Server removes players when now >= deadline (player failed to renew their lease)
  5. Events emitted: PlayerTimedOutEvent when a player times out
Deadline Approach

When a player joins or sends a heartbeat:

deadline = currentTime + HeartbeatTimeout

When checking for timeouts (every tick):

if currentTime >= deadline {
    // Player timed out - remove from lobby
}

This approach is simpler than tracking "last heartbeat time" because:

  • No subtraction needed at check time (now >= deadline vs now - lastHeartbeat > timeout)
  • The deadline is the actual removal time, making debugging easier
Configuration
w.RegisterPlugin(lobby.NewPlugin(lobby.Config{
    LobbyWorld:       cardinal.OtherWorld{...},
    HeartbeatTimeout: 30, // Remove player after 30 seconds without heartbeat
}))
Client Implementation

Clients should:

  1. Start a heartbeat timer immediately after creating or joining a lobby
  2. Send HeartbeatCommand at the configured interval
  3. Stop the timer after leaving the lobby
// Client-side pseudocode
ticker := time.NewTicker(10 * time.Second)
go func() {
    for range ticker.C {
        sendCommand(lobby.HeartbeatCommand{})
    }
}()

Important: Start heartbeats immediately after joining. The timeout clock starts the moment a player joins, not when they send their first heartbeat.

Timeout Behavior

When a player joins a lobby, their deadline is set to now + timeout. This means:

  • Players must send heartbeats before their deadline expires or they are removed
  • This prevents "zombie" players who join but never send heartbeats from occupying slots indefinitely

When a player times out:

  • Player is removed from the lobby
  • PlayerTimedOutEvent is emitted
  • If player was leader, leadership auto-transfers to another player
  • If lobby becomes empty, it is deleted

Documentation

Overview

Package lobby provides a flexible lobby/party system for Cardinal worlds.

This package handles player grouping and session management. Players can create lobbies, invite friends via invite codes, form teams, ready up, and start sessions.

Usage:

w, err := cardinal.NewWorld(cardinal.WorldOptions{...})
if err != nil {
	panic(err)
}
w.RegisterPlugin(lobby.NewPlugin(lobby.Config{
	LobbyWorld: myLobbyWorld,
}))
w.StartGame()

The package registers the following systems:

  • InitSystem (Init hook): Invalidates the lookup index so the next tick rebuilds it
  • LobbySystem (Update hook): Processes lobby commands

Commands:

  • CreateLobby: Player creates a new lobby, becomes leader
  • JoinLobby: Player joins via invite code
  • JoinTeam: Player moves to a different team
  • LeaveLobby: Player leaves current lobby
  • SetReady: Player marks ready/unready
  • KickPlayer: Leader removes a player
  • TransferLeader: Leader gives leadership to another
  • StartSession: Leader starts the session
  • EndSession: End the current session
  • GenerateInviteCode: Leader generates new invite code

Index

Constants

View Source
const (
	SessionStateIdle               = component.SessionStateIdle
	SessionStateAwaitingAllocation = component.SessionStateAwaitingAllocation
	SessionStateInSession          = component.SessionStateInSession
)

Session states.

Variables

This section is empty.

Functions

This section is empty.

Types

type AssignShardCommand

type AssignShardCommand = system.AssignShardCommand

Re-export types for easier user access.

type Component

type Component = component.LobbyComponent

Data structures.

type Config

type Config struct {
	// LobbyWorld is this lobby shard's address.
	// Included in NotifySessionStartCommand so game shard can send NotifySessionEndCommand back.
	LobbyWorld cardinal.OtherWorld

	// Provider is the customizable provider for the lobby system.
	// If nil, DefaultProvider is used.
	Provider Provider

	// AssignmentAuthority is an accident-prevention filter — not
	// authentication. Dropped commands whose cmd.Persona differs from
	// this value. cmd.Persona is not signature-verified at this layer, so
	// this does NOT protect against a malicious client; real auth belongs
	// above the plugin (NATS ACLs, gateway auth). Empty = no filter.
	AssignmentAuthority string

	// MaxAllocationTimeout bounds how long (in seconds) a lobby may sit in
	// SessionStateAwaitingAllocation before the lobby fails the start
	// itself. Values <= 0 disable timeout enforcement.
	MaxAllocationTimeout int64

	// HeartbeatTimeout is how long (in seconds) before a player is removed for not sending heartbeats.
	// Clients should send heartbeats more frequently than this (e.g., every timeout/3 seconds).
	// Default: 30 seconds.
	HeartbeatTimeout int64

	// LobbyPresets is the server-owned registry of team configurations
	// that clients can reference by label in CreateLobbyCommand.Preset.
	// The map key is the preset label; the value is the ordered list of
	// teams that a lobby created with that preset will contain. Server
	// operators are the source of truth for team caps; clients cannot
	// supply arbitrary team configurations.
	LobbyPresets map[string][]TeamConfig
}

Config holds configuration for the lobby package.

type CreateLobbyCommand

type CreateLobbyCommand = system.CreateLobbyCommand

Commands.

type CreateLobbyResult

type CreateLobbyResult = system.CreateLobbyResult

CommandResult (persona-prefixed responses).

type CreatedEvent

type CreatedEvent = system.LobbyCreatedEvent

Events (Broadcast).

type DefaultProvider

type DefaultProvider = system.DefaultProvider

Re-export types for easier user access.

type DeletedEvent

type DeletedEvent = system.LobbyDeletedEvent

Re-export types for easier user access.

type GameWorld

type GameWorld = cardinal.OtherWorld

Re-export types for easier user access.

type GenerateInviteCodeCommand

type GenerateInviteCodeCommand = system.GenerateInviteCodeCommand

Re-export types for easier user access.

type GenerateInviteCodeResult

type GenerateInviteCodeResult = system.GenerateInviteCodeResult

Re-export types for easier user access.

type GetAllPlayersCommand

type GetAllPlayersCommand = system.GetAllPlayersCommand

Re-export types for easier user access.

type GetAllPlayersResult

type GetAllPlayersResult = system.GetAllPlayersResult

Re-export types for easier user access.

type GetLobbyCommand

type GetLobbyCommand = system.GetLobbyCommand

Re-export types for easier user access.

type GetLobbyResult

type GetLobbyResult = system.GetLobbyResult

Re-export types for easier user access.

type GetPlayerCommand

type GetPlayerCommand = system.GetPlayerCommand

Re-export types for easier user access.

type GetPlayerResult

type GetPlayerResult = system.GetPlayerResult

Re-export types for easier user access.

type HeartbeatCommand

type HeartbeatCommand = system.HeartbeatCommand

Re-export types for easier user access.

type InviteCodeGeneratedEvent

type InviteCodeGeneratedEvent = system.InviteCodeGeneratedEvent

Re-export types for easier user access.

type JoinLobbyCommand

type JoinLobbyCommand = system.JoinLobbyCommand

Re-export types for easier user access.

type JoinLobbyResult

type JoinLobbyResult = system.JoinLobbyResult

Re-export types for easier user access.

type JoinTeamCommand

type JoinTeamCommand = system.JoinTeamCommand

Re-export types for easier user access.

type JoinTeamResult

type JoinTeamResult = system.JoinTeamResult

Re-export types for easier user access.

type KickPlayerCommand

type KickPlayerCommand = system.KickPlayerCommand

Re-export types for easier user access.

type KickPlayerResult

type KickPlayerResult = system.KickPlayerResult

Re-export types for easier user access.

type LeaderChangedEvent

type LeaderChangedEvent = system.LeaderChangedEvent

Re-export types for easier user access.

type LeaveLobbyCommand

type LeaveLobbyCommand = system.LeaveLobbyCommand

Re-export types for easier user access.

type LeaveLobbyResult

type LeaveLobbyResult = system.LeaveLobbyResult

Re-export types for easier user access.

type NotifySessionEndCommand

type NotifySessionEndCommand = system.NotifySessionEndCommand

Re-export types for easier user access.

type NotifySessionStartCommand

type NotifySessionStartCommand = system.NotifySessionStartCommand

Cross-Shard Commands.

type PlayerChangedTeamEvent

type PlayerChangedTeamEvent = system.PlayerChangedTeamEvent

Re-export types for easier user access.

type PlayerComponent

type PlayerComponent = component.PlayerComponent

Re-export types for easier user access.

type PlayerJoinedEvent

type PlayerJoinedEvent = system.PlayerJoinedEvent

Re-export types for easier user access.

type PlayerKickedEvent

type PlayerKickedEvent = system.PlayerKickedEvent

Re-export types for easier user access.

type PlayerLeftEvent

type PlayerLeftEvent = system.PlayerLeftEvent

Re-export types for easier user access.

type PlayerPassthroughUpdatedEvent

type PlayerPassthroughUpdatedEvent = system.PlayerPassthroughUpdatedEvent

Re-export types for easier user access.

type PlayerReadyEvent

type PlayerReadyEvent = system.PlayerReadyEvent

Re-export types for easier user access.

type PlayerTimedOutEvent

type PlayerTimedOutEvent = system.PlayerTimedOutEvent

Re-export types for easier user access.

type Plugin

type Plugin struct {
	// contains filtered or unexported fields
}

Plugin owns the configuration and derived lookup index for one Cardinal world. Create a separate instance for each world.

func NewPlugin

func NewPlugin(config Config) *Plugin

NewPlugin creates a new lobby plugin with the given configuration.

func (*Plugin) Register

func (p *Plugin) Register(w *cardinal.World)

Register implements cardinal.Plugin. Each plugin instance belongs to one world. Registering the same instance twice panics.

type Provider

type Provider = system.LobbyProvider

Provider.

type Session

type Session = component.Session

Re-export types for easier user access.

type SessionAwaitingAllocationEvent

type SessionAwaitingAllocationEvent = system.SessionAwaitingAllocationEvent

Re-export types for easier user access.

type SessionEndedEvent

type SessionEndedEvent = system.SessionEndedEvent

Re-export types for easier user access.

type SessionPassthroughUpdatedEvent

type SessionPassthroughUpdatedEvent = system.SessionPassthroughUpdatedEvent

Re-export types for easier user access.

type SessionStartedEvent

type SessionStartedEvent = system.SessionStartedEvent

Re-export types for easier user access.

type SessionState

type SessionState = component.SessionState

Re-export types for easier user access.

type SetReadyCommand

type SetReadyCommand = system.SetReadyCommand

Re-export types for easier user access.

type SetReadyResult

type SetReadyResult = system.SetReadyResult

Re-export types for easier user access.

type ShardAddress added in v0.14.0

type ShardAddress = component.ShardAddress

Re-export types for easier user access.

type StartSessionCommand

type StartSessionCommand = system.StartSessionCommand

Re-export types for easier user access.

type StartSessionPayload

type StartSessionPayload = system.StartSessionPayload // Alias for NotifySessionStartCommand

Re-export types for easier user access.

type StartSessionResult

type StartSessionResult = system.StartSessionResult

Re-export types for easier user access.

type Team

type Team = component.Team

Re-export types for easier user access.

type TeamConfig

type TeamConfig = system.TeamConfig

Re-export types for easier user access.

type TransferLeaderCommand

type TransferLeaderCommand = system.TransferLeaderCommand

Re-export types for easier user access.

type TransferLeaderResult

type TransferLeaderResult = system.TransferLeaderResult

Re-export types for easier user access.

type UpdatePlayerPassthroughCommand

type UpdatePlayerPassthroughCommand = system.UpdatePlayerPassthroughCommand

Re-export types for easier user access.

type UpdatePlayerPassthroughResult

type UpdatePlayerPassthroughResult = system.UpdatePlayerPassthroughResult

Re-export types for easier user access.

type UpdateSessionPassthroughCommand

type UpdateSessionPassthroughCommand = system.UpdateSessionPassthroughCommand

Re-export types for easier user access.

type UpdateSessionPassthroughResult

type UpdateSessionPassthroughResult = system.UpdateSessionPassthroughResult

Re-export types for easier user access.

Directories

Path Synopsis
gen
Code generated by world sdk generate.
Code generated by world sdk generate.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL