TL;DR: try my Lua web games here, see github for self-hosting instructions: https://alexbarry.github.io/AlexGames
Hi all, here’s a hobby project I’ve been working on: I wrote a bunch of simple Lua games, compiled the Lua interpreter to web assembly, and defined a simple API to draw on a canvas and handle input. It all builds to static HTML/JS/WASM, except a few hundred lines of python for a websocket server for multiplayer. I recently added some dockerfiles so I think it should be easy to self host.
Here is the web version on github pages: https://alexbarry.github.io/AlexGames/ , and the source on github (self-hosting instructions in the README).
I’ll list some of the games:
- local/network multiplayer: chess, go, checkers, backgammon, gomoku
- single player or network multiplayer: minesweeper
- single player only: solitaire, “word mastermind”[1], “endless runner”, “fluid mix”, “spider swing”, “thrust”
[1]: it may not technically be multiplayer, but my partner and I enjoy picking our own hidden word and sharing the puzzle state as a URL or just passing a phone to each other.
Part of my motivation is to avoid ads on mobile games, and to be able to play different multiplayer web games with friends without having to get them to make an account and all that (just share the generated URL, it contains a multiplayer session ID). I also like the idea of having my own private web games server, and not having to be reliant on some service that might eventually get enshittified.
I figure that if I can throw together a similar game in a few hundred lines of Lua, then no one should have to deal with full screen ads or pay ~$10 to play them. Especially since most mobile games that I like are simple and I only play them for a few minutes at a time, maybe only a few times per week.
Self hosting isn’t necessary to try it out, but without SSL it should just be a simple one-line command to host the HTTP and websocket server with docker compose. For SSL support it is a few more steps, I added steps to the README: one command to build the static HTML (so you can copy it to your web hosting server, which should already take care of SSL), and another to host the websocket server, which can have your SSL certs passed as parameters. But you don’t strictly need the websocket server, it should just fail to connect after a few seconds and then you can play the games without network multiplayer. You can even use my websocket server and your own static HTML, just add &ws_server=wss://alexbarry.net:55433
as a URL parameter to your own URL. I haven’t self hosted much on my public server, so I’d love to hear feedback on how to better handle SSL certs. Ideally you could just choose to not use SSL for your websocket server, but firefox at least prevents you from connecting to a websocket server without SSL if you’re using SSL to visit the page itself on the same server. (On a local network without SSL it’s fine, though)
Some features that I’m proud of:
- the network multiplayer works pretty well, I’m pleased with websockets (previously I was hoping to get WebRTC working but I didn’t have much luck). On the wxWidgets and Android prototypes I had a normal socket server working too, but I’ve focused on the web version since it’s good enough
- an English dictionary for word puzzle games. (aside: loading ~220k English words as javascript strings and a javascript array took like 12 MB of browser memory or more, but I got it down to ~6 MB by moving the dictionary to C managed memory)
- state sharing via URL: for most games I serialize the state and then you can export it as a base 64 string in a URL. This is useful to keep playing on a different device, send a puzzle that you liked to a friend, or for “word mastermind”, to choose your own word and get your friend to guess it.
- built in autosave, undo/redo, and browsing previous saved states. I used the same code to render state previews that I wrote to render the games for normal play, so all a game has to do is implement state serialization, implement a few APIs to get that state, and call “save_state” whenever the player makes a useful move. Then games can simply call a few lines to add an “undo” and “redo” button, and those can call a one line function to fetch the previous or next state. (I’d like to add a full history tree at some point, but for now if you undo many times and make a new move, you lose the moves that you un-did (“undo-ed”?))
- playing arbitrary games as zips of Lua files. While the self hosting community might not need this much (since they can just add their own games to the source and rebuild), I figured many people might be interested in writing a game without having to build and host my project. So I added support for unzipping bundles of Lua source files and storing them in the built in emscripten filesystem in the browser. I added an example game and an API reference, see the “Options” menu and the “Upload Game Bundle” section.
Let me know what you think! I’d love to hear feedback, or get new game contributions or bug fixes / features.
I did not try it out yet, but I will make sure I do. I love a lot of things about the approach you described