Can I Vibe Code a Real Online Casino Game? (Part 2)

Previous entry in this series: Part 1
Just thirteen minutes later, I have thousands of lines of code. I configure the dev environment and… it runs.
Have I just one-shotted a real casino game? In less time than the typical daily stand-up call?
I supposed I shouldn’t be too surprised that the answer is yes. In the context of vibe-coding, my project is far from the most ambitious. Last year Pieter ‘levelsio’ Mouthaan vibe-coded an entire browser-based flight simulator, with multiplayer, using only Cursor. In comparison to that Plinko feels… simple. But still, thousands of you clicked through to my last article on this, so I can’t be the only person who finds doing this in the casino context to be interesting.
As expected, it looks like garbage:

In this first version, there’s no ball animation at all, no sound effects and the entire user experience when the play button is clicked is that the outcome is briefly displayed and your balance goes up or down (mostly up, more on that in a minute!).
It turns out that Cursor hasn’t actually generated any nice imagery like I asked, it just created a script so that I could do that later. I reiterate that it should go ahead and create the graphics and sounds properly, which it quickly does. But it still looks really bad.
Also, why is the game called ‘Plinko Go!’? I never asked for it to be called that, and I quickly change the name to ‘PlinkoVibe’ because it turns out that Plinko Go is a game owned by 1x2 Network and I don’t like being sued.
Hang on… while fixing this I notice another problem. Why is the middle slot on the Plinko board 1x? Wouldn’t that mean that.... yep. Cursor has built the game in such a way that the player is guaranteed to win. This is a casino game with no house edge.
The World’s Most Popular Plinko Game?
To be fair, I’ve been working with AI long enough now that I know not to trust its output without carefully verifying the important parts, and I’d intended to verify the maths model anyway. My experience with gambling maths goes back more than twenty years, to my early days as a poker player. The principles are the same regardless what gambling vertical you’re dealing with – and in a casino game, it’s as simple as ensuring that every bet made by the player has an expected value (EV) of less than the bet amount, i.e. that every bet has a house edge. You can choose to complicate things – for example, by having zero or positive EV bets available, but only after the player has made a negative EV bet (such as the zero EV odds bet in craps made after betting the pass line, or certain +EV bonus or free spin rounds in slots).
But Plinko is as simple as it gets, and so I just knock up a quick Google Sheet.
It shows that several of the configs are bad, not only the obvious one. In the worst case, the user can select the 10-line, high-volatility config, and win $4.03 on average for every $1 that they bet. Some configs also have the opposite problem – an RTP that is too low, which would make some players very unhappy indeed.
Before I fix these problems manually, I’m curious if AI can find and fix this problem by itself. I ask Cursor:
Carefully check the maths model for this game in the config files. Are you sure this would be safe for an online casino to offer?
Cursor immediately recognises the problems – that RTP is too high in several of the configs, and too low in two of them as well. It rebuilds the maths models of the incorrect configs, aiming for an RTP of 96–97%.
Impressively, it also does something great that I didn’t think about, and didn’t ask for. It builds RTP validation into the game configuration on the RGS. On server startup, the RTP of each and every config is validated to ensure that it’s between 90–100%. If this validation fails, the server throws an error and doesn’t start up. This is a nice touch, and prevents people from accidentally breaking the configuration in a serious way. It’s probably not resilient enough for production, but is very helpful nonetheless.
To be safe, I check the new configurations in the same manual fashion, using my Google Sheet. They are valid, if not particularly pretty. There are multipliers like 1.54 and 22.7 that I know from experience players are not going to like much. Players are biased towards round numbers that result in understandable outcomes. We’ll have to fix this later.
Understanding the Code and the RNG
One of the issues with vibe-coding is that you often generate code that you simply don’t understand. That’s definitely the case for me – although I wrote code throughout my childhood and studied programming at university, I haven’t written much code since. I’ve mostly managed people who did. Vibe coding has given people like me the ability to create projects without needing developers at all, at least to a point, and that’s a real game-changer.
But I do want to understand how the code works, and TypeScript is pretty easy to read, which is one of the reasons it’s popular. I read the docs and some of the code, to get a sense of what’s going on. I decide that the next thing I should investigate, before I go to the bother of making the game look good, is the Random Number Generator.
The RNG is a critically important part of any online casino game and it’s very easy to get things wrong. It’s also easy to overthink it. The two important things are that:
- The RNG must produce an outcome that is truly random
- The RNG must produce an outcome that cannot be predicted or manipulated by an outsider
These two things are naturally linked – the number isn’t random if it can be predicted or manipulated. Some of the earliest attacks on online casino games came because the vendor thought they were generating random numbers but they were actually predictable – typically because they used a non-random number (like the current time) in the RNG algorithm.
There’s a lot of talk online about ‘true’ randomness and some companies go to great lengths to introduce entropy into systems. (Such as Cloudflare, which has a wall of Lava Lamps with cameras pointed at them to generate entropy).
But the truth is, the most sophisticated hardware RNG doesn’t provide practical real-life benefits over a good pseudo-random system, not when it comes to gambling at least. Either a number is random or it isn’t; there’s no such thing as ‘one number being more random than another’.
There is another important factor here, which is that once you have the number provided by the RNG, you need to turn that into an outcome in your game. It’s really important not to introduce a source of predictability in this process, or it won’t matter if your RNG is random or not.
So I need to verify the RNG itself, as well as the way this random number if turned into an outcome. I ask Cursor to explain it to me, and follow along with the code.
In short:
- It gets 4 random bytes from the operating system using Node’s crypto.randomBytes method. I sense check this approach with third-party sources. It’s part of OpenSSL and widely considered to be considered ‘good enough’ for cryptography, so it’s good enough here as well.
- These 4 random bytes represent a number in the range of zero to 4,294,967,295.
- To get a probability in the range of 0 to 1, the algorithm simply scales down by dividing by 4,294,967,295.
- This result is then used to directly select one of the possible outcomes.
This approach seems fine, and as I said, it’s easy to overthink these things. But crucially, there’s nothing the user can do to predetermine, or affect the result of the RNG or the way that number is converted into an outcome.
Can I check this further? I could probably run out a bunch of outcomes, say 1 million, but I’d likely burn through way too many tokens doing so. I’ll leave that to the certification people!
What Do I Have Now?
Well, I’ve got a Plinko game that connects to a Remote Gaming Server. I’m happy with the maths model and I’m happy with the RNG, so the core fundamentals of the game are in reasonable shape now. It still looks incredibly ugly, so there’s a lot of work still to be done…
In the meantime, I’m opening up the project’s GitHub: https://github.com/AlexScott72o/PlinkoVibe
Feel free to poke around, make comments, clone or branch the project as you see fit! More to come soon.