A POC for a Go game server hosting long-running Lua games
3 min read
Hello. I've decided to try something for the game I'm developing. The game is a long-running online solo/coop space strategy game with resource balancing and 4x elements, but that's not the subject of this post.
I decided to separate game logic code from the actual framework that operates the server and all the online side of things. Writing logic in Lua would be nice, while the rest of the backend is written in Go. This is what I wanted to try with a nice proof-of-concept I've been working on in the last 3 days or so.
The basic idea is that game workers will process the Lua code which in turn can "notify" about events happening in the game, e.g. "construction of shipyard on planet Whatever completed", "save" the game to some persistent storage in case we need to restart the server, which will also have "load" functionality to continue the game where it stopped. Workers will also receive user input (say, from Redis) and send them to the Lua code for fun and control.
So I wrote the POC, it works and goes as follows:
There's a Go "host" application
tiny.luaECS from here
The host application starts several workers to emulate multiple games for several players, opening a Lua state for each
The host also has an "input-loop" that publishes commands to the chosen game worker channel
The host Lua's state is provided with a
savemethod to persist entities,
addEntityused by the host when loading a saved game, and
tickwhere the host instructs Lua to make a simulation step (ECS world update). Additionally an
inputmethod is provided to receive and process outside input.
Entities are saved to an SQLite database as an example of persistence
A simple examination of the SQLite database is a "view" of the world (which theoretically can be sent to a game client to show graphical stuffies)
It looks something like this:
As you can see, I'm writing commands sent to different games (g1, g2, g3, g4) and that makes the chosen spaceship "turn around" on a 1-dimensional universe. When a ship reaches beyond the 500 coordinate, it notifies that it had reached the moon which is propagated to the worker which prints it to stdout (in the real game it would push data to the game client, send an email, whatever). After reaching the moon the ship turns around back to 0 and then turns again to reach the moon again.
This example can be found on my GitHub.
So the POC has been completed successfully and I can now incorporate it into my real game server code, and maybe someday eventually work on some Lua logic and create amazing things. Fun!