Exit Full View

Games Cupboard

Play board games, and card games across the internet in a web browser. A virtual cupboard of games.

The prototype was created during covid lock down. This is a complete rewrite.

Unlike most computer games, Games Cupboard does not enforce game rules. It's just a set of pieces/cards, that you can move around the table just as you would in real-life. So it's not designed for playing against strangers (with the likely chance of meeting a cheater!)

The Lobby lets you pick which type of game you want to play. (card games, chess, Super7, Scrabble ...)

Some have different varieties. e.g. Scrabble has the regular variety as well as numbers (instead of letters) and ''blitz'' (which is not turn-based - like Bananagram).

screenshot

Progress

It's now playable ;-) But hasn't had real-world usage yet. Beware of Bugs! There aren't many game types yet, the cupboard is only half full ;-)

You can see a sneak preview running on my server

Next Goals

  • Ensure it works well on phones.
  • Add help for "commands".
  • Add more game types.

I have a long list of new features, I'd like to implement.

Limitations

Currently, the game state is stored in memory. So when the server is restarted, all games will be lost.

There's no way to create "private" games. At the moment, anybody can join your game!

Project Directory Structure

  • gamescupboard-server: Contains server code (no GUI). Built using the Ktor web server framework.
  • gamescupboard-client: Connects to the server (so you must start the server first!). Responsible for drawing the game, and receiving input from the player. Sends and receives data about the positions of the players. Built using the KorGE framework. You can run clients within a browser as well as a window.
  • gamescupboard-common: Common code that's used by both the server and client. The common code is mostly the messages sent between the server and the client. Later there may be additional common code. e.g. rules for how pieces can move.

Running the Games

  1. Start the server : ./gradlew run
  2. Point your browser at http://0.0.0.0:8088

Open multiple browser tabs to mimic playing with other people.

Or play on my server

During Development

The gradle run task is slow (because it has to mangle Kotlin code into Javascript). So I tend not to use it during development. Instead, I have two configurations in IntelliJ :

  • Server - Runs GamesCupboardServer.main()
  • Client - Runs Launch.main() (A JVM client)

Compilation is then fast, but we cannot test in the browser. If you do try to launch a game in the browser, it will use a stale version of the client! If Message implementations have changed, expect exceptions!

Sometimes this "trick" causes the build to fail. The solution is to run the clean task :

./gradlew clean

A minor annoyance, so I've not investigated further.

Choice of server CIO, Netty ...

I originally used CIO, but ran into a bug. On my server, using the routing "host(...)" caused 404s. On my development machine it worked fine. Note, the requests were getting to the Ktor server, but somewhere in the Ktor pipeline the requests were refused. Even a simple "Hello World" server did the same. Switching from CIO to Netty "fixed" the problem. I suspect that it is related to port-forwarding.

Resources

Thanks to Kietyo for a client/server demo using KorGE. As a noob to KorGE, this was exactly what I needed to get started.

Create a password file for admin access (to delete games etc) :

Calculate a hash of each password using :

echo -n ntcMY_PASSWORD_LENGTH'MY_PASSWORD' | sha256sum

e.g. for "password" this would be :

echo -n ntc8'password' | sha256sum

Then create a file, wherever you want. The format is username SPACE password hash. e.g.

nick 4e00df21bd781f1f9876e53fefae13694f088bd2b4541e079a0bfc26326fec7b

This would give user "nick" access, using "password"

Example systemd setup

In /etc/systemd/system/games-cupboard.service (replace the locations of gamescupboard-server script, the password file, and www root as required) :

[Unit]
Description=Games Cupboard

[Service]
User=tv
WorkingDirectory=/gidea/projects/gamesCupboard/
ExecStart=/gidea/projects/gamesCupboard/gamescupboard-server/build/install/gamescupboard-server/bin/gamescupboard-server --port=8088 --pass=/etc/gamescupboard.pw --www=/gidea/projects/gamesCupboard/gamescupboard-client/build/www/
Restart=always

[Install]
WantedBy=multi-user.target

Then to start/stop/view logs...

systemctl daemon-reload
systemctl start games-cupboard
systemctl stop games-cupboard
systemctl restart games-cupboard
journalctl -u games-cupboard.service
journalctl -u games-cupboard.service --since="10 minutes ago"

Housekeeping

To periodically remove inactive games, here's an example crontab entry :

*/10 * * * * curl --data filter=inactive --data filterMinutes=15 --user ADMIN_USER:ADMIN_PASSWORD  http://localhost:8088/deleteGames

Every 10 minutes, it deletes games that have been inactive for 15 minutes or more. Note. This isn't secure, because the username and password are part of a curl command, and are therefore visible via commands such as "ps".

You can also delete games manually, by going to (replace host and port as required ) :

http://localhost:8080/admin