(Author’s note: The goal of this series of posts will be to build a “minimally viable” multiplayer game on the ethereum blockchain, with support for scarce resources and appropriate protections against economic attacks.) Edwalt had finally found the nightshade, obsidian vapors, and mantis mushrooms he needed to open the magic portal into the next realm. At his camp fire, he mixed the potion and…

…POOF! the portal opened before his eyes. With trepidation, he entered the portal- Is this where he would find the magical sword of Azkerzoink?

ACT 1 – Entering the Realm

Demon: Hello and welcome to my realm, weary traveler! I have already talked with HR and procured a desk for you- At twelve noon there will be an orientation meeting, including a tour of the lunchroom facilities.

Edwalt: Wait… I’m confused… can you help me find the magical sword of Azkerzoink?

Demon: Well, not directly- The place with that stuff is the next realm over. In this realm we don’t have magical swords of Azkerzoink- However, we have other things that are even more exciting!

Edwalt: Yeah, OK… so what exactly is this realm? Why is it so exciting?

Demon: This realm goes infinitely in all dimensions. It is filled with open-layout office space that spans into infinity- Within this office space, it operates as a sweat shop for computer game development, spanning all of space and time! You, too, will now toil day after day, developing computer games, along with all the others!

Edwalt: Computer games?! What kind of computer games?

Demon: We specialize in fun computer games that run on the blockchain!

Edwalt: But… but that’s impossible! Nobody can build a fun game that runs on the blockchain!

Demon: Nonsense! The ethereum blockchain is perfectly suited for game programming. Shortly after the initial ethereum whitepaper was released in 2014, everyone speculated that games where going to be one of the earliest use cases for the platform. There’s many reasons why this prediction made sense:

Game code can be very small, allowing it to be easily encoded as smart contracts

The blockchain can take care of all the ugly networking logistics for a multiplayer game

The built-in ether currency should make it easy to monetize games

Blockchains make it easy to set up artificial scarcity in a game to establish a challenge- You can easily limit how many prizes can be generated in a game (for instance, making sure there are never more than 10 “swords of Azkerzoink”)

If all the core rules for a game are enforced via smart contracts and not via code running on client computers, it may be possible to build a game that is more resistant to cheating than traditional multiplayer games.

Additionally, we already have many developers that have released super fun games for this platform- For instance, there’s a roulette game and also, uhm, rock-paper-scissors. All you need to do to escape my realm is develop a FUN game with ethereum: If you accomplish this task, a new portal will open up that will get you to the place you seek!

Edwalt: Hmm… I don’t know, those games don’t sound particularly fun [1]. When they finished, did a portal open up for the developers of those “fun” games?

Demon: Uhm, well no… not yet. We’re not sure what’s wrong, actually… we’re hopeful at least that a portal will open up for the rock-paper-scissors devs any moment now…

Edwalt: Sigh… I guess I don’t really have a choice at this point. I guess I will give it my best shot and try to make my own fun game for ethereum, so I can escape your realm.

Demon: Wonderful! …Again, remember to meet in the hallway at twelve noon for the orientation- You will see many amazing things! Did I mention we have cold brew coffee and iced matcha green tea on tap in the lunchroom?

Act II – Wherein Edwalt Determines What Makes a Game “Fun”

Demon: Hello Edwalt, how are things going so far?

Edwalt: Great! I’ve worked my way through the solidity tutorial and have come to some conclusions as to what elements are needed to make an ethereum game fun. I’ve decided it must have at least these four things:

Simple rules that lead to a huge variety of game scenarios

Nifty graphics and animation

Multiplayer interaction

Scarce items of some sort

The first of these two items are things almost every great computer game has, whether it’s Robotron 2084, Civilization, or Half life. The second two items are elements that build on the strength of ethereum, making it hard to imagine a fun game without them.

Demon: I agree, these are all items that look necessary, though definitely not sufficient, for making a fun game on a blockchain.

Edwalt: Great! Then I’ll start coding up my game so I can get out of here.

Demon: Yes, you can begin coding your game, my Edwalt… but be forewarned: After you have completed a game design, it will need to be tested by three of our most evil QA testers. There is one for each of the three deadly sins of ethereum users:

Belphegor, the QA tester of Sloth

Leviathan, the QA tester of Envy

And, of course, the QA tester that embodies the most vile sin of ethereum users:

Mammon, the QA tester of Greed

Before you leave my realm, you will learn to fear every one of these sins, dear Edwalt!

Act III – Belphegor

Belphegor: Who’s at the door?

Edwalt: Hi Mr. Belphegor, I have a game prototype I’d like you to start QA testing. It’s an adventure game that runs on the blockchain!

Belphegor: Darnit! I was just about to start my mid-day nap. Can’t this wait?

Edwalt: Please sir, I’m in a hurry- Would it help if I bring you some cold brew coffee?

Belphegor: Yawn… Tell you what, could you start by first giving me a quick executive summary of the gameplay?

Edwalt: It’s a game of exploration! You walk through a magical land, looking for valuable items!

Belphegor: OK, suppose I’m at point (X,Y) in your game world and take a step to walk to (X+1,Y), can you explain what happens in your game engine, from a technical standpoint?

Edwalt: It’s pretty simple: The user presses an arrow key to walk to the new location, and the game engine sends a transaction to the ethereum blockchain to update the player’s coordinate.

Belphegor: Sigh… OK, I think it’s time I explain to you what my role is here at the QA testing department.

You see, the average player of your ethereum game is going to be a sloth. What I mean by this is that running transactions against the blockchain is a bit of a hassle, and your players are going to consider it to be a chore. There are several reasons for this:

Even though ethereum’s 14 second block time is fast compared to other cryptocurrencies, it’s still going lead to excruciating waits for each step they take, walking around in your game. Most ethereum nodes will require the player to respond to confirmation dialogs for each transaction generated by your game, which will make a game with lots of transactions really annoying. A player is going to be responsible for paying the required transaction fees, which are likely to be in the type of game you’re describing. For instance, imagine that a player needs to walk 400 steps in your game in an hour- even if each transaction only costs half a penny, that will still add up to 2 dollars of fees per hour! And remember, ethereum transaction fees are paid to the miners that support the network NOT to the developer of the game…

So the bottom line, Edwalt, is that you’re going to have to come up with a different game mechanic in your game for anyone to want to play it. It needs to be a mechanic that only generates a limited number of transactions, and each transaction should only have a limited amount of code associated with it, to keep the transaction costs low.

Here are some tips for how to accomplish this:

Certain genres of games that require constant user interaction (arcade games, real time strategy games, etc.) are not as suitable as games that require slower, more thoughtful actions (item trading games, board games, etc.)

You are going to have to leverage the first rule of “fun” games that we discussed: Build a game with simple rules that generate interesting gameplay through rich interaction . These types of games will be the easiest to enforce in a smart contract, using few virtual machine instructions. Consequently, these will be the ones that will require the most modest transaction fees.

. These types of games will be the easiest to enforce in a smart contract, using few virtual machine instructions. Consequently, these will be the ones that will require the most modest transaction fees. One of the most important lessons of blockchain programming of any type is that “blockchains are about verification, not computation”- This means you want to strip anything out of your smart contracts that can be computed by the player’s client machine. A classical example of this is that smart contracts, usually shouldn’t contain “indexes” for data- An index is a data structure that lets you find out where a piece of data is in another data structure. Instead, you should compute any indexes you need in the client-side code of your game, then pass the correct position the index has calculated into each smart contract function.

For instance, here is an example of a smart contract that lets you check the age of a person by their name: //Example of sub-optimal contract contract foo { struct person { bytes32 name; uint age; } person[] people; mapping (bytes32 => uint) indexByName; ... function getAge(bytes32 name) public returns (uint) { return people[indexByName[name]].age; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 //Example of sub-optimal contract contract foo { struct person { bytes32 name ; uint age ; } person [ ] people ; mapping ( bytes32 = > uint ) indexByName ; . . . function getAge ( bytes32 name ) public returns ( uint ) { return people [ indexByName [ name ] ] . age ; } } Maintaining the data structure indexByName on the blockchain is going to be costly, in terms of transaction fees. Instead, see if you can write all your code so that the index into the people array can just be pre-calculated on the client computer and then be passed in and verified by the smart contract: //Example of a more optimal contract contract foo { struct person { bytes32 name; uint age; } person[] people; ... function getAge(bytes32 name,uint index) public returns (uint) { person p=people[index]; if (name!=p.name) throw; return p.age; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 //Example of a more optimal contract contract foo { struct person { bytes32 name ; uint age ; } person [ ] people ; . . . function getAge ( bytes32 name , uint index ) public returns ( uint ) { person p = people [ index ] ; if ( name != p . name ) throw ; return p . age ; } } This second version of the contract may look less elegant, but is likely superior because it follows the rule that “blockchains are for verification, not computation”. (Note: There may still be instances where the first approach is superior, even in light of the importance of verification: For instance, the indexByName variable in the first example makes it possible to verify that there aren’t name collisions, something that would require a full array scan in the second example. The rule that “smart contracts shouldn’t have indexes” is not a hard and fast rule, as indexes are sometimes needed to verify information.) Another, more sophisticated application of this rule is to use Merkle trees– With Merkle trees, you could potentially store most of the game data off-chain but still allow a player to execute a rule in the smart contracts by supplying a “Merkle proof” against this offline data.

Some other ways to decrease the transaction count:

Consider adding procedurally-generated elements to your game. For instance, you might be able to store a single integer in a smart contract and then use graphics code to generate unique and rich graphics for a magical item, or the layout for a dungeon, solely from a single random integer stored in the blockchain. (Idea: You could even place a simple procedural algorithm to generate and entire game world directly on the blockchain, and then use optimized smart contract calculations to quickly verify the state of the map at an important location the player is visiting…)

If none of the tricks above work, you may want to look into state channels, which theoretically allow a player to store transactions “off chain”, while still enforcing the game rules encoded in a smart contract “on chain”- This is an advanced technique.

The difficult part in keeping the transaction count low for a blockchain game is that you still want your game to benefit from the strong correctness guarantees provided by a smart contract on the blockchain. Edwalt, please rethink the design of your game and come back to me once your transaction count and size is more reasonable. Time for my nap!

Edwalt: Thank you Mr. Belphegor. I can see why most ethereum games never make it past your testing department. I will now rethink the design of my game.

Act IV – Leviathan

After meeting with Mr. Belphegor, Edwalt returned to his desk, toiling for several days to rework the design of his game engine.

Leviathan: Hey you, new guy… did I see you walk over to Mr. Belphegor’s desk the other day? What were you doing there?

Edwalt: Uhm Hi Sir- Do I know you?

Leviathan: I am the most important QA tester there is! I’m Mr. Leviathan!

Edwalt: Oh sorry, the demon said Mr. Belphegor was the first tester I should visit. Hmmm… he also said Mr. Mammon was particularly important…

Leviathan: I don’t know why those other guys keep getting all the credit- I, Leviathan, am the person a game developer like yourself should be most concerned about! Tell me about the game you are working on!

Edwalt: Well, alright… The game I am now working on a creature trading game- It only requires a few ethereum transactions a day for active players. Also, my game engine can procedurally generate an infinite number of creatures on the client, using a simple integer stored on the blockchain. Here, have a look at some creatures heads generated with a very early version of my engine:

(Note: All source code will be made openly available in followup posts)

To play the game, new players can buy a random creature, which is created from the latest block hash. Most of the gameplay revolves around trading creatures with other players. When this happens, multiple players are put into a “battle room” and where they place bids which are just entered as a simple transaction, for other creatures in the same room. These “bids” are sort of like the attack moves of the creatures. Players have a time window for placing their bids and can do so in any order. Players that trade poorly in these battles lose their creature.

Leviathan: Sigh… OK, I think I need to tell you a little bit about what I do here in the QA department. You see, a lot of the ethereum users that are going to play your game are going to be filled with envy– They will constantly worry that they are getting a raw deal and that the other players are getting the better of them. This means they will play your game in ways that will spoil the fun of other players.

For instance: You told me that in your game a player will get a random creature assigned to them, based on the hash of the block in which they purchase the creature. However, the mining of blocks is not instantaneous in ethereum- It usually takes around 14 seconds. Within that window, it’s possible to know the current block hash, even if a transaction has not yet been submitted.

Given this situation, an envious programmer who wants to get the best creatures (the ones that are the fastest, strongest, etc) can just write a bot that checks every new block hash, and only buy a creature whenever the hash is most favorable- They can essentially “harvest” the very best creatures in this way.

Edwalt: Darn, I hadn’t thought of that- I will never escape this realm if my game isn’t fun for casual players… What can I do to prevent this from happening?

Leviathan: Well, a few basic ideas come to mind. First, you can make sure that the “value” of a creature has strong subjective elements- Maybe its value derives from being beautiful instead of fast or strong. A human may be able to recognize “beauty” more easily than a computer. The term for this in the cryptocurrency literature is proof of human. Another suggestion would be to wait until the next player submits a transaction in a future transaction, then use that future block to set the random seed for a creature.

Those are some basic suggestions to get you started- But only touches the surface of how players could abuse randomness in your game. Come back to me once you’ve written the first draft of your code and we’ll talk about some others.

Edwalt: Thanks, I will do that! I’m starting to see why random numbers on a blockchain are so difficult.

Leviathan: Hold on, Edwalt! I’m not through with you yet. There is another way that envious players can ruin the fun of your game: They can abuse the bid submission process in your battle rooms.

In the game you’re describing, creatures enter a battle room, then the players submit bids in the form of transactions. Now let me ask you Edwalt: Is it better for a player to submit a bid before or after you’ve seen the bids of the opponents?

Edwalt: Hmm… well I guess the player who is last at entering a bid will have a slight advantage over the others.

Leviathan: Exactly- This means if several envious players are in the same battle room, everyone will try to be the last person to submit a bid, and your battles will devolve into a sniping game, where players all try to “snipe” their opponents, submitting their bid at the last possible moment!

Edwalt: Darnit, that won’t be fun either…

Leviathan: Luckily, that problem has a pretty simple solution: You can use a Hash-Commit-Reveal scheme (discussed in detail on the wikipedia page for commitment schemes) Here is a contract that implements a simple hash-commit-reveal scheme in solidity:

contract HashCommitReveal { mapping (address=>bytes32) hashes; mapping (address=>bytes32) moves; uint deadlineBlock=123456; function commit(bytes32 hash){ if(block.number>deadlineBlock) throw; if(hashes[msg.sender]!=0x0) throw; hashes[msg.sender]=hash; } function reveal(bytes32 secret,bytes32 move) { if(block.number<=deadlineBlock) throw; if(sha3(secret)^move!=hashes[msg.sender]) throw; moves[msg.sender]=move; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 contract HashCommitReveal { mapping ( address = > bytes32 ) hashes ; mapping ( address = > bytes32 ) moves ; uint deadlineBlock = 123456 ; function commit ( bytes32 hash ) { if ( block . number > deadlineBlock ) throw ; if ( hashes [ msg . sender ] != 0x0 ) throw ; hashes [ msg . sender ] = hash ; } function reveal ( bytes32 secret , bytes32 move ) { if ( block . number <= deadlineBlock ) throw ; if ( sha3 ( secret ) ^ move != hashes [ msg . sender ] ) throw ; moves [ msg . sender ] = move ; } }

All the players first hash together their bid with a random number, the secret. Next, they call the function commit() to have the hash stored in the contract. Finally, after the bidding phase has ended, all the players call the reveal() function. This function confirms that the bid and the secret can be used to generate the hash. It accomplishes this on line #15, where we can see it hash the secret value and XOR it against the submitted move. Since a sha3 is considered irreversible, it means the submitter must have known both the secret and the move at the time of committing the hash in the pre-reveal phase of the game. In this way, the HashCommitReveal contract guarantees that each player can submit their bid in confidence, while still preventing anyone from altering their bid after the bidding phase.

Edwalt: Thanks you Mr. Leviathan, I will implement the algorithms you’ve suggested and return when I have some functioning code to show you!

Leviathan: Bye Edwalt! I hope I’ve opened your eyes to the dangers of envy- Clearly I deserve as much attention as those other QA testers, if not more…

Act V – Mammon

After visiting with Mr. Leviathan, Edwalt returned to his desk and reworked the workflow for his creature collecting game. Next, it would be time to pay a visit to the last of the QA testers, Mr. Mammon.

Mammon: Hi, who’s at the door?

Edwalt: Hi Mr. Mammon, I’m a new game developer in this realm. I’ve already met with Mr. Belphegor and Mr. Leviathan to discuss a new ethereum game I’m working on. I was told that you are the most fearsome of the QA testers… but I have to say, you don’t look that scary to me- Would you have some time to chat about the design of my game?

Mammon: Righty-O, dear Edwalt, there’s no need to be afraid of me. In fact, I’m just a friendly fellow who loves chit-chatting about people’s game ideas!

Hmm…the only problem is my schedule is booked solid at the moment, so you’ll need to stop by again in a couple months.

Edwalt: But, I can’t wait that long! Darnit, at this rate I’ll never make it to the other realm to find the magical sword of Azkerzoink…

Mammon: Say… that helmet you’re wearing… is it made of silver?

Tell you what, I’m going to walk over to the lunchroom now to get some coffee and maybe while I’m over there your helmet could accidentally fall off and land on my desk. If that were to happen, hypothetically speaking, I might just find that additional time has opened up on my schedule…

Mammon: Huh! Will you look at this! My afternoon calendar suddenly cleared up!

Ok… so tell me about your game, Edwalt.

Edwalt: It’s a creature collecting game! Players buy new creatures that are randomly generated. However, you only get a new creature after another user performs an action in a future ethereum block, to prevent exploits against the creature generation code. Players are randomly assembled into rooms, where they bid against other creatures in a sort of battle- Bids are entered using a hash-commit-reveal scheme. Players that do well in battles will see their creatures advance to higher levels. At higher levels, creatures can procreate and earn new creatures for their owners, who can then keep them or share them with their friends!

Mammon: Hmm… I think it’s time I explain to you what I actually do here in the QA testing department. You see, I’m the embodiment of greed in the ethereum users that are going to play your game.

To understand how greedy players will impact your game, you have to understand the core lesson that the world of cryptocurrencies has taught all of us: It taught us that you only need three things to create money:

Scarcity Desirability Transferability

Unfortunately, these will also be features shared by the creatures in your game, if we charitably assume that anyone will actually want to play your game to begin with. Hence, a greedy gamer who manages to collect a lot of creatures will likely be able to find someone to sell creatures to at a market price.

The moment your creatures have a market price, Edwalt, it will be a disaster for your game: Greedy and determined players will use economic attacks against your game. In your case the most dreaded attack will be a type of sybil attack commonly referred to as double sitting. (In the online poker world, this attack is also referred to as MAing, or “multiple accounting”)

In a sybil attack, an attacker impersonates multiple entities to fool honest users. More specifically, in a “double sitting attack” a player uses such impersonation to “sit” twice at the same poker table, or in your case, get two creatures in the same battle room. Double sitting and other sybil attacks are the bane of all multiplayer games that run on a blockchain.

What a greedy player will do is buy many, many creatures at the same time, with the hope that some of them will end up in an identical battle room. When this happens, these creatures owned by the same player will be able to collude on their bids, giving them an edge over other creatures in the same room.

These players will be able to win the majority of the creature battles, and hence be able to reach higher levels than anyone else. Since your game only allows creatures on high levels to have offspring, these players can eventually own the vast majority of creatures, destroying you and your feeble game.

These greedy players will crush you like the pathetic, two-bit developer that you are.

Edwalt: What? No, I don’t believe you Mr. Mammon! I am not a “pathetic two-bit developer” and I refuse to believe any players will go through such immense effort and cost to break my game!

Mammon: It doesn’t matter what you believe, Edwalt: The moment a market price is attached to a creature in your game, there will be greedy players that can and will do the napkin calculations to see that it will pay to buy large numbers of creatures, leading to creature collusions in the battle rooms. Then, they will sell their rewards on the open market, leading to a collapse.

These players will take the embarrassing drivel you insist on calling a “smart contract” and they will dismember it into meaty chunks like a feral pig.

Edwalt: Jeez, Mr. Mammon, that sounds awful- But what can I do to prevent this?

Mammon: Tsk… Edwalt, Edwalt, Edwalt. This is a very difficult question, but the answer can be summed up with one word: Reputation.

Edwalt: Alrighty, Mr. Mammon, I guess I will rethink the architecture of my game and try to…

Mammon: Shut up, Edwalt, and get out of my office. Don’t show up again until you have done some serious thinking about reputation and how it relates to the economic attacks that are possible against your game.

This concludes Part I of “Building a Fun Ethereum Game.”

Join us next time for Part II, wherein Edwalt thinks deeply about reputation, begins writing his solidity smart contract code, and realizes what the perfect name is for his new creature-collecting game!

[1] The existing developers of games on the ethereum blockchain are true innovators right now and deserve tons of respect. I think it’s likely that the developers of great efforts like rouleth and etheria would agree with me in the sentiment that building games on blockchains is unusually challenging. And, that we still have a long way to go in offering a variety of compelling games on this platform.