Awesome
AlexGames
A collection of simple Lua and Rust games, and an API for playing them including an English dictionary (for word puzzles), websocket multiplayer, state sharing via URL, and auto saving with undo/redo. You can also upload your own Lua games and play in the public web version.
Try the web version here: https://alexbarry.github.io/AlexGames
<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="80">
Some games incude:
- Solitaire (Lua)
- "Word Mastermind" (Lua): Guess 5 letter words, finding out if you guessed the right letter, or the right letter in the right position.
- Chess (Lua)
- "Crossword Letters" (Lua): Try to make as many words as you can with the letters provided, with a crossword as a hint.
- "Gem Match" (Rust): Swap gems to make lines of three or more of the same kind.
- Go/Weiqi/Baduk (Lua)
- Reversi (Rust)
- Checkers/Draughts (Lua)
- "Endless Runner" (Lua): Tap the screen or press space bar to propel yourself upwards, dodging the endless oncoming obstacles.
- Minesweeper (Lua)
- Fluid Mix (Lua): Rearrange the stacks where you can only move stacks onto empty stacks or stacks of the same colour, until each stack has only a single colour.
- Backgammon (Lua)
- Cribbage (Lua)
- "Spider Swing" (Lua): swing from point to point, being careful not to lose too much height or speed.
- "Thrust" (Lua): Race your space ship around the track, trying to control your momentum.
- Gomoku/Wuziqi/Omok (Lua): Place stones on a Go board, trying to be the first to create a line of 5.
Screenshots:
<p float="left"> <img src="metadata/en-US/images/phoneScreenshots/screenshot1-solitaire.png" alt="Screenshot of Solitare on the mobile version of AlexGames" width="32%"/> <img src="metadata/en-US/images/phoneScreenshots/screenshot2-crossword_letters.png" alt="Screenshot of "Crossword Letters" on the mobile version of AlexGames" width="32%"/> <img src="metadata/en-US/images/phoneScreenshots/screenshot3-chess.png" alt="Screenshot of Chess on the mobile version of AlexGames" width="32%"/> </p>Brief technical overview
High level:
- Simple API for handling input/output defined in
game_api.h
. e.g. "draw rectangle", "handle touch", "send/receive multiplayer message". - Wrappers to this API for Lua, Rust. (C/C++ can call the API directly).
- Games are written for this API in Lua and Rust. (See the "history browser" (described below) for an example of implementing the game API in C++).
- The API is implemented by the following platforms:
- web (HTML/JS/WASM): (C wrapper, JS callbacks, JS Game APIs),
- wxWidgets, and
- Android bundles the web version for offline play, and (experimental) Android supports the native AlexGames API, no browser or WebView required: (C wrapper, Java JNI Interface, Android canvas writes).
The web version is polished and fairly robust. The wxWidgets and Android native versions serve more as proof of concepts for now, demonstrating how relatively easy it is to bring up a new platform that supports all the games. But they are lacking some functionality.
Some other cool features:
- Handling arbitrary game uploads: You can write your own Lua game (see this example Lua game for reference), zip it, and upload it to the browser version in the "Options" menu. This doesn't actually send your game over the network, it simply writes it to the Emscripten virtual filesystem on the AlexGames page running in your browser. Then I use libzip to unzip it locally, and treat it similar to the preloaded games. See
fileReader.onload
inindex.html
for the Javascript web calls, and the C implementation of these APIs can be found ingame_api.c
. (NOTE: this is intended for easily sharing a game with your friends, without having to download and build this repo. But if you are interested in submitting a game then I'd be very happy, see the "Contributing" section in this README) - History Browser allows you to view previously saved game states, including a preview. The history browser code itself implements the same API as the games, so it should be easy to support it on a new platform. The history browser code also uses the games' code to render previews, meaning it runs them as games within itself, which is also implementing the game interface.
- Saved State database to keep the API simple, the only persistent state is writing to key value pairs (based on HTML local storage). The "saved state database" is a C++ wrapper to allow games to simply call
save_state
with auint8_t
array every time there is a state change, and the saved state database keeps track of the move ID. It also handles distinguishing between game sessions, and supports undo/redo and loading initial state on game start (e.g. browser refresh). - (Experimental) Android web games server: this isn't often a useful feature, but if you had a WiFi network with no public internet access, and IP isolation isn't enforced, you could use a phone with the AlexGames Android app to host the simple static HTTP and websocket server. This would allow you to play games with your friends on your local network, without relying on the public internet.
How to build
Using docker
TL;DR: you can simply run sudo docker-compose up --build
, then navigate to http://localhost:1234 . This hosts an HTML server on port 1234, and a websocket server on port 55433. But if you want to host it on a public server, you should build the static HTML separately, copy that to your HTML server content path, and run the websocket server separately (see below).
Build and host static HTML/JS/WASM
Run this script to build and run the docker image to build the HTML/WASM implementation. This mounts the project as a volume, so that incremental builds are supported. (NOTE: you will need to remove build/wasm/out
if you have previously built from outside the docker image.)
docker/http_server/build.sh
For development purposes, you can host a simple HTTP server like this, on port 1234:
docker/http_server/start_http_server.sh
Alternatively, copy build/wasm/out/http_out/*
to your HTTP server path.
Build and host the websocket server
For development purposes, from a separate terminal, run this command to host the websocket server:
sudo docker build -t alexgames_ws_server -f docker/ws_server/Dockerfile .
sudo docker run -p 55433:55433 -it alexgames_ws_server
But for hosting on a public server, assuming you are using SSL (HTTPS), you will need to pass your SSL certs to the websocket server:
sudo docker run -p 55433:55433 -it alexgames_ws_server \
--use_ssl \
--ssl_fullchain /path/to/your_fullchain.pem \
--ssl_privkey /path/to/your_privkey.pem
Try your server
If you ran the command to host the static HTML on port 1234, then simply navigate to http://localhost:1234.
If you copied it to your existing HTTP server, then you should be able to open it now.
How to build manually
See BUILD.md. I find this much more convenient for incremental builds.
Matrix Widget
In the branch matrix-widget
, the source has been modified to use the matrix.org widget API for multiplayer messages.
See the "AlexGames" section of "This Week in Matrix" 2024-09-27 for more information. Here is a demo video:
I'm happy to polish this and merge it into main if there is any interest.
Contributing
I would be very happy if anyone wants to add their own game, or implement the API on a new platform. Feel free to contact me if you are interested. I would be happy to guide you through the code or investigate any bugs you are running into.
The goal is that both adding a new game or supporting a new platform should be fairly easy.
If you would like to add a new API for your game, then consider briefly discussing it with me first. If it is something that could be handled by the other APIs without much difficulty, a library is preferred. Ideally each platform should have to implement as few APIs as possible.
Contact
- Email:
alexbarry.dev2 [ at ] gmail.com
. - Matrix:
#alexgames:matrix.org
- Github: https://github.com/alexbarry/AlexGames
- Discord: https://discord.gg/rhy8SuHPYU
- Lemmy:
!alexgames@lemmy.ca