Covenant MUD

“Don't let the technical stuff frighten you—it's only there to make everything work. Don't feel you have to be a programmer—you don't, although sometimes, programming can be most of the fun. Why else would somebody stay up until three o'clock in the morning cursing, and then claim the next day they had a wonderful time? That's part of what it's about.”
—Jim Butterfield, Commodore 64 Training Video (1983)

February 2019

Quick shout out to the folks at the Mud Coders Guild. When I revived Covenant MUD in 2016, I was not aware that the MUD community was even alive—in fact, it turns out to be thriving. It's great to see that MUD coders are still pushing the boundaries with new languages, technologies, and game designs.

I've taken a bit of a break from code updates because I really needed to devote some time to updating the website. I've documented the history of the website elsewhere, but the tl;dr version is that the site hadn't seen a real update since 2002. What's worse is that there were entire pages that have been empty for seventeen years. Updating the site has been a laborious process because I'm not only updating the layout, but also filling in the blanks and fleshing out content, which is turning into a significant writing project. I'll get there in the end but it may take some time.

The original version of the MUD website from 1998 optimistically declared, "You may soon find valuable player information located on these pages." It's been twenty years or so; perhaps we can get a little closer to fulfilling that promise.

March 2019

A short list of release notes this month, and only one item of any real consequence, but it is a big one. Rather than try to describe this new feature, I think I will let the game speak on its own behalf.

You have reached the western gates of Tierceron. To the east is Queen Street
where you can find shops to resupply or a place to sleep. If you head west out
of the city you begin your travels towards what is largely uncharted territory.
Above, you see a bridgeway where several guards now patrol, watching all who
enter or exit the city.
Exits: East West

> west

Room Number: 10015  Invis. Level: 0> w

              0                                                 __
         ___________                                         __/%%\__
        /           \           Location:  97,  84,  2    __/``\%%/==\__
  300  /             \  60      Terrain:  City           /""\`1/%%\=9/  \
      /               \                                  \"1/""\%1/@@\__/
     /                 \                                 /``\"1/**\@2/  \
270 (         *         )  90   Speed:      Stopped      \`1/##\#2/==\__/
     \                 /                                 /##\#2/  \=9/  \
      \               /         Heading:    North        \#2/  \_3/==\__/
  240  \             /  120                                 \_3/~~\=9/
        \___________/                                          \~1/


> ne
Heading changed to 60 degrees.

> jog
You start jogging.

(time passes)

You have arrived at the City of Tierceron's Queensgate, leading into the
city via Queen Street West. You enter the city--welcome to Tierceron!

You have reached the western gates of Tierceron. To the east is Queen Street...

In the example above, the player starts out at the Queensgate, a normal room in a format that should be familiar to anyone who's ever played a Diku MUD. As soon as the player walks out the west exit, they are outside the city, on the RealSpace map, which is a large Cartesian plane segmented into hexagonal map cells. In RealSpace, there are no rooms and no exits; you can be anywhere on the map that the terrain allows (with your position specified to a precision of fifteen decimal places) and you can go in any direction you like.

In our example, the player is shown standing just outside the gate, as indicated by the ** symbols on the map display. They decide to head northeast, toward the @@ symbols that mark the city entrance, and start jogging. After a short jog, the player arrives at the city gate and is whisked off the map and back into the zone that is the City of Tierceron—back into the comfort of a normal Diku room.

This release completes the integration between RealSpace and "normal" MUD space. I'm beginning to realize that adding new features in code is a relatively quick process, but adding content takes a lot of time, and Smaug's online building tools are painful to work with. Next month, I will turn my attention to a project that should ease some of that pain and make building a much more pleasant process.

April 2019

One strategy for building a setting for a large, open-world game is procedural generation—you define a number of reasonable parameters and devise an algorithm that will create locations, items, and characters on demand. At least one MUD coder out there is working on natural language processing and generated locale descriptions. When done correctly, such alogrithms can conjure up thousands of pieces of content without repeating themselves, creating a world that is both rich in variety and consistent in tone.

Covenant MUD is not a game that can rely on procedural generation. We have always aimed for a setting that conveys its narrative through traditional descriptions provided by a human story-teller. Building our kind of world is labour-intensive, requiring a fair bit of writing and proofreading—processes that cannot be automated. Fortunately, we have a lot of content from the old days—two thousand rooms or so, with a number of objects and mobiles to populate them; unfortunately, the old data format is not 100% compatible with the new codebase. I really didn't feel like writing a data migration script for anything other than the rooms, so I started repopulating the world the old-fashioned way, building via "Online Creation" (OLC) while logged into the MUD. It didn't take long to realize that trying to build in a MUD via a dumb terminal makes for a terrible user experience.

Enter a new suite of online building tools: the Tierceron Construction Set (TCS), available on GitHub (please see this month's release notes), written in Ruby on Rails, and deployed to Heroku, where it is easily accessible to any builder with an internet connection and a web browser. I wasn't terribly surprised to learn that I'm not the first to implement a browser-based building application; the MUD development community even has a name for this kind of app: "webadmin". OLC may have been adequate for the 1990s, but it is unacceptable in 2019. Actually, I'm not even convinced that OLC was adequate in the 1990s. I know that back in the day, Wrathmolten had cooked up his own program in Visual BASIC that allowed him to create content on his desktop and export data files the MUD could consume, so the impulse to have something better is not a new one.

Screenshot of a web form in the Tierceron Construction Set. The form is showing edit options for the 'apologize' social command
Editing the most Canadian social command ever.

The screenshot above shows a segment of an edit form in TCS. Right now, I've only implemented the ability to edit social commands, but it's a start. You can see the advantages that the form gives us: we can include help text, hints, sensible defaults, and notify the user when their input would cause an error in the MUD. Builders don't have to worry about getting disconnected, crashing the MUD, or accidentally trashing their area files because of some silly mistake. There's also file handling, so we can import datafiles from the MUD into the TCS database, and then export new datafiles to send back to the MUD when we are done editing. Multiple builders can work on different areas at the same time, and we can segment their work so that each builder only has permission to edit their own assigned content regions.

Creating an original world with the size and scope that could rival something procedurally-generated feels a bit like John Henry going up against the steam-powered rock drill, but at least TCS gives us a pretty good hammer to swing.

May 2019

This month, I continued work on the Tierceron Construction Set (TCS)—please see this month's release notes. I've tried be disciplined and not overdesign TCS with some fancy, enterprise-level architecture. Developers like to play "what if" with their pet projects—what if someday I need this to be both a floor polish and a dessert topping? It's tempting to cram in everything you could ever possibly want, but it's not a smart use of your time. An important principle to keep in mind is, "build for today, design for tomorrow". Think about what you may need in the future, and don't paint yourself into any corners, but only build the features you need today.

I've also tried to be a lot more disciplined about breaking down the work into small chunks, with each pull request representing a discrete segment of the application. I'm supposed to be teaching an "Intro to Rails" workshop later this year, so I've been writing while considering how small segments of code can serve an instructional purpose. With any luck, TCS could serve as a good jumping-off point for a novice coder trying to write their own webadmin application, whether in Rails or Laravel or some other web framework. To that end, TCS and its constituent commits are open source and browsable on GitHub.

The only thing you can do right now in TCS is create and edit social commands, but the process works from start to finish. Right now the workflow is like this:

  1. Log in with an admin account.
  2. Upload SMAUG's socials.dat file via the admin interface.
  3. Create new socials and make edits with the web forms.
  4. Export the updated socials into a new .dat file (again, through the admin interface) to be uploaded to the MUD.

With the MUD data in its database, TCS is capable of useful operations such as searching, sorting, and reporting, giving us powerful tools to look at the state of the entire MUD world through a tidy web interface. What TCS does not do is sync up automatically with the MUD; an admin still has to transfer data files back and forth by hand. In the short term, this is a reasonable approach because it isn't as if we have teams of writers generating new content around the clock. In the long term, I can see questions arising as to which application is the system of record: the MUD and its live data, or the TCS database? Build for today...

Next month, I'll start working on the ability to create and edit SmaugFUSS objects so that TCS can actually start being useful.

June 2019

I have continued working on the Tierceron Construction Set (TCS) although I think I'll save the release notes for next month's update. TCS is publicly available on GitHub for anyone who wants to take a look at the most recent changes to the source code.

Having wrapped up the work on editing social commands, I wanted to turn my attention to making tools to help our builders create the MUD world. However, I quickly ran into a design question: how do I handle authorizations for multiple builders? If Gladstone is working on a set of rooms, and Wrathmolten is working on another set of rooms at the same time, how do I keep them from accidentally overwriting each other's stuff?

In a Diku MUD, the world is composed of three primary data structures: rooms, objects, and mobiles (NPCs). Every room, object, and mobile has a VNUM that acts as a unique identifier. When we grant a builder access in the MUD, we assign them a range of VNUMs. For example, the City of Tierceron spans the VNUM range of 10000 to 10999; all the VNUMs in the city fall into that range. So the question is not so much how do we keep builders from messing with each other's stuff, but how do we ensure that builders can only work with their own assigned VNUMs?

We could implement some kind of connection between each VNUM and the builder who "owns" it, but that method becomes unwieldy as the MUD grows and also makes it complicated for builders who want to collaborate on a shared set of VNUMs. Fortunately, Diku has a means of organizing VNUMs: the "area" or "zone". A zone is a contiguous set of VNUMs and a bit of metadata, like the zone name and its recommended level for explorers. In TCS, I give each zone an "owner" who must be a user in the system; each owner has the authority to create, edit, and delete anything tied to the VNUMs that they own.

At the moment, each zone can have a single builder assigned to it, but somewhere down the road, I'll add the ability to assign multiple builders to a single VNUM range. For now, my main concern is deploying the Minimum Viable Product version of TCS so that I can get it up and running and actually usable. And now that I can have zones and owners, I can set up the following:

Screenshot of an index listing, showing a number of in-game zones and the builders who own them.
Oh, the places you'll go...

The zones don't actually do anything yet but having them defined makes it feel like TCS is actually going somewhere. I can see the outline of all our old areas and it's as though the MUD is finally experiencing spring after a very long winter. Now that I have zones configured, I've started work on the object editor. It's actually almost ready as of this writing but I'll outline the details (with complete release notes) in July's update.

July 2019

A screenshot of the TCS object edit form showing a mix of text inputs and select inputs.
Enlarged Image

This month, I worked on getting Smaug 'Objects' into Tierceron Construction Set (TCS). Even though my goal for TCS has been to deploy the Minimum Viable Product (MVP) so that I can start using it right away as a builder, I found myself with some extra time and decided to flesh out some of the building features to make the object create and edit forms more friendly. You can see from the list of release notes that I couldn't resist adding in a few extras.

In a Diku MUD, an object is anything that you place in the world that is not an NPC or a monster. An object can be a sword, or a pair of socks, or a church pew, or a doughnut. There is one small problem: Object is a reserved word in Rails so there will be naming conflicts. It is possible to overcome this problem by overloading reserved words; I once worked on a large app that overloaded keywords like Resource and Filter, and even tried (unsuccessfully) to overload Application. Overloading reserved words is possible but is usually not a great idea—just choose a new name and save yourself a lot of future maintenance grief. All of which is a really long and roundabout way of explaining why the TCS object model is called Item, something that you'd probably never notice unless you look at the TCS source code.

Defining the Item model and building the supporting web forms simply transfers Smaug's OBJ_DATA structure into something that Rails and PostgreSQL will understand. Now that we're in a web app and not the "On-Line Creation" (OLC) command line, we can tweak the way we represent data types to make them more convenient for builders:

  • keyword and description fields are free-form text inputs,
  • object 'type' is a single select, and
  • collections of flags are multi-selects, backed by the PostgreSQL array type in the database.

Having a web form that maps Smaug's fields to useful inputs is adequate to satisfy an MVP deployment, but we can always do better. One of my frustrations with OLC is that I find myself constantly consulting help files to work out what fields I should be setting or what flags are available. Because OLC does not validate its inputs, it can be hard to know whether a newly-created object will even make sense to the MUD. Some of the most challenging fields to keep track of are a set of six object values unhelpfully called value0, value1, value2, value3, value4, and value5.

These six object value fields mean different things depending on what type of object you are working on. In many contexts, the fields aren't used at all, so setting them is pointless. An obvious improvement is to have TCS provide some guidance so that you can see how the meaning of the values changes depending upon whether you are making a sword or a cup of coffee. For the sword, value1 represents the number of dice the MUD rolls to determine damage; for the cup of coffee, value1 represents how much liquid is in the cup, measured in ounces. When you choose an object type, TCS will update the labels of the generic value fields to tell you what sort of values you should be setting.

Screenshot of the object value fieldset for editing a weapon.
Weapon object values.
Screenshot of the object value fieldset for editing a drink container.
Drink container object values.
Screenshot of the object value fieldset for editing a furniture object.
Furniture object values.

There are further improvements we can make. All of the generic value fields are stored as integers. If you use OLC, you'll be setting a numeric value with a command like oset sword value1 3. However, sometimes that numeric value is an ordinary integer, sometimes it is a key to a lookup value in a list, and sometimes it's a bitvector. Why can't the form be smart enough to manage these different types? In the "weapon" values fieldset above, the first three fields (Weapon Condition, Number of Dice, and Size of Dice) are ordinary integer inputs but the fourth field, Weapon Type, is a select field where you can specify whether your weapon is a sword or an axe or whatever. When using OLC, you'd have to look up these weapon types to learn that a long sword is 9 and an axe is 10. It's much more intuitive to be able to choose the weapon type you want by name and let TCS figure out the magic numbers for you.

In the drink container example, you can see that the Liquid Type list selector is on the third value where on the weapon example, the Weapon Type selector is on the fourth. These inconsistencies are frustrating to deal with so it's much better to let TCS sort them out. The furniture example is for a table that up to four people could sit at, on, or under. We want the MUD to realize all these actions are possible but that the most likely action is that you will want to sit at the table. With OLC, we'd have to calculate the bitvectors that correspond to each action as well as looking up the magic number that is the list key of the default preposition. Even if you are comfortable with bitvectors, working them out can be a bit of a pain and I can't think of any good reason to carry out this calculation by hand in 2019.

I've left off two important parts of object creation and those are "extra decriptions" which allow you to add additional flavour text to an object, and "progs" which allow for greater interactivity with objects. However, extra descriptions and progs are properties of not only objects, but also mobiles and rooms, so I'll wait to implement those features until I can standardize them across all building models. My next project will be to implement the creation of mobiles (Diku's name for NPCs)—a bit of a more involved feature but I hope to have it ready by the end of the summer.

December 2019

We're very nearly at the end of 2019 and I don't have much of an update. I've done some work on the Tierceron Construction Set but want to finish the NPC edit forms before making a new release. Clearly the "end of summer" target was a bit ambitious. I've also been easily distracted—I spent a bunch of time writing a 6502 instruction simulator (without clock or interrupts) in Ruby just for the heck of it and also had emergency surgery because apparently the human body has optional organs that can fail for no good reason and I had to have my insides refactored. So that was interesting.

In spite of everything, I think I can be satisfied with the year's batch of release notes, having made substantial progress with RealSpace and fleshing out the online build tool. I also devoted a fair amount of time to giving the site a long-overdue redesign, an effort which is not 100% finished, but still manages to drag most of the site kicking and screaming into the 21st century. Not bad for 2019.

I'll see y'all in 2020. I think it will be another good year.

« PREV   2019 News   NEXT »