Skip to content

Latest commit

 

History

History
196 lines (149 loc) · 8.43 KB

README.md

File metadata and controls

196 lines (149 loc) · 8.43 KB

Games on Hydra

An experiment to build distributed and decentralised games running on top of Cardano Layer 2, Hydra. This project started with Black Jack and then switched to focus on Chess which is a much more interesting game.

Warning

This project is a work-in-progress and experimental, it's not meant (yet?) to be used for real playing on mainnet and it's advised to only run it on test networks. The code follows a duct-tape-and-staples design strategy which basically means I hack stuff until they work just enough to make some progress, then move on. Furthermore, it suffers from premature generalisation as I attempted to decouple from the interaction with the execution and settlement layer too early.

Status

  • Rules in PlutusTx test-driven in Haskell
  • Barebones Console based interface
  • Mock server simulating lifecycle on Hydra (for testing purpose)
  • Basic Plutus smart contract
  • Create Cardano transactions using only cardano-cli
  • Advanced smart contract: Check play is valid for any given game state
  • Proper "randomness"
  • Startup & configure Hydra server in the background
  • Startup & configure cardano-node in the background
  • Use mithril to bootstrap Cardano-node
  • Support for 2-players
  • User manual
  • Provide pre-compiled binaries
  • Web UI

Installation

Warning

The only tested and supported operating systems are currently Linux (and more precisely Debian-ish distros) and Mac OS X. There are of course plans to support other operating systems and in particular Windows.

The only currently supported method for installing hydra-chess is to build it from source.

Build from source

Requirements:

  • Haskell toolchain: Checkout ghcup which is a great tool to provision a Haskell toolchain. hydra-chess requires GHC 9.6 and Cabal 3.10
  • System libraries: Install libffi, libiconv, and libz
  • Custom libraries: hydra-chess still depends on some custom native libraries for compilation, checkout the cardano-node installation page for instructions on how to install those, in particular libsodium and libsecp256k1.

Assuming that all dependencies are installed, then do:

$ cabal install hydra-chess

to build all the components of hydra-chess and install binaries in the ~/.cabal/bin directory.

Usage

Starting up

The main program is called hychess and is started with:

hychess --network <network name>

where <network name> argument is one of Preview, Preprod, or Mainnet.

hychess should automatically download a cardano-node, its configuration files, start it, and then starts synchronizing, displaying progress on the command-line. Note that first time synchronisation will take some time, possibly a couple hours.

Then it does the same for hydra-node, downloading a pre-built binary, configuring it, and starting it. On its first start, hychess will create two dedicated pairs of Cardano Payment keys, one to drive the Hydra protocol on-chain, and one to hold a Game Token and some funds used as collateral to drive the game itself.

Should everything goes well, one should end up with the following output in their terminal

Cardano|Synced    ▶
Hydra  |Started   ▶
Chess  |Started   ▶
>

Playing

The command-line interface provides a very limited set of commands to play chess. Typing help at the prompt will list them:

  • init : Starts a new game session opening a Hydra head (can take a while)

  • newGame : Starts a new game when head is opened or a game concludes with a check-mate. Displays the initial board.

  • play <from>-<to> : move a piece on the board <from> some location <to> some other location. <from> and <to> are denoted using cartesian coordinates, for example:

    > play d2-d4"
    
    Displays updated board upon validation of the move
    
  • stop : Stops the current game session, closing the Hydre head (can take a while)

  • quit : Quits hydra-chess gracefully (Ctrl-D or Ctrl-C also work)

The normal sequence of operation is therefore to: init the head and game session, starts a newGame, play the game until completion, eg. check-mate for one of the players, then possibly do more newGames, and finally stop to close the head and quit to exit.

If things go well, one should see in their terminal the initial board:

Initial game board

Moving a piece updates the board after it's processed in the Head:

Board after a black move

Connecting to other players

By default hydra-chess runs in "solo" mode allowing one to play both sides. While this is nice for testing, it's definitely much more fun to play remotely with a partner. After all, disintermediated peer-to-peer computing is the whole purpose of Cardano and blockchain!

Warning

The process of connecting 2 players is currently very annoying and manually intensive. This will of course be improved in future versions of hydra-chess

To connect with another player, one needs to configure a file named peers.json which looks like:

[
    {
        "name": "somename",
        "address": {
            "host": "192.168.1.140",
            "port": 5551
        },
        "cardanoKey": "582068b950cd549a80b011a1ce7f6f384de0788cca685e24058e196ab450a7076989",
        "hydraKey": "582018b42eb2fca922c893521b90386c00f32710888362138cc137c10b292eb8815c"
    }
]

This file should be placed in a directory named after the cardano network used under one's home directory:

  • hychess --network Preview 👉 ~/.config/hydra-node/preview/
  • hychess --network Preprod 👉 ~/.config/hydra-node/preprod/
  • ...

This file defines the information needed to connect to one or more peers (should be only one in the case of Chess):

  • The IP and TCP port of the remote peer

    The port is currently hardcoded to be 5551

  • The base16 CBOR-encoded Cardano verification key of the peer.

    This corresponds to the cborHex field of the configuration file ~/.config/hydra-node/preview/cardano.vk,

  • The base16 CBOR-encoded Hydra verification key of the peer.

    This corresponds to the cborHex field of the configuration file ~/.config/hydra-node/preview/hydra.vk,

Therefore the process to connect to a peer is currently the following (assuming network used is Preview):

  1. Start hychess on some network at least once in order to generate needed data,

  2. Put the relevant information for one's node into a JSON formatted file, retrieving the data as explained in the previous paragraph,

  3. Ensure one's firewall is properly configured to enable incoming and outgoing connections from the remote peer,

  4. Share the content of the file with the peer,

  5. Put the peer's information into a ~/.config/hydra-node/preview/peers.json file,

  6. Stop hychess,

  7. Remove the content of the ~/.cache/hydra-node/preview/ directory which contains the state of hydra-node

    Not doing this will result in an error upon node's restart as the peers configuration will havechanged

  8. Restart hychess

Troubleshooting

hychess keeps a log of messages from cardano-node, hydra-node, and hychess processes. Those logs are placed respectively in:

  • cardano-node ➡️ ~/.cache/cardano-node/preview/node.log,
  • hydra-node ➡️ ~/.cache/hydra-node/preview/node.log,
  • hychess ➡️ ~/.cache/chess/preview/game.log.

Why?

The ability to play games in a safe and decentralised way is one possible use case of blockchains. However, Layer 1 is way too expensive and slow to enable a good gaming experience, hence the need to rely on Layer 2 to speed things up and make it cheap and affordable to play games with other people.

Having contributed to Hydra since its inception, I also wanted to start experimenting with how one could build such a system and application to make it reasonably easy to use Hydra for gaming purpose.

The Experience Report contains some thoughts about Cardano, Hydra, DApps development, stemming from this experiment.