1 of 11

背包乱斗�代码解析

匹配与加分

2 of 11

目录

  • 段位分数详解
  • 匹配机制概括
  • 对手池选取逻辑详解
  • 对局数据上传机制
  • 匹配逻辑详解——匹配惩罚分计算
  • 举例与总结
  • 加分算法概括
  • 加分逻辑详解
  • 加分实例
  • 小玩具demo

3 of 11

段位分数详解

段位 (League)

索引 (Index)

Rating 区间 (Range)

区间长度 (Span)

Bronze (青铜)

0

0 - 49.9

50

Silver (白银)

1

50 - 119.9

70

Gold (黄金)

2

120 - 199.9

80

Platinum (白金)

3

200 - 299.9

100

Diamond (钻石)

4

300 - 399.9

100

Master (大师)

5

400 - 479.9

80

Grandmaster (宗师)

6

480 - 549.9

70

Grandma (大爷)

7

550 - 849.5

299.5

  • 在玩家的本地存档里,每个职业都有一个rating,通过以下规则映射为段位+分数

4 of 11

匹配机制概括

  • 1.获取所有候选数据
  • 2.在每回合开始时,对所有数据计算匹配惩罚分(mmscore)
  • 3.对匹配惩罚分做升序排列
  • 4.从匹配惩罚分最小的数据开始轮询,是否是合法数据?
  • 5.找到的第一个合法数据就是本回合对手

5 of 11

对手池选取逻辑详解

  • 获取源
    • Steam(2000条)+silentwolf(400条)
    • 如果steam+silentwolf的总数不足30,从本地缓存读取。正常情况下,本地缓存应该就是上次获取的内容
  • 获取时机
    • 游戏启动时
    • 游戏启动后,每五分钟轮询,如果距离上次获取超过20分钟,则再获取
  • 本地缓存覆盖
    • 每次获取时完全覆盖本地缓存

6 of 11

对局数据上传机制

  • PushRun的判定条件
    • 自定义规则激活时
    • Lobbies模式
    • 主动投降·放弃
    • 非排位模式第一回合投降(神秘代码,有啥用?)
    • 曾中途离开
      • 回到主菜单,强退,任何形式都算数。只有一局游戏从头打到尾才不算中途离开
    • 非开发模式,非工程师测试模式,非预览版,非编辑器模式

7 of 11

匹配惩罚分计算

因素分类 (Category)

触发条件 (Condition)

惩罚分 (Malus/Score)

逻辑解释

自身规避

run.playerId == self.id

+10,000.0

绝对排除。防止匹配到自己的 Run。

名字碰撞

run.encodedName == self.name

+5,000.0

绝对排除。防止匹配到重名

模式隔离

玩家与对手 Ranked 状态不一致

+1,000.0

强力排除。Ranked 玩家不应排到 Unranked 数据

10胜隔离

theirWins == Game.MAX_WINS(10)

+1,000.0

强力排除。很神秘的逻辑。可能是bug。这会导致进入生存模式更困难。10胜的排不到10胜,只能找11胜的。

重复遭遇 (极刑区)

距离上次遇到 < 5 轮

+1,100.0 + (12 - 距离)

强力排除。极短时间内绝对不许遇到同一个人。

重复遭遇 (强效区)

5 ≤ 距离 ≤ 12 轮

+131.0 + (12 - 距离)

严重惩罚

重复遭遇 (轻微区 I)

13 ≤ 距离 ≤ 22 轮

+0.2

微弱惩罚

重复遭遇 (轻微区 II)

23 ≤ 距离 ≤ 32 轮

+0.1

微弱惩罚

胜场差 (强敌)

对手胜场 > 目标胜场

+10.0 × 胜场差

匹配逻辑。向上匹配惩罚更重,尽量不让玩家打胜场比自己高太多的对手。

胜场差 (弱敌)

对手胜场 < 目标胜场

+5.0 × 胜场差

匹配逻辑。向下匹配惩罚较轻。

巨大分差

Rating 差 > 150

+12.0

中度惩罚。防止分段差距过大的匹配(如青铜打钻石

Rating 微调

任意分段差

+ (Rating差 / 1000.0)

微调

职业连撞 (单连)

上一把(-1)是该职业

+0.2

微调

职业连撞 (双连)

上两把(-2)全是该职业

+22.0

中度惩罚。防止连续三把打同一个职业

职业抑制 (泛滥)

该职业近期出现最多

+0.1

微调

职业奖励 (稀缺)

该职业近期出现最少

-0.1 (奖励分)

奖励

随机噪声

无条件

+0.0 ~ 0.05

防死锁。打破同分僵局。

8 of 11

举例

  • 100分以上的调整就是一票否决,剩下的就是十几二十分的
    • 不可能碰见自己
    • 不可能碰见自己同名
    • 不可能碰见12轮内遇到过的人
    • 不可能碰见10胜的人(神秘源代码)
    • 非常难连续三把碰见同样的人(+22)
  • 优先碰见和自己胜场完全一样的对手
    • 剩下的小数点后逻辑基本上都是在同胜场下的微调,毛毛雨
  • 如果没有胜场完全一样的,倾向于寻找胜场-1的对手而非+1
  • 如果胜场+1,胜场-2的对手都没有,可能会寻找分差150以上的同胜场

9 of 11

加分算法概括

  • 加分基本元素
    • Rating,rating变化后会根据映射关系在游戏中显示为段位+分数
  • 加分时机
    • 一局游戏结束后结算,不会在比赛途中动态结算
  • 加分公式
    • 基础分计算
    • 奖励分计算与大师衰减
    • 重力衰减
    • 掉分保护
    • 更新限速

10 of 11

加分公式

  • 基础分计算
    • 胜场:+2.0 * wins
    • 负场 (存活时):-0.5 * losses
    • 负场 (死亡时):-1.0 * losses (惩罚加倍)
  • 奖励分计算与大师衰减
    • 以下4个奖励全部互斥,实际情况只能4选1,红字可以和生存模式奖励叠加
      • 无伤普通(10-0):+7.5
        • 无伤普通情况下进入生存模式,继承3.75分,可以叠加
      • 普通(10-X):+5
      • 生存模式无伤存活:+12
      • 生存模式存活:+7
    • 大师衰减:大师及以上段位,奖励分*0.6
    • 以上基础分和奖励分的和我们叫原始加分(说是加分也可能是负的)
  • 重力衰减
    • 零时总分=(原本总分+原始加分)*0.96
  • 掉分保护
    • 中间加分=零时总分-原本总分
    • 如果中间加分<0,则中间加分*0.6
  • 更新限速
    • 最终加分=中间加分*0.63
  • 升段保送
    • 当你升段的时候,自动帮你加到段位20%水位
  • 一个实例:
  • 大师10分约等于408rating
  • 13胜5负,生存奖励,大师惩罚
    • 13*2-0.5*5+7*0.6=27.7
    • 零时总分=(27.7+408)*0.96=418.2
    • 中间加分=418.2-408=10.2
    • 最终加分=10.2*0.63=6.426
    • 最终分数=414.426
  • 大师区间为400到479.9
    • 1rating相当于1.25分
    • 14.426*1.25=18.0325分

11 of 11

ご清聴ありがとうございました

引き続きよろしくお願いいたします。