The Gambler
The gambler plays the slot machine, until he wins by running out of coins, at which point a 3-step firmware sequence allows the gambler to erase himself. At this point the device is functional, but the microcontroller’s flash is essentially empty, except for a program that keeps it sleeping. The game code is not recoverable at this point. With the use of secure boot, encryption, and e-fuses, this allows the device to truly erase itself. Interesting security implications aside, this is just one part of the game.
the game
the rules and math
Each spin he wagers about a third of his coins. If matching symbols land, he wins coins back: the more symbols matching the bigger the payout, and the rarer the symbol the bigger the payout. The trophy is special — it counts as any symbol and doubles whatever you win. Most spins land on flies, which pay nothing. The first time he almost goes bankrupt, plot intervenes with destiny and the machine rolls a jackpot. The second time it deletes itself. Various numbers and tables follow that probably mean nothing to most people.
The machine has 4 reels, and 1 line. I calculated payouts in coins at reference bet 5 (2-of-a-kind nets ×1, 3 nets ×5, 4 nets ×20).
| Symbol | P(reel) | Weight | 2× | 3× | 4× |
|---|---|---|---|---|---|
| flies | 24.074% | 13 | — | — | — |
| cherry | 11.111% | 6 | 2 | 10 | 40 |
| green | 11.111% | 6 | 2 | 10 | 40 |
| blue | 9.259% | 5 | 3 | 15 | 60 |
| yellow | 9.259% | 5 | 3 | 15 | 60 |
| opal | 7.407% | 4 | 4 | 20 | 80 |
| pearl | 7.407% | 4 | 6 | 30 | 120 |
| heart | 5.556% | 3 | 8 | 40 | 160 |
| silver | 5.556% | 3 | 12 | 60 | 240 |
| gold | 3.704% | 2 | 20 | 100 | 400 |
| seven | 3.704% | 2 | 40 | 200 | 800 |
| trophy | 1.852% | 1 | 80 | 400 | 1600 |
Based on 20,736 possible outcomes at the 5 coin reference,
- Return to player (expected payout per unit bet):
87.15% - House edge (avg loss per spin):
12.85% - Win frequency (% spins that earn at least 1 coin):
37.57% - Lose frequency:
62.43% - std dev:
4.215 - E[payout] per spin:
4.357



the resources
I made it in Piskel which was wonderful. I made the main screen in a single sprite with layers, and I drew some icons pretty much at random to use for the slots.

![]()
Everything else derives from these two sprite (sheets) and code to adjust how they look.
Here’s a video I made by capturing frames from the device into ffmpeg, in a special capture firmware (in the main .cpp with #ifdefs) which plays through some of the possible states in a run of the game.
self-erase thingie
step 0:
On boot, the device erases as much as it can to speed up transition to phase 2 on game end. If the game doesn’t end this doesn’t affect anything.
step 1:
Inform the user that they have won and then load the embedded phase 2 firmware bin with OTA, followed by a reboot.
step 2:
The reboot marks the main app code as inactive to allow it to be erased. Once it boots into phase 2 firmware, it begins erasing itself starting with the mushiest parts first. If it’s unplugged at this point all it’ll do is resume the erase. Once it’s satisfied, it does the trick from before again, loading phase 3’s firmware via OTA and rebooting to clear the active app.
step 3:
The phase 3 firmware hates you so all it does is erase phase 2 and disable as many features on the device as it can without being malicious.
the device
I had a t-dongle s3 so that’s what I used, if I had a larger screen I’d probably have gone way too overboard on graphics.
conclusions
This was quite a fun project! I’m regularly surprised at how capable the esp32 is, and they make a vast variety of doohickeys and doodads with esp32s in them so I’ll probably be doing more things like this. The actual game code was relatively easy, I spent more time drawing the icons and added random useless features. Total cost: $12 and ~15 hours of time in total.