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.
- 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
- handle castling
- handle quitting a game
- handle proposing/accepting a draw
-
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
- Basic user manual
- Provide docker image
- Provide pre-compiled binaries
- Web UI
- Allow user to supply own cardano-node and/or hydra-node
- Manage ELO score on-chain
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.
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 particularlibsodium
andlibsecp256k1
.
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.
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 ▶
>
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
orCtrl-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 newGame
s, and
finally stop
to close the head and quit
to exit.
If things go well, one should see in their terminal the initial board:
Moving a piece updates the board after it's processed in the Head:
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
):
-
Start
hychess
on some network at least once in order to generate needed data, -
Put the relevant information for one's node into a JSON formatted file, retrieving the data as explained in the previous paragraph,
-
Ensure one's firewall is properly configured to enable incoming and outgoing connections from the remote peer,
-
Share the content of the file with the peer,
-
Put the peer's information into a
~/.config/hydra-node/preview/peers.json
file, -
Stop hychess,
-
Remove the content of the
~/.cache/hydra-node/preview/
directory which contains the state of hydra-nodeNot doing this will result in an error upon node's restart as the peers configuration will havechanged
-
Restart
hychess
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
.
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.