规则集示例
概述
PGOS的规则集可以覆盖多种匹配场景。以下示例展示了规则集结构和属性表达式语法。您可以复制这些规则集并根据需求进行自定义。 有关规则集编辑器和参考的更多信息,请参见以下链接:
示例1. 匹配MMR排名相近的玩家
本示例说明如何按照以下要求设置两支实力相当的玩家队伍:
- 创建两支玩家队伍。
- 尝试为每支队伍找到3名玩家。
- 两支队伍的玩家人数相等。
- 包含玩家的MMR值(如未提供,默认为1000)
- 匹配MMR值相近的玩家。确保两支队伍的平均玩家技能差异在0.5分以内。
- 如果匹配未能快速完成,放宽以下限制以在合理时间内完成匹配。
- 5秒后,将队伍最小人数降至2人,MMR差异上限扩大到50。
- 10秒后,将队伍最小人数降至1人,MMR差异上限扩大到100。
{
"version":"v1.0",
"playerAttributes":[
{
"name":"mmr",
"type":"number",
"default":1000
}
],
"teams":[
{
"name":"red",
"maxPlayers":3,
"minPlayers":3
},
{
"name":"blue",
"maxPlayers":3,
"minPlayers":3
}
],
"rules":[
{
"name":"mmr_calc",
"type":"distanceRule",
// get mmr values for players in each team, and flatten into a one-dimension list
"measurements":[
"flatten(teams[*].players.playerAttributes[mmr])"
],
// get the average mmr for all players
"referenceValue":"avg(flatten(teams[*].players.playerAttributes[mmr]))",
"minDistance":0,
"maxDistance":0.5
},
{
"name":"equal_team_size",
"type":"comparisonRule",
// get the size of blue team
"measurements":[
"count(teams[blue].players)"
],
// compare with the size of red team
"referenceValue":"count(teams[red].players)",
"operation":"="
}
],
"expansions":[
{
// select the minPlayers of each team
"target":"teams[*].minPlayers",
"steps":[
{
"waitTimeSeconds":5,
"value":2
},
{
"waitTimeSeconds":15,
"value":1
}
]
},
{
// select the maxDistance of specific rule
"target":"rules[mmr_calc].maxDistance",
"steps":[
{
"waitTimeSeconds":5,
"value":50
},
{
"waitTimeSeconds":15,
"value":100
}
]
}
]
}
示例 2. 根据玩家选择的地图进行分组
本示例演示如何按照以下要求设置可变数量的队伍:
创建 10~20 个玩家队伍。
- 每个队伍包含 3~4 名玩家。
- 最终的队伍必须拥有相同数量的玩家。
- 根据匹配中的玩家数量确定队伍数量,范围在 10~20 个之间。
- 队伍将按照
team_001
、team_002
、team_003
等方式命名。
包含玩家的地图名称(如未提供则默认为空)
选择选择相同地图的玩家。
如果匹配未能快速完成,放宽队伍数量要求以在合理时间内完成匹配。
10 秒后,将最小队伍数量降低至 8。
30 秒后,将最小队伍数量降低至 5。
map_binding
规则确保玩家具有相同的 map
属性。
在匹配系统内部,玩家属性将被索引以优化匹配器根据动态需求选择票据的性能。规则集不仅在玩家分组时进行检查,还会在匹配过程中应用。
匹配器使用线性规划方法来减少匹配所需的时间成本,在面对大量玩家时表现良好。
{
"version":"v1.0",
"playerAttributes":[
{
"name":"map",
"type":"string",
"default":""
}
],
"teams":[
{
"name":"team",
"maxPlayers":4,
"minPlayers":3,
"maxQuantity":20,
"minQuantity":10
}
],
"rules":[
{
"name":"map_binding",
"type":"comparisonRule",
// get the map of players in each team and flatten into a one-dimension list
"measurements":[
"flatten(teams[*].players.playerAttributes[map])"
],
// the map of these players must be the same
"operation":"="
},
{
"name":"equal_team_size",
"type":"comparisonRule",
// get the size of each team, as a one-dimension list
"measurements":[
"count(teams[*].players)"
],
// the size of each team must be the same
"operation":"="
}
],
"expansions":[
{
// select the minQuantity of each team
"target":"teams[*].minQuantity",
"steps":[
{
"waitTimeSeconds":10,
"value":8
},
{
"waitTimeSeconds":30,
"value":5
}
]
}
]
}
##示例 3. 预制队优先与其他预制队匹配 本示例说明如何优先匹配人数相同的预制队,并放宽时间限制,让群组玩家和单人玩家混合在一起。
- 创建 4 支玩家队伍。
- 每支队伍有 4 名玩家。
- 变量队伍将被命名为
team_001
、team_002
、team_003
和team_004
。
- 包含一个名为
partysize
的属性 ,即群组的大小。 - 预制队将优先与其他预制队匹配。
- 尝试将 4 人预制队与其他 4 人预制队匹配,将 2 人预制队与其他 2 人预制队匹配。该规则也适用于单人玩家,因此单人玩家应该与其他单人玩家匹配。
- 30 秒后,放宽预制队规模差异的上限为
1
,让 2 人预制队和单人玩家一起匹配。 - 60 秒后,将预制队伍规模差异的上限放宽至
2
,以便 4 人预制队伍和 2 人预制队伍可以一起匹配。 - 90 秒后,将预制队伍规模差异的上限放宽至
3
,以便理论上随机混合预制队伍和非预制队伍。
- 30 秒后,放宽预制队规模差异的上限为
请注意,partysize
由游戏客户端提供,可能会影响最终的匹配结果。对于单人玩家,该值应为 1
,对于双人玩家,该值应为 2
,对于四人玩家,该值应为 4
。
{
"version": "v1.0",
"playerAttributes": [
{
// the value should be the party size when premade team players enter matchmaking
"name": "partysize",
"type": "number",
"default": 1
}
],
"teams": [
{
"name": "team",
"minPlayers": 4,
"maxPlayers": 4,
"minQuantity": 4,
"maxQuantity": 4
}
],
"rules": [
{
"name": "partyRule",
"type": "distanceRule",
// get the max party size of existing premade teams
"measurements": [
"max(flatten(teams[*].players.playerAttributes[partysize]))"
],
// get the min party size of existing premade teams
"referenceValue": "min(flatten(teams[*].players.playerAttributes[partysize]))",
// limit the difference of party size close to zero
"maxDistance": 0.1,
"partyAggregation": "max"
}
],
"expansions": [
{
// relax the difference of party size to let premade teams and non-premade teams match together
"target": "rules[partyRule].maxDistance",
"steps": [
{
"waitTimeSeconds": 30,
"value": 1
},
{
"waitTimeSeconds": 60,
"value": 2
},
{
"waitTimeSeconds": 90,
"value": 3
}
]
}
]
}
示例 4. 允许特定范围的玩家数量并平均限制队伍大小
本示例说明如何在开发阶段让少量玩家一起匹配。
- 创建四个4人队伍。
- 规则集应允许4~16名玩家一起匹配,而不是分散在多个对局中。
如果直接将每个队伍的 minPlayers
设置为 1
,当8名玩家陆续进入匹配时,有一定概率这8名玩家会被分成两个对局,每个对局包含4名玩家。这是因为 minPlayers
为 1
,且当匹配器工作时,一些后进入匹配的玩家可能不在票据池中。
因此在这种场景下,让4~16名玩家一起匹配的安全方法是利用扩展机制,在玩家陆续进入匹配之间创建一个可容忍的时间。
{
"version": "v1.0",
"playerAttributes": [],
"teams": [
{
"name": "A",
"minPlayers": 4,
"maxPlayers": 4
},
{
"name": "B",
"minPlayers": 4,
"maxPlayers": 4
},
{
"name": "C",
"minPlayers": 4,
"maxPlayers": 4
},
{
"name": "D",
"minPlayers": 4,
"maxPlayers": 4
}
],
"rules": [],
"expansions": [
{
// select the minPlayers of each team
"target": "teams[*].minPlayers",
"steps": [
{
"waitTimeSeconds": 30,
"value": 3
},
{
"waitTimeSeconds": 60,
"value": 2
},
{
"waitTimeSeconds": 90,
"value": 1
}
]
}
]
}
示例 5. 匹配三支不同阵营的队伍
本示例说明如何在匹配中设置不同阵营。
- 创建三支队伍,每支队伍有四名玩家。
- 包含玩家的 MMR 值(如未提供,默认为 1000)。
- 包含玩家的阵营值(应为
ghost
或human
) - 其中两支队伍为
human
阵营,一支队伍为ghost
阵营。
{
"version": "v1.0",
"playerAttributes": [
{
"name": "level",
"type": "number",
"default": 0
},
{
"name": "side",
"type": "string",
"default": ""
}
],
"teams": [
{
"name": "red",
"minPlayers": 3,
"maxPlayers": 3
},
{
"name": "green",
"minPlayers": 10,
"maxPlayers": 10
},
{
"name": "blue",
"minPlayers": 10,
"maxPlayers": 10
}
],
"rules": [
{
"name": "mmr_calc",
"type": "distanceRule",
// get mmr values for players in each team, and flatten into a one-dimension list
"measurements": [
"flatten(teams[*].players.playerAttributes[level])"
],
// get the average mmr for all players
"referenceValue": "avg(flatten(teams[*].players.playerAttributes[level]))",
"maxDistance": 3
},
{
"name": "side_binding",
"type": "comparisonRule",
// get the side value of each team, as a two-dimension list
// inside the two-dimension list, the sides inside a team must be the same
// feel free to validate the possible result of your expression using `ruleset debugger`
"measurements": [
"teams[*].players.playerAttributes[side]"
],
"operation": "="
},
{
"name": "side_binding_red",
"type": "comparisonRule",
// get the side value of red team, as a one-dimension list
"measurements": [
"teams[red].players.playerAttributes[side]"
],
// red team are all attackers
"referenceValue": "ghost",
"operation": "="
},
{
"name": "side_binding_green",
"type": "comparisonRule",
// get the side value of green team, as a one-dimension list
"measurements": [
"teams[green].players.playerAttributes[side]"
],
// green team are all attackers
"referenceValue": "human",
"operation": "="
},
{
"name": "side_binding_blue",
"type": "comparisonRule",
// get the side value of blue team, as a one-dimension list
"measurements": [
"teams[blue].players.playerAttributes[side]"
],
// blue team are all attackers
"referenceValue": "human",
"operation": "="
}
],
"expansions": []
}
示例 6. 大逃杀
本示例说明如何设置具有可变数量队伍的规则。
- 创建一支包含4名玩家的队伍
- 将队伍数量限制在10~20支之间
- 随着时间推移逐步放宽限制,允许较少的队伍进行对战
{
"version": "v1.0",
"playerAttributes": [],
"teams": [
{
"name": "squad",
"minPlayers": 4,
"maxPlayers": 4,
"minQuantity": 10,
"maxQuantity": 20
}
],
"rules": [],
"expansions": [
{
"target": "teams[squad].minQuantity",
"steps": [
{
"waitTimeSeconds": 30,
"value": 7
},
{
"waitTimeSeconds": 50,
"value": 5
},
{
"waitTimeSeconds": 70,
"value": 3
}
]
}
]
}
示例 7. 将短时间内发起匹配的玩家匹配到同一场战斗中
此示例说明如何使用“扩展”功能将短时间内开始匹配的玩家分组到同一场比赛中。
- 本规则要求每场战斗有 1~6 名玩家
- 限制团队至少由 6 名玩家组成
- 逐渐将限制从 6 人扩大到 1 人
如果将 minPlayers
配置设置为 1 而不使用 expansion
功能,则匹配算法将立即启动并为第一个发起匹配的玩家生成一个满足 minPlayers
要求的游戏会话。即使尝试回填以将后续玩家添加到游戏会话中,也存在生成新游戏会话并回填旧游戏会话的趋势,这不能保证所有新玩家都会回填到旧游戏会话中。
通过使用扩展功能,首先发起匹配的玩家可以短暂等待,并在短时间内与其他发起匹配的玩家开始游戏。
{
"version": "v1.0",
"playerAttributes": [],
"teams": [
{
"name": "SoloTeam",
"minPlayers": 6,
"maxPlayers": 6,
"minQuantity": 1,
"maxQuantity": 1
}
],
"rules": [],
"expansions": [
{
"target": "teams[SoloTeam].minPlayers",
"steps": [
{
"waitTimeSeconds": 1,
"value": 5
}
]
},
{
"target": "teams[SoloTeam].minPlayers",
"steps": [
{
"waitTimeSeconds": 2,
"value": 4
}
]
},
{
"target": "teams[SoloTeam].minPlayers",
"steps": [
{
"waitTimeSeconds": 3,
"value": 3
}
]
},
{
"target": "teams[SoloTeam].minPlayers",
"steps": [
{
"waitTimeSeconds": 4,
"value": 2
}
]
},
{
"target": "teams[SoloTeam].minPlayers",
"steps": [
{
"waitTimeSeconds": 5,
"value": 1
}
]
}
]
}
示例 8. 多模式、多映射 匹配
本例演示如何实现多模式、多映射 匹配 。要求如下:
- 玩家发起匹配时,可以从 3 种模式、n 张地图中选择,并允许多次选择。
- 3 种游戏模式玩法不同,在匹配规则中体现为不同的队伍结构。
- 模式 1 为两队 PvP,每队 2 名玩家。
- 模式 2 为单队 PvE,总共 4 到 8 名玩家。
- 模式 3 为大逃杀,有 m 个队,每队 4 名玩家,但 m 的范围是 4 到 8 名。
- 映射选择不影响队伍结构。
要使用规则集实现这些要求,可以采用以下方法:
- 用基于bit的数字表示玩家选择的不同地图。为每个映射分配一个数字,每个bit代表该映射是否被选中,并将其商店为“ 映射 ”属性。然后编写一个表达式对“ 映射 ”属性进行按位与运算,创建一个比较规则,要求结果大于零。这确保所有玩家选择的地图都有交集。
- 对于 3 种游戏模式,定义三个规则集并创建一个 MatchConfig。为每个规则集分配一个单独的Placer ,将它们放置在不同的 Fleets 上以支持不同的游戏玩法。由于不同的游戏模式具有不同的在线玩家数量,因此混合 Fleets 有助于提高资源利用率。 提示
有几点需要注意:
- 在bit-wise运算中使用数字类型属性时,将
bitmap
字段设置为 true。 - 由于不同的模式具有不同的团队结构,因此需要多个规则集,并且每个模式具有唯一的属性。当客户端选择模式时,设置相应的属性。
- 将多个规则集关联到匹配配置时,所有规则集必须共享相同的玩家属性定义。
:::
子规则集 1
{
"version": "v1.0",
"playerAttributes": [
{
"name": "map",
"type": "number",
"bitmap": true,
"default": 0
},
{
"name": "mode1",
"type": "number",
"bitmap": false,
"default": 0
},
{
"name": "mode2",
"type": "number",
"bitmap": false,
"default": 0
},
{
"name": "mode3",
"type": "number",
"bitmap": false,
"default": 0
}
],
"teams": [
{
"name": "red",
"minPlayers": 2,
"maxPlayers": 2,
"minQuantity": 1,
"maxQuantity": 1
},
{
"name": "blue",
"minPlayers": 2,
"maxPlayers": 2,
"minQuantity": 1,
"maxQuantity": 1
}
],
"rules": [
{
"name": "map_intersection",
"type": "comparisonRule",
"description": "",
"measurements": [
"and(flatten(teams[*].players.playerAttributes[map]))"
],
"referenceValue": "0",
"operation": ">"
},
{
"name": "mode_selection",
"type": "comparisonRule",
"description": "",
"measurements": [
"flatten(teams[*].players.playerAttributes[mode1])"
],
"referenceValue": "1",
"operation": "="
}
],
"expansions": []
}
子规则集 3
{
"version": "v1.0",
"playerAttributes": [
{
"name": "map",
"type": "number",
"bitmap": true,
"default": 0
},
{
"name": "mode1",
"type": "number",
"bitmap": false,
"default": 0
},
{
"name": "mode2",
"type": "number",
"bitmap": false,
"default": 0
},
{
"name": "mode3",
"type": "number",
"bitmap": false,
"default": 0
}
],
"teams": [
{
"name": "one",
"minPlayers": 4,
"maxPlayers": 8,
"minQuantity": 1,
"maxQuantity": 1
}
],
"rules": [
{
"name": "map_intersection",
"type": "comparisonRule",
"description": "",
"measurements": [
"and(flatten(teams[*].players.playerAttributes[map]))"
],
"referenceValue": "0",
"operation": ">"
},
{
"name": "mode_selection",
"type": "comparisonRule",
"description": "",
"measurements": [
"flatten(teams[*].players.playerAttributes[mode2])"
],
"referenceValue": "1",
"operation": "="
}
],
"expansions": []
}
Sub Ruleset 3
{
"version": "v1.0",
"playerAttributes": [
{
"name": "map",
"type": "number",
"bitmap": true,
"default": 0
},
{
"name": "mode1",
"type": "number",
"bitmap": false,
"default": 0
},
{
"name": "mode2",
"type": "number",
"bitmap": false,
"default": 0
},
{
"name": "mode3",
"type": "number",
"bitmap": false,
"default": 0
}
],
"teams": [
{
"name": "one",
"minPlayers": 4,
"maxPlayers": 4,
"minQuantity": 4,
"maxQuantity": 8
}
],
"rules": [
{
"name": "map_intersection",
"type": "comparisonRule",
"description": "",
"measurements": [
"and(flatten(teams[*].players.playerAttributes[map]))"
],
"referenceValue": "0",
"operation": ">"
},
{
"name": "mode_selection",
"type": "comparisonRule",
"description": "",
"measurements": [
"flatten(teams[*].players.playerAttributes[mode3])"
],
"referenceValue": "1",
"operation": "="
}
],
"expansions": []
}
然后创建一个匹配配置并添加这三个规则集。