Welcome to the Settlers of CorDan! This is a fully distributed board game, based on the classic 'Settlers of Catan.' Funny enough, board games are an excellent example of why we need Distributed Ledger Technology (DLT) and some of its advantages over centralized systems.
In a non-digital, real-life board game, players use symbolic tokens and intricate game boards to maintain a shared understanding of the state of a given game. They update this shared representation of the game by first announcing their intent, verifying that the move is valid with the other players (based on the previously agreed upon rules), and then imparting that change by making a physical update on the game board. This update could include any number of actions depending on the game, moving a tile, advancing a piece, flipping over a card. The action or vehicle of delivery is irrelevant, but it's payload and impact are the same - with the consent of the counterparties, the player has changed our shared understanding of the game - see where we're going here?
They have persisted new information to each of our perspectives of the ledger. That shared understanding then forms the basis for future updates. Players continue this cycle of proposing updates, verifying these proposals and making updates until the game is won.
Corda is a DLT platform that enables mutually distrusting parties to maintain consensus over a set of shared facts. They do so by proposing valid updates to their peers, peers (fellow Corda nodes) verify these transactions and finally all relevant nodes persist new information to their respective ledgers. Notice the similarities to a board game? In a decentralized board game built on Corda, the set of shared facts is comprised of all of the relevant information of a board game! In this implementation we use Corda states, contracts and flows to model Settlers of Catan.
So why DLT? The short answer is that we eliminate (or at least reduce) the possibility of cheating.
Imagine you are playing a digital game of Catan in a traditional, centralized architecture. You and all counterparties (opposing players) are accessing a front-end, which communicates with a webserver, hosted by a cloud-provider. The hosted webserver then makes updates to a hosted DB in order to persist the current version of the game state.
There's nothing inherently villanous about this architecture, our issue however, stems from the fact that we cannot be 100% certain that the hosting party has not impacted the state of a given game. What if this was a professional match of Catan and we had millions of dollars on the line? A centralized architecture means that we are completely reliant on the honesty and ability of the hosting party to maintain our source of truth.
If the hosting party does make a malicious or even erroneous update to the DB, changing the history of moves made in the board game - we will have no recourse. To use a real-world example, imagine all players of a board game describing their actions, or moves they wish to make, to an unknown third party - who is updating a boardgame in another room. If they suddenly decide the playerA has lost all their money, they will be able to make that change with no consequences (besides a very angry PartyA). The solution here, is to have PartyA maintain their own copy of the board game or their own copy of a ledger with all information relevant to them. In fact, all players should keep their own copy of the board game which effectively, will now act as a distributed ledger. This is what's happening under the hood of this CorDapp!
Clone the repo from github:
git clone https://github.com/rogersanick/SettlersOfCordan
Run the deploy nodes Gradle script:
./gradlew clean deployNodes
Run the following to deploy all nodes locally (four players, one notary and one dice-roll oracle):
build/nodes/runNodes
When started via the command line, each node will display an interactive shell:
Welcome to the Corda interactive shell.
Useful commands include 'help' to see what is available, and 'bye' to shut down the node.
Tue Nov 06 11:58:13 GMT 2018>>>
You can use this shell to interact with your node and make moves on behalf of a given player.
For example, to initialize between all of the nodes running locally, use the following command:
flow start SetupGameBoardFlow p1: PartyA, p2: PartyB, p3: PartyC, p4: PartyD
Use the following scripts to run the tests inside of this project:
// Run all tests
./gradlew test
// Run all tests related to the oracle
./gradlew test --tests com.oracleFlowTests.*
// Run all of the tests related to the issuance and use of resources
./gradlew test --tests com.resourceFlowTests.*
// Run all of the tests related to setting up a game board
./gradlew test --tests com.setupGameBoardFlowTests.*
// Run all of the tests related to trading amongst players
./gradlew test --tests com.tradeTests.*
If you would like to use intellij to debug the tests add the following flag to any of the scripts listed above:
--debug-jvm
The test execution will pause after providing the message:
Listening for transport dt_socket at address: 5005
Select the All tests remote debugging
config from the intellij test config dropdown in the top right of Intellij
and then click the debug button. This will attach the intellij debugger to the running gradle process and enable you
to set breakpoints in the code.