Original author: @therealbytes @_yonada
Translation: @hiCaptainZ
Original article link: https://world.mirror.xyz/fL3IMnsOPMqQ_Td1pPEd_kYYNdWu0NW7aBDb_CwfarA
As creators of the virtual world, our goal is to create an environment that is fun and engaging for users. This requires us to strike a balance between designing digital physics that allow for complex and unexpected behaviors to emerge, and ensuring that the existing infrastructure can support these behaviors. To do this, we need to consider three main dimensions of digital physics: time, the form of its laws, and the scope to which these laws apply.
Time#
We refer to the passage of time in the virtual world as the application of world laws to itself. Each discrete application is a "moment" in the flow of world time. One way to design time in the world is to have it progress continuously with external time. In a blockchain-based virtual world, each block corresponds to a certain number of moments in the world, regardless of what transactions the block contains. This is known as synchronized time, or the "tick" phenomenon. This approach makes the world more interesting to users as they can see the real-time results of their actions. Additionally, it leads to longer times in the world, keeping the world continuously updated and facilitating the emergence of interesting behaviors.
However, this approach also has its drawbacks. Larger time spans often require more computational resources, which may quickly exceed the capacity of the chain or servers. Implementing this system on a regular blockchain can also be challenging as all changes on the chain must be initiated by transactions from external users.
This difficulty becomes apparent when you imagine something seemingly simple, like having non-player characters (NPCs) in a game on-chain. On mainnet Ethereum, you could define an update function that sets the positions of each NPC on the game map and have an external account call it periodically to update their positions. But this may be unreliable as you cannot guarantee that the external account won't be outbid for gas fees in the block where the update should be called. The time structure of your game would drift as a result (as an example, consider the giveBirth() function in the original CryptoKitties; as gas fees on-chain increased, Axiom Zen actually had to increase the reward for calling the giveBirth function to ensure that the transaction for the birth of a new NFT was called within 256 blocks after the user bred the Kitty). We refer to this method of using external accounts as "manual ticking".
Custom rollups give us more flexibility to add "ticking" functionality on-chain without the need for external accounts, and the progression of synchronized time is guaranteed by the protocol. We refer to this approach as "automatic ticking". Automatic ticking can be achieved by writing a "ticking contract" that is called by the protocol itself, rather than by an external account.
For example, @therealbytes developed a proof-of-concept ticking chain based on OP Stack, which ran an automatic ticking implementation of Conway's Game of Life (you can find a video demonstration of it here). Bytes used a modified system transaction to automatically call a ticking cellular automaton simulation contract. To stress test the limits of the chain itself, he implemented the game in two ways: as a Solidity smart contract running on-chain, and as a precompiled engine of the chain. The Solidity implementation reached the limit of the CPU with a 70x70 grid updated twice per block (1 block/second, or approximately 10k cells/second), while the custom precompiled engine of the chain reached the same rate with a 256x256 grid using about 6% of the CPU (approximately 130k cells/second).
In the last sentence of the final paragraph, the keyword is "reaching the limit". Ticking chains add an additional layer of complexity: as each block increases, more states need to be touched by transactions simulating the game. Eventually, rollup nodes will be limited by the original computation (CPU, disk IO, etc.). The only solution here is to have higher-capacity nodes.
An alternative to "synchronized time" is "asynchronous time". In this scheme, the passage of time in the world does not necessarily progress when external time advances. Instead, time usually moves forward when certain events (typically user actions) occur. Traditional board games that do not involve timers fall into a similar category. Implementing asynchronous time on-chain is easier as it is the model that blockchains are designed to support. However, it also sacrifices some of the features that could make the world more interesting, such as NPCs that move automatically.
An early version of a proof-of-concept game by @notdavidhuang and cha0sg0d called WildWood illustrates this sacrifice. In this game, two players must defend their base from aggressive NPCs. In the early versions of the game, NPC movement was only triggered when the players themselves moved - an unrealistic implementation of asynchronous time. After adding ticking, the NPCs moved, but another problem remained. The chain ticked once per second, which meant that if a player moved more than once per second, the game had to use optimistic rollup updates to broadcast the player's position on the map. However, your teammate wouldn't automatically see your client, resulting in a delay in player position updates. To overcome this problem, the team utilized a MUD relay service, a peer-to-peer network for broadcasting local clients to the entire chain. Voila, the transition from asynchronous to synchronized time was achieved.
Closed and Open Form Laws#
World builders also have to decide whether their virtual world follows closed-form or open-form expressions. Closed-form expressions have a fixed number of operations. On the other hand, open-form (or recursive) expressions have a number of operations that grow with the increase of given variables. In open-form expressions, the future state of the world can only be computed by repeatedly applying the world's laws to known states. Complex, vibrant environments like Dwarf Fortress typically fall into this category. On the other hand, closed-form expressions allow for the calculation of any future state based on past states and the passage of time between them (assuming no future user actions change the state), such as resource extraction rates in Age of Empires II.
Open forms can make virtual worlds more interesting as they are unpredictable, much like the real world. Predicting the future state of the world requires increasing amounts of time and computational resources (a good example is the Conway's Game of Life implemented on-chain: you cannot compute an arbitrary future state as you need to run the game over time). Additionally, unexpected macro behaviors can emerge from simple micro interactions. In worlds governed by closed forms, these emergent behaviors typically only occur externally, through user actions (which themselves act like open forms), rather than within the physical world itself.
The trade-off between open and closed forms involves a balance similar to that of time. Closed forms may reduce the potential interest of the world, but they also make it more computationally efficient. Closed forms can be used in conjunction with synchronized or asynchronous time. When implemented on a blockchain, they have a significant advantage over open forms when time is synchronized. Since the cost of any length of time is constant, the world can be designed to update its on-chain state only when users send transactions, but it is set to the state after the passage of time since the last update.
The Scope of Time and Form#
Consider the standard method of dynamic on-chain updates, a method known as "lazy updates". In lazy updates, the start and end of player-initiated actions are marked, but the time in between is simulated rather than directly computed. For example, a player plants an apple tree in the first block and harvests apples in the tenth block. Lazy update logic can be written to allow the player to harvest one apple per time unit, for a total of nine apples. This is entirely possible for update logic with closed-form functions (such as one apple per block), but it fails if the agricultural logic varies based on inputs between player actions. If, for example, a rainstorm increases the growth rate of apples in the fifth block, and a locust plague nearly destroys the crop in the seventh block, it becomes impossible to effectively calculate how many apples the player can harvest in the tenth block without truly applying all the events that have occurred (you wouldn't have enough computational power to catch up with the new state). Nonetheless, lazy updates are still useful for inexpensive calculations of certain entities (such as plants with fixed growth rates), but they fall short for a complete toolbox of a dynamic world.
In the real world, time is everywhere, a one-way flow, and the universe may be infinite (though with some complexities of relativity). However, in a virtual world, this is not necessarily the case.
First, the virtual world may be explicitly finite. Interesting possibilities often increase with size - more things happen in a world composed of two billion galaxies than in a world composed of two atoms - but the computational cost also increases. Both of these relationships are closely related to the two trade-offs mentioned earlier: the passage of time and physical form.
Second, time does not have to flow everywhere in the virtual world. The world can be divided into discrete regions with different rates of time passage to reduce the computational burden of the world. For example, more complex and expensive physical rules can be used in areas with user activity, while simpler physical rules can be used in areas without activity. The drawback of this approach is twofold: it can make the world appear inconsistent and lacking in completeness, limiting the design space for world rules and putting pressure on world builders to avoid confusing users; and it also limits the propagation of causality within the world, as behaviors in one region may not have consequences in distant regions frozen in time. The size of the areas where physical rules are applied is an important design consideration that will affect the resources the world needs and the level of interest it can achieve.
To create an interesting and engaging virtual world, it is necessary to carefully balance computational efficiency and interest. This includes deciding what type of time to use (synchronized or asynchronous) and evaluating the form of the physical laws that govern the world. The size of the areas where physical laws are applied is another important decision. By making these choices thoughtfully, world builders can not only manage the computational burden of the world while maintaining interest, but also provide a highly fertile foundation for other developers to innovate.