How does Curio integrate the ECS game engine into OP Stack?

How does Curio integrate ECS engine into OP Stack?

On May 31st, Curio (@0xcurio) open-sourced Keystone, an L2 chain that features a game tick and ECS full-chain game engine built on the OP Stack. This design allows all ECS operations (such as querying and setting state) to have faster performance compared to writing ECS state through smart contracts. Smart contracts can access the underlying ECS chain state through custom precompilation. Game logic can be written in Go instead of Solidity, which can be massively parallelized. This article will provide an in-depth analysis of the Curio project itself, as well as how it achieves the above goals.

Curio was founded in 2022 by engineer and gamer Kevin Zhang (@kzdagoof) and Yijia Chen (@0x1plus), with the goal of creating fully chain-driven games powered by smart contracts. This makes a new form of multiplayer computing possible, allowing all participants to contribute to a “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 Blockingrtners, and multiple angel investors.

There are currently multiple ways to narrate full-chain games, with common ones being decentralized games (DeGame) and autonomous worlds. Curio proposes their own idea: User Generated Logic (UGL). I estimate that Curio encountered many difficulties in making their first fully-chain game Treaty, and thus came up with the idea of making their first chain and embedding the game engine into it, which coincidentally aligns with Argus’s approach, but differs in that Argus uses sharding while Curio takes a shortcut and directly uses OP Stack.

MUD’s ECS game framework

First, let’s take a look at how MUD’s ECS framework works. If you have read my popular science 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 know that ECS increases game development flexibility and maintainability by separating logic, data, and entities. The programming language used is Solidity, and the attribute state of game objects is stored in smart contracts. Taking the ERC-20 contract as an example: The ERC-20 contract stores the token balance of each address in a mapping (from address to uint256 balance). We can think of each ERC-20 contract as a two-column table: “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 a balance in many independent ERC-20 contracts, which corresponds to an entity being associated with many independent component values. In the current ERC-20 reference implementation, state and logic are coupled in the same contract. In ECS, there will be a universal “transfer system” to handle the logic of transferring tokens from one address to another, by modifying the state stored in the token component.

Because game object property status in MUD is stored in smart contracts, each change of ECS status (client status synchronization to blockchain node) needs to be synchronized through smart contracts, and this synchronization process cannot be parallelized and requires frequent calling of contracts. Therefore, Curio hopes to solve this problem by introducing precompiled contracts.

Precompiled Contracts

Precompiled contracts in the Ethereum Virtual Machine (EVM) are a special type of smart contract whose code is hard-coded directly into the Ethereum node’s code, rather than being written in Solidity or other EVM-compatible languages. These contracts are usually used to execute complex computational tasks, as the hard-coded implementation is often 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. Choose an address: The precompiled function needs an address. Ethereum has chosen addresses from `1` to `ff` (inclusive of `ff`) to store precompiled contracts.

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

3. Calculate gas costs: 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. Integrate 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 then recompiling and deploying the node.

Then, smart contracts can use this precompiled function by calling the address of the precompiled contract. The EVM will check if the address has a precompiled contract, and if so, the EVM will directly call the hard-coded function in the node’s code, rather than interpreting the contract code in the EVM.

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

Curio Solution

As we discussed in the precompiled contract discussion above, although using precompiled contracts can greatly improve performance, it requires modifying the node code of the chain and recompiling and deploying the node. The Ethereum main chain cannot do this at all. So Curio chose the OP Stack. In this customized Layer2, they modified the node code to add the ECS precompiled contract. It is precisely through this custom precompiled contract that smart contracts can directly access the underlying ECS chain state. Therefore, this design allows all ECS operations (such as querying and state setting) to have faster performance. And because OP Stack nodes use the “Go-Ethereum” client, this allows Keystone game logic to be written in Go, not Solidity, which can be massively parallelized.

In Keystone, ECS is mainly implemented through the code in the ‘engine’ and ‘game’ directories.

In the ‘engine’ directory, we see the main data structures that define ECS, such as World and Component. World is an ECS basic world structure that includes the two main parts of entities and components. Each Component contains a data type (DataType) and a mapping between entities and values (EntitiesToValue) and values and entities (ValueToEntities).

In the ‘game’ directory, we see some specific game components, such as position components (PositionComp), target position components (TargetPositionComp), tag components (TagComp), etc. These components each have their own data type and a flag indicating whether they need to store values to entities (ShouldStoreValueToEntities).

Benefits of integrating game engine into the chain

Through the above discussion, we can see that directly building ECS (Entity-Component-System) state into a customized blockchain can achieve faster performance than implementing ECS state through smart contracts. This performance improvement comes from the following aspects:

1. Data structure optimization: Writing ECS state in a smart contract usually requires the use of some 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 EVM (Ethereum Virtual Machine) needs to interpret and execute the code of the smart contract, which incurs a certain overhead. However, directly building ECS state into the blockchain can avoid this overhead, because ECS operations are directly executed in the core code of the blockchain, rather than through interpreting and executing smart contracts.

3. Parallelization : Keystone allows game logic to be written in Go, which means that Go’s parallel and concurrent features can be used to speed up ECS operations. This is not possible in smart contracts because the EVM is single-threaded.

4. Precompiled contracts : Accessing ECS state through precompiled contracts can speed up ECS operations. Precompiled contracts are functions that are hard-coded directly into the blockchain node code, and they execute faster than interpreting code in the EVM.

5. State update optimization : Keystone uses an approach that allows state updates to be made in a sub-world and then applied to the parent world. This approach can reduce unnecessary state updates and therefore speed up state setting.

Where is the game ticker?

The concept of GameTick is often used in game development to manage the passage of time in the game. Each tick represents a cycle of the game’s main loop, and various game events can be scheduled based on these ticks. This is also why we say that traditional games are “loop-based”.

However, the blockchain state itself does not include the concept of “current time” as we typically understand it. The blockchain operates on the concept of blocks, which are added to the chain in linear order. While these blocks typically include a timestamp, it is not used as a measure of “current time” in the same way that it is in traditional computing environments.

Curio claims to have GameTick integrated into the blockchain (GameTick built into the chain), but I searched the entire codebase and didn’t find any code snippets about GameTick, so I’m very curious about how Keystone implements game ticks in the blockchain and I hope Curio has the opportunity to provide more detailed information on this feature. However, my guess is that in Keystone’s GameTick environment, the next_tick field may be used to determine when the next cycle of the game loop should occur, based on the internal clock of the blockchain node server, which is used to manage game time within the internal logic of the game and is separate from the block process inside the blockchain.

We will continue to update Blocking; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Blockchain

Lugano, the Crypto Wonderland of Switzerland: Embracing Polygon with Open Arms

Lugano Embraces Polygon Revolutionizing Crypto Evolution with Layer 2 Scaling Solution on Ethereum Ecosystem

Market

Will Shein's Stylish Stance on the Global Stage Pay Off? Chinese Fashion Giant Files for US IPO

Online fashion retailer Shein is planning to go public in the US, aiming to grow its presence in the global apparel m...

Market

Apple Update Sends Investors Soaring

The fashion-forward tech company Apple continues to dominate the semiconductor world with the latest release of new i...

Blockchain

Squid Raises $4 Million to Expand Cross-Chain Interoperability

PolyChain Capital spearheaded a $4M funding round for Squid, joined by a group of renowned investors, to fuel the com...

NFT

CoinGecko Acquires Zash: Uniting the Forces of Crypto Data and NFT Analytics

CoinGecko's latest acquisition aims to incorporate Zash's valuable NFT data into their API by the second quarter of n...

Market

Fed's Rate Rollercoaster Steady for Now, but Get Ready for 3 Cuts in 2024 as Core PCE Falls to 2.4%

The Federal Reserve has decided to maintain the borrowing rate at 5.25-5.5 percent for the third consecutive time, ac...