Matchmaking 配置参数说明
Matchmaking 配置参数说明
在本篇章中,我们会依次介绍 Matchmaking 配置参数的结构组成,具体参数说明和必要的举例示范。在篇章的最后一节中,我们提供了完整的「配置示例」供大家使用或者参考。
Player Attributes
playerAttributes 声明使用该匹配规则的 ticket 中所涉及的玩家需要包含哪些属性。playerAttributes 是由一系列玩家属性所构成的数组,其示例结构如下:
[
{
"name":"skill",
"type":"number",
"defaultValue":"10"
},
{
"name":"mode",
"type":"string"
}
]在以上示例中定义了通过该匹配规则进行匹配的玩家,需要提供 skill(技能熟练度: 类型为数值,默认值为10)和 mode(游戏模式: 类型为字符串,默认值为 ranking )这两个属性。
playerAttributes 参数说明
| 参数 | 说明 | 必填项 |
|---|---|---|
| name | 该属性的名称 | √ |
| type | 该属性的类型,目前支持的类型有 number 和 string | √ |
| defaultValue | 该属性的默认值,如果没有填默认值,则 ticket 里面必须携带该 attribute;如果填了默认值,则 ticket 里面如果没有该 attribute,会自动添加上该 attribute 并附上默认值 | - |
Team Definitions
teamDefinitions 声明了一局游戏的队伍规格和属性。teamDefinitions 是由一系列队伍属性所构成的数组,其示例结构如下:
[
{
"name": "red",
"minTeams": 1,
"maxTeams": 1,
"minPlayers": 5,
"maxPlayers": 5
},
{
"name": "blue",
"minTeams": 1,
"maxTeams": 1,
"minPlayers": 5,
"maxPlayers": 5
}
]在以上示例中定义了该匹配规则中一局对局需要由1个由5位玩家构成的红队和1个由5位玩家构成的蓝队。
teamDefinitions 参数说明
| 参数 | 说明 | 必填项 |
|---|---|---|
| name | 队伍名称,不允许有重复队伍名 | √ |
| minTeams | 最少队伍数量 | - |
| maxTeams | 最多队伍数量,如果想要设置固定队伍(team)数量,可将 minTeams 和 maxTeams 设置为一样 | - |
| minPlayers | 队伍最少玩家数,匹配过程中,如果达到了 minPlayers,则可认为该队伍满足了匹配条件 | √ |
| maxPlayers | 队伍最多玩家数,在一个队伍(team)达到最少玩家数之后,匹配系统也会尽可能抓取玩家到满足最多玩家数 | √ |
Tips: 如开启自动回填的情况下, 在达到 minPlayers 但没达到 maxPlayers 时,系统在开启一局游戏的同时,会为这局游戏开启 Backfill, 继续为这局游戏添加玩家,直到达到 maxPlayers
Rules
rules 声明了一局游戏的玩家之间的匹配规则。rules 是由一系列规则所构成的数组,其示例结构如下:
[
{
"name": "matchRule",
"description": "所有玩家的游戏模式都必须是 'ranking'",
"type": "comparison",
"operation": "=",
"reference": "ranking",
"measurements": "match.players.attributes[mode]"
},
{
"name": "teamAggregationRule",
"descriptions": "两个team的平均分之差不超过20",
"type": "distance",
"maxDistance": 20,
"measurements": "avg(teams[*].players.attributes[skill])"
}
]在上述示例中定义了两条匹配规则:
- matchRule:对这场匹配(match)中的所有玩家的游戏模式(mode)进行比较(comparison),其比较的对象(reference)为 'ranking',使得 所有玩家的游戏模式都必须是 'ranking'。
- teamAggregationRule:对每个队伍的玩家的技能熟练度(skill)进行求和(sum),并且比较两个队伍的分数和的差值(distance),让其不超过最大差值(maxDistance)20,使得 两个team的平均分之差不超过20。
在上述示例中,所有规则中出现的相关参数,诸如:游戏模式(mode)和技能熟练度(skill)都来自 playerAttributes 中所定义的参与匹配的玩家的属性, 如果使用了 playerAttributes 中没有定义的attribute, 将无法成功创建匹配配置
rules 参数说明
| 参数 | 说明 | 必填项 |
|---|---|---|
| name | 匹配规则的名称,不允许有重复 rule name | √ |
| description | 匹配规则的描述,用于描述自己的规则 | - |
| type | 匹配规则的类型,当前支持的类型有 comparison 和 distance | √ |
| operation | 匹配规则的类型为 comparison 时,需指定比较操作符,支持的 operation 有:>=、>、<=、<、=、!= | - |
| reference | 匹配规则的类型为 comparison 时,指定操作符之后,有些操作符还必须指定比较对象 | - |
| maxDistance | 匹配规则的类型为 distance 时,指定玩家之间的 attributes 值之差在一定范围之内 | - |
| measurements | 指定被比较的玩家属性以及如何比较的聚合函数 | √ |
Measurements
measurements 指定了用于比较的玩家属性,及其相应的聚合运算。在对局匹配的规则设计中,用于比较的玩家属性可以来自于某个特定的 team 表达式(例如 team[red].players.attributes 指定了比较红色方阵营玩家的属性),也可以来自整个匹配对局的所有玩家(例如match.players.attributes 指定了当前对局中的所有玩家的属性)。基于 playerAttributes 中对于玩家属性的定义,measurements 可以获取到特定的属性值并对其进行相应的聚合运算。
team 表达式
| 表达式示例 | 含义 | 输出类型 |
|---|---|---|
| teams[red] | 标识一个队伍:红队(red) | Team |
| teams[red, blue] | 标识多个队伍:红队(red)和蓝队(blue) | List<Team> |
| teams[*]` | 标识所有(队伍) | List<Team> |
基础 measurement 表达式
| 表达式示例 | 含义 | 输出类型 |
|---|---|---|
| teams[red].players.attributes[skill] | red team(红队)的所有玩家的 skill attribute(技能属性)值 | List<number> |
| teams[red, blue].players.attributes[skill] | red team(红队)和 blue team(蓝队)的所有玩家的 skill attribute(技能属性)值,按 team(队伍)分组 | List<List<number>> |
| teams[*].players.attributes[skill] | 所有队伍的玩家的 skill attribute(技能属性)值,按 team(队伍)分组 | List<List<number>> |
| match.players.attributes[skill] | 匹配中所有玩家的 skill attribute(技能属性)值 | List<number> |
聚合 measurement 表达式
| 表达式示例 | 含义 | 输出类型 |
|---|---|---|
| avg(teams[red].players.attributes[skill]) | Red team(红队)所有玩家的平均 skill attribute(技能属性)值 | number |
| avg(teams[red, blue].players.attributes[skill]) | Red team(红队)和 Blue team(蓝队)各自所有玩家的平均 skill attribute(技能属性)值(注:按队伍分别计算平均值,故输出为列表) | List<number> |
| avg(teams[*].players.attributes[skill]) | 每个 team(队伍)的所有玩家的平均 skill attribute(技能属性)值 | List<number> |
| avg(match.players.attribute[skill]) | 匹配中所有玩家的平均 skill attribute(技能属性)值(注:原文“attrbibute”修正为“attribute”) | number |
当前支持的聚合表达式有: avg, sum, min, max, median
rules 举例
根据 Rule 的类型,可以将 Rule 分成以下两类:
1. distance rule
用于比较玩家/队伍的分数差在一定范围之内,所以其作用对象必须是一个数组,即measurements字段的 输出类型 必须是一个 List。比如 avg(teams[red].players.attributes[skill]) 的 输出类型 是一个 number,所以它不是一个合法的distance rule 的 measurements。 此外,distance rule也可以作用于输出类型为 List<List<Any>> 的 measurements(其中,List<Any>表示 List<string> 或者 List<number>,下同)。当distance rule 作用于 List<List<Any> 类型的 measurements时,会对其中的每一个 List<Any> 创建 distance rule,即该measurements返回的每一个 List<Any> 都需要满足该 distance rule(参见示例1.2)。
示例 1.1 每个team的所有玩家的skill attribute的平均值与其他所有team的值之差都在20以内;其中,measurements 的输出类型为 List<number>
{
"name": "test-distance",
"type": "distance",
"measurements": "avg(teams[*].players.attributes[skill])" ,
"maxDistance": 20
}示例 1.2 每个team 内所有玩家的skill attribute值之差必须在20以内;其中,measurements 的输出类型为 List<List<number>>,所以其中的每一个 List<number> 都需要满足该 distance rule
{
"name": "test-distance",
"type": "distance",
"measurements": "teams[*].players.attributes[skill]",
"maxDistance": 20
}示例 1.3 一局游戏所有玩家的skill attribute值之差必须在20以内;其中,measurements 的输出类型为 List<number>
{
"name": "test-distance",
"type": "distance",
"measurements": "match.players.attributes[skill]",
"maxDistance": 20
}2. comparison rule
既可以作用于一个作用于 number 或者 string的数组,也可以作用于 number数组 经过聚合计算得到的 number,即 measurements 字段的 输出类型 可以是一个 List 或者 number。当作用于数组时,代表 List 中每一个成员与 reference 的比较;作用于 number 时,代表这一个 number 与 reference 的比较。 此外,comparison rule也同样可以作用于输出类型为 List<List<Any>> 的 measurements(同distance rule的用法,参见示例2.3)
示例 2.1 red team 的所有玩家的平均 skill值等于20;其中,measurements 的输出类型为 number;此外,operation为=时,若measurements字段输出类型 为 List, 其reference字段值可以不填,代表匹配skill值相互相等的玩家;但若measurements字段输出类型为 number, 则其reference字段为必填
{
"name": "test-comparison",
"type": "comparison",
"measurements": "avg(teams[red].players.attributes[skill])",
"operation": "=",
"reference": "20"
}示例 2.2 red team所有玩家的mode相等,但不指定具体等于多少 (可用于匹配选择相同游戏模式或是相同地图的玩家);其中,measurements 的输出类型为 List<number> 或者 List<string>
{
"name": "test-comparison",
"type": "comparison ",
"measurements": "teams[red].players.attributes[mode]",
"operation": "="
}示例 2.3 每个team内所有玩家的mode必须相等;其中,measurements 的输出类型为 List<List<string>>,所以其中的每一个 List<string> 都需要满足该 comparison rule
{
"name": "test-comparison",
"type": "comparison ",
"measurements": "teams[*].players.attributes[mode]",
"operation": "="
}示例 2.4 所有玩家的mode必须相等;其中,measurements 的输出类型为 List<number> 或者 List<string>
{
"name": "test-comparison",
"type": "comparison ",
"measurements": "match.players.attributes[mode]",
"operation": "="
}Expansions
expansions 声明了匹配规则或是队伍人数动态更新的条件。expansions 是由一系列规则所构成的数组,其示例结构如下
[
{
"target": "rules[teamAggregationRule].maxDistance",
"steps": [
{
"waitTimeSeconds": 10,
"value": "40",
"type": "replace"
},
{
"waitTimeSeconds": 20,
"type": "disable"
}
]
},
{
"target": "teams[red].minPlayers",
"steps": [
{
"waitTimeSeconds": 10,
"value": "3",
"type": "replace"
},
{
"waitTimeSeconds": 20,
"value": "1",
"type": "replace"
}
]
}
]在上述示例中定义了两条匹配规则动态更新的条件:
- 针对teamAggregationRule规则中的最大差值限制:如果在等待10秒钟之后没有成功创建对局匹配,那么将两个队伍积分之和的最大差值更新成40;如果在等待20秒钟之后没有成功创建对局匹配,那么取消对于两个队伍积分之和的差值的限制
- 针对red队伍的最少玩家数目限制:如果在等待10秒钟之后没有成功创建对局匹配,那么将red队伍的最少玩家数目限制调整为3;如果在等待20秒钟之后没有成功创建对局匹配,那么将red队伍的最少玩家数目限制调整为1
本示例中,匹配规则或是队伍人数动态更新的对象(target)都于上文中 teamDefinition 和 rules 所给出的示例相对应。
target: 作用对象,其分为三段:
- 第一段指定是作用于 teams 还是 rules
- 第二段指定 teamName 或是 ruleName
- 第三段指定作用于哪个字段,作用于 teams, 可填 minPlayers ; 作用于 rules,可填maxDistance
Target 举例: teams[team1].minPlayers, rules[rule1].maxDistance
steps: 作用时间, 作用类型以及作用值
- 当type 为 disable时,代表到达某个时间后禁用该规则 (只能作用于rule)
- 当type 为 replace时, 代表到达某个时间后替换target值
step 参数说明
| 参数 | 说明 | 必填项 |
|---|---|---|
| waitTimeSeconds | 触发匹配规则动态更新的等待时间阈值(单位:秒) | √ |
| value | 当规则动态更新的类型是 replace 时,用于将目标(target)规则参数替换成的对应数值 | - |
| type | 匹配规则动态更新触发后,执行的更新操作类型,目前支持的类型有 disable(禁用规则)和 replace(替换规则参数) | √ |
配置示例
快速启动
介绍:快速创建1个游戏队伍,最少1名玩家,最多4名玩家
{
"teamDefinitions": [
{
"name": "quick-game",
"minTeams": 1,
"maxTeams": 1,
"minPlayers": 1,
"maxPlayers": 4
}
]
}5V5 排位赛
参考:王者荣耀
介绍:一局游戏对局中,有红蓝两个队伍阵营,双方各有五名玩家;所有玩家的游戏模式都必须是 'ranking';两个team各自内部玩家skill分差不超过10;两个team的skill平均分之差不超过20;当匹配时长达到一定阈值,对于两个team的skill平均分之差限制进行阶段性放宽
{
"playerAttributes": [
{
"name": "skill",
"type": "number"
},
{
"name": "mode",
"type": "string"
}
],
"teamDefinitions": [
{
"name": "red",
"minTeams": 1,
"maxTeams": 1,
"minPlayers": 5,
"maxPlayers": 5
},
{
"name": "blue",
"minTeams": 1,
"maxTeams": 1,
"minPlayers": 5,
"maxPlayers": 5
}
],
"rules": [
{
"name": "teamRule",
"description": "两个team各自内部玩家skill分差不超过10",
"type": "distance",
"maxDistance": 10,
"measurements": "teams[*].players.attributes[skill]"
},
{
"name": "matchRule",
"description": "所有玩家的游戏模式都必须是 'ranking'",
"type": "comparison",
"reference": "ranking",
"operation": "=",
"measurements": "match.players.attributes[mode]"
},
{
"name": "teamAggregationRule",
"description": "两个team的平均分之差不超过20",
"type": "distance",
"maxDistance": 20,
"measurements": "avg(teams[*].players.attributes[skill])"
}
],
"expansions": [
{
"target": "rules[teamAggregationRule].maxDistance",
"steps": [
{
"waitTimeSeconds": 10,
"value": "40",
"type": "replace"
},
{
"waitTimeSeconds": 20,
"value": "60",
"type": "replace"
}
]
}
]
}3v3 快速11分赛
参考:全明星街球派对
介绍:一局游戏对局中,有红蓝两个队伍阵营,双方各有三名玩家;两个team的skill平均分之差不超过20;当匹配时长达到一定阈值,对于两个team的skill平均分之差限制进行放宽,直至取消限制
{
"playerAttributes": [
{
"name": "skill",
"type": "number"
}
],
"teamDefinitions": [
{
"name": "red",
"minTeams": 1,
"maxTeams": 1,
"minPlayers": 3,
"maxPlayers": 3
},
{
"name": "blue",
"minTeams": 1,
"maxTeams": 1,
"minPlayers": 3,
"maxPlayers": 3
}
],
"rules": [
{
"name": "teamAggregationRule",
"description": "两个team的平均分之差不超过20",
"type": "distance",
"maxDistance": 20,
"measurements": "avg(teams[*].players.attributes[skill])"
}
],
"expansions": [
{
"target": "rules[teamAggregationRule].maxDistance",
"steps": [
{
"waitTimeSeconds": 10,
"value": "40",
"type": "replace"
},
{
"waitTimeSeconds": 20,
"type": "disable"
}
]
}
]
}1v1 卡牌对战
参考:炉石,皇室战争
介绍:一局游戏对局中,有红蓝两个队伍阵营,双方各有一名玩家;两个玩家的游戏模式都必须等于 'pk';两个玩家所选择的地图必须一样;两个玩家所选择的英雄必须不一样
{
"playerAttributes": [
{
"name": "map",
"type": "string"
},
{
"name": "mode",
"type": "string"
},
{
"name": "role",
"type": "string"
}
],
"teamDefinitions": [
{
"name": "red",
"minTeams": 1,
"maxTeams": 1,
"minPlayers": 1,
"maxPlayers": 1
},
{
"name": "blue",
"minTeams": 1,
"maxTeams": 1,
"minPlayers": 1,
"maxPlayers": 1
}
],
"rules": [
{
"name": "modeRule",
"description": "两个玩家的游戏模式都必须等于 'pk' ",
"type": "comparison",
"measurements": "match.players.attributes[mode]",
"operation": "=",
"reference": "pk"
},
{
"name": "mapRule",
"description": "两个玩家所选择的地图必须一样",
"type": "comparison",
"measurements": "match.players.attributes[map]",
"operation": "="
},
{
"name": "roleRule",
"description": "两个玩家所选择的英雄必须不一样",
"type": "comparison",
"measurements": "match.players.attributes[role]",
"operation": "!="
}
]
}无阵营大乱斗
参考:球球大作战
介绍:一局游戏对局中,没有明确的阵营划分;当匹配时长达到一定阈值,对游戏人数要求进行阶段性放宽
{
"teamDefinitions": [
{
"name": "relax",
"minTeams": 1,
"maxTeams": 1,
"minPlayers": 20,
"maxPlayers": 40
}
],
"expansions": [
{
"target": "teams[relax].minPlayers",
"steps": [
{
"waitTimeSeconds": 10,
"value": "15",
"type": "replace"
},
{
"waitTimeSeconds": 20,
"value": "10",
"type": "replace"
}
]
}
]
}非对称对抗
参考:黎明杀机,第五人格
介绍:一局游戏对局中,有五名玩家构成人类玩家阵营,一名怪兽构成怪兽阵营;人类玩家阵营的玩家的 wantsToBeMonster 属性必须为 0;怪兽阵营的玩家的 wantsToBeMonster 属性必须为 1
{
"playerAttributes": [
{
"name": "wantsToBeMonster",
"type": "number",
"defaultValue": "0"
}
],
"teamDefinitions": [
{
"name": "human",
"minTeams": 1,
"maxTeams": 1,
"minPlayers": 5,
"maxPlayers": 5
},
{
"name": "monster",
"minTeams": 1,
"maxTeams": 1,
"minPlayers": 1,
"maxPlayers": 1
}
],
"rules": [
{
"name": "humanRule",
"description": "human team的玩家的 wantsToBeMonster 值必须为 0",
"type": "comparison",
"measurements": "teams[human].players.attributes[wantsToBeMonster]",
"operation": "=",
"reference": "0"
},
{
"name": "monsterRule",
"description": "monster team的玩家的 wantsToBeMonster 值必须为 1",
"type": "comparison",
"measurements": "teams[monster].players.attributes[wantsToBeMonster]",
"operation": "=",
"reference": "1"
}
]
}大逃杀
参考:和平精英,荒野行动
介绍:一局游戏对局中,最少10个队伍,最多20个队伍,每队最少人数1人,最多人数4人;所有玩家的游戏模式都必须是 'battle-royale'
{
"playerAttributes": [
{
"name": "mode",
"type": "string"
}
],
"teamDefinitions": [
{
"name": "battle-royale",
"minTeams": 10,
"maxTeams": 20,
"minPlayers": 1,
"maxPlayers": 4
}
],
"rules": [
{
"name": "battle-royale",
"description": "所有玩家的游戏模式必须是 'battle-royale'",
"type": "comparison",
"measurements": "match.players.attributes[mode]",
"operation": "=",
"reference": "battle-royale"
}
]
}