这些天创建的许多游戏都带有其自己的成就系统,该成就系统会奖励玩家/用户完成某些任务。这里stackoverflow上的徽章系统完全相同。
尽管有些问题我无法找到好的解决方案。
成就系统必须时刻注意某些事件,想一想为战斗提供20到30个成就的游戏。服务器必须一直检查这些事件(例如:玩家在这场战斗中避免了x对手的攻击或玩家走了x英里)。
成就系统通常需要仅在游戏核心引擎中使用的数据,如果没有那些令人讨厌的成就,则无论如何也不需要使用这些数据(例如:玩家在每次战斗中跳跃的频率是多少,不想将所有这些信息存储在数据库中。)我的意思是,在某些情况下,添加成就的唯一方法是将检查其当前状态的代码添加到游戏核心,这通常是一个非常糟糕的主意。
我的示例似乎“无害”,但请考虑一下《魔兽世界》中当前可获得的1000多个成就,以及同时在线的许多众多玩家。
最佳答案
成就系统实际上只是一种日志记录形式。对于这样的系统,publish/subscribe是一个很好的方法。在这种情况下,玩家可以发布自己的信息,感兴趣的软件组件(处理个人成就)可以订阅。这使您可以使用专用的日志记录代码查看公共(public)值(value),而不会影响任何核心游戏逻辑。
以您的“玩家行走x英里”为例。我可以将走过的距离实现为玩家对象中的一个字段,因为这是一个简单的值,无需随时间增加空间。然后,奖励步行10英里的玩家的成就就是该 Realm 的订阅者。如果有很多参与者,那么将这个值(value)与一个或多个中间经纪人级别进行汇总是有意义的。例如,如果游戏中存在100万玩家,那么您可以将值与1000个经纪人进行汇总,每个经纪人负责跟踪1000个单独的玩家。然后,成就订阅这些经纪人,而不是直接订阅所有参与者。当然,最佳的层次结构和订户数量是特定于实现的。
就您的战斗示例而言,玩家可以以完全相同的方式发布其上一场战斗的详细信息。监视战斗中跳跃的成就将订阅此信息,并检查跳跃数。由于不需要历史状态,因此也不随时间增长。同样,无需修改任何核心代码。您只需要能够访问一些值。
还请注意,大多数奖励不需要是瞬时的。这使您在管理流量方面有一些余地。在上一个示例中,您可能不会更新经纪人发布的行进距离,直到玩家再走一英里,或者自上次更新以来已经过去了一天(此后一直在内部递增)。这实际上只是一种缓存形式。确切的参数将取决于您的问题。
关于optimization - 在复杂的现代游戏中实现成就系统,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2343538/