Conway's Life Server

A few years back I was experimenting with Go and SDL2, I wrote a dead-simple Conway's Game of Life program with it, added loading of a couple popular pattern file formats, and was pretty much finished with it. The other day I came across this cool project while preparing for Thanksgiving by browsing . Brett has an e-ink display running life and is seeding it from tarpit data which struck me as a really neat idea to keep the world from becoming static as most of the more complex ones tend to do.

sdl2-life running

I dusted off my sdl2-life project and got busy adding a server to it as the first step towards feeding it with live data. I shuffled some code around to make it easier for the patterns to be applied to a running system, and found a major bug in my loading code. That’s what happens when you have no tests, and make changes while manually testing one file format and not the other. I added a simple server listening for POSTs on port 3051 and faster than you can type “Bob’s yer Uncle” I was able to update the running sdl2-life world by using curl to post pattern files. eg.

curl --data-binary @./examples/

After taking a break to stuff myself with Turkey and all the fixings I started on a new project to feed sdl2-life with the logs from the webserver. A few lines of Go later I had log2life working . Have I mentioned how much I mostly really like Go? Except for math, getting the types right when doing division always takes me longer than in python. Anyway, I quickly had a program to read the logs, convert the IP to an x, y coordinate (thanks to my friend Rob, I was trying to over-think it), XOR the data together and POST it to the live server as a pattern file. Standards and text data formats win again.

Building and Running

As long as you already have Go setup on your system it will be easy (guaranteed!) to get this up and running. Grab the code from sdl2-life and from log2life and build each of them with go build. Test out sdl2-life by running it with no parameters. You should see a randomly generated world start up.

Restart it with the server listening and a blank world by running:

sdl2-life sdl2-life -rows 250 -columns 250 -server -empty

Test out posting a pattern to it by running curl with one of the example files:

curl --data-binary @./examples/

Now grab a logfile from a webserver. I use lighttpd with mod_accesslog's default format which may work with other servers. If not, see the code here and adjust to fit your situation.

Feed the log to sdl2-life by running this:

log2life -columns 250 -rows 250 /path/to/logfile.log

This will read the log, one line at a time, send the pattern file to the server, and then delay based on the timestamp, send the next line, etc. You can speed it up and slow it down with the -speed option. eg. -speed 10 will speed it up 10x.

Note that the rows and columns should match the ones used for sdl2-life, which defaults to 100x100, so that the IPs are mapped to the whole world.

You can also pass logs to log2life on stdin by passing it - instead of the logfile name. When you do that the speed is set to realtime, it will display the lines as they are received and not delay between them.

ssh foo@server tail -f /var/log/lighttpd/access.log | log2life -rows 250 -columns 250 -

One last thing to note is that I use dwm as my window manager, so the sdl2-life window has no decorations on my system, and I’ve never bothered to add resize support. If you drag the corners you may find bugs :) The size of the window can be adjusted using -width and -height but you need to make sure that it is evenly divisible by -rows and -columns so that the cells remain square. If you do not it will round down which can result in a bunch of unused space.