我们将虚拟世界中时间的流逝称为世界法则对其自身的迭代应用。
原文标题:Timekeeping For Digital Gods
原文作者:bytes and yonada
原文来源:mirror
作为虚拟世界的创造者,我们的目标是创建出能让用户感到有趣并深度参与的环境。这就需要我们在设计允许复杂和不预期行为浮现的数字物理学,与确保现有基础设施能够支撑这些行为之间找到平衡。为此,我们需要考虑数字物理学的三个主要维度:时间,它的法则形式,以及这些法则适用的范围。
我们将虚拟世界中时间的流逝称为世界法则对其自身的迭代应用。每个离散的应用就是这个世界时间流中的一个“瞬间”。设计世界内的时间的一种方式是让它与外部时间连续进行。在基于区块链的虚拟世界中,每个区块对应世界内过去的一定数量的瞬间,无论该区块包含的是什么交易。这被称为同步时间,或者“滴答”现象。这种方法可以使世界对用户更有趣,因为它们可以实时看到自己行为的结果。另外,它导致世界内的时间更长,世界持续更新,从而促进有趣行为的出现。
然而,这种方法也有其缺点。更大的时间范围通常需要更多的计算资源,这可能会很快超过链或服务器的能力。在普通区块链上实施这个系统也可能很困难,因为所有链上的变化都必须由外部用户发起的交易来启动。
当你想象一些看似简单的事情时,这个困难就变得明显了:一个链上的游戏有非玩家角色(NPC)。在主网以太坊上,你可以定义一个更新功能,设置游戏地图上每个NPC的位置,并让一个外部账户定期调用它来更新他们的位置。但这可能不可靠,因为你不能保证外部账户在应该调用更新的区块中不会因为gas fee 被竞价超过。你的游戏中的时间结构会因此发生漂移(以原始CryptoKitties的giveBirth()功能为例;随着链上gas fee 的增加,Axiom Zen实际上不得不增加调用giveBirth功能的奖励,以确保新的NFT出生交易在用户繁育Kitty后的256个区块被调用)。我们将这种使用外部账户的方法称为“手动滴答”。
定制的 rollups 让我们有更多的灵活性,在链上添加"滴答"功能,无需外部账户,而且同步时间的推进由协议保证。我们将这种方法称为"自动滴答"。自动滴答可以通过编写一个“滴答合约”来实现,该合约由协议本身调用,而不是由外部账户调用。
举个例子,@therealbytes 开发了一个基于OP Stack的概念验证型滴答链,它运行了一个自动滴答的康威生命游戏实现(你可以在这里找到这个视频演示)。Bytes 使用了一个修改过的系统交易来自动调用滴答式元胞自动机模拟合约。为了充分测试链本身的极限,他用两种方式实现了游戏:一种是作为一个在链上运行的Solidity智能合约,另一种是作为链本身的预编译。Solidity实现在达到每个区块两次更新的70x70网格后让CPU达到极限(1个区块/秒,或者大约10k个细胞/秒),而自定义预编译引擎的链在使用大约6%的CPU(大约130k个细胞/秒)时,达到了相同速率的256x256网格。
在最后一段的最后一句中,关键词是“达到极限”。滴答链添加了额外的复杂性层次:每增加一个区块,就需要由模拟游戏的交易触及更多的状态。最终,rollup 节点会被原始计算(CPU,磁盘IO等)所限制。这里的唯一解决方案是采用更高容量的节点。
“同步时间”的替代方案是“异步时间”。在这个方案下,世界中时间的流逝并不一定会在外部时间推进时前进。相反,时间通常会在某些事件(通常是用户行为)发生时向前移动。传统的不涉及计时器的棋盘游戏就属于类似的范畴。在链上实现非同步时间更容易,因为它就是区块链被设计来支持的模型。然而,它也牺牲了一些可能使世界更有趣的特性(如自动移动的NPC)。
@notdavidhuang 和 cha0sg0d 的一款概念验证游戏早期版本 WildWood,就揭示了这种牺牲。在这个游戏中,两个玩家必须从侵略性NPC的围攻中保卫他们的基地。在游戏的早期版本中,NPC的移动只有在玩家自己移动时才会被触发 — 这是一种不太现实的异步时间实现。在添加滴答之后,NPC移动了,但另一个问题仍然存在。链每秒滴答一次,这意味着如果玩家每秒移动多于一次,游戏必须使用 optimistic rollup 的更新来广播玩家在地图上的位置。然而,你的队友不会自动看到你的客户端,这意味着在玩家位置更新上会有延迟。为了克服这个问题,团队利用了 MUD 的中继服务,一个用于向全链广播本地客户端的点对点网络。瞧,异步时间到同步时间的转变就实现了。
世界构建者还必须决定他们的虚拟世界遵循开放形式的表达还是封闭形式的表达。封闭形式的表达具有固定数量的操作。然而,开放形式(或递归)表达的操作数量则根据给定变量的增长。在开放形式的表达下,只能通过反复应用世界的法则到已知状态,才能计算出世界的未来状态。复杂、生动的环境,比如《矮人要塞》,通常属于这个范畴。另一方面,封闭形式的表达允许从过去的状态和它们之间流逝的时间,计算出任何未来的状态(假设没有未来的用户行动改变状态),比如《帝国时代 II》中的资源开采速率。
开放形式可以使虚拟世界更有趣,因为像现实世界一样,它们是不可预测的。预测世界未来状态需要越来越多的时间和计算资源(在链上实现的康威生命游戏就是一个很好的例子:你不能计算出未来的任意状态,因为你需要按时间运行游戏)。此外,从简单的微观交互中可以出现意想不到的宏观行为。在由封闭形式管理的世界中,这些出现的行为通常只在外部发生,通过用户的行动(他们自己就像开放形式一样),而不是在世界物理本身中发生。
开放和封闭形式之间的权衡涉及到一个与时间相似的平衡。封闭形式可能会降低世界的潜在趣味性,但它们也使其更具计算效率。封闭形式可以与同步或异步时间一起使用。在区块链上实现时,他们在时间同步时对开放形式有显著的优势。因为任何长度的时间的成本是恒定的,所以世界可以被设计为只在用户发送交易时更新链上状态,但它被设置为在上次更新后的时间流逝后的状态。
考虑一下当前链上动态的标准方法,一个被称为“懒更新”的方法。在懒更新(lazy update)中,玩家启动行动的开始和结束,但中间的时间是模拟的,而不是直接计算的。比如,一个玩家在第1个区块时种下一棵苹果树,然后在第10个区块时收获苹果。可以编写懒更新逻辑,使得玩家每个时间单位可以收获一个苹果,总共9个苹果。对于有封闭形式函数(如每个区块一个苹果)的更新逻辑,这是完全可以的,但如果农业逻辑基于玩家行动之间的输入而变化,这种方法就会失效。如果在第5个区块,一场暴雨增加了苹果的生长速度,而在第7个区块,蝗虫灾害几乎摧毁了作物,那么在第10个区块时,玩家能收获多少苹果就无法有效计算,除非真正应用所有已经发生的事件(你不会有足够的计算能力去赶上新的状态)。尽管如此,懒更新仍然对于某些生物(如固定生长速度的植物)的廉价计算非常有用,但对于一个动态世界的完整工具箱来说,这仍然不足。
在现实世界中,时间无处不在,一次性流逝,宇宙可能是无限的(虽然有一些相对论的复杂性)。然而,在虚拟世界里,情况并非必然如此。
首先,虚拟世界可能是明显有限的。有趣的可能性通常随着大小的增加而增加——由二百亿个星系组成的世界发生的事情比由两个原子组成的世界更多——但计算成本也会增加。这两种关系都与之前提到的两个权衡密切相关:时间的流逝和物理形态。
其次,时间并不必须在虚拟世界的所有地方流逝。世界可以被划分为时间流逝不同的离散区域,以减少世界的计算负担。例如,可以在有用户活动的地区使用更复杂和昂贵的物理规则,而在没有活动的地方使用更简单的物理规则。这种方法的缺点是双重的:它可能使世界显得不一致,缺乏完整性,这限制了世界规则的设计空间,也给世界建造者带来了压力,要避免让用户感到困惑;同时,它也限制了因果关系在世界内部的传播,如果一个区域的行为不能在远方的区域产生后果,那么两者之间的空间就被冻结在时间中。物理规则应用的区域大小是一个重要的设计考虑因素,它将影响世界需要的资源以及它能达到的趣味性水平。
为了创建一个有趣而吸引人的虚拟世界,有必要仔细平衡计算效率和有趣性。这包括决定使用何种类型的时间(同步或异步)并评估统治世界的物理法则的形态。物理法则应用的区域大小是另一个重要的决策。通过谨慎地做出这些选择,世界建造者不仅可以在保持世界的计算负担管理得到有趣性,他们还可以为其他开发人员提供一个高度肥沃的创新基础。