# 全链游戏:谈谈Web游戏引擎 **Published by:** [0xlukema](https://paragraph.com/@lukema95/) **Published on:** 2023-09-26 **URL:** https://paragraph.com/@lukema95/web ## Content 概述提起游戏引擎,大家最先想到的可能是Unity或者虚幻引擎这些在游戏领域早已耳熟能详的引擎。这些引擎功能强大,提供丰富的组件与图形渲染功能。Web3的游戏引擎的概念可能和Web2的有些差别(至少目前来说),Web3的游戏框架主要解决的问题是如何提供一套框架和套件,使得开发人员可以快速方便的构建一个逻辑和数据都在链上,并且方便拓展的链上游戏(或者自治世界),它们并不提供图形引擎。 PSE Trading将全链游戏的产业链划分为四个关键层次,与 Web2 游戏领域的层次相呼应:基建层、中间件层、服务 / 工具层和应用 / 游戏层。[图片来自https://foresightnews.pro/article/detail/41671] 目前比较知名的Web3游戏引擎有Dojo和MUD。虽然都习惯称Dojo和MUD为链上游戏引擎,不过可能称之为开发框架更为准确。下文也将主要分析这两个引擎的设计理念和提供的功能。Autonomous Worlds注意到在上图的应用层中的组件被标记为「自治世界」(Autonomous Worlds),这个名词很重要,可以说为Web3游戏引擎的设计提供了指导思想。该词最先出自 Lattice(后续会谈到)的文章,文章中对其定义为:「由区块链执行的实体和客观引入规则系统。从某种意义上说,自治世界是相互客观的现实」。同时也谈到: 「自主世界具有明确的硬叙事边界、形式化的引入规则,不需要特权个体来维持世界的存在」。我们可以理解为自治世界就是一个任何人都可以参与(包括参与构建)、开放、没有明确规则(意味着每个人都可以定义自己的一套规则),没有人能完全掌握话语权的客观世界。这同时也作为全链游戏的另一种诠释。 Dojo在其文档中认为游戏必须至少具备以下两个基本特征才能被视为自治世界:分散的数据可用性层:虽然状态执行可能驻留在集中层上,但如果执行层不复存在,则可以重建状态至关重要。Rollups 提供了一种解决方案,提供增强的容量执行层,同时确保数据永久存储在以太坊上。这保证了世界的永久存在。扩展世界的无许可入口点:世界合约必须能够在不需要许可的情况下接受新的系统和组件。虽然这并不意味着每个组件和系统都会被利用,但它们必须遵守这种模式,确保对潜在增强功能的开放和不受限制的访问。ESC和ARC模型用于构建游戏引擎的一种常见设计模式是ESC(Entity Component System)模型。其中:Entity(实体)- 代表了游戏中的对象或角色,它们通常是一个抽象的容器,可以附加不同的组件。Component(组件)- 代表了实体的特定属性或功能,比如位置、渲染器、碰撞器等。组件是可以重复使用的模块,它们可以附加到不同的实体上。System(系统)- 系统处理特定类型的组件,它们控制实体和组件之间的交互。系统在游戏循环中运行,负责更新组件的状态和处理各种游戏逻辑。这种模式的优势在于它将游戏对象分解成更小的、可重用的部分,使得游戏开发更加灵活和可扩展。同时,ESC 模型也有助于提高游戏性能,因为系统只处理特定类型的组件,而不需要遍历所有实体。ESC 模型通常与面向数据的设计一起使用,以实现高效的游戏开发。目前包括Dojo在内的很多框架都是参考的ERC模型。 下面是一个简单的例子用来方便理解: // 一个实体 Entity player { } // 定义组件 Component Position { float x float y } // 一个系统来处理位置更新 System MovementSystem { position = entity.get(Position) position.x += 1 position.y += 1 } ARC(ActionRegistryCore)模型由Jump提出,下面引用其文章中的定义和解释: ARC是一个受传统ECS架构启发的链上信息组织框架。与传统的 ECS 一样,ARC 的实体是组件的无数据容器,而组件是普通数据类型,没有可以“附加”到实体的行为。与 ECS 不同,ARC 具有可以针对特定组件执行的“操作”而不是“系统”。主要区别在于,传统 ECS 中的系统是围绕传统游戏中使用的基于循环的架构构建的,而动作捆绑则说明了区块链架构是基于推送的。这里概述的 ARC 的具体实现是针对 Solana 生态系统的,但类似的架构也可以用于其他生态系统。ARC 的基本结构是三层洋葱。首先,核心负责维护注册管理机构和实体。其次,您有各种注册表合同,用于维护组件和操作的注册以及治理特征。最后,您拥有修改组件的(可选)游戏或操作合约。这里不对ARC做过多展开,想对其有更多了解的可以查看原文。Web3游戏引擎MUDMUD(这个名字借用了 Multi-user dungeon 的首字母缩略词)以太坊上的游戏开发框架,也可以说是链上游戏开发框架的开创者,由 Lattice 团队开发。Lattice 正是开发了大名鼎鼎的全链游戏<黑暗森林>(Dark Forest) 的团队。Lattice 在开发Dark Forest时遇到了很多困难,包括:智能合约中状态和逻辑的耦合导致逻辑升级困难,链和客户端之间缺乏同步可能导致游戏状态不一致,访问控制的不规范给试图创建自己的插件和客户端的潜在第三方开发者带来了问题。于是,Lattice 团队构思并开发了MUD框架,试图解决上述问题。使用MUD框架,Lattice团队仅用1.5个月就开发出了OPCraft,OPCraft 是一个完全链上的像素世界,可以把它当成链上版本的<我的世界>。OPCraft 也取得了不小的成功。 MUD框架解构开发程序的过程,通过不同的堆栈来实现对应的功能:Store:链上数据库,应用程序的所有数据都存储在Store中。World: 调用的入口点,标准化的访问控制、升级和模块,相当于逻辑合约。Indexer:可以使用tRPC查询的索引器,快速查询应用的链上数据。从以上的组件可以看出,MUD使用Store和World将逻辑和存储进行了解耦,类似于后端中的数据库和服务端代码。传统的代理(Proxy)合约和钻石(Diamond)合约虽然能在一定程度上对逻辑和数据存储进行解耦,但是都需要遵循一些规范,这无疑对合约开发者提出了不小的要求。MUD的解耦顺利的解决了这个问题,开发人员在开发程序时只需要定义好表单的数据结构,然后使用MUD配套的工具就可以直接生成对应的Solidity合约代码,该合约代码拥有对数据进行CURD的方法。 MUD中的Store存储整体上要比原生的存储节省一些Gas(当然Store中存储的数据也是在链上的,只是对数据存储结构做了一些优化)。下面是一个定义的表单的示例:// table definition Allowance: { keySchema: { from: "address", to: "address", }, valueSchema: { amount: "uint256", }, } 通过MUD配套的命令行工具通过定义的表单文件直接生成对应的表单Solidity合约,然后就可以在World合约中通过如下的方法访问表单:// storing AllowanceTable.set(address(0), address(1), 10); // getting allowance = AllowanceTable.get(address(0), address(1)); Store和原生Solidity存储之间存在的一些差异:Store以与Solidity编译器不同的方式编码存储,从而节省具有多个数组的表的Gas。Store不支持嵌套结构,每个表只允许14个动态类型(即:数组,字符串和字节列)。这与Solidity不同,Solidity支持嵌套结构体和无限数量的动态类型。Store的数组上限为65,536个元素。然而,Store并没有限制每个表可以存储的记录数量。另一个重要概念是World,World其实就是一个入口点内核,负责协调不同合约对 Store 的访问,也就是说World是没有状态的,但是可以通过World来修改状态。Store的读写权限使用命名空间来进行控制,这里不展开,总的来说修改Store的合约会继承一个System合约,System可以读取任何表,并且它们对在其所在的同一命名空间下注册的表具有默认的写访问权限。为了写入不同命名空间中的表,需要由拥有相应命名空间的地址授予显式访问权限。 此外,World和Diamond(或Proxy)之间的还有一个区别在于World允许在World上无许可地注册新的逻辑和表。后者需要管理员才能添加和升级逻辑。World有针对Store的存储访问管理,它们可以放宽这一要求,允许任何人向应用程序添加新逻辑和新表,而不会引入安全风险。这也就是为什么称之为World而不是类似Logic之类的词的原因,World一开始的设想就是为了建立一个开放自治世界,允许玩家可以在此之上添加拓展。 最后一个重要的概念就是Indexer,在开发程序时很多场景前端或者客户端都需要及时同步链上的数据,一般情况下开发人员会使用轮询或者监听链上事件来获取最新数据,当然也可以使用第三方的RPC服务来获取。有了Indexer,开发人员可以将Indexer配置成指向对应的Store。然后,MUD 客户端连接到索引器就可以直接获取到最新的 Store 中的数据,这样就无需考虑数据同步的问题啦。 此外MUD还提供了一些配套的命令行工具和SDK方便开发者使用。DojoDojo是以太坊二层网络StarkNet上的游戏开发框架,也是目前StarkNet上最完善和最被广泛应用的框架。Dojo 的工具套件消除了构建链上游戏的基础设施复杂性,使开发人员能够专注于其游戏的开发。Dojo 利用 ECS(Entity Component System)作为其核心架构,有效地管理自治世界(Autonomous Worlds)的状态和行为。该模型围绕作用于Entry的系统,Entry是纯数据组件的集合。系统根据对这些组件的持久查询有效地确定要处理哪些实体。Dojo的设计理念其实和MUD有些类似(应该是参考了MUD的实现),主要是提供工具套件将链上的数据存储和逻辑进行解耦。 Dojo提供如下的套件:Torii - Starknet 索引器。Dojo 标准化了合约状态以反映传统的关系数据库,能够自动索引所有合约状态,并通过通过 GraphQL API 或 gRPC 公开这些状态,使开发人员能够轻松查询和检索数据。Katana - 一个可定制的 StarkNet 开发网络。它的速度非常快,可以让您快速迭代游戏逻辑。Sozo CLI - CLI管理工具。它使您能够创建、构建、测试和部署您的世界(World)。此外,您可以制作新的组件和系统并将它们注册到您的世界中。其中Sozo的工作流程如下:Dojo使用了ECS模型作为其核心架构,其使用Sozo生成的项目目录结构如下:src - components.cairo - systems.cairo - lib.cairo Scarb.toml 其中的一些关键概念:World - World合约作为一个核心系统内核,作为启动和解决所有交互的基础。在这个内核中,合约被部署、注册和执行,通过允许客户端参与单个而不是可能的多个合约,从而简化了下游系统的流程。Component - 定义世界结构的基础,封装了系统可能发生变化的状态,即 Component = Data。System - System 支撑着你的世界的逻辑。虽然系统本质上是无状态的,但它们的主要作用是修改组件的状态,即 Systems = LogicEntry - 在Dojo中,实体被视为世界中的主键值,可以将Component附加到其上。Authorization - 组件的部署者是它的初始所有者。组件所有者能够授予owner和writer角色。只有owner可以授予系统writer角色,该角色允许系统更新组件。Event - 事件在解码Dojo世界的动态方面起着关键作用。每当组件有更新时,World合约就会发出这些事件。当然,Dojo也提供了必要的SDK提供给客户端使用。总结除了 Dojo 和 MUD 之外,Argus 和 Curio 也是备受关注的游戏引擎,不过这两个项目都还处于比较早期的阶段。下面是IOSG Ventures对这四款引擎的总结对比:[图片来源https://foresightnews.pro/article/detail/41671] 目前Web3游戏引擎主要还是参考了ECS模型,遵循的是数据和逻辑解耦思路并提供一系列方便开发的工具坊。这些引擎确实很大程度方便了链上游戏开发者,也提供了一个未来链上游戏引擎开发的思路。但是同时我们也要看到,像以太坊这中运行缓慢的链要在其之上构建全链游戏是很困难的,Rollup 或者一些其他TPS更高的主网可能更适合。 此外,构建全链游戏目前还有一些需要解决的问题,Paradigm在其论文<**The Open Problems of Onchain Games**>中也指出了无权限区块链的某些属性阻止了对主流游戏设计机制的支持:Incomplete Information (不完全信息)- 许多游戏中的关键机制。现有的解决方案存在不可接受的缺陷(例如,DarkForest的加密战争迷雾演变成硬件挖矿竞赛)。Automation & Collusion(自动化和勾结)- 根本无法阻止。bot不能与真正的玩家区分开来,玩家也不能保证是独一无二的。开发者必须创造出不会被bot meta或Sybil合谋破坏的游戏。Ticking - 区块链是由异步交易驱动的。大多数传统游戏都是围绕着独立于玩家互动的基于时间的游戏循环而创造。当前的Web3游戏引擎虽然算不上完美,但是也算是开了个好头,而且目前游戏引擎还没有一个处于统治地位的项目出现,这是一片蓝海,相信后面会有更多游戏引擎的项目出现,各个公链也会跟进设计出符合自己链的设计的游戏引擎。参考链接https://mud.dev/ https://book.dojoengine.org/ https://www.paradigm.xyz/2023/08/onchain-games https://foresightnews.pro/article/detail/41671 https://0xparc.org/blog/autonomous-worlds https://jumpcrypto.com/writing/introduction-to-arc/ ## Publication Information - [0xlukema](https://paragraph.com/@lukema95/): Publication homepage - [All Posts](https://paragraph.com/@lukema95/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@lukema95): Subscribe to updates