如何为多人对战游戏添加匹配机制

关键洞察

关键洞察

关键洞察

Edgegap 的 匹配系统 是一个完全托管、无限可定制的匹配系统,能够最佳地将全球玩家分组——在您开发战斗类多人游戏期间使用是免费的。

它也是我们所知的 唯一的 匹配系统,具有 基于延迟的匹配规则,为您的游戏提供理想的在线多人体验,无论引擎是哪个(Unity、Unreal 等)或游戏服务(EOS、UGS、PlayFab、Heroic Labs、Braincloud 等)。

由于我们的匹配系统是基于参数的,因此无需编写代码。因此,集成非常简单,如果需要,我们的 入门指南 会在每一步引导您。

当您的游戏上线时,由于我们的匹配系统是完全托管的,您无需处理基础设施、错误、故障、可扩展性或数据库管理。我们为您处理这一切。将您的 DevOps 工作负担减少到几乎为零。

如何在你的多人格斗游戏中整合匹配机制

-> 本文基于 匹配机制文档。如果你遇到问题或不一致,请确保参考 原始指南,因为它们更新得更频繁。

以下示例将帮助你测试核心匹配机制玩家流程,即:

  • 在共享托管集群上创建匹配器实例,

  • 在你的匹配器配置中定义规则和设置,

  • 最后,测试玩家流程并通过我们的API管理玩家票据

将我们的匹配器实现到你的游戏中有五个步骤

  1. 第一步是创建一个账户并使用我们的格斗游戏示例,你(从技术上讲)已经完成了一半!你只需在你的游戏中整合匹配器(见第5步)。

  2. 现在,你绝不能盲目遵循你在网络上找到的JSON示例,因此强烈建议根据你的游戏调整上述规则。第二步(“探索配置”)是我们的“如何阅读”,深入介绍每个 匹配机制规则的功能(“探索配置”)。

  3. 第3步(“查看实例详细信息”)涵盖了你的个人特定匹配器以确保它部署并与游戏设计相符合。

  4. 第4步,顾名思义(“4.测试票据API”),完全是关于测试匹配器收到的玩家匹配请求,即票据

  5. 第5步(“在你的游戏中集成匹配机制”)强调如何将在你的引擎项目中整合匹配器。

如果你在排除故障时遇到挑战,我们深入的学习中心提供了额外的排除故障技巧。

1. 设置免费层

注册你的免费Edgegap账户,并导航到 匹配器仪表盘页面

在此,首先点击 创建匹配器 ,然后输入:

  • 一个匹配器名称 – 仅供你自己参考,例如 quickstart-dev

  • 接下来,上传以下适合你格斗游戏的JSON配置简单示例:

{
  "version": "1.0.0",
  "max_deployment_retry_count": 3,
  "ticket_expiration_period": "5m",
  "ticket_removal_period": "1m",
  "profiles": {
    "casual-example": {
      "application": {
        "name": "my-game-server=>CHANGE-THIS-NAME-HERE",
        "version": "2024.01.30-16.23.00-UTC=>CHANGE-THIS-HERE "
      },
      "rules": {
        "initial": {
          "match_size": {
            "type": "player_count",
            "attributes": {
              "team_count": 2,
              "team_size": 5
            }
          },
          "beacons": {
            "type": "latencies",
            "attributes": {
              "difference": 25,
              "max_latency": 100
            }
          },
          "league_rank": {
            "type": "number_difference",
            "attributes": {
              "max_difference": 1
            }
          },
          "selected_maps": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          },
          "selected_beacons": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          }
        },
        "expansions": {
          "10": {
            "beacons": {
              "difference": 40,
              "max_latency": 150
            }
          },
          "30": {
            "beacons": {
              "difference": 50
            }
          },
          "60": {
            "league_rank": {
              "max_difference": 2
            }
          },
          "180": {
            "beacons": {
              "difference": 100,
              "max_latency": 500
            }
          }
        }
      }
    },
    "competitive-example": {
      "application": {
        "name": "my-game-server",
        "version": "2024.01.30-16.23.00-UTC"
      },
      "rules": {
        "initial": {
          "match_size": {
            "type": "player_count",
            "attributes": {
              "team_count": 2,
              "team_size": 5
            }
          },
          "beacons": {
            "type": "latencies",
            "attributes": {
              "difference": 25,
              "max_latency": 100
            }
          },
          "league_rank": {
            "type": "number_difference",
            "attributes": {
              "max_difference": 0
            }
          },
          "selected_maps": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          },
          "selected_beacons": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          }
        },
        "expansions": {
          "30": {
            "beacons": {
              "difference": 40,
              "max_latency": 150
            }
          },
          "60": {
            "beacons": {
              "difference": 50
            }
          },
          "180": {
            "beacons": {
              "max_latency": 250
            }
          }
        }
      }
    },
    "challenger-example": {
      "application": {
        "name": "my-game-server",
        "version": "2024.01.30-16.23.00-UTC"
      },
      "rules": {
        "initial": {
          "match_size": {
            "type": "player_count",
            "attributes": {
              "team_count": 2,
              "team_size": 5
            }
          },
          "beacons": {
            "type": "latencies",
            "attributes": {
              "difference": 25,
              "max_latency": 100
            }
          },
          "league_rank": {
            "type": "number_difference",
            "attributes": {
              "max_difference": 0
            }
          },
          "selected_maps": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          },
          "selected_beacons": {
            "type": "intersection",
            "attributes": {
              "overlap": 1
            }
          }
        },
        "expansions": {
          "30": {
            "beacons": {
              "difference": 40,
              "max_latency": 150
            }
          },
          "180": {
            "beacons": {
              "difference": 50
            }
          },
          "240": {
            "beacons": {
              "max_latency": 250
            }
          }
        }
      }
    }
  }
}

(友情提醒请确保更改应用程序 name 和 version 以匹配你的 应用程序和版本!)

如果没有出现验证错误,请点击 创建并开始 并等待过程完成。这将导致一个新的免费集群启动,并与你的简单示例匹配器。

你现在可以继续进行下一步。

2. 探索配置

独特的格斗游戏规则

专为格斗游戏定义多个 匹配机制配置文件 以适应游戏模式特定的规则和设置:

  • 限制两名玩家之间的排名差,以便进行更休闲的游戏,

  • 限制排名差只允许相同排名的对手用于排位赛,

  • 让玩家提供他们的地图偏好并选择适合大家的地图,

  • 添加 中心选择用户界面 以限制对手到指定的 延迟信标

  • 将 匹配机制延迟 限制在最大阈值内,以防止匹配远方的玩家,

  • 限制 匹配机制延迟 在最大差异内,以最大化延迟公平性,

  • 在允许更多玩家时使用不同的 应用版本 分配更多CPU或内存,

  • 以组的形式加入 用于预制的大厅或填充团队而不超过团队规模。

从理想条件开始,并 扩展限制 以确保快速匹配:

  • 随着时间的推移,逐渐放宽延迟限制以找到更多玩家,

  • 逐渐增加允许的排名差以找到更多玩家,

  • 在最高排名(挑战者)之间扩展的时间增加,因为可用的玩家较少。

为晋级赛创建更高排名的票据,以匹配更强的对手。

定义单独的作弊者配置文件 以确保被标记的作弊者或拥有大量管理报告的玩家不会对排位赛中合法玩家的体验产生负面影响。

语义版本控制

每个新版本使用 语义版本控制 以通过解释格式 major.minor.patch 清晰地传达更改的影响:

  • major 版本包括破坏性更改并需要整合审查,

  • minor 版本包括实质性的向后兼容改进,

  • patch 版本包括错误修复和小幅改进。

一些 部署可能会导致错误。我们会通过最多自动重试 max_deployment_retry_count 次部署来尝试解决此问题(无需客户确认)。

为了确保意外的客户端崩溃或被放弃的票据不会停留并占用你的匹配器资源,票据将在超过 ticket_expiration_period 后被取消,其状态将更改为 CANCELLED ,然后在 ticket_removal_period 后永久删除。

我们匹配机制逻辑的核心在于 匹配机制配置文件。每个配置文件都是一个完全独立的匹配队列,指向具有预定义所需CPU和内存(RAM)资源的 应用版本

匹配机制规则 在初始规则集中必须满足,以便将玩家组合在一起,每个规则由三个属性定义:

  • 你选择的名称,例如 - 匹配大小

  • 规则类型,也称为运算符,例如 - 玩家数量

  • 最后是运算符属性,例如 团队数量 或 团队大小

玩家数量规则

这是一个特殊规则,定义了需要匹配的玩家数量以启动分配:

  • 团队数量 指的是团队数量,1个团队可用于合作或自由组队模式,

  • 团队大小 指的是每个团队的 玩家数量。

我们的简单示例展示了一个合作游戏,允许2名玩家。

请注意,“玩家数量”规则是必需的,只可在你的初始配置规则中定义一次

延迟规则

使用此规则为所有玩家提供最低可能的延迟。一旦客户端测量并提交他们与所有可用信标之间的往返时间(延迟),Gen2将仅考虑在特定 差异 内的匹配延迟值,经过与 延迟信标的测量。这提供了一种“软性”解决方案,用于拆分你的玩家基础,使匹配邻近区域的可能性增加,特别是改善了较少人口地区的匹配速度。使用 max_latency防止与远方玩家进行匹配。

你现在可以继续进行下一步。

我们的示例 信标 规则设置是 "difference": 50, "max_latency": 200 初步:

  • 由于北京被丢弃(>200),艾丽斯和博伯将匹配,而其余在 | A-B | < 50内:

    • 艾丽斯 {蒙特利尔: 12.3, 纽瓦克: 45.6, 达拉斯: 59.9, 北京: 264.4}; 和

    • 博伯 {蒙特利尔: 27.3, 纽瓦克: 32.4, 达拉斯: 23.1, 北京: 252.2}。

  • 查理和戴夫将不会匹配,因为 | C-D | > 50适用于达拉斯信标:

    • 艾丽斯 {蒙特利尔: 5.7, 纽瓦克: 44.2, 达拉斯: 59.5, 北京: 263.2}; 和

    • 博伯 {蒙特利尔: 57.8, 纽瓦克: 32.0, 达拉斯: 24.2, 北京: 272.3}。

请注意,“延迟规则”只能在你的初始配置规则中定义一次

3. 查看实例详细信息

在仪表盘上查看新匹配器的详细信息,一旦它初始化:

状态 指示服务健康,可能是在线、离线或错误。

  • 标识符 如果你需要帮助排除故障,可以帮助Edgegap工作人员快速找到你的匹配器。

  • 开始于 对追踪最新更新时间非常有用。

  • 大小 对应于我们的 定价层之一。

  • API URL 将由游戏客户端和游戏服务器用于与Gen2进行通信。

  • Swagger URL 是我们提供的方便开源API规范GUI,用于探索API架构。

  • 认证令牌 是游戏客户端和游戏服务器用于身份验证的唯一秘密令牌。

要使用API测试你的新匹配器, 你将需要Swagger URL、API URL和认证令牌

你现在可以继续进行下一步。

4. 测试票据API

首先, 打开你的Swagger URL 以检查你的开源API架构在Swagger GUI中

点击“匹配器”标题下方的/...swagger.json URL以打开原始JSON架构:

将此页面保存为文件到你的驱动器(CTRL/CMD+S)。

打开你的 Postman应用程序 并登录到你的免费账户。

从上一步导入你的 swagger.json 文件:

  • 保持 Postman集合 选中,

  • 选择 查看导入设置 并将设置 参数生成 更改为 示例

确认导入,这将导致在左侧的集合列表中显示一个名为“匹配器”的新集合。

查看更多操作,打开标签 授权 并选择:

  • 认证类型 - API密钥

  • 密钥 - “授权

  • 值 - 在此插入你的 AuthToken 值,

  • 添加到 - 头部

按(CTRL/CMD+S)或保存图标以 保存更改。你在Postman标签中的橙色点应该消失。

在你的匹配器集合中,选择 票据 和 创建匹配票据,打开一个新标签。

选择标签 主体 以预览你的 玩家票据请求

注意 player_ip 设置为 null-这将导致自动使用添加到你的请求中的IP地址(见 服务器到服务器的集成 以获取其他选项),

  • profile 指的是你的 匹配机制配置文件

  • attributes 包括匹配器规则的值,在这种情况下是 latencies 规则,

    • 规则 player_count 是唯一一条不需要在玩家票据中包含任何属性的规则。

注意:确保参考示例的Swagger导入配置

点击 发送 并查看你玩家票据请求的响应:

  • id 是你的唯一匹配票据ID,保留此ID以便稍后检查你的票据,

  • profile 确认选择了 匹配机制配置文件

  • group_id 是每个票据发出的唯一组ID,单个玩家代表为1的组,

  • player_ip 是玩家的解析公共IP地址,无论使用何种识别方式,

  • assignment 设置为 null 以表示票据尚未匹配或分配给服务器,

  • created_at 提供有关玩家票据创建时间的信息供游戏用户界面使用,

  • status 指示票据的当前状态,所有票据起始状态为 SEARCHING (见 匹配机制过程 以了解详细信息)。

再次点击 发送 以创建第二个票据,以便我们的两个玩家匹配并启动服务器。

在你的匹配器集合中,选择 {ticketId} 和 读取匹配票据

输入之前步骤中的票据ID,然后点击 发送

查看你的玩家票据的更新分配状态:

  • 状态先变为 MATCH_FOUND ,同时保持 assignment 设置为 null 以表示玩家已匹配且正在分配一个服务器,

再次点击 发送 检查票据,并查看你的玩家票据的更新分配状态:

  • 状态变为 HOST_ASSIGNED ,且 assignment 包含分配服务器的详细信息。

 在我们的仪表盘中检查你的新部署

  • 注意每个部署都标记了所有票据ID和配置文件以增加可追溯性。

尝试从你的游戏客户端连接到分配的服务器。

一旦确认你可以顺利连接到你的部署,并完成测试, 停止你的部署 以释放你账户中的容量,准备下一个构建。

你现在可以继续进行下一步。

5. 在你的游戏中整合匹配器

Edgegap的匹配机制整合:

  • 与 游戏客户端,以管理 玩家票据

  • 与 游戏服务器,以:

    • 处理通过他们的票据传递的玩家偏好,

    • 可选地支持 填补 在开始后添加或替换玩家。

对于 游戏客户端,我们建议在整个 匹配机制过程 中通过游戏内UI向玩家提供票据状态更新,以获得最佳玩家体验。请参见:

在 游戏客户端中,确保处理不可重试的错误:

  • HTTP 404未找到 - 票据已被删除,

  • HTTP 500内部服务器错误 - 临时服务中断。

在 游戏服务器中,处理玩家偏好和初始服务器上下文。无需API集成:

  1. 读取 注入的环境变量(Gen2) 以检索初始玩家的匹配数据。

  2. 读取 注入的环境变量(应用版本) 以获取特定于版本的参数、设置(玩家容量)和秘密。

  3. 读取 注入的环境变量(部署) 以获取部署信息,例如IP地址、位置等。

一旦玩家连接, 游戏服务器和游戏客户端 启动加载场景以执行同步步骤(例如选择和加载地图/场景/关卡)。我们建议使用完整的3D场景、类似大厅的社交用户界面,或带有进度条的加载屏幕,以指示初始化正在进行。

一旦 游戏客户端 完全加载,玩家就会加载/移动到主要游戏场景。

可选地, 游戏服务器 可以创建和管理 填补 和玩家容量(增加或替换离开的玩家)。

确保你的 部署将被正确停止 使用 注入的DELETE_URL,如果:

  • 没有玩家加入比赛,

  • 所有玩家已离开比赛,

  • 比赛正确结束。

恭喜你,完成了Edgegap匹配器的集成!如果你想了解更多,请在我们的学习中心中阅读更多内容。

书写者

Edgegap团队

Get your Game Online Easily & in Minutes

Get your Game Online Easily & in Minutes