Optimization 在现代复杂游戏中实现成就系统

Optimization 在现代复杂游戏中实现成就系统,optimization,achievements,code-separation,Optimization,Achievements,Code Separation,现在创建的许多游戏都有自己的成就系统,奖励完成特定任务的玩家/用户。stackoverflow上的徽章系统完全相同 不过,有些问题我无法找到好的解决办法 成就系统必须时刻注意某些事件,比如一个提供20到30项成就的游戏,例如:战斗。服务器必须始终检查这些事件(例如:玩家在这场战斗中避免了对手的x次攻击,或者玩家走了x英里) 服务器如何在不降低速度甚至崩溃的情况下处理如此大量的操作 成就系统通常需要只在游戏核心引擎中使用的数据,如果没有这些糟糕的成就,这些数据无论如何也不会被需要出来(比如,想

现在创建的许多游戏都有自己的成就系统,奖励完成特定任务的玩家/用户。stackoverflow上的徽章系统完全相同

不过,有些问题我无法找到好的解决办法

成就系统必须时刻注意某些事件,比如一个提供20到30项成就的游戏,例如:战斗。服务器必须始终检查这些事件(例如:玩家在这场战斗中避免了对手的x次攻击,或者玩家走了x英里)

  • 服务器如何在不降低速度甚至崩溃的情况下处理如此大量的操作
成就系统通常需要只在游戏核心引擎中使用的数据,如果没有这些糟糕的成就,这些数据无论如何也不会被需要出来(比如,想想玩家在每次战斗中跳起的频率,你不想将所有这些信息存储在数据库中)。我的意思是,在某些情况下,添加成就的唯一方法是将检查其当前状态的代码添加到游戏核心,这通常是一个非常糟糕的主意

  • 成就系统是如何与游戏的核心互动的,而游戏的核心保存着后来不必要的信息?(见上文示例)

  • 他们是如何从游戏的核心中分离出来的


我的例子可能看起来“无害”,但想想魔兽世界目前提供的1000多个成就,以及许多、许多玩家同时在线。成就系统实际上只是一种日志记录形式。对于这样一个系统,这是一个很好的方法。在这种情况下,玩家发布自己的信息,感兴趣的软件组件(处理个人成就)可以订阅。这允许您使用专门的日志代码查看公共值,而不会影响任何核心游戏逻辑

以“玩家步行x英里”为例。我将把步行距离作为播放器对象中的一个字段来实现,因为这是一个简单的增量值,不需要随时间增加空间。奖励步行10英里的玩家的成就就是该领域的用户。如果有许多参与者,那么将该值与一个或多个中间代理级别聚合是有意义的。例如,如果游戏中存在100万名玩家,那么您可以使用1000名经纪人汇总这些值,每个经纪人负责跟踪1000名玩家。然后,该成果将由这些经纪人认购,而不是直接由所有玩家认购。当然,最佳层次结构和订阅者数量是特定于实现的

在您的战斗示例中,玩家可以以完全相同的方式发布上次战斗的详细信息。监控战斗跳跃的成就将订阅此信息,并检查跳跃次数。由于不需要历史状态,这也不会随着时间而增长。同样,不需要修改核心代码;您只需要能够访问一些值


还要注意的是,大多数奖励不需要是即时的。这使您在管理流量时有一定的回旋余地。在上一个示例中,您可能不会更新代理发布的行驶距离,直到玩家总共多走了一英里,或者自上次更新以来已经过了一天(在此之前内部递增)。这实际上只是一种缓存形式;确切的参数将取决于您的问题。

如果您的游戏架构是,那么您可以使用实现系统。

在普通游戏中有两种方法

  • 离线游戏:没有什么比酒吧/酒吧更复杂的了——这是一个巨大的过度杀伤力。相反,您只需使用一个大地图/字典,并记录名为“事件”的日志。然后,每X帧或Y秒(或者,通常是:“每次有东西死了,在关卡结束时是1x”),你就要迭代成就并进行快速检查。当设计者想要记录一个新事件时,程序员添加一行代码来记录它是很简单的
  • 注:pub/sub不适合这种IME,因为设计师从不希望“when player.distance=50”。他们真正想要的是“当观看屏幕的人感觉到玩家的距离似乎经过了第一个村庄,或者至少向右4个屏幕宽度”——也就是说,比一个简单的计数器要模糊和抽象得多

    在实践中,这意味着逻辑发生在变化发生的地方(甚至在事件发布之前),这是一种糟糕的使用发布/订阅的方式。有一些游戏引擎使“逻辑发生在接收点”(即“订阅”部分)变得更容易,但它们不是大多数

  • 在线游戏:几乎相同,除了你存储“计数器”(整数上升),通常还有“Delta”(帧对帧发生的事情的循环缓冲区)和“事件”(游戏中发生的复杂事情,可以硬编码成单个ID加上固定大小的参数数组)。然后通过SNMP等方式公开这些数据,供其他服务器以低CPU成本异步收集
  • i、 e.与上文第1条几乎相同,只是您注意做两件事:

    • 固定大小的内存使用;如果“阅读”服务器离线一段时间,在这段时间内赢得的成就将需要重新赢得(尽管您通常可以让客户支持人员手动查看主要系统日志,确定“可能”获得了成就,然后手动奖励)
    • 非常低的开销;SNMP是一个很好的标准,我知道的大多数团队最终都会使用它

    如果您没有访问源代码的权限,您甚至可以这样做,例如在视频游戏模拟器中。例如,可以编写一个简单的记忆故障诊断仪来查找显示的分数。一旦你有了这些,你的成就系统就和轮询记忆一样简单了