How to be a god at FlappyBird (and feel like a supahacka)
This is the occasion to take a revenge against this horribly frustrating game.
Go to http://flappybird.io/. Open devtools with ctrl(command for mac users)+maj+I. (This will work best on Chrome or Firefox; with Safari, you have to toggle their visibility before).
Flappy score to the moon
Enter the Matrix
In the sources tab, click on the app.js file. You should have a pretty-print button. Click it.
Search var stage
.

See ? All variables and functions are in the global scope. It means that the whole page, including devtool, can see, access, and mutate those variables. If you try to type stage
in the console tab, your should see a result.
Therefore we’re going to play with it. Try preventing the death sentence by typing
die = null
You should now be able to continue playing after hitting a pipe, generating some glitches with the pipe due to their regenerations.

But that’s quite unfortunate, as without the death menu, it’s now impossible to submit our score to the global leaderboard :((
Submit score
Well, I think you already thought about it, right ? Yep, correct, there is a function to do that. I’ll save you some seconds : it is named submitScore
. It takes a single argument, which is a google analytics token to be able to identify you, which is also available in the window
scope (window
is the name of the global scope in the browser context). It is even visible in the console at the beginning of the game.
So, to submit your score, simply type
submitScore(token)
Tadaam ! You’re in the official leaderboard.
Choose your score
Getting a high score like this is way more handy. But, what if you could directly modify the score ?
As the game is coded thanks to a special engine which uses canvas, you can not simply change the value of a HTML tag in the elements tab. Fortunately, via some JS variables, you can still access it.
With some research in the die
function, you will end up finding the counter.text
variable holding the score. In Javascript, everything is mutable by default. That’s why you can simply type
counter.text = 455654567485987589
It will give a weird visual rendering as the outline is not updated consequently. Nevermind. Don’t forget to launch a game before so that you get a token ! You can just repeat the submit step to push the score to the leaderboard after that, with a funny pseudo if you like :

Avoid this on your game
Make stuff immutable
As we said earlier, everything in JS is mutable by default.
var variable = "i am mutable"
variable = "i am mutated" // validvar obj = { property: "i am mutable" }
obj.property = "i am mutated" // valid
To protect against this possibility, you have two mechanisms in JS. For primitive variables, using const
instead of var
will make it immutable.
const immutable = 'i am immutable'
immutable = 'i am mutated' // Uncaught TypeError: Assignment to constant variable.
NB: regardless of what you are trying to achieve, it is generally a good idea to use const in the most places you can to avoid unwanted variable mutation. 90% of the time, you do not need var
or let
.
For compound objects, this is slightly more complicated. There is a whole thread about this on StackOverflow : https://stackoverflow.com/questions/7757337/defining-read-only-properties-in-javascript
Make stuff inaccessible
Rather than making stuff immutable (functions will still be overridable), you can make it inaccessible.
To achieve that, you have to put your variables and functions in a dedicated scope unaccessible via window. This is achievable with a IIFE: https://en.wikipedia.org/wiki/Immediately_invoked_function_expression
Make stuff unreadable
Last but not least, to mitigate the investigation process of the gentle cheaters, you can prevent them from simply searching var stage
as we just did. This is one of the many features provided by web bundlers like Webpack, Rollup, Parcel, Esbuild, and others. The goal of these tools is to transpile, assemble, and compress JS code. To achieve this compression goal, they will rename every identifier with a single letter identifier. So, var score
will become var s
, for example.
So next time you want to beat your friends at some random browser game, maybe try this technique ? I remember it was also quite easy to do that on messenger minigames, so why not on the one you’re playing ?