Bored Ape Yacht Club have difficult days of manual Dookey Dash score validation ahead of them. Regardless of how they do, it’s going to cause turmoil. This could all have been avoided if they haven’t made critical security mistakes.
Dookey Dash is setting the standards on how to release an NFT game – right before our eyes. The roadmap of the game, the tension, the hype, the way Sewer Passes are distributed… It’s an impressive masterclass in NFT collection utility. Something future generations of projects will look up to. It’s also very well designed with consistent art style and well-crafted, polished animations. Having said that, there are massive architecture flaws in the way the game is implemented, which makes it way too easy for cheaters to hack the game, as well as add bots that ruin the fun in leaderboard competitions.
Before going any further – cheating and cheat prevention have always been a duel between developers and exploiters, and there are no perfect solutions that don’t hurt gameplay. However, there are certain steps that you simply have to take as a game developer. A major mistake made in Dookey Dash is taking the client-authoritative approach. Client authoritative gameplay refers to a type of game code architecture, where the client (i.e. device) is responsible for verifying user inputs and executing the whole game code. This approach reduces the load on the server (or eliminates the need of it), but it can also open up the possibility of cheating, since the client can manipulate its own data. There’s only so much you can do in terms of security. This is most likely what was exploited by 0xCygaar in their popular tweet. https://twitter.com/0xCygaar/status/1618298727663546370?s=20&t=-3WAhEDca8fmWnBwDJerqQ.
What’s happening is we’re seeing manipulated game code that is executed entirely on the client side. You can do this by modifying the game code in the browser, removing collisions, slowing down the simulation, etc. This approach could’ve been sufficient for cheating in a full client-authoritative design if there was no server-side validation done by Yugalabs (which is fortunately not the case). So let’s examine how this game was secured by Yugalabs. We are only posting this after public access to the game has been disabled (Feb 8th 2023), as we have no intention of helping cheaters exploit these potential vulnerabilities.
Disclosure: this is based on my own research and gaming security experience. I could be wrong in some aspects, though. If you want to skip the tech part, go to part describing solution.
Dookey Dash is entirely client-authoritative with additional security mechanisms, meaning the whole game code is executed on player’s device (in the browser). This means, in general, you submit your score and security info to the server after the game has been played. Player’s level in the game (the layout of the sewer) is entirely deterministic, based on a seed that you get when starting a game. The seed comes in a form of a string that the server generates. A sample seed looks like this: 9e13a123-4342-7e4f-8afc-a25ba6ff6f71. After that, you’re playing the game in the browser.
This means that you can predict with 100% accuracy which obstacles you’ll get and what their positions will be. Additionally, you can take your time when playing the game, because your final score is submitted to BAYC servers by you, right after finishing the game. The real server-side validation, that was implemented by Yugalabs, was the input submission, which is sent to the server alongside your final score, as a validation, or ‘proof’. This is the part that they’ll be (most likely) checking in order to validate the runs.
So what is the inputs key about? Let’s look at a sample submission of the game finish. As we can see, there’s this really long inputs key, which contains a base64-encoded array of integers.
This array of inputs is recorded during playtime. It stores mouse position (target player position) and dash events performed by the player. With some simple decoding, you can map ticks (game time steps) to their corresponding game positions and dashes performed.
Dashes are represented by inverting the x position (making it negative), which is a clever way of compressing input! Let’s look at some of them after decoding:
These inputs represent the tick number (on the left) and desired player position on the right, with an optional minus sign in tick 0955 (which means a dash was performed by the player). Both x and y values are represented in Int16, ranging from 0 to 20000.
- The length of input data is exactly correlated to gameplay time. This can be checked against game start time and game finish registered by the server (with some tolerance)
- The length of the game (derived from input length) is very much correlated with the game score (which depends on the length of gameplay and items collected)
- The validity of the seed (was the seed submitted with the result the same as one generated for a particular player? were seeds reused?)
- A more costly verification is replaying the entire saved game input history which should provide a perfect replay with a valid seed (provided the game is deterministic, which it should be).
All of those approaches fail to prevent a method of cheating, by simply generating the map upfront and predicting where all the obstacles will be. Then, using simple algorithms, a bot that simulates player movements on the mouse level can be implemented.
There may be some more realtime checks implemented by Yugalabs, that check gameplay integrity during playtime. However, client authority with full map generation on-device will always be hackable. So what is the solution? Server-authoritative gameplay with additional security mechanisms!
The server-authoritative approach is considered a better option for skill-based games with rewards, as it provides more secure experience. In this approach, the server is responsible for managing state, verifying actions, and making the decision on the outcome of the game. With the server-authoritative approach, players can be confident that the rewards they earn are a reflection of their actual skill, providing a sense of fairness and competition to the game. Does server-authoritative design prevent all kinds of cheats? Well, no. Does it make it significantly more difficult to exploit the game? Hell yes!
Server-authoritative gameplay has always been the domain of competitive multiplayers and esports. It used to come with its own challenges, like upfront development cost and infrastructure overhead (because you need a dedicated server for every game). Having said that, there’s absolutely no way that you can make a secure competitive game (regardless of it being realtime or leaderboard competition) without server authority. The example of Dookey Dash makes this painfully clear.
At Elympics we’ve been working on exactly that – a complete platform that makes it super easy for developers to create secure, server-authoritative gameplay. Creating such games doesn’t have to be costly to develop and operate!