I've recently had sometime off, which I didn't realise quite how badly I needed. It's been really nice to decompress from work with a few little side projects. One of which is a little proof of concept for my game Finger Guns & High Fives (@fghfgame). I'm flirting with the idea of having the game run completely via sockets using the famous socket.io library. The "graphics" are currently handled via the p5js.org processing library/framework. I am however thinking to truly achieve what I'm after, I'll need to migrate to unity in the near future which may make this slightly trickier.
Currently the super early alpha of the game simply allows a player to move their dot around and shoot a giant laser beam at the cursor position. The matchmaking has been fleshed out to a point where the player enters a username, joins the main chat lobby and can add themselves to the queue for the next available match, or join a match by inputting a match ID. These are randomly generated 5 digit codes that socket.io uses to create rooms and assign players to. The idea being that a player makes an action, sends the data for the action to the server (via the socket) which makes the change to the game state, then everyone in the room is updated with the new game state which the graphics would then reflect.
My current WIP is only using in-memory storage for the game state, which means there is a clear burden linked with the amount of games that can be played using one server. My guess is this will probably have an exponential relationship too, resulting in huge server load after only a small amount of live matches.
Aside from the above burning issue, my other worries with the current approach are:
- Lag - a player may experience significant lag if their connection to the server is slower or flaky as the full game state is solely owned by the server & actions don't actually take place on their local client.
- Flooding - to juxtapose the above if someone has a really good connection they could make many actions before other players are able to make one, possibly even preventing others actions.
- Desynch - if the game state isn't matched between the player and the server the actions taken may make little to no sense and would introduce game & physics breaking bugs or exploits, i.e. wall clipping, etc.
To alleviate some of the above issues I've been thinking of adding a SQLite or similar database that will hold the state and can be queried at the rate of a 128 tick game server to provide constant updates for the match. Then have the player actions actually received and processed by a separate thread(s) that would write the changes to the game state store. Some safety processing will still need to be part of the client game code to ensure physics & base game mechanics function without significant impact to the player experience.
I will update with a future blog post about how the final state of the backend architecture solidified once I've nailed down the core functional requirements & criteria for minimum spec play - i.e. minim stats for: fps, ping, ticks, etc to allow for pleasant gameplay.