Creature Server

The Creature Server runs on any Linux (or macOS) host. I develop it on macOS, and deploy it in a Docker Container on Linux. I use both amd64 and arm64 hosts, too!

The code is written in C++.

The Creature Console and server communicate over gRPC. It’s not designed to be used over non-local networks. (But I have used it via Tailscale successfully!)

The server itself is stateless. All state is maintained in the database (MongoDB).

I made a cute hat for a Pi running the server! The LEDs are connected via GPIO pins on the server, and are triggered via events in the event loop. (Turning them on and off is scheduled like any other event.)

Event Loop

The heart of the creature server is an event loop. Each frame is 1ms. (1000Hz)

It maintains an event queue internally, and on each frame it looks in the queue to see if there’s work to do. If there is, it performs that work. If there’s not, it sleeps and waits for the next frame.

When an animation is scheduled, each frame of animation is put into the queue with the spacing that the animation was recorded at (usually 50Hz, or 20ms per frame).

This makes the creature server soft real-time, since it’s using the wall clock as the pacing, but overrunning a frame only results in time being dilated, not a crash or a pre-emption of the work. It does not make sense to preempt the work, since it would leave the creature in an odd state. It’s better for time to dilate slightly instead.


The server talks to the creatures via E1.31 (sACN) over UDP. Most of the time it sends the packets to an Open Lighting Architecture server1 (on either localhost or a remote host, it doesn’t matter), which translates the E1.31 packets to DMX on the wire.

It doesn’t have to be OLA, however! Anything that speaks E1.31 (sACN) over UDP will work. For example, WLED speaks E1.31! I use WLED to test things when I’m developing software since it reacts quickly and it’s fun to watch lights flash. 😍

Only using network communication allows for a lot of flexibility. It makes running the server in a container easy, and I can locate things wherever I wish.

  1. Here’s the Docker container I use: ↩ī¸Ž