match

package
v1.1.1 Latest Latest
Warning

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

Go to latest
Published: Aug 4, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Index

Constants

View Source
const (

	// RelayFanoutChannel is the Redis Pub/Sub channel for client-relayed match fan-out.
	RelayFanoutChannel = "uge:match:relay"
)

Variables

View Source
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 (d *GoMatchDispatcher) BroadcastMessage(opCode int64, data []byte, presences []runtime.Presence, sender runtime.Presence, reliable bool) error

func (*GoMatchDispatcher) BroadcastMessageDeferred

func (d *GoMatchDispatcher) BroadcastMessageDeferred(opCode int64, data []byte, presences []runtime.Presence, sender runtime.Presence, reliable bool) error

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

func (ml *MatchLoop) EnqueueSignal(data string)

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 (ml *MatchLoop) KickPlayer(sessionID string)

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

func (ml *MatchLoop) SetSandbox(sb *runtime.Sandbox)

SetSandbox injects an extensibility runtime sandbox for custom script execution.

func (*MatchLoop) Start

func (ml *MatchLoop) Start(ctx context.Context)

Start initiates the authoritative tick loop.

func (*MatchLoop) SubmitInput

func (ml *MatchLoop) SubmitInput(input MatchInput)

SubmitInput queues an input action from a player.

func (*MatchLoop) SubmitLeave

func (ml *MatchLoop) SubmitLeave(userID, sessionID string)

SubmitLeave queues a leave request onto the match loop.

func (*MatchLoop) SubmitSignal

func (ml *MatchLoop) SubmitSignal(data string) (string, error)

SubmitSignal queues a signal request onto the match loop.

func (*MatchLoop) UpdateLabel

func (ml *MatchLoop) UpdateLabel(label string) error

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 NewRegistry

func NewRegistry() *Registry

NewRegistry creates a new match metadata registry.

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) Remove

func (r *Registry) Remove(matchID string)

Remove deletes a match metadata entry.

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 NewRouter

func NewRouter() *Router

NewRouter creates a new match Router.

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

func (r *Router) ForwardInput(ctx context.Context, matchID string, input MatchInput) error

ForwardInput routes client inputs to the targeted match loop, forwarding to peer nodes if needed.

func (*Router) ForwardSignal

func (r *Router) ForwardSignal(ctx context.Context, matchID string, data string) (string, error)

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) GetMatch

func (r *Router) GetMatch(ctx context.Context, matchID string) (*runtime.MatchInfo, error)

GetMatch returns metadata for one match.

func (*Router) GetMatchLoop

func (r *Router) GetMatchLoop(matchID string) (*MatchLoop, bool)

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

func (r *Router) MatchSignal(ctx context.Context, matchID, data string) (string, error)

MatchSignal delivers a signal to a match loop.

func (*Router) Register

func (r *Router) Register(matchID string, loop *MatchLoop)

Register adds a match loop to the routing registry.

func (*Router) RegisterLuaMatchSource

func (r *Router) RegisterLuaMatchSource(name, source string)

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

func (r *Router) SetLuaModulePath(path string)

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

func (r *Router) StartClusterInputListener(ctx context.Context)

StartClusterInputListener subscribes to this node's input channel and submits to local match loops.

func (*Router) StartClusterSignalListener

func (r *Router) StartClusterSignalListener(ctx context.Context)

StartClusterSignalListener subscribes to this node's signal channel and submits to local match loops.

func (*Router) Unregister

func (r *Router) Unregister(matchID string)

Unregister removes a match loop from the registry.

func (*Router) UpdateMetadata

func (r *Router) UpdateMetadata(matchID string, label string, playerCount int)

UpdateMetadata updates match metadata in Redis globally.

type SessionRegistry

type SessionRegistry interface {
	SendToSession(sessionID string, payload []byte)
}

SessionRegistry abstracts WebSocket session message delivery to prevent circular dependencies.

Jump to

Keyboard shortcuts

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