Acme MUD

formerly "untitled gamification platform"

Acme Network

I made a rather drastic design decision a few weeks ago and haven’t really told anyone about it. What prompted it was the question of exactly what to do with EotL. It was probably the first question I asked myself, even before I knew what I was building. Until now, the plan has always been some variant of having a “compatibility layer” between the Acme mudlib and the EotL mudlib. EotL and Acme would run side-by-side in the same runtime environment the result would be some sort of EotL-Acme hybrid where most new content would be developed using the Acme toolkit and the legacy stuff would run off in its own bubble. This was what spurred the whole ‘flavor’ concept because I thought I might be able to make an ‘eotl’ flavor. The solution has never sat quite right with me though, it’s just ugly. Then it dawned on me – yo dawg, what if I just keep running EotL as it is and create a telnet client in the Acme mudlib and you can mud while you mud? I can build some adapters for the messaging, send them to a console pane in the GUI, and easy peasy, you get an authentic EotL experience while still being in the Acme ecosystem. But let’s not stop there, let’s say this is how we build the entire Acme network! What Acme network? I haven’t talked much about the Acme network, but there is one.

Continuous Delivery And Containerization

It looks like the next project is going to be containerization. The reason this is happening now is more about EotL than Acme, but since Acme is open source I’d rather do it here first and backport it over. In addition to setting up a CD pipeline and using containers to organize the game, there’s also adding a git command to the mudlib and migrating EotL over to use it. There’s obviously also environmental concerns with getting all this working on bfb, and getting the approval from the Janitors to actually do it, but there’s so much I don’t know yet that I’ll wait on worrying about that until I get a handle on this stuff. I haven’t done much yet but install Jenkins and Docker, but I did go ahead and make a github project for this and create some issues. Project management? I know! Crazy! But I’m hoping to maybe collaborate on this with someone who has more devops experience than me and issue tracking is a good thing. Anyway, here’s the link: https://github.com/acmemud/ops/projects/1

Checking In

I haven’t worked on the mudlib in a while but I’ve been pretty active with the project in other ways. The biggest thing I did was to start on the web application. It’s Flux+React and all I’ve really done is stand it up and implement a couple small features for connection management. Still it’s been a great learning experience and I think I’m going to have a lot of fun working on it. Probably before I go any farther I want to try swapping out Flux for Redux and see how they compare. Flux seems the more accessible solution which is semi-important to me if I want people be able to mod the UI.

Some Stuff I Did

Some stuff I did: I went through and added #pragma no_clone to a bunch of stuff. Mostly mixins and libs and the trackers and stuff. I guess basically most stuff, except for the few things that actually get cloned. Part of me is anti-pragma. I didn’t add no_inherit or no_shadow to anything; no_inherit just is wrong to me, and shadowing should be configuarable. The pragma statements don’t leave a lot of room for negotiation. But no_clone is a little different, it’s a compile time thing and I don’t mind invoking something lower level like a pragma.

Goodbye Gabbo Hello Acme

I moved the project from my personal github account to a github organization, and officially changed the name of the project to “Acme MUD.” I’ve been pondering the name change for a while and was just waiting for a good time to pull the trigger, and this is it. It’s actually the second namechange, if you count when I demoted the name “Gabbo” to just a codename and adopted “untitled gamification project.” When I settled on not giving it an official name, it was because I wanted the name to be chosen later by the players, to reflect the democratic nature of the gameplay I was designing. But there’s about giving it a real name now that procludes that from happening, and I think trying to actually say something with the name is just all around better than purposefully saying nothing.

`register devo`

I’m getting pretty close to finishing everything that’s needed to actually connect to the game, register a new player and get them to their workroom. It doesn’t sound like much, but a lot of decision making went into how everything is modeled and I’m confident enough at this point it won’t change that I decided to post about it. I wrote a rough outline of the whole process that I’ll take you through. The list is organized more by how things happen in my head than how the code might actually be structured. I won’t set it up too much except to point out that I’ve designed the code to easily support “multiplaying,” which I use in quotes because I’m still trying to figure out exactly what that means. The great thing about living in a virtual world is we really can be multiple places at once if we want to be. I can imagine being logged into the game and wanting to have an avatar going at home taking care of the family, meanwhile a separate avatar is going at your workplace, doing work stuff, and still another can be off in Narnia fighting laser orcs or whatever. That’s one kind of multiplaying, but there are others. For some game-lovers, it’s also easy to see wanting to have not just multiple copies of oneself in the game, but multiple actual selves. To support this, I’ve introduced (at least) two levels of accounts: a “user” account, and a “player” account underneath it. When you login in you get a user avatar, which you can then use to control a separate player avatar that you’re moving around out in the world with. Right now you’re only allowed one player account per user account, but that limitation is purely self-imposed. This separation of users and players lends itself well to the idea of encapsulation; the user avatar only depends on platform-level code, while the player avatar is supplied by flavor-level code. The backbone supporting all this is the session graph, which allows you to attach avatars to “sessions” are organized in a directed graph where every session can have a number of “subsessions” and “supersessions.” This allows you to easily forward commands you enter down to avatars attached to your subsessions, your sub-avatar so to speak. In the same way, messages you receive can be forwarded up through your supersessions. This also frees you up to have not just multiple sessions attached to one connection, but multiple connections attached to the same session (and its session chain). So in a way, this is yet another kind of multiplaying. All these ideas surrounding multiplaying went into the design because I think it’s important to have this kind of capability even at the lowest levels of the lib, but how for we should take the actual practice remains to be seen.

Roadmap To Alpha

I realized I haven’t posted any sort of roadmap of where I’m going with all this stuff I’m coding. I have one, kinda. It’s just a lot easier to write about stuff I’ve done than stuff I haven’t done. But I’ll try.

Login Object Pt. 2

This weekend I made a dent in command processing. The code I wrote is pretty boring, just marshalling an XML document into an LPC data structure, but some of the decisions that went into are kind of interesting. I decided a while ago that I would be writing my own command router, as opposed to using the one built into the driver. The whole add_action() and init() thing isn’t super elegant; I’d like more accountability between command givers, command providers, and command controllers, to promote command modularity and uniformity, and to make more metadata available to players and developers about commands and their availability.

Login Object Pt. 1

Big commit today. I’ve gotten users to their initial login state which is a milestone. Tomorrow I’ll continue to work on actually getting them into the game, which I don’t expect to finish before the weekend’s out. Here’s the breakdown: The most noticeable change is a shift from the traditional “Enter name here” input_to() chain to a plain angle bracket prompt, with a collection of commands the user can enter to engage with the game from the login object: login, register, quit, and if I have time, guest. Also maybe help, though I’m conflicted on that one for reasons that are tough to explain. I’ve always wanted help to be something you had to unlock, for instance by visiting a library, or by engaging with someone has visited one. I’m also opposed to it for philosophical reasons; I feel like you shouldn’t ever have to ask for help at that stage of the game, the code should be robust enough to sense when you need help and provide it. Once you’re in the game, though, then you’re on your own. If you need help, get a map and find the nearest library. And don’t get killed on the way.

Master.c Now Loads Let's Celebrate

I’ve been coding again. I did what you’re not really supposed to do and started up a bunch of new features I didn’t finish, then committed a crapload of broken code that I’m now paying the price for. That’s okay, though, I like having a stack of stuff to work through as long as I can keep moving. The first thing I had to do was fix master.c after I half-implemented a new sys include handler. It depends on the DomainTracker, this thing I wrote to keep track of managed branches of the filesystem. The /.include/ directory (more on the dot later) of your domain root is the thing that’s searched in sys includes, and /paths/ in sys includes are domain paths, not directory paths. A domain may be separated from its child domains by several directory levels, so ‘#include <../auto.h>’ will always include /.include/auto.h relative to your parent domain’s root directory. There’s also a platform sys include directory it checks if it doesn’t find anything in your domain.

Github Proof Of Concept

So instead of finishing the access object work I started, I ended up coding a proof of concept for GitHub integration. Specifically, I wanted to write a mudlib command that would display pull requests for a project using the TCP socket support of the ERQ.

Euids And Such

I don’t have anything super cool to report, but I have been steadily working on some stuff that’s worth updating about. So after getting the demo instance up and running, I started working on permissions and access control. It’s kinda funny, I invited some EotLers to log into the server after it went live and the very first thing they attempted to do was ‘rm -rf /’ Thanks guys! Everything there is on github, plus rm doesn’t have support for a recursive flag, so it’s all just harmless fun. But I do want to use the demo instance as a live place where people can start sandboxing stuff, so I’m going to need access controls before I can do any of that. Here’s how I think it’s going to work.

We Have Lift Off

I’ve procured a server on which to host a demo instance of the platform. You can currently telnet to mud.panterasbox.com:2010, or try your luck with the web client at http://mud.panterasbox.com/~bobby/. This is the first time I’m really looking at this stuff since I stopped the major coding effort this past winter, there’s a lot of holes to fill in before I can really show it off to anyone. Everything appears to be working that that should be working, though, so that’s encouraging.

The Clock Is Ticking

I left my day job last month and I realized I haven’t posted about it yet. My focus hasn’t shifted much since my last post; what I’m mainly working on now is securing funding. However I’ve got a clock ticking now, and if I have to start a new job somewhere I will have a lot less time to work on the project. That said, the increase in urgency has narrowed my focus quite a bit. I have a couple specific avenues of funding to tell you about as well as some potential engineering updates in the near future. Hopefully this post will give you a better idea of how exactly I’m managing my time.

What I'm Working On Right Now

I’m working on some larger-scale issues right now so I haven’t been posting a lot. I’ll have some rather lengthy posts forthcoming but right now the project’s a little trapped inside my head. My focus has shifted from engineering to more business-oriented goals, specifically figuring out how to pay for this thing. I’ve got a couple different threads going.

Flavors And Persisting State

Flavors provide a framework for modding the basic mudlib. It’s an idea I came up with while plotting out how zones will work, because I wanted it so that any zone could be running an alternate version of any module if it so desired, but also retain some continuity for the player as they move across zones. This may result in shaking up how I’m organizing things in github, as a lot of the things I’m currently calling part of the “gabbo foundation” project might now be considered part of the “gabbo-basic” flavor, and I might want to bundle those two things separately. I’m getting ahead of myself though.

Spherical Room Coordinates

In my post about MobileMixin I mentioned that rooms will now be plotted on a 3d Cartesian grid, so every room will have coordinates and needs to enforce some referential integrity to make sure all the exits make sense, etc. I also made an alternate API that uses a spherical coordinate system instead of Cartesian. These work like polar coordinates in 2d space if you remember your highschool math. Every position is expressed as some angle and distance from the origin.

Object Expansion At Last

A while ago I wrote a post about some of the problems I was having designing how the command line would be parsed. Well I am pleased to report that a big chunk of that puzzle, how a user refers to objects in command line args, is now ready to be used. It’ll need some enhancements down the line to support author mode and alternative ospecs, but I’m not there yet. In this post I’ll go over the API, the query language (ospec), and some usage examples. The primary source of inspiration for this project was AcmeOSpec from EotL, but there are enough differences in my design that the code had to be completely rewritten.

Websocket Fun

Taking a little break from LPC this week to play around with the web client. I actually already built a prototype with Iffy for a different incarnation of gabbo a few years ago that is mostly reusable. The UI was pretty basic, there’s a big console window on the bottom of the screen for typing commands looking at output. Then there were a few other panes for displaying current room description, exits, what’s in your inventory…I think that’s it. I also had it working so the exits were links and you could click em to move around. Another cool piece was the rendering engine I wrote, where the server would send output with a buncha XML markup and it’d run it through an xslt transform to render/style the xhtml. The xhtml was then nested inside a larger declarative language sorta thing for drawing everything out in the DOM that the client code would execute. I didn’t get to take it very far so I’m not sure how well the model would hold up for more complicated tasks down the road, but for the few things I did have it doing I thought it worked pretty well. The biggest change since the first prototype is that support for websockets is now common. Iffy got it working so you could telnet to the server over flash, and we never got to handling things like telnet negotiations. There was also this token you had to host somewhere if I remember correctly…it was just weird. From what I’d read, websockets were great. I remember the first time I saw it in use was this pretty impressive multiuser game, so I know it can do what I want it to do.

Mobile Mixin

This weekend I finished MobileMixin, a module that provides the capability for objects to move on their own. This is the evolution of EotL’s move_player lfun in the player body. The new API provides two distinct functions, one for movement via a room exit, and one movement via teleportation: <pre>int exit(string verb, string dir, int flags); int teleport(mixed dest, int flags); </pre>

Intro To Programming

So a friend of mine is taking his first intro CS course, and I found myself ranting on EotL this morning about education. Most of my grumbling here is specifically about intro classes, but I really feel that’s the kind of programming we’re going to need for the future. Sure, programming the big fancy thing in the big fancy building will still be done by expert programmers who are probably very well served by an advanced CS curriculum; but I’m convinced the most demand is gonna come from the programming of everyday things that are all around us – the kind of programming done by the layman or hobbyist who probably isn’t going to take more than one or two programming “classes” their entire life, most likely at the community level.

Move Object

I tried to break the coding deadlock today by implementing the move_object driver hook in master.c. And I did to a certain point. I picked move_object because it’s simple and figured I could bag it in a day. And I was right, to a certain point. I was all committed and pushed to origin and started to write about it and I just then realized that I did it wrong and I’m gonna have to rewrite a large amount of it tomorrow.

Analysis Paralysis

Haven’t coded anything in over two weeks now…I’m got hung up on this object parsing stuff. More new questions keep popping up than answers, and I don’t feel like I’m any closer to movement on it than I was two weeks ago. Pretty sure I’m gonna have to use my phone-a-friend on this one. Object parsing, for the uninitiated, is the algorithm that takes an “object spec” and turns it into a collection of matching objects. It’s kind of like the path expansion stuff I did a few weeks ago, only that takes a file spec and turns it into a list of matching files. While this does make the Unix shell friendlier, most commands out in the world operate on objects, not files. Filename is definitely one way to refer to an object, but you could also refer to it with an alternate syntax, like “cat” for id, “Spot” for name, or a custom specifier, like “here:i3” to mean the third item in the command giver’s environment.

Oh And A Couple Other Things

I got a couple decisions I made early on that I haven’t quite made peace with. The first is canonical names for directories and files. I went with directories being defined with a leading slash but no trailing slash. So you’ll see stuff like this in the global include file:

#define ModulesDir  "/modules"
#define RoomCode    ModulesDir "/room"
This is usually how I represent directories in code, though I’m too tired right now to try and articulate any reason why. Something about this still smells wrong to me, though, so I dunno.

A Quick Post Before Bed

Haven’t coded anything for about a week. I started to code the pager last week but lost interest pretty quickly. It does need to get done though; having to use the editor to browse code is definitely sub-optimal. Now is when I kinda wish I had an apprentice or an intern or something to hand off projects to. It might be a bit much for someone who is brand new to programming, but on the other hand it might not be. Either way, it’s something that I don’t personally need to code the rest of my stuff, because I have my own development environment and can more code externally out in zsh. However, it does need to be done were I to throw up a demo instance of the game anywhere. All this makes it a good candidate for a junior programmer, because they don’t have to stress over too much over how quickly they’re progressing. Meanwhile I’d be free to work on the more architecty stuff. Kinda makes me think that maybe I should table the pager and instead put a little more effort into looking for a good candidate. The only reason I decided to work on it now was because I’ve got most of the rest of the shell already done.

Three New Mixins

Welp, I was going to try and finish path expansion tonight but I left the stupid plug for my laptop at the office today so here we are. Not looking forward to driving all the way back up to the city tomorrow to get it, but at least this gives me the opportunity to catch the blog up on some of my recent commits. Tonight I will be writing about the APIs for object ids, player names, detail descriptions.

Logging

So I made I a project plan this week. Well not so much a project plan as a bunch of issues that are marked as either release 0.1 or 0.2. But I have a list, so that’s something. Working my way from top to bottom in order of unsexiness, the next task after documentation generator is logging. Writing it was kind of a grind (as was most of the doc generator), but without a solution in place pretty much every piece of code is going to have to be amended later when it eventually does come along. Logging is in everything. I suspect there are still a number of bugs to be found since I didn’t really test everything, but whatever, that ubiquity just means we’ll find em faster.

Building Api Docs

By far the most involved project of the week was building the LPC API documentation generator. Lesse I started programming for EotL in ‘94 or so, and in that time I’ve probably had to deal with a dozen different languages at some point. Deal with, as in, making something that does something. That’s a dozen different langauges with at least a dozen different ways of doing things (and that’s just Perl!). One of the few constants, though, is how important the documentation was when I showed up to the party. When it comes to programming, I’ve always been more a grab-a-book guy than a take-a-class guy. Hell, pretty much the only reason I was able to land my first coding job was because I grabbed a copy of the Camel book off someone’s desk during the interview.

Maintained by Bobby Schaetzle