Games
I built a console-style arcade for my self-hosted games
My browser games were scattered one-off HTML files, so I gave them a home: a nostalgic, console-style dashboard with a profile, achievements, and a built-in waiting-room mini-game — all self-hosted on the Pi.
Somewhere along the way I'd accumulated a little pile of browser games — a top-down zombie survival, a neon brick-breaker, a few half-finished experiments. Each one was a single self-contained HTML file, opened by double-clicking it off the desktop. They worked, but they didn't live anywhere.
So I gave them a home: a nostalgic, console-style dashboard at games.iameberhard.com, running on the same Raspberry Pi as this blog.
The idea
A pile of one-off .html files isn't a collection — it's clutter. I wanted the feeling of turning on a game console: a warm home screen, a profile that's mine, a row of games to flip through, and that little hit of dopamine when an achievement slides in from the top of the screen.
The whole thing is still just HTML, CSS, and a few hundred lines of vanilla JavaScript per page. No frameworks, no build step. It just needed a front door.
![]()
A dashboard with blades
The dashboard leans hard into late-2000s console nostalgia — glossy rounded tiles, a green-and-cream palette, soft glows, and menu "blades" that lift and slide as you move between Home, Games, Friends, Awards, and Settings.
It's fully keyboard-driven: arrow keys move between blades and tiles, Enter selects, Escape backs out — so it feels right whether you're on a laptop trackpad or just tapping arrow keys like a controller.
The Home screen is the part I enjoy most. Your profile card is yours to customize: upload a photo straight from your device, set your online status, and watch your recent activity and featured game fill in. It all persists locally, so the arcade remembers you next time.
The goal wasn't a games list. It was the five seconds before you pick a game — the part old consoles made feel like an event.
![]()
The waiting room
Here's the detail I'm fondest of. Before you launch a "real" game, the default tile drops you into Sky Dodge — a tiny built-in mini-game that acts as a waiting room.
You slide a little ship left and right, dodge the falling blocks, and catch the green stars for points. It has lives, a score, a game-over screen, and a high score that sticks between sessions. Cross a points milestone and the same achievement banner the dashboard uses slides down to congratulate you.
It's deliberately simple — something to keep your hands busy for thirty seconds — and there's an Exit button to drop you straight back to the dashboard when you're ready for the main event.
![]()
How it's served
The games live in a plain folder on the Pi — one directory per game, each with an index.html. A ~70-line dependency-free Node static server hands them out on a local port, kept alive by a systemd unit so it survives reboots and crashes.
Public access is the same trick the rest of my setup uses: a Cloudflare tunnel. I added one ingress rule pointing games.iameberhard.com at the local server and a DNS record for the subdomain, and that was it — HTTPS, no open ports, no fuss. New games are now just a matter of dropping a folder in and adding a card to the dashboard.
![]()
Play it
The arcade is live at games.iameberhard.com — flip through the blades, upload a profile photo, and see how long you last in the zombie survival or how high you can push your Sky Dodge score. It runs entirely in the browser, so a phone works too.
More games will land on those shelves over time. For now, the front door is open.
Filed under