I started with familiar games and fake money. The difficult work turned out to be identity, accounting, automation, compatibility, and knowing when not to deploy.
Casino Simulator began with a fairly contained idea: put a few familiar games in a browser, give each player some play tokens, accept a wager, calculate a result, and update the balance. There would be no payment processor, cash-out system, or real money. The rules of the games already existed. Most of the work, I assumed, would be in implementing them correctly.
I had that backward.
Roulette, Slots, Blackjack, Baccarat, Keno, and American Bingo all knew how to be games. The harder question was how they could belong to the same casino without each inventing its own version of a player, a wallet, a session, or an error. They had to agree on when a wager became final, what happened after an interruption, which actions a bot could take, and how the system could explain a balance later.
The public history reflects that. The repository starts with a substantial application import rather than a ceremonial hello-world commit. By then, the software was already large enough to produce surprises.
Casino Simulator is a local, private-beta play-token simulator. It is not a real-money gambling service, and the tokens have no cash value. That distinction is part of the design, not a disclaimer added after the fact. It affects the security assumptions and what the tests are supposed to prove.
Inside the simulator
The interface makes the shared rules of the project visible. The lobby is the common front door, Roulette keeps a complete round and its settlement on one screen, and Admin shows the events running underneath both.
The shared lobby

A round in context

The control plane

The wallet is the center
The obvious way to implement a casino wallet is to let each game edit a number. Subtract the wager, add the payout, save the new balance. That works in a demo. It gets harder to trust when Blackjack introduces splits and insurance, when a wager needs to be refunded, when two actions arrive close together, or when the application restarts halfway through a round.
Casino Simulator has one rule for all of this: debits and credits go through the shared ledger. Games can request settlements, but they do not quietly rewrite player balances. A ledger entry records the player, game, round, amount, transaction type, and details behind the change.
The money is fake. The bookkeeping problems aren’t.
Removing real money takes away the player’s financial risk, but the software still needs to answer a basic question: why does this balance have this value? That answer should not depend on reconstructing whichever code path happened to run inside a game.
The same boundary applies to storage. JSON remains a convenient local default, while MySQL is available for a durable multi-user environment. The game engines should not care which one is underneath them. Concurrent debit tests and restart tests matter because the ugliest balance errors usually occur between two operations, not in the tidy middle of one function.
Games shouldn’t become little kingdoms
Each game owns its rules. Roulette knows its wheel and bets. Blackjack knows cards, splits, and insurance. Neither should reach into another game, and neither gets a private wallet or automation system.
Players, accounting, logs, bots, autoplay, audio settings, and Admin telemetry belong to shared parts of the application. The architecture document makes those boundaries explicit.
They can feel inconvenient while working on a single feature. It is faster, in the moment, to put one more special case into a central router or lobby file. The cost appears later, when changing Roulette unexpectedly affects Keno or adding a game requires editing the same growing collection of allowlists.
The original six games made that bottleneck visible. Before expanding the catalog, the project moved to descriptors: each game declares its backend registration, frontend route, labels, contract, module revision, and long-test driver. The main branch now contains ten games, adding Multi-Hand Video Poker, Casino War, Big Six Wheel, and Red Dog to the original group.
The number itself is not the interesting part. The order is. Catalog discovery and reusable primitives came first, then the new game slices. The catalog governance is there to keep “supporting more games” from turning into “maintaining a longer hardcoded list.”
Bots find the cracks
Automation is an excellent way to discover whether an interface is real.
The easy version of a bot would call game internals directly. In Casino Simulator, a bot is instead a controller for a player account. It uses the same legal actions and the same ledger as a human player. If a bot needs a secret entrance into the game engine, that is usually a sign that the public action model is missing something.
Autoplay uncovered a less obvious problem: what should happen when someone presses Stop?
The answer cannot be “stop at some point.” An atomic action already in progress may finish safely, but another action must not begin afterward. The browser schedules one action at a time, the server registers the autoplay session, and Admin can see or stop it.
Bingo exposed the issue clearly. A single request that continued calling balls until somebody won could not be interrupted in a meaningful way. Autoplay had to move through stepwise ball calls instead. One ordinary-looking Stop button ended up defining behavior across the browser, server, game engine, and Admin console.
Small controls have a habit of revealing the real architecture.
A correct response can still produce a bad screen
Roulette once displayed a zero before the first spin. The backend had not returned zero; the interface was simply filling an empty space. It looked harmless, but it was invented history. The correction became a permanent requirement: no result appears until a spin actually happens.
Other visual reviews found problems that API tests never would have caught: clipped navigation, an oversized Roulette layout, Keno overflowing on mobile, internal identifiers appearing in player-facing text, and a Spin control that could disappear at an ordinary laptop resolution.
The response from the server could be completely valid while the button needed to request the next one was off-screen.
Browser-facing changes are now checked against a visual design standard. It defines viewports, layout expectations, and the screenshots needed as evidence. A screenshot of a known failure documents a problem; it does not prove the work is finished.
The test setup has become equally specific. Long suites run repeated gameplay scenarios in disposable copies of the application. Browser audio checks instrument speechSynthesis and AudioContext, so sound and voice behavior can be tested without pretending a CI machine has speakers.
There are also hundreds of permanent requirement IDs, frozen /api/v1 compatibility rules, independently versioned modules, and validators that catch drift between code and documentation. That is a lot of ceremony for something still described as a toy simulator. It also means a requirement is retired instead of quietly rewritten, and a breaking API change has to admit that it is breaking.
A green unit test is useful. It does not tell you where the Spin button went.
An upload is not a deployment
Local software can rely on conveniences that become liabilities as soon as it is public. A loopback-only service can tolerate development defaults. A public service needs explicit credentials, externalized secrets, TLS, persistent storage, backups, health checks, and sensible failure behavior.
The recent hosting audit ended with a useful non-result. The available shared host provided Python 3.9 and no confirmed way to run a persistent Python application. Casino Simulator requires Python 3.10 or newer.
It would have been possible to upload the static files and call that a deployment. It also would have been misleading. Without the backend, it would not be the application. Trying to force the backend into an unsupported runtime would produce something fragile and difficult to operate.
So the deployment stopped at the audit. The deployment issue records what was checked and why the shared host was not suitable. The WordPress blog can live there. The Casino backend will need a different home.
There is no public Casino deployment to announce yet. That is better than announcing one that cannot be trusted.
Still a toy, on purpose
The visible part of Casino Simulator should remain the games: a wheel, cards, controls, and a balance that behaves predictably. Players should not have to think about transaction boundaries, compatibility rules, session isolation, or the two phases hidden behind an autoplay stop.
Working on the project has made a few things hard to ignore. Shared mutable state needs a clear owner. Bots are unforgiving API clients. Module boundaries become valuable earlier than expected. Visual correctness is still correctness. Files arriving on a server does not mean an application has been deployed.
I still like calling Casino Simulator a toy. “Toy” describes the stakes, not the standard of care.
The repository shows the unfinished work along with the completed parts: issues, pull requests, tests, screenshots, version changes, and decisions that sometimes resulted in more work instead of a launch. The game catalog is still growing, and the public hosting path is still open.
That is fine. I would rather build a simulator that admits what is not ready than one that wins its own rigged demo.
The bet was the easy part. Keeping the house honest is the project.