可扩展性游戏机制建模 #
在构建游戏时,很容易直接根据玩家的经验对服务器代码进行建模,特别是对于基于进度的机制。但其中潜伏着代价高昂的问题。
考虑一个假设的角色扮演游戏,对玩家获得经验分并在一周内每天完成任务给予奖励。您可能会构建两个系统:一个系统在玩家获得足够的经验分以获得奖励时升级玩家,另一个系统(或使用 cron 作业)在每天午夜检查玩家的每日任务进度。
虽然这两个系统很容易解释,但随着时间的推移,您的游戏可能会有更多的系统。这就是这种方法的弊端:它爆炸性地增加成本,滋生复杂性,并隐藏脆弱性。
它的成本很高,因为处理量随每个新玩家的加入而线性增加。 夜间 cron 作业将耗费越来越长的时间来完成,或者需要额外、昂贵的计算能力来快速运行,更不用说夜间负载阻塞服务器。
它很复杂,因为您必须为每个新的机制、计时器或事件构建一个新的系统。 您的等级晋升系统不能方便地利用每日任务系统中的代码,反之亦然。
它很脆弱,因为您可以将服务器代码与时钟联系起来。 如果没有在午夜完成每日进度检查,游戏可能会中断,或者需要在深夜进行救援。更糟糕的是,一些周期性的系统可能会变得完全不稳定,例如玩家资源的不断流失或积累。cron 作业不能在每一秒都对每个玩家正常运行。
那么游戏开发者该怎么办?
摆脱天真做法的一种方法:以玩家为中心的处理 #
好消息是,有一种方法可以借助通用的方式对服务器代码进行建模,这种方法适用于许多游戏系统:对玩家事件(如登录、注销、结束比赛等)作出反应。
与其定期检查给定玩家、团队或物品可能经历的更改,不如等待并响应真正发生的事件。这有点类似于事件驱动的编程范例:服务器的作用类似于主循环,会触发回调功能。
此方法可降低服务器成本,最大限度降低复杂性并提高游戏的稳健性,因为:
- 进度代码只有在直接影响一个玩家时才在服务器上运行。
- 服务器负载的时间分布更加均匀。
- 事件处理在更接近玩家活动的时间发生,而不是等待预定的 cron 作业。
- 在游戏机制之间可以更方便地重新利用进度代码。
让我们看一下这个方法的概要,然后看一个真实的例子。
实现模式:进度模板 #
实现此模型的一种模式的工作分为三个部分:
- 定义静态进度:编写一个模板,定义系统进度的里程碑、奖励和默认值。
- 进度开始:进度开始时,将模板复制到玩家的数据。
- 玩家操作更新:每次相关事件发生时,更新玩家的进度副本。
通过模板和事件处理实现每日连局 #
让我们看一个例子:在我们假设的游戏中,我们想奖励连续几天登录游戏的玩家。如果玩家每 24 小时至少登录一次,重复 7 次,他们将获得完成奖励,此外第三天还获得小奖励。
为了进行设置,我们将创建一个 JSON 格式的静态进度模板(JSON 只是这里的一个选项,您可以使用不同的格式或数据结构,但这个概念仍然适用):
|
|
每当玩家登录时,我们都会为该玩家运行一些代码,以确定他们是否有活动的连局。如果他们没有活动的连局(或他们现有的连局已被打破),我们将把模板复制到该玩家的数据中:
function onLoginEvent(player)
if (player.streak == undefined or streakIsExpired(player.streak))
player.streak = copyNewStreakFromTemplate()
如果玩家已有活动的连局,并且他们在合适的时间登录,我们可以解锁其连局,让他们前进:
if (time.now() > next_login_after and time.now() < next_login_after + ONE_DAY)
player.streak.progress += 1
awardUnlock(player, player.streak.rewards[player.streak.progress])
setTimeForNextUnlock(player.streak)
如果我们到达连局末尾,我们需要一些额外的逻辑来重新开始(更复杂的模板可能支持倍数并对连局进行迭代)。
其他事件也有可能触发对连局的操作。例如,玩家可以选择取消连局(或许为了开始其他进度)。这将有其专用的事件处理程序。
Nakama 中的事件挂钩 #
在 Nakama 中,我们可以用 after 挂钩实现此模式。您可以注册一个在服务器接收到每条消息后执行的函数。在此函数中,您可以调度更具体的事件处理程序来晋级玩家、奖励奖杯,或者就像在本例中一样,更新连局。
在这种情况下,您可以编写一个 after 挂钩,每当客户端调用 getAccount()
功能(发送有关该连局的带外通知),它就会更新玩家的连局进程。
在本例中,我们在一个 Nakama 已经提供且您可能会使用的 API 上获得一个事件触发器:getAccount()
。在客户端,不需要额外的代码来触发连局更新。
一种模式,多种应用 #
此方法适用于许多进度式游戏机制,包括:
- 玩家、NPC 和物品晋级
- 资源消耗与续费,例如物品降级和充能
- 挑战、请求和成就
- 留人激励,例如连局和每日奖励
别碰无休无止的 cron 作业带来的麻烦,以事件为中心考虑对游戏机制建模。