=nil; chronicle

=nil; chronicle

=nil; chronicle is an autobattler game using zk to keep players' choices hidden from their oppononents.

The problem =nil; chronicle solves

One of the key components of many games is information asymmetry. Information becomes a valuable resource and its asymmetry enables important mechanics such as social dynamics, player coordination/deception, rich metagame (operation on knowledge of the current strategic trends within a game), etc. Due to the public nature of blockchains, achieving information asymmetry with on-chain games is hard without zkSNARKs.

An auto battler, or auto chess, is a subgenre of strategy video games that typically feature chess-like elements where players place units on a grid-shaped battlefield during a preparation phase. Then, units fight the opposing team's units without any further direct input from the player, i.e., algorithms control units.

The one-off setup phase and the ability to auto-fight make this genre a good choice for zk/on-chain implementation because:

  • Auto-fight can be too expensive to execute on-chain. Battles should run off-chain with their results submitted to contracts, e.g., to issue rewards/payouts to the winners.
  • Information on unit composition and placement should not be public and valid. A player should be able to learn about someone else's team's setup only by playing against them.
  • A player should be able to change the behavior of auto-controlled units. Advanced players can alter the default AI of a unit, and the game engine can prove that the battle was executed according to the correct algorithm.

Challenges we ran into

zkLLVM produces dynamic circuits depending on the input. This means we have to create a new EVM verifier for EACH chosen strategy, making it practically unusable in a real-world scenario. =nil; is aware of that, and this should be fixed in the future (we tried to hack around to obtain constant time but we ran into time constraints).

The circuit size varies depending on the chosen strategy, somewhere between 2^13 rows and 2^16. The =nil; prover is, for the moment, single-threaded; therefore, the proof generation takes a couple of seconds (~1 minute in the super worst case). As soon as =nil; releases the multithreaded prover, a proof of this size should compute instantly.

We had a lot of problems with =nil;’s EVM verifier.

We tried to deploy smart contracts on Scroll and on Mantle Testnet. On Scroll Testnet our transaction got stuck, as seen in the attached screenshot.