It's no secret that Web2 games currently process more transaction than any web3 game can handle. Although more recent games like our onchain RPG game Tarochi handled hundreds of concurrent players at launch with no problem, online games like FF14 peaks at over 20,000 active players daily. Our goal, therefore, has to be to scale decentralized gaming experiences to the same player count. This post describes our plans on how to get there by leveraging ZK cryptography.
Layers 1s currently have the most users and the most liquidity with the top 10 chains representing over 80% of the entire crypto market. The problem, however, is that these layer 1s cannot hope to realistically scale to native support a single MMO - let alone multiple of them. This poses an obvious question: how can we support these large scale decentralized games while leveraging the security, assets and users from the most popular chains?
It's tempting to think of L2s as the answer, but rollups simply turn computation cost into data cost, and so you just move the bottleneck to be the amount of data that can be stored on L1 blockchains. For example, popular online games like RuneScape and World of Warcraft have millions of active players and over 100 million lifetime total. Even if you assume an 1 megabyte of data generated per player at most, that amounts to 100 terabytes of data just for save files alone - let alone the magnitude more data needed to store all the historical information about actions users performed in a game that needs to be preserved if you want anybody to be able to reconstruct the current game state in a decentralized network. To compare, the entire Ethereum history is only approximately 1.4 terabytes.
Therefore, a system more complicated than simply leveraging an optimistic rollup like Arbitrum (given Arbitrum settles all its data to Ethereum L1). Instead, we need to turn to Zero Knowledge ("ZK") layers and Data Availability layers ("DA").
Mina as our ZK Layer
Online games typically do not have all players interacting on the same global state directly. Rather, users are typically split into instances. Some may be large such as a group exploring a dungeon together, and some may be small such as a PVP battle between two players. In either case, note that from out outside point of view we do not care about what happens in these instances - we only care about the result (or at most an occasional checkpoint).
Fortunately, there is a technology that allows taking information about such an instance and compressing what happened in that instance down to a single constant-sized crypographic proof. The name of this technique is called Recursive SNARKS and they are a kind of ZK (zero-knowledge) proof. Therefore, we just need to ensure that the way the code for the game logic is written is friendly to this technique.
In fact, there is a blockchain optimized exactly for this called Mina Protocol and it supports smart contracts with private inputs as well. Better yet, it also uses Typescript (o1js specifically) for its smart contracts (same as what is used to write state machines in Paima Engine). However, there are a few problems that need to be tackled to make it suitable as the ZK layer for Paima:
- The block time needs to be faster. Games require blocks of at most 1~2 seconds to feel responsive.
- We cannot just settle everything to Mina L1 (throughput wise this is unrealistic). Instead, we need to be able to spin up "instances" as needed.
- We need to connect Mina to other chains, as most people in crypto do not have a Mina wallet (and will most likely not download one just to play a game)
- It needs to be able to store large amounts of data
Making it scale
To solve points (1) and (2), we've partnered with Zeko Labs who is building a L2 for Mina that behaves just like Mina L1 (meaning any contract on Mina L1 can work as-is on the Mina L2. This is sometimes called "isomorphic" and behaves like a type-2 rollup in the Vitalik definition of rollup types). Zeko works perfectly for our use-case as it allows spinning up new instances of Mina as needed all with the same execution environment that are all recursively proven down to the Mina L1. These Zeko L2s can additionally have faster block times and finality than Mina L1, allow us to tune the parameters as needed for gaming.
Since the Mina L1 itself is composed entirely of ZK circuits, Zeko is built by leveraging and extending the L1 circuits (unlike zkEVMs that need to rewrite the EVM from scratch). This means that Zeko can easily leverage any new feature or improvement to the L1 without having to spend a large engineering effort porting any change. However, this does not mean that Zeko is limited to the same protocol parameter constraints as the L1, as Zeko L2s can update key protocol parameters like the maximum circuit size or the maximum number of account updates in a single transaction to ensure their L2 is powerful enough for their purpose (all without having to increase the minimum specs required to run a Mina L1 node).
To solve (3) we need to build account abstraction inside Mina protocol to allow people from other blockchains to play without owning a Mina wallet. To enable this, we will combine Paima's existing account abstraction framework with circuits written in Mina for common cryptographic standards like
secp256k1 (many of these standards like those for EVM already being available in Mina). With this, we can allow players to delegate their actions to a Mina wallet created for them that we can link back to their original wallet on their original chain. To bring state back to the user's original chain, we leverage the fact that all Zeko L2s settle to the Mina L1 whose entire history can be compressed into a single proofs (thanks to recursive SNARKs) and sent to be verified on any EVM chains using the LambdaClass zkBridge.
With these components in place, games can be built where the user deposits their funds on Ethereum in a PVP match with the ZK proof of who won the match being used to unlock the rewards for the winner. In fact, the game state can be used to prove the PVP battle result on any chain that has a zkBridge with Mina. Thanks to the properties of Mina's recursive SNARKs and Paima's architecture, bridging Mina state to another chain does not require any opt-in from the Mina side - meaning anybody who wants to build a game can deploy their own zkBridge to the chain they're interested in deploying their game to without any permission or changes required from Mina itself (Mina essentially acting as ZK coprocessor for all blockchains) making our construction fairly universal.
Note that this massively helps scaling games by increasing max throughput and lowering transaction fees. Instead of building PVP games where every user move is a transaction ($0.25 per tx on many L1s), you can instead have the entire game play out on a ZK layer and then have the result settle as a single constant-sized constant-cost verifiable ZK proof on the L1 of your choice.
Connecting it all together for developers
Typically this kind of construction is extremely difficult as a game developer to deal with from an engineering perspective, as it means developers now need to be a domain expert in both Ethereum (or other L1) and Mina and wrangle multiple different sets of developers tools and indexers in parallel. However, Paima applications written with Paima allow developers to write a single state machine that computes on top of aggregate state from multiple chains - essentially supporting mixed-mode computation where parts of the game logic live in Solidity and other parts live in Mina. This hugely simplifies the developer experience and makes leveraging ZK on large L1 networks like Cardano, Ethereum (or even Arbitrum) possible without having to resort to isolated ZK environments that do not compose with the rest of the ecosystem.
Paima calls the system to pull in and aggregate state from different chains funnels and currently has funnels for both EVM and Cardano. This funnel system can be extended to support other networks in the future to increase the number of ecosystems Paima (and therefore Mina) can target. Importantly, everything from the data the funnel pulls to how it is processed in the state machine has to be deterministic for the same reason smart contracts have to be deterministic. That means these funnels are not arbitrary oracles, but rather a way to feed deterministically-derived state into the state machine in a unified data format.
Dynamically spinning up new instances of Zeko is also relatively trivial. Note that for any single Paima deployment, information is only aggregated from three chains: an EVM chain, Mina and one Zeko instance. Apps do not need to monitor or process data from any other Zeko instance in realtime (instead, only processing information from other instances when their recursive proof if posted to the Mina L1).
Which means whenever you need to scale or shrink the number of Zeko instances for your game, all you need to do increase/decrease the number of Paima deployments you are running. All the state settles to the Mina L1 eventually, so lowering the number of instances (if done properly) does not lead to any state loss.
Paima additionally comes with a primitive catalogue for various primitives onchain games might want to leverage from different chains. This means that for majority of cases, Paima allows developers to write their frontend, ZK circuits, sovereign rollup, any offchain code (and basically the entire application) all in a single language (Typescript) which not only hugely simplifies the developer experience, but enables building games that feel very fast since shipping a game client in the browser to power optimistic updates for the game becomes much easier.
But why Mina at all?
It is tempting to try and simplify the tech stack by trying to use a technology like a ZK state channel instead of leveraging Mina. However, in practice, the cryptoeconomics around state channels are extremely hard to make work (what happens if somebody stops responding in a state channel? What happens if you need a dynamic set of participants in the channel? What happens if somebody submits a challenge for a state channel?). Leveraging Mina gets rid of a lot of these problems (which is why generally speaking rollups have significantly outperformed state channels in adoption despite state channels coming first from an R&D perspective in the blockchain space) while at the same time providing all the functionality we need when combined with Zeko.
Not all state necessitates settling to Mina or other L1s though. Notably, any kind of player-vs-environment action could be written leveraging o1js without having to settle to Mina with these PVE instances acting more like sovereign rollups. Given the importance of PVE content in web3 to keep players engaged with the game between social interactions, we believe this is an important R&D track, but the fact that this can be done using o1js without resorting to a separate ZK stack means this work is still complementary to the Mina ecosystem in the same way the prevalence of the EVM has strengthened Ethereum's position in the market.
But how will all the data for these applications be stored?
Good question! Paima has an ambitious roadmap for handling all the data for these games, but that will have to be for a different blog post.
Can't wait to learn more about it? Follow us on social media: