Documentation
¶
Index ¶
- Constants
- Variables
- func NewAuthoritativeMatchID() string
- func NewPubSubForwarder(rdb *redis.Client, sourceNode string, logger *zap.Logger) ...
- func NewPubSubSignalForwarder(rdb *redis.Client, sourceNode string, logger *zap.Logger) func(ctx context.Context, targetNodeID, matchID string, data string) error
- func PublishRelayFanout(ctx context.Context, rdb *redis.Client, sourceNode, matchID, kind string, ...) error
- func ResolveNodeID() string
- type ActiveMatch
- type ClusterInputMessage
- type ClusterSignalMessage
- type GoMatchDispatcher
- func (d *GoMatchDispatcher) BroadcastMessage(opCode int64, data []byte, presences []runtime.Presence, ...) error
- func (d *GoMatchDispatcher) BroadcastMessageDeferred(opCode int64, data []byte, presences []runtime.Presence, ...) error
- func (d *GoMatchDispatcher) MatchKick(presences []runtime.Presence) error
- func (d *GoMatchDispatcher) MatchLabelUpdate(label string) error
- type MatchDataImpl
- type MatchInput
- type MatchLoop
- func (ml *MatchLoop) EnqueueSignal(data string)
- func (ml *MatchLoop) GetPresences() []*PresenceImpl
- func (ml *MatchLoop) JoinAttempt(userID, username, sessionID string, metadata map[string]string) (bool, error)
- func (ml *MatchLoop) KickPlayer(sessionID string)
- func (ml *MatchLoop) SetGoMatch(goMatch runtime.Match, initialGoState interface{}, logger runtime.Logger, ...)
- func (ml *MatchLoop) SetSandbox(sb *runtime.Sandbox)
- func (ml *MatchLoop) Start(ctx context.Context)
- func (ml *MatchLoop) SubmitInput(input MatchInput)
- func (ml *MatchLoop) SubmitLeave(userID, sessionID string)
- func (ml *MatchLoop) SubmitSignal(data string) (string, error)
- func (ml *MatchLoop) UpdateLabel(label string) error
- type MatchState
- type PresenceImpl
- type Registry
- type RelayFanoutMessage
- type Router
- func (r *Router) CreateAndRegisterMatch(ctx context.Context, matchID string, module string, ...) error
- func (r *Router) ForwardInput(ctx context.Context, matchID string, input MatchInput) error
- func (r *Router) ForwardSignal(ctx context.Context, matchID string, data string) (string, error)
- func (r *Router) GetLocalMatch(matchID string) (*ActiveMatch, []PresenceImpl, bool)
- func (r *Router) GetLocalMatches() []*ActiveMatch
- func (r *Router) GetMatch(ctx context.Context, matchID string) (*runtime.MatchInfo, error)
- func (r *Router) GetMatchLoop(matchID string) (*MatchLoop, bool)
- func (r *Router) ListMatches(ctx context.Context, limit int, authoritative bool, label string, ...) ([]*runtime.MatchInfo, error)
- func (r *Router) MatchSignal(ctx context.Context, matchID, data string) (string, error)
- func (r *Router) Register(matchID string, loop *MatchLoop)
- func (r *Router) RegisterLuaMatchSource(name, source string)
- func (r *Router) SetClusterConfig(nodeID string, rdb *redis.Client, ...)
- func (r *Router) SetClusterSignalForwarder(...)
- func (r *Router) SetDependencies(hr *runtime.HookRegistry, logger runtime.Logger, zapLogger *zap.Logger, ...)
- func (r *Router) SetLuaModulePath(path string)
- func (r *Router) SetSessionRegistry(reg SessionRegistry)
- func (r *Router) StartClusterInputListener(ctx context.Context)
- func (r *Router) StartClusterSignalListener(ctx context.Context)
- func (r *Router) Unregister(matchID string)
- func (r *Router) UpdateMetadata(matchID string, label string, playerCount int)
- type SessionRegistry
Constants ¶
const (
// RelayFanoutChannel is the Redis Pub/Sub channel for client-relayed match fan-out.
RelayFanoutChannel = "uge:match:relay"
)
Variables ¶
var ErrDeferredBroadcastFull = errors.New("deferred broadcast queue full")
ErrDeferredBroadcastFull is returned when deferredCh is at capacity.
Functions ¶
func NewAuthoritativeMatchID ¶
func NewAuthoritativeMatchID() string
NewAuthoritativeMatchID returns `{uuid}.{node}` for authoritative matches.
func NewPubSubForwarder ¶
func NewPubSubForwarder(rdb *redis.Client, sourceNode string, logger *zap.Logger) func(ctx context.Context, targetNodeID, matchID string, input MatchInput) error
NewPubSubForwarder publishes MatchInput destined for peer nodes; peers subscribe via StartClusterInputListener.
func NewPubSubSignalForwarder ¶
func NewPubSubSignalForwarder(rdb *redis.Client, sourceNode string, logger *zap.Logger) func(ctx context.Context, targetNodeID, matchID string, data string) error
NewPubSubSignalForwarder publishes MatchSignal payloads destined for peer nodes.
func PublishRelayFanout ¶
func PublishRelayFanout(ctx context.Context, rdb *redis.Client, sourceNode, matchID, kind string, envelope []byte) error
PublishRelayFanout publishes a relayed match envelope for other nodes.
func ResolveNodeID ¶
func ResolveNodeID() string
ResolveNodeID returns a stable-ish node label for cluster metadata and match ID suffixes.
Types ¶
type ActiveMatch ¶
type ActiveMatch struct {
MatchID string `json:"match_id"`
Label map[string]interface{} `json:"label"`
PlayerCount int `json:"player_count"`
MaxSize int `json:"max_size"`
Authoritative bool `json:"authoritative"`
}
ActiveMatch represents metadata for an ongoing match, searchable by labels.
type ClusterInputMessage ¶
type ClusterInputMessage struct {
SourceNode string `json:"source_node"`
TargetNode string `json:"target_node"`
MatchID string `json:"match_id"`
Input MatchInput `json:"input"`
}
ClusterInputMessage is published when ForwardInput must reach a remote node.
type ClusterSignalMessage ¶
type ClusterSignalMessage struct {
SourceNode string `json:"source_node"`
TargetNode string `json:"target_node"`
MatchID string `json:"match_id"`
Data string `json:"data"`
}
ClusterSignalMessage is published when ForwardSignal must reach a remote node.
type GoMatchDispatcher ¶
type GoMatchDispatcher struct {
// contains filtered or unexported fields
}
GoMatchDispatcher implements the reference engine's MatchDispatcher methods.
func (*GoMatchDispatcher) BroadcastMessage ¶
func (*GoMatchDispatcher) BroadcastMessageDeferred ¶
func (*GoMatchDispatcher) MatchKick ¶
func (d *GoMatchDispatcher) MatchKick(presences []runtime.Presence) error
func (*GoMatchDispatcher) MatchLabelUpdate ¶
func (d *GoMatchDispatcher) MatchLabelUpdate(label string) error
type MatchDataImpl ¶
type MatchDataImpl struct {
PresenceImpl
OpCode int64 `json:"op_code"`
Data []byte `json:"data"`
Reliable bool `json:"reliable"`
ReceiveTime int64 `json:"receive_time"`
}
MatchDataImpl implements runtime.MatchData.
func (*MatchDataImpl) GetData ¶
func (m *MatchDataImpl) GetData() []byte
func (*MatchDataImpl) GetOpCode ¶
func (m *MatchDataImpl) GetOpCode() int64
func (*MatchDataImpl) GetReceiveTime ¶
func (m *MatchDataImpl) GetReceiveTime() int64
func (*MatchDataImpl) GetReliable ¶
func (m *MatchDataImpl) GetReliable() bool
type MatchInput ¶
type MatchInput struct {
UserID string `json:"user_id"`
SessionID string `json:"session_id"`
Username string `json:"username"`
OpCode int64 `json:"op_code"`
Action string `json:"action"` // legacy demo fallback
Payload string `json:"payload"`
Reliable bool `json:"reliable"`
}
MatchInput represents a player action sent during a match.
type MatchLoop ¶
type MatchLoop struct {
MatchID string
PlayerIDs []string
// contains filtered or unexported fields
}
MatchLoop handles the authoritative tick loop of a multiplayer match.
func NewMatchLoop ¶
func NewMatchLoop( matchID string, playerIDs []string, tickRate int, logger *zap.Logger, registry SessionRegistry, ) *MatchLoop
NewMatchLoop creates a new MatchLoop.
func (*MatchLoop) EnqueueSignal ¶
EnqueueSignal queues a signal without waiting for the match-loop response (cluster fan-in).
func (*MatchLoop) GetPresences ¶
func (ml *MatchLoop) GetPresences() []*PresenceImpl
GetPresences returns all active presences in the match.
func (*MatchLoop) JoinAttempt ¶
func (ml *MatchLoop) JoinAttempt(userID, username, sessionID string, metadata map[string]string) (bool, error)
JoinAttempt queues a join request onto the match loop.
func (*MatchLoop) KickPlayer ¶
func (*MatchLoop) SetGoMatch ¶
func (ml *MatchLoop) SetGoMatch(goMatch runtime.Match, initialGoState interface{}, logger runtime.Logger, db *sql.DB, nk runtime.RuntimeModule)
SetGoMatch configures the loop to run a Go native match instead of a Lua one.
func (*MatchLoop) SetSandbox ¶
SetSandbox injects an extensibility runtime sandbox for custom script execution.
func (*MatchLoop) SubmitInput ¶
func (ml *MatchLoop) SubmitInput(input MatchInput)
SubmitInput queues an input action from a player.
func (*MatchLoop) SubmitLeave ¶
SubmitLeave queues a leave request onto the match loop.
func (*MatchLoop) SubmitSignal ¶
SubmitSignal queues a signal request onto the match loop.
func (*MatchLoop) UpdateLabel ¶
type MatchState ¶
type MatchState struct {
Tick int64 `json:"tick"`
Score map[string]int `json:"score"`
Positions map[string]string `json:"positions"`
IsFinished bool `json:"is_finished"`
}
MatchState represents the match state inside the server loop.
type PresenceImpl ¶
type PresenceImpl struct {
UserID string `json:"user_id"`
SessionID string `json:"session_id"`
Username string `json:"username"`
NodeID string `json:"node_id"`
}
PresenceImpl implements runtime.Presence.
func (*PresenceImpl) GetNodeId ¶
func (p *PresenceImpl) GetNodeId() string
func (*PresenceImpl) GetSessionId ¶
func (p *PresenceImpl) GetSessionId() string
func (*PresenceImpl) GetUserId ¶
func (p *PresenceImpl) GetUserId() string
func (*PresenceImpl) GetUsername ¶
func (p *PresenceImpl) GetUsername() string
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry stores and queries metadata for all active matches.
func (*Registry) Add ¶
func (r *Registry) Add(matchID string, label map[string]interface{}, playerCount, maxSize int, authoritative bool)
Add registers a new active match.
func (*Registry) Search ¶
func (r *Registry) Search(key string, val interface{}) []*ActiveMatch
Search searches active matches matching a specific label key and value.
type RelayFanoutMessage ¶
type RelayFanoutMessage struct {
SourceNode string `json:"source_node"`
MatchID string `json:"match_id"`
Kind string `json:"kind"` // "match_data" | "match_presence"
Payload json.RawMessage `json:"payload"`
}
RelayFanoutMessage carries client-relayed match payloads (data / presence) across nodes.
type Router ¶
type Router struct {
HookRegistry *runtime.HookRegistry
Logger runtime.Logger
ZapLogger *zap.Logger
DB *sql.DB
NK runtime.RuntimeModule
Registry SessionRegistry
// LuaModulePath is the directory for Lua match modules (e.g. data/modules).
LuaModulePath string
// contains filtered or unexported fields
}
Router maps active match IDs to their local loop execution thread. It abstracts cross-node routing by providing local in-memory lookups and falling back to cluster forwarding.
func (*Router) CreateAndRegisterMatch ¶
func (r *Router) CreateAndRegisterMatch(ctx context.Context, matchID string, module string, params map[string]interface{}) error
CreateAndRegisterMatch instantiates a Go or Lua match and registers its MatchLoop.
func (*Router) ForwardInput ¶
ForwardInput routes client inputs to the targeted match loop, forwarding to peer nodes if needed.
func (*Router) ForwardSignal ¶
ForwardSignal routes an admin signal to the targeted match loop, forwarding to peer nodes if needed.
func (*Router) GetLocalMatch ¶
func (r *Router) GetLocalMatch(matchID string) (*ActiveMatch, []PresenceImpl, bool)
GetLocalMatch retrieves details of a specific local match.
func (*Router) GetLocalMatches ¶
func (r *Router) GetLocalMatches() []*ActiveMatch
GetLocalMatches retrieves all active matches hosted on this node.
func (*Router) GetMatchLoop ¶
GetMatchLoop retrieves a match loop from the registry.
func (*Router) ListMatches ¶
func (r *Router) ListMatches(ctx context.Context, limit int, authoritative bool, label string, minSize, maxSize int) ([]*runtime.MatchInfo, error)
ListMatches returns active match metadata (local or Redis registry).
func (*Router) MatchSignal ¶
MatchSignal delivers a signal to a match loop.
func (*Router) RegisterLuaMatchSource ¶
RegisterLuaMatchSource registers in-memory Lua match module source (tests / hot reload).
func (*Router) SetClusterConfig ¶
func (r *Router) SetClusterConfig(nodeID string, rdb *redis.Client, forwarder func(ctx context.Context, targetNodeID, matchID string, input MatchInput) error)
SetClusterConfig configures the router for multi-node operations.
func (*Router) SetClusterSignalForwarder ¶
func (r *Router) SetClusterSignalForwarder(forwarder func(ctx context.Context, targetNodeID, matchID string, data string) error)
SetClusterSignalForwarder overrides the cluster signal forwarder.
func (*Router) SetDependencies ¶
func (r *Router) SetDependencies(hr *runtime.HookRegistry, logger runtime.Logger, zapLogger *zap.Logger, db *sql.DB, nk runtime.RuntimeModule)
SetDependencies injects dependencies required to instantiate Go native matches.
func (*Router) SetLuaModulePath ¶
SetLuaModulePath configures the directory used to resolve Lua match modules by name.
func (*Router) SetSessionRegistry ¶
func (r *Router) SetSessionRegistry(reg SessionRegistry)
SetSessionRegistry configures the SessionRegistry reference.
func (*Router) StartClusterInputListener ¶
StartClusterInputListener subscribes to this node's input channel and submits to local match loops.
func (*Router) StartClusterSignalListener ¶
StartClusterSignalListener subscribes to this node's signal channel and submits to local match loops.
func (*Router) Unregister ¶
Unregister removes a match loop from the registry.
type SessionRegistry ¶
SessionRegistry abstracts WebSocket session message delivery to prevent circular dependencies.