Posted on April 29, 2015 | By Bleck
I’ve spent the last six months or so working on a project called RMUD. Here it is on github. It’s a mud engine, as the name would suggest.. and I must say it is quite a nice one. Clearly I am biased, but I still think you would agree it is rather nice. A mud engine is deceptively simple until you actually want to get anything done, and then it becomes immensely complex. I want to talk about some of the bits and pieces of RMUD, and some of the missteps that got it to where it is now: A massive, gorgeous, sophisticated mass of humming genius.. excuse me. I did warn you I was biased. Here are some of the things I want to talk about:
- Rule-Based object behavior, and how it can be used in games that aren’t muds. And an implementation in C#.
- The module system, why it is awesome, and why C# can go fuck itself.
- Command Parsing. The parser is really quite sophisticated.
- Using Github as a world database server. Yes, I really did that. It works ‘well’.
- Trying to adapt a mud engine to a single player text adventure. It turned out pretty good. Except for the part where I have no motivation to write an actual game with it.
But first, some things that went wrong. Before I moved to the rule based system, I tried implementing behavior using a smorgasbord of interfaces. You want an object to be openable? Okay! Implement IOpenable. This actually works pretty good, up until a point. That point happened to be status effects. Suddenly I had this status effect (It happened to by lycanthrope; the status effect was whether or not the player was a wolf at the moment) and it had to affect all sorts of properties of that object. I also had multiple effects, and the player could be affected by multiple effects at once. I knew from experience that effects that modify attributes when they are applied, and then change them back when they are taken off, wouldn’t work. If I apply effect A, and it changes Y, and then I apply effect B, and it changes Y again, and then effect A is removed.. what does it change Y to? It can’t possibly know.
Still, I went down this hopeless path. I figured out a way to allow the wolf effect to change the player’s name (from the perspective of other players) to ‘a wolf’. (Rather than, say, Robert Squarepants.) Here’s how it worked: Instead of just being a property, ‘name’, the player’s name became a function that queried every status effect currently on the player and asked it, hey there, do you want to override this value? It worked. It was relatively simple. But then… what? Was I going to implement similar functionality for every single property an object can have???
Oh heavens no. I have done quite a lot of stuff in Inform7 and it is a rule-based language, more or less. (Inform7 is one of those languages that is both dreadful and mind blowingly awesome, often in the same line of code.) So, I used rules. Eureka! Status effect nirvana! And as I implemented more and more of those rampant interfaces in rules instead, the codebase got smaller, the modules, less coupled, the world, easier to build… except now you have to remember the names of all sorts of rule books to do anything interesting. All that, and how rules implement things like calling the player a wolf, in a post dedicated to them.
Something else happened too, something I’m not afraid to say now that I’m basically the only person working on this behemoth. (I’m not sure I still am. I might have to apply the knowledge learned and code generated to something else just to keep myself sane.) That thing is that every project needs a visionary. I was (am) that visionary, architecture wise. I designed this mud engine from scratch, I wrote every aspect of it. It is MINE, from top to bottom, and it works the way I want it to. I briefly had other people working with me. I’m going to tell myself my vision was too much for them. More likely it’s just that I wrote so much code, that I pushed so hard they couldn’t keep up. At one point I ignored a vital aspect of the engine because someone else expressed interest in working on it. Eventually I wrote it anyway… and ignored all of his input. Well okay, I was willing to do it your way. BUT YOU DIDN’T DO IT. He never contributed again after that. It’s a recurring theme…