A deeper look into how Cartesi can be used to easily build verifiable turn-based games using mainstream software components
As discussed in the first article of this series, the current state of affairs in blockchain technology has so far kept the mainstream gaming industry from investing more significant resources in decentralization. Major limitations faced by the industry include not only the restrictive computational power available for blockchain games but also a lack of tools necessary to achieve the required productivity in software development.
In this context, Cartesi offers a Layer-2 blockchain solution that runs an entire Linux OS, so that application logic can be developed using mainstream tools and components. This allows for a radical boost in productivity and scalability. On top of that, Cartesi’s technology allows the resulting DApps to remain protected from malicious agents since the entire application execution can be verified and the correct result enforced on-chain. And all of this while still keeping the application fully decentralized.
The TurnBasedGame smart contracts, introduced in the previous article in the context of Cartesi’s Texas HODL’em showcase application, illustrate Cartesi’s vision within the practical use case of the gaming industry. With these contracts, any developer can create a turn-based game on Ethereum by implementing its logic in any language of preference and using mainstream software components, without needing to write a single line of Solidity. In this article, we will further detail how these contracts currently work, and how they can be used to develop any arbitrary turn-based game.
The framework consists basically of a set of smart contracts that leverage Cartesi’s Descartes SDK to create a general-purpose solution for any turn-based game to work out of the box on an EVM-compatible blockchain. The smart contracts are available on Cartesi’s public Github repository and are also already deployed to Polygon’s Mumbai PoS Testnet.
The basic goal of the framework is to allow a developer to create a new game simply by building its logic and UI using mainstream tools. The game’s UI should use the TurnBasedGame smart contracts to mediate the interactions between the players and resolve any disputes. The framework assumes that the game’s outcome should result in an exchange of ERC-20 tokens among the players.
The following diagram better illustrates how all of these pieces work together:
First of all, the Game Engine concentrates the logic of the game and can be thought of as the “back-end” of the application. It can be implemented in any language that runs on Linux.
On the client-side, a front-facing Client App with an appropriate UI should be made available to the users. It will make use of the Game Engine to perform the necessary logic when each player makes his turn, keeping track of the game’s state. The app will also interact with the TurnBasedGame smart contracts in order to join a game, submit turns/moves and, if necessary, raise disputes.
On the blockchain, the TurnBasedGame Lobby Contract is responsible for matching users that want to play the same type of game using the same parameters. Once players are matched, the contract starts the game and locks each player’s ERC-20 tokens in it. The current implementation is capable of handling any turn-based game and offers a very minimalistic approach to player matching. Of course, an alternative Lobby contract can be developed with more specific and/or sophisticated matching logic.
The main TurnBasedGame Contract has the purpose of mediating a game between its players. It has no idea of the internal logic of any specific game, and as such can handle anything in which players stake ERC-20 tokens, submit turns sequentially, and in the end, redistribute those staked tokens among themselves according to the game’s results. In this context, a normal game’s life cycle would consist of the following interactions with the contract:
When the game starts, an event is emitted to notify the players’ Client Apps that everything is set up and ready to go. The players then submit turns by sending data as opaque bytes objects, which are recorded on-chain as an indisputable game log. This is relevant to avoid any data availability issues since in the case of a dispute a verification can only take place if the necessary data is guaranteed to be available. For that reason, the data should usually be stored on-chain. However, this poses certain limitations to the size of the data that can be used, which even for sidechains such as Polygon’s are still restricted to tens of kilobytes at most. In the future, Cartesi’s Noether sidechain could be used to provide cheap short-term storage for large chunks of data in the order of tens of megabytes, which would further widen the possibilities for decentralized applications.
At all times, the TurnBasedGame Contract can be called to challenge the game state, be it to protest against an illegal move during the course of the game, or to dispute a claimed result at the end. In any case, the current implementation assumes that when a game is challenged it is no longer safe for it to progress any longer. The contract thus ceases to accept any new turn submissions, collects the entire recorded game’s log, and calls the Descartes Contract to trigger a computation that will verify the correct result, which will then be enforced on-chain.
The verification computation itself is performed off-chain by Descartes Validator Nodes, which replay all the submitted turns using a game-specific Verifier Cartesi Machine. This machine boots an entire Linux OS and is thus capable of executing the same Game Engine used in the Client App, even while retaining the capacity of proving the correctness of the computation performed. The Verifier is thus able to securely compute the true result of the game, and on top of that, it should also include logic to decide if and how players should be punished in case of misbehavior, such as submitting illegal moves or claiming false results. Players should generally also be penalized for triggering challenges for no reason.
The game of Chess is in principle simple enough that it could be executed directly on Layer-1, or alternatively using any other Layer-2 technology. However, being a turn-based game it is also a good example to illustrate how Cartesi can be used to easily implement such games on an EVM-compatible blockchain without coding any Solidity — but still ensuring they are fully verifiable! A working implementation of this Chess game (without a Client App) is available in our public Github repository.
After that, we can place this code inside a file and use a tool such as webpack to bundle all dependencies into one .js file. This bundle can then be executed inside a Cartesi Machine using the included QuickJS interpreter. And that’s it: we now have a Chess engine running on a Layer-2 solution for EVM-compatible blockchains!
Of course, instead of just executing predefined chess movements, we want to really replay a specific match given its log, and determine what to do in case of misbehavior. To that end, when our Verifier is instantiated it will receive the following information from the TurnBasedGame Contract:
- metadata: optional parameters for the game that were previously agreed among the players; this could include timeout restrictions or a starting board configuration;
- players: players involved and their respective funds locked in the game;
- turnsMetadata: informs which turn was submitted by which player and at what time;
- turnsData: sequence of moves submitted by the players; the contents are game-specific and in this case will correspond to chess moves represented as strings in Standard Algebraic Notation (SAN) — such as the “b3” and “g5” moves used above;
- verificationInfo: informs which player challenged the game and triggered the verification; if a result was claimed by a player, it also includes what result was claimed and by whom.
As such, the full machine needs to include code to read and interpret this data in order to feed the Chess Verifier. Additionally, as stated above it should also include the logic for punishing illegal moves, false claims, or any other kind of misbehavior. Luckily, once again this can all be implemented and tested using mainstream tools on the host machine, just like any regular piece of software, in order to ensure everything is working as expected. And that is a huge productivity boost that is really hard to overstate.
After all the implementation is set and done, we need to effectively create the Verifier Cartesi Machine by bundling all our code into a flash drive. The machine can then be executed with input drives pointing to test data in order to ensure that the Verifier is also performing correctly inside Cartesi’s RISC-V emulator. At last, we can build the final Cartesi Machine Template to be used inside the Descartes Validator Nodes, which will not use test data but rather expect those input drives to be automatically filled in by Descartes upon instantiation.
Needless to say, to complete the implementation of a fully operational game, an appropriate front-end application with a nice user interface should be created. In effect, this could be any client application that uses the same Game Engine, and thus could be a desktop, web, or even mobile app. The only requirement is that the application must interact with the deployed smart contracts in order to join and start a game. After a game starts, it should communicate the chess moves with the other player, which normally is done by submitting each turn to the TurnBasedGame Contract. Optionally, other techniques could be used to minimize the need to submit every turn as a transaction. For instance, the application could allow direct communication between the players using signed messages (such as state channels), and only submit a turn containing a full log of the game in case of a dispute. Of course, this would require the Verifier Machine to also include logic for analyzing and validating player signatures.
To set up the game for practical use, the first step is to have the Verifier Cartesi Machine deployed to the Descartes Validator Nodes that will be invoked when a game verification is requested. For development purposes, the Descartes SDK Environment can be used, which runs everything locally and already includes two validator nodes.
In a real deployment, several alternative validator node topologies can be considered. In a quorum setup, the application itself defines a set of third-party validator nodes to be used in case of disputes. On the other hand, in a user-centric topology, the players themselves install and run their own validator nodes. The TurnBasedGame contracts allow for both setups, which are ultimately defined by the Client App when submitting the requests to join and start a game.
Be it a real or development deployment, the game can always be tested even without a Client App. To that end, the project provides a number of Hardhat tasks that allow players to join, start, and fully interact with any game by communicating with the TurnBasedGame contracts from the command line.
The use case of turn-based games illustrates our vision for using Cartesi’s verifiable computation VM to unlock the potential of decentralized applications, allowing for a dramatic increase in the complexity and productivity of blockchain application development.
Cartesi’s potential for increasing blockchain application complexity will be further explored in the next article of the series, in which we will take a deeper dive into the implementation of a complex Mental Poker Engine using C++ libraries. Like Chess, this engine implementation will then be used in conjunction with the TurnBasedGame contracts in order to build Texas HODL’em, the first fully decentralized Poker game ever built for the Ethereum blockchain.
Interested in diving deeper into TurnBasedGame contracts? Support our superstar R&D team in its initiatives or explore new ones altogether by applying for our grants program. Apply now to Cartesi Labs!
Cartesi is a multi-chain layer-2 infrastructure that allows any software developer to create smart contracts with mainstream software tools and languages they are used to while achieving massive scalability and low costs. Cartesi combines a groundbreaking virtual machine, optimistic rollups and side-chains to revolutionize the way developers create blockchain applications.