Superchain interop is in active development. Some features may be experimental.
Check out the frontend documentation to see how the game UI is presented to the player.
How it works
We use events to define the ordering of a game with players only maintaining a local view. By default, a chain is also a part of its own interoperable dependency set, which means players on the same chain can also play each other with no code changes! The system predeploy that enables pulling in validated cross-chain events is the CrossL2Inbox.1
Intent to play
A game is uniquely identified by the chain it was started from with a unique nonce. This identifier is included in all event fields such that each player can uniquely reference it locally.To start a game, a player invokes
newGame
which broadcasts a NewGame
event that any opponent on any chain can react to.2
Accepting a game
When a To prepare for the game, the event data is decoded and a local view of this game is stored.
NewGame
event is observed, any player can declare their intent to play via acceptGame
, referencing the NewGame
event. An AcceptedGame
event is emitted to signal to the creator that a game is ready to begin.3
Starting the game
As The event fields contain the information required to perform the necessary validation.
AcceptedGame
events are emitted, the player must pick one opponent to play. The opponent’s AcceptedGame
event is used to instantiate the game and play the starting move via the MovePlayed
event.- The game identifier for lookup
- The caller is the appropriate player
- The player is accepting from the same starting chain
4
Making moves
Once a game is started, players can continually make moves by invoking Similar to When a move is played we check if the game has been drawn or won, determining the subsequent event to emit.The
makeMove
, reacting to a MovePlayed
event of their opponent.acceptGame
, validation is performed and the move of their opponent is first locally recorded.- The game identifier for lookup
- The caller is the player for this game
- The opponent event corresponds to the same game
- Ordering is enforced by ensuring that the supplied event is always forward progressing.
makeMove
function is only callable when an opponent has a new MovePlayed
event. Therefore, if the game is won or drawn, it cannot be progressed any further by the opponent.Takeaways
Leveraging superchain interop, we can build new types of horizontally scalable contracts that do not rely on hub/spoke messaging with relayers.- As new chains are added to the superchain, this contract can be installed by anyone and immediately playable with no necessary code changes. The frontend simply needs to react the addition of a new chain.
- The concept of a “chain” can be completely abstracted away from the user. When connecting their wallet, the frontend can simply pick the chain which the user has funds on with the lowest gas fees.
- Event reading enables a new level of composability for cross-chain interactions. Imagine contests contract that resolves based on the outcome of a TicTacToe game via the
GameWon
orGameLost
event without the need for a trusted oracle, nor permission or native integration with the TicTacToe contract.