matchmaker

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Aug 19, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package matchmaker 提供基于属性匹配的组队原语。

玩家/会话携带 string + numeric 属性注册一张 ticket,匹配器按"桶(bucket, 如 region+mode)+ 最低共同属性"策略聚合候选,凑齐队伍即成匹配。

默认按 skill 数值排序贪心组队;可通过 WithMatchFunc 注入多维质量函数 (延迟差、地理距离等,见 MultiDimScore / GeoScore / LatencyScore)。 评分系统(Glicko-2 / TrueSkill)在 pkg/rating 下独立计算,经 RatingStore + ApplyResult 在对局结束后写回 skill,本包不直接依赖评分实现。

与基于 Bluge 全文索引的做法不同,本包用纯标准库实现一个 倒排索引 + 桶分组的轻量匹配器,适合中小规模(单机万级 ticket)。 超过此规模建议接入专用检索引擎。

零值不可用,用 New 构造。

Index

Constants

View Source
const (
	// AttrSkill 是默认技能分 numeric 属性名。
	AttrSkill = "skill"
	// AttrLatency 是延迟(毫秒) numeric 属性名。
	AttrLatency = "latency"
	// AttrLat / AttrLng 是地理匹配用的经纬度 numeric 属性名。
	AttrLat = "lat"
	AttrLng = "lng"
)

Variables

This section is empty.

Functions

func ApplyResult

func ApplyResult(store RatingStore, rater Rater, participants []string, result map[string]float64) error

ApplyResult 根据对局结果更新所有参与者的评分。 participants 为参与者 ID,result 为 userID → 得分(1/0.5/0)。

Types

type Dimension

type Dimension struct {
	Attr     string  // numeric 属性名("skill","latency")或 GeoScore 返回的哨兵
	Weight   float64 // 权重,MultiDimScore 会按总和归一化
	MaxDelta float64 // 最大容忍差值,超过则该维得 0;<=0 时跳过该维
}

Dimension 一个 numeric 属性的匹配维度。

func GeoScore

func GeoScore(maxKm, weight float64) Dimension

GeoScore 按 Haversine 距离评分。maxKm 为最大可接受距离(千米), ticket 需带 lat/lng numeric 属性。

func LatencyScore

func LatencyScore(maxDeltaMs, weight float64) Dimension

LatencyScore 按延迟差值评分。maxDeltaMs 为最大可接受延迟差(毫秒)。

func SkillScore

func SkillScore(maxDelta, weight float64) Dimension

SkillScore 按 skill 差值评分。maxDelta 为最大可接受分差。

type Handler

type Handler func(ctx context.Context, m Match) error

Handler 由业务实现,在匹配成功时被调用(在工作池 goroutine 中)。 返回 error 会让相关 ticket 重新进入候选池。

func RatingHandler

func RatingHandler(inner Handler, store RatingStore, rater Rater) Handler

RatingHandler 包装匹配成功回调。inner 负责开房间等业务; 匹配时尚无胜负,只把 store 中的最新 skill 填回 ticket 便于下游展示。 对局结束后调用 ApplyResult(store, rater, ...) 把胜负写回评分。

type Match

type Match struct {
	Tickets []*Ticket
	Pool    string
}

Match 是一次成功匹配的结果。

type MatchFunc

type MatchFunc func(a, b *Ticket) float64

MatchFunc 评估两个 ticket 的匹配质量,返回 [0,1](1=完美匹配,<=0 视为不兼容)。

func MultiDimScore

func MultiDimScore(dims ...Dimension) MatchFunc

MultiDimScore 创建多维匹配评分函数。各维加权平均,任一维得 0 则整体为 0 (硬约束:超出 MaxDelta 即不匹配)。weights 会被归一化;全为 0 时返回恒 0。

type Matchmaker

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

Matchmaker 管理候选池并周期性尝试匹配。

func New

func New(h Handler, opts ...Option) *Matchmaker

New 创建匹配器。h 在每次匹配成功时被调用。

func (*Matchmaker) Add

func (m *Matchmaker) Add(t Ticket, pool, bucketKey string) (string, error)

Add 注册一张 ticket 进候选池。pool 用于隔离不同匹配类型(如 "5v5"/"3v3")。 bucketKey 由 string 属性拼成(如 "eu|ranked"),决定同桶匹配优先级。

func (*Matchmaker) Count

func (m *Matchmaker) Count() int

Count 返回当前候选 ticket 数。

func (*Matchmaker) QueryNearBySkill

func (m *Matchmaker) QueryNearBySkill(pool string, val float64, n int) []*Ticket

QueryNearBySkill 返回 pool 中 skill 最接近 val 的 n 个 ticket(用于调试/扩展)。

func (*Matchmaker) Remove

func (m *Matchmaker) Remove(ticketID string) bool

Remove 移除一张 ticket(如玩家取消)。

func (*Matchmaker) Start

func (m *Matchmaker) Start(ctx context.Context)

Start 启动匹配循环。幂等。ctx 取消时停止。

func (*Matchmaker) Stop

func (m *Matchmaker) Stop()

Stop 停止匹配循环。幂等。

func (*Matchmaker) Wait

func (m *Matchmaker) Wait()

Wait 阻塞直到循环退出。

type MemoryStore

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

MemoryStore 内存 RatingStore,便于测试与单机演示。并发安全。

func NewMemoryStore

func NewMemoryStore() *MemoryStore

NewMemoryStore 创建空的内存评分存储。

func (*MemoryStore) Get

func (s *MemoryStore) Get(userID string) (float64, error)

Get 读取 userID 的 skill;不存在返回 0, nil error。

func (*MemoryStore) Set

func (s *MemoryStore) Set(userID string, skill float64) error

Set 写入 userID 的 skill。

type Option

type Option func(*config)

Option 配置 Matchmaker。

func WithMatchFunc

func WithMatchFunc(fn MatchFunc) Option

WithMatchFunc 设置可插拔的匹配质量函数。未设置时 tryMatch 仍按 skill 排序贪心 (向后兼容)。设置后改为按质量评分凑队,0 分视为不兼容。

func WithMaxWaitSec

func WithMaxWaitSec(sec int) Option

WithMaxWaitSec 设置 ticket 最长等待秒数:超时后放宽桶约束(忽略 string 属性差异)强匹配。 默认 30。<=0 不放宽。

func WithTickInterval

func WithTickInterval(d time.Duration) Option

WithTickInterval 设置匹配扫描周期,默认 500ms。

type Presence

type Presence struct {
	UserID    string
	SessionID string
	Node      string
	Username  string
}

Presence 表示一个待匹配的参与者。

type Properties

type Properties struct {
	String  map[string]string  // 如 {"region":"eu","mode":"ranked"}
	Numeric map[string]float64 // 如 {"skill":1200,"latency":45}
}

Properties 是 ticket 的属性集合:string 类(用于桶分组、精确匹配)与 numeric 类(用于范围/排序)。

type Rater

type Rater func(participants []string, result map[string]float64) map[string]float64

Rater 根据参与者与对局得分计算新 skill。 result 的 value 是该玩家得分(1=胜,0.5=平,0=负); 返回 userID → 新 skill,由 ApplyResult 写回 store。

type RatingStore

type RatingStore interface {
	Get(userID string) (skill float64, err error)
	Set(userID string, skill float64) error
}

RatingStore 评分存储接口,业务实现持久化(内存/Redis/DB)。

type Ticket

type Ticket struct {
	ID         string
	Presence   Presence
	Properties Properties
	CreateTime int64 // unix nano
	MinCount   int   // 最小成队人数
	MaxCount   int   // 最大成队人数
}

Ticket 是一次匹配请求的句柄。

Jump to

Keyboard shortcuts

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