It was a year ago to the day that I wrote about taking the plunge into a web-based client for Ares. In that time, it has evolved from a half-baked necessity for game configuration, to a modestly-functional supplement with web-based chargen and some other novelties, to a full-fledged game wiki replacement.
There have been some technical speedbumps along the way and I thought it might be interesting to talk about them.
TL;DR; – Turns out that grafting a full-fledged web UI onto a system that wasn’t designed to handle it is hard. (Shocker, right? :P)
Code geeks, read on…
My first attempt was simple. Using Sinatra, the game’s central EventMachine reactor could serve up web pages too. Because it was integrated with the reactor, the web server could use the shared code libraries exactly like the telnet server did. There was no risk of data collision because everything was being funneled into the same reactor thread. The template engine (ERB) was the same as the telnet side too. Sweet!
Just one problem… server-side rendering of HTML with ERB is fine by web standards, but slow by MUSHer standards. On a web site, you’d barely notice the processing time. But when you’re typing +who in the game and it takes half a second to respond? It’s annoyingly noticeable.
So I split out the web server using Passenger. Same setup – Sinatra+ERB – but now it was running in its own process.
That fixed the lag, but now we’ve got a new problem. Passenger is essentially spawning a new copy of the game for each web request. Not only is this a horrible memory hog, it basically means that when the web server tries to use a game library function like “tell me who’s connected” or “notify players of a new bbpost” – it’s asking a different copy of the game that has nobody logged in.
I fixed that problem by splitting the game into three parts – the engine (telnet side), the web server, and a set of shared libraries that are used by both. The engine and the web server communicate via a special socket connection. That means the engine can tell the web server when someone posts a new bbpost, and the web server can ask the engine who’s connected. Both sides can access the database independently.
That basically works, but the 3-way split between engine/web/libraries made the code annoyingly complex. The communication between web and engine adds an extra layer of complexity that I really wish wasn’t there. The potential for database collisions isn’t disastrous, but it does present a minor nuisance. And since the whole thing is designed to run on a lightweight server, the performance of the web server is just a touch too sluggish for my liking.
So! For the past month or so I’ve gone back to the drawing board. As much as I’ve resisted shifting the architecture around, I think that the right thing to do is to split out the server into a REST API backend with a Javascript framework front-end. Some of the benefits include:
The down side is adding a new technology into the mix that folks have to learn to code for Ares. But something’s gotta give. We can’t make something that’s simplistic code-wise and has oodles of features and can run on a tiny, cheap server.
I did some early prototyping with Ember, but I think React is a better choice for the long haul. It’s got more traction in the Ruby community.
It’s been a bit of a winding road, but I think it’s leading to a good place. As always, stay tuned for updates. Feedback is always welcome on the Discussion Forums.