CaptainZ

CaptainZ

Prompt Engineer. Focusing on AI, ZKP and Onchain Game. 每周一篇严肃/深度长文。专注于AI,零知识证明,全链游戏,还有心理学。
twitter

How does Curio integrate the ECS game engine into OPStack?

On May 31st, Curio (@0xcurio) open-sourced Keystone, an L2 chain with a built-in game tick and ECS full-chain game engine, based on the OP Stack. Compared to writing ECS states through smart contracts, this design allows all ECS operations (such as querying and state setting) to have faster performance. Through custom precompilation, smart contracts can access the underlying ECS chain state. Game logic can be written in Go language instead of Solidity, allowing for massive parallelization. This article will provide an in-depth analysis of the Curio project itself and its principles, and explore how it achieves the aforementioned goals.

Curio was founded in 2022 by engineers and gamers Kevin Zhang (@kzdagoof) and Yijia Chen (@0x1plus), dedicated to creating fully blockchain-driven games powered by smart contracts. This enables a new form of multiplayer computation, allowing all participants to contribute to the "shared universe," with the founders stating that this allows games to be almost entirely player-created. The company's first game, Treaty, is an on-chain strategy game where users can write and deploy smart contracts. On February 21, 2023, Curio announced the completion of a $2.9 million seed round of financing, led by Bain Capital Crypto, with participation from TCG Crypto, Formless Capital, Smrti Lab, Robot Ventures, Zonff Partners, and several angel investors.

There are currently various ways to narrate a full-chain game, with common examples being decentralized games (DeGame) and autonomous worlds. Curio has proposed its own idea: User Generated Logic (UGL). I estimate that Curio encountered many difficulties in the process of creating its first full-chain game, Treaty, which led to the idea of creating its own chain and embedding the game engine into it. This idea aligns with Argus, with the difference being that Argus adopts a sharding mechanism, while Curio took a shortcut by directly using the OP Stack.

MUD's ECS Game Framework#

Let's first take a look at how MUD's ECS framework works. If you have read my explanatory article "In-depth Analysis of the Full-Chain Game Engine MUD" (https://captainz.xlog.app/shen-du-jie-xi-quan-lian-you-xi-yin-qing-MUD), you should understand that ECS improves game development flexibility and maintainability by separating logic, data, and entities. The programming language used is Solidity, and the attribute states of game objects are stored in smart contracts. Taking the ERC-20 contract as an example: the ERC-20 contract stores the token balances of each address in a mapping (from address to uint256 balance). We can consider each ERC-20 contract as a table with two columns: "address" and "balance." This corresponds to a component with a single pattern value ("balance"). Each row in the table associates an entity ("address") with a component value ("balance"). An address can hold balances in many independent ERC-20 contracts, corresponding to an entity associated with many independent component values. In the current ERC-20 reference implementation, the state and logic are coupled in the same contract. In ECS, there will be a general "transfer system" to handle the logic of transferring tokens from one address to another by modifying the state stored in the token component.

Because the game object attribute states in MUD are stored in smart contracts, the synchronization of ECS state changes (client state synchronization to blockchain nodes) needs to be done through smart contracts, and this synchronization process cannot be parallelized and requires frequent contract calls. Therefore, Curio hopes to solve this by introducing precompiled contracts.

Precompiled Contracts#

Precompiled contracts in the Ethereum Virtual Machine (EVM) are a special type of smart contract whose code is directly hardcoded into the Ethereum node's code, rather than being written in Solidity or other EVM-compatible languages. These contracts are often used to perform complex computational tasks because the hardcoded implementation is usually more efficient than code interpreted in the EVM. Precompiled contracts are typically used to optimize performance and reduce gas costs.

Implementing a precompiled function involves the following steps:

  1. Choosing an address: The precompiled function needs an address. Ethereum has chosen addresses from 1 to ff (including ff) to store precompiled contracts.

  2. Implementing functionality: The precompiled function needs to implement some functionality. This usually involves some complex calculations, such as elliptic curve operations or large integer operations. This function is typically written in Golang or C++, and then directly integrated into the Ethereum node's code.

  3. Calculating gas cost: The precompiled function needs a function to calculate the gas required for its execution. This function should determine the gas cost based on the size of the input data and the complexity of the operation.

  4. Integration into Ethereum node: The precompiled function needs to be integrated into the Ethereum node's code. This typically involves modifying the Ethereum node's code to add the new precompiled contract and recompiling and deploying the node.

Then, smart contracts can use the address of the precompiled contract to invoke the precompiled function. The EVM will check if the address corresponds to a precompiled contract, and if so, the EVM will directly call the hardcoded function in the node's code instead of interpreting the contract code in the EVM.

It should be noted that adding new precompiled functions requires modifications to the Ethereum protocol, which usually require consensus from the community. Additionally, since precompiled functions are hardcoded into the Ethereum node's code, every node running this new version needs to include the code for this new precompiled function. This means that adding new precompiled functions is a complex and thoughtful process in practice.

Curio's Solution#

From the discussion on precompiled contracts above, we can see that while using precompiled contracts can greatly improve performance, it requires modifying the node's code and recompiling and deploying the node, which is not feasible for the Ethereum main chain. Therefore, Curio chose the OP Stack, and in this customized Layer 2, they modified the node's code to add the ECS precompiled contract. It is through this custom precompiled contract that smart contracts can directly access the underlying ECS chain state. Thus, this design allows all ECS operations (such as querying and state setting) to have faster performance. Additionally, since OP Stack nodes use the "Go-Ethereum" client, Keystone's game logic can be written in Go language instead of Solidity, allowing for massive parallelization.

The ECS in Keystone is mainly implemented through the code in the 'engine' and 'game' directories.

In the 'engine' directory, we can see the main data structures defining ECS, such as World and Component. World is an ECS foundational world structure that includes entities and components as its main parts. Each Component contains a data type (DataType) and mappings for storing entities to values (EntitiesToValue) and values to entities (ValueToEntities).

In the 'game' directory, we can see some specific game components such as PositionComp, TargetPositionComp, and TagComp. These components have their own data types and a flag indicating whether the value-to-entity mapping should be stored (ShouldStoreValueToEntities).

Advantages of Integrating a Game Engine into the Chain#

From the above discussion, we can see that building ECS (Entity-Component-System) states directly into a customized blockchain can achieve faster performance compared to writing ECS states through smart contracts. This performance improvement comes from several aspects:

1. Data structure optimization: Writing ECS states in smart contracts often requires the use of non-optimized data structures, while in Keystone, they can use efficient data structures (such as sparse sets) to store and manipulate ECS data, thereby improving the speed of querying and setting states.

2. Avoiding smart contract execution overhead: The Ethereum Virtual Machine (EVM) needs to interpret and execute smart contract code, which incurs certain overhead. However, building ECS states directly into the blockchain can avoid this overhead because ECS operations are executed directly in the core code of the blockchain instead of being interpreted by the EVM.

3. Parallelization: Keystone allows game logic to be written in Go, which means that Go's parallel and concurrent features can be utilized to improve the speed of ECS operations. This cannot be achieved in smart contracts because the EVM is single-threaded.

4. Precompiled contracts: By using precompiled contracts to access ECS states, the speed of ECS operations can be improved. Precompiled contracts are hardcoded functions in the blockchain node's code, which execute faster than interpreted code in the EVM.

5. State update optimization: Keystone adopts an approach that allows state updates to be performed in sub-worlds and then applied to the parent world. This approach reduces unnecessary state updates and improves the speed of state setting.

Where is the Game Tick?#

The concept of Game Tick is often used in game development to manage the passage of time within the game. Each tick represents one cycle of the game's main loop, and various game events can be scheduled based on these ticks. This is also why we say traditional games are "loop-based."

However, the blockchain's state itself does not include the concept of "current time" as we typically understand it. The blockchain operates based on the concept of blocks, which are added to the chain in a linear order. Although these blocks usually contain a timestamp, it is not used as a measure of "current time" in the same way as in traditional computing environments.

Curio claims to have integrated the Game Tick into the blockchain (Game Tick built into the chain), but I have searched through the entire codebase and have not found any code snippets related to Game Tick. Therefore, I am very curious about how Keystone implements the game tick in the blockchain and hope that Curio will have the opportunity to provide more detailed explanations about this feature. However, one speculation I have is that in Keystone's Game Tick environment, the next_tick field may be used to determine when the next cycle of the game loop should occur. This is based on the internal clock of the blockchain node server and is used to manage the progression of game time within the game's internal logic, separate from the progression of blocks within the blockchain.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.