I've been lurking for awhile, reading articles and such. This is a great resource, thanks!

Question: I am playing with making a MUD. Really, just an exercise for myself to see how far I can get. Currently, I have it up and talking, a basic NLP and am working on command support, etc.

I am looking for opinions on implementing objects in the game.

What I have noticed, looking at a few mud codebases and reading lots of posts is that the common idea is to have a single object or struct to represent objects. Objects have names and descriptions attached to them and lots of bit flags to indicate attributes / behaviors.

The approach that I am thinking of taking is to have a shallow object hierarchy of object classes to maintain state common to every object type (location, etc). For attributes / behaviors I am thinking of having an object type to encapsulate these concepts and have the object instances own these. So if I need to see if I can "unlock" an object I check for that behavior in the object. If I need to see if it is already unlocked, I would check the same behavior. All attributes would be structured this way: Is it a weapon, wearable, light source, magical, etc. The behavior hierarchy would probably be deeper than the object hierarchy since that is where the depth of functionality of objects would be represented.

Thoughts? I like the idea of having anything be able to take on any behavior, in theory. So spells like the old D&D "light" spell could work by making anything a light source.

My only real worry is performance. Every time :

- Need to operate on an object I would have to scan this list- See if there is a light source in a room, scan the lists of all objects in the room- etc.

Thoughts? I like the idea of having anything be able to take on any behavior, in theory. So spells like the old D&D "light" spell could work by making anything a light source.

My only real worry is performance. Every time :

- Need to operate on an object I would have to scan this list- See if there is a light source in a room, scan the lists of all objects in the room- etc.

I'm not sure I understand why you think that the design you're proposing (which seems pretty straightforward) is going to necessarily result in more memory-intensive operations. Here's what I think:

The example of a light source is a bit of a special case in that I'm guessing you want an active light source to affect what everyone around can or cannot see/do. Now, there's nothing stopping you from defining the "light source" behavior as something that sets a "lit" flag on a location whenever the item changes locations while activated. That saves you from having to scan all items in the room, and it changes nothing in the way you've put the item properties together.

All this means is that your behaviors should be sufficiently flexible to encompass all cases you can think of. I strongly advise against trying to design a behavior framework that can handle "everything can be everything". Instead, start from concrete and build up from there, as needed.

Thanks for the feedback, its appreciated. I agree. The goal is not to create a completely flexible system where anything can be anything. The goal, really, is to create a system where I relate the parser / semantics to objects in the world and store and retrieve state while hard coding as little as possible. There would be some flexibility though. A door could respond to "lock" by way of behavior and that could set the "locked" attribute on the object.

You are right. Light was a bad example to use. Light is special and I have a separate question on that relating to change notification on objects which I will ask in a separate thread, unless you think its relevant here.

My concern for performance wasn't memory related. I may have mis-communicated. I am more worried about cycles used to scan lists rather than what I see some current mud code bases do: hit a field on struct that is a bit string representing state. Obviously the latter would be really fast while scanning lists of behaviors of objects could be time consuming. Though, with today's hardware, shouldn't be a huge issue. I hope. I haven't written any game-like code since the 80s. I was surprised when I wrote my language processor… it parses 100 sentences (over 4000 edges) in 9 milliseconds. So maybe performance isn't as big of a concern. Though I do worry about the accumulation of a lot of traversals.

I will follow your suggestion and build it up slowly and see how it pans out.

My concern for performance wasn't memory related. I may have mis-communicated. I am more worried about cycles used to scan lists rather than what I see some current mud code bases do: hit a field on struct that is a bit string representing state. Obviously the latter would be really fast while scanning lists of behaviors of objects could be time consuming. Though, with today's hardware, shouldn't be a huge issue.

I feel the same way. Performance shouldn't be a big concern at this point in time but obviously you don't want to scan lists for stuff that is very commonly needed. The light source example is actually pretty good for establishing a rule of thumb for yourself. If a state is commonly accessed and simple enough to set when changed, then you can certainly do what the "tried and true" codebases do? Rather than set a flag when an active light enters, as was my quick suggestion earlier, Diku increments and decrements a counter of lights so that you won't have to scan the whole room when a light exits.

On the other side of the argument, if something is not that difficult to check (and can be determined dynamically with a utility function), why not take advantage of your hardware? In a modern language, utility functions that scan for properties can be really multi-functional, and can save you from having to maintain various flags and counters. Also, sometimes it really helps to have an "absolute" property and all its possible modifications kept separate. One case where this is patently true is player affects. You can avoid a whole lot of pain by never modifying a player attribute such as max health, and calculating its current modified state as needed.

My biggest suggestion if you want to have a flexible object model is this. When you start deciding what things you add to your game, really sit down and question the nature of the system you're about to add. Ask yourself if it's similar to anything else, and if it is… can you make a more generic version as a parent and make the two "different" systems inherit it?

A common example is the typical MUD dichotomy between "rooms", "objects", and "npcs (or players)".

In old game systems, they were immutably different things, and code had to be written to keep track of them distinctly. If you wanted to set a creature on fire, that was entirely different code from setting a torch on fire, or a forest…

However, if you think about it. What makes these things distinct from each other?

A room is an environment which holds things, has properties that pertain to the interior of that environment, and has exits that link it to other environments. It may have events that occur, and act upon things inside it, or things in adjacent rooms (linked via their exits).

An "object" is generally a physical game item. It may be a container, in which case it also has an interior environment – usually called an inventory – and may contain other items. It has properties that pertain to the exterior of itself. If it's a container, it has an implicity "exit" in the form of the opening that allows things to be put into or taken out of itself. It may also have events that occur, acting upon things around it or (if a container) upon things inside it.

So, how is a room different from a container? The answer is… they're not. Not on a fundamental level. You could easily make one into the other, simply by having a parent class that supports the kinds of things each can do.

Let's say you created a "thing" class to use as a basis for rooms and objects. A "thing" has an interior and an exterior, each of which have properties (descriptions, etc). A thing has a weight. It has a volume (the interior space), and it occupies a volume (the exterior space). It has exits allowing things inside it to go elsewhere, possibly into the outside environment containing it, or possibly into another "thing".

To make a "thing" into a room, you pretty much ignore the external properties and restrict access to a subset of what it can do. To make it into an "item", you probably want to use the external properties by default, restricting the internal properties for specialized commnads.

But, my point here is, if you wanted to allow a player to "enter" a sword, all you need to do is ensure the sword has an enterance and some volume which the player could be placed into. In essence, normally, a sword has no exits and an internal volume of 0 cubic inches, but you COULD change that if you wanted.

Is it worth the extra hassle? That depends on how often you'll actually use such mutability. If you only do stuff like this for very special events, it's probably easier to just special-case it. But if you want your game to allow people to shrink, climb into bottles, be placed onto a boat that sails around the world and then climb back out as a regular kind of thing… maybe it is worth it. :)

In old game systems, they were immutably different things, and code had to be written to keep track of them distinctly. If you wanted to set a creature on fire, that was entirely different code from setting a torch on fire, or a forest…

I think you know that things are really not that clear-cut. There's nothing immutable about the structs in an old Diku. You want to have items that contain people? Add a list of character pointers, some code to add and remove pointers, some text messages, and you're done. It's very doable.

On the other hand, if you choose to design your game so every "thing" can catch fire, and creatures and environments both inherit from thing, then that carries implications. Now you have to write code to differentiate what happens to a forest vs. what happens to a creature, even if you really didn't want to have to worry about forests catching fire yet. Once things are hierarchical, you may find yourself pleasing the gods of inheritance so often that you'd forget what actual gameplay feature you wanted to add.

Is it worth the extra hassle? That depends on how often you'll actually use such mutability. If you only do stuff like this for very special events, it's probably easier to just special-case it. But if you want your game to allow people to shrink, climb into bottles, be placed onto a boat that sails around the world and then climb back out as a regular kind of thing… maybe it is worth it. :)

As you've probably guessed by now, I don't think inheritance = mutability, and I don't think it makes the things you're describing any easier to implement. In many scenarios, inheritance can help with code re-usability (especially compared to hastily written procedural code). And if well-thought out, it can help add new entities with complex properties and methods quicker. But it's a double-edged sword. It can also add bureaucracy (stone inherits from "thing", so it can catch fire, now we have to special-case it even though it's just a stupid stone with no real game impact :) and impose its own logic on the game logic you actually want.

As you've probably guessed by now, I don't think inheritance = mutability, and I don't think it makes the things you're describing any easier to implement. In many scenarios, inheritance can help with code re-usability (especially compared to hastily written procedural code). And if well-thought out, it can help add new entities with complex properties and methods quicker. But it's a double-edged sword. It can also add bureaucracy (stone inherits from "thing", so it can catch fire, now we have to special-case it even though it's just a stupid stone with no real game impact :) and impose its own logic on the game logic you actually want.

That just means you didn't factor the inheritance very well.

Catching fire shouldn't be a part of "thing", it should be a part of "burnable", which stick, forest, and human might all inherit. As you might guess, I've seen this done in LPMUD mudlibs, so it's not just academic.

Of course it can become a hassle, but show me any complex system that isn't? You have to have some kind of hierarchy if you intend to make a game that has rules, otherwise it's just a chaos of spaghetti code My thought is that most codebase limitations come from the designer not really thinking through how similar actions or properties could be abstracted and reused. The room/object thing is one example. Another was the classic DikuMUD player/npc using different structures.

And yes, I would absolutely call "adding a list of character pointers, some code to add and remove pointers, and some text messages" a big heaping pile of spaghetti code. You're just asking for things to break further down the line, as something forgets to tidy up one of the dozens of extra pointers you threw in to avoid multiple inheritance.

The more interesting features of inheritance to me is things that are not gameplay models, but interactions. It's also much simpler to manage and build exclusion trees.

Although, I agree, the hierarchy of inheritance always is more intuitive to understand from a real life example point of view. That's exactly why I think this pitfall is more common in game development than other types of software when there's not a real life analog.

That's how I think about it, too, and I think that's the "behaviors" the OP is talking about. The gist of it is that inheritance is not sufficiently complex to describe differences between entities. Even multiple inheritance isn't. It requires heavy abstraction, and to get anything close to reality, it would have to have 30-40 levels at least, so that you don't add "can catch fire" too early in the "tree". It's much more conceivable and manageable to cluster together properties and methods and assign them as a group. In practical terms, you don't need to structure all of creation in your virtual world just so you can set down the relatively simple rules of gameplay.

IAlthough, I agree, the hierarchy of inheritance always is more intuitive to understand from a real life example point of view.

I actually find it less intuitive that way. 'dog inherits animal inherits thing" works ok, but what about your dove-skinned gloves? Do they inherit from animal just so they can get the leather skin property? And if so, do they walk away from you unless you made sure the property was inherited from a dead animal :) Parent-child is just one way of structuring things, and there are real ways you can hurt yourself by trying to fit everything into that mold.

And yes, I would absolutely call "adding a list of character pointers, some code to add and remove pointers, and some text messages" a big heaping pile of spaghetti code. You're just asking for things to break further down the line, as something forgets to tidy up one of the dozens of extra pointers you threw in to avoid multiple inheritance.

This sounds like a lot of wishful thinking to me. I would just point out the glaring assumption that inheritance somehow solves the problem of writing bad code. Unfortunately, it doesn't. And while when you fix something big up the inheritance tree, everything "under" it also benefits, that has its flipside, too: when something is buggy up the tree, everything misbehaves, and it's not apparent from looking at your part of the code what exactly is the problem because it's somewhere upstream.

As I've shared before, I write all kinds of code. I just think it's wrong to paint things in black and white, especially for people who are wondering which way to go.

Take a look at this Wikipedia page Prototype-based programmingThere are several Mud programming languages listed there: MOO, ColdC, LPCThere are other Mud languages with similar features that aren't listed, like Coda, MUL, Cool, MUF, Mica.

Generally speaking, in these Muds, prototypical objects are created based on behavior, and assembled via multiple inheritance.But this style of inheritance is not static like C++, it's runtime dynamic. If you look at the mud sources, which are in C/C++, you'll see how it's implemented.

Here's a reprise of a previous post which describes the programming environment of ColdC (ColdCore):

Quote

Here's something simple in ColdC. Let's say I want to add a new stat to the game called will.

> @add_var $npc,stat_will = 10;

Since all my characters and mobiles are descended from $npc they all now a will stat, that defaults to 10.I don't have to modify a structure nor do I have to create database routines, since cold is implicitly persistent.

We don't need to edit huge modules like in Diku nor even a whole objects source file like in LPMud. You create, delete or edit a single method on an object.

I can test the accessor code on myself, or in the context of a different object.

@eval me.will();=> 10

@eval me.will(25);=> 25

@eval me.will();=> 25

Now that I have a will stat I can modify some of my spells to use it. Let's say I want to modify some thatused to use the intelligence stat. I can search a particular objects variables and code, and its childobjects.

I can @list and @program the .charm method on the $spells object, possibly replacing one of the .int checks with a .will check.

Note the entire architecture of the game, include having objects named $npc, $character, and $spells and their relationships were programmed online. The only objects that a starting server has are two special objects called $root and $sys. But like LPMud, Mush and MOO there are starter databases and libraries you can use and borrow from.

Wow, thanks for all the responses. And thanks Tyche for the link, I will take a look at that as well.

Intuitively, it feels right to have objects in a somewhat shallow hierarchy (which I am still thinking about defining). And then add behaviors to the objects which define what they can do. My goals are probably overkill. For example, Rather than have "forest" I would like to have a group of locations in which there are a lot of trees. The trees can individually catch fire and have a probability of catching the other tress on fire. The benefit there is that when you walk into one of those locations, you are not in a "forest" because the location says you are. You are in a forest because you are surrounded by trees.

Having hierarchical relationships seems like a good idea too, though. Having the knowledge that something "isa" something which "isa" a something else might help game logic. But, I suppose, that could also be modeled through behaviors. My biggest fear is that if there are a lot of behaviors describing the attributes / abilities of an object then performance could drag. Like, the light example that Plazmi gave above. If I bury the attack values of a weapon in a list of attributes for an object then I will be searching that thing a lot to get values during combat. So, to Plazmi's comment, a scheme for caching these commonly used values would probably be a necessary compromise.

Which leads me to.. 1. You have these behaviors stored in object instances. 2. You need a value a lot so you cache it. (Like the armor class of what you are wearing). So then you have to remember to update those values when the state changes, like when the player removes his/her armor. So while I am in the midst of thinking about object design I am also having to think about object change notification. So there'll need to be a dependency graph to deal with change notification. It does seem like the more abstract a system is, the more maintenance is required to support it.

Hard coding seems simpler. Everything has "hit points" for example. Rather than have some sort of "health" behavior / attribute. So I guess the trick will be to

1. Come up with a base shallow hierarchy that has cached values that are used frequently. I am thinking base noun classes that represent mass nouns, locations (which are objects), and count nouns (which have presence, location). And then maybe extend the count noun to include living and non living entities. And I am toying with the idea of having a weapon class of object, but that might not be necessary if I cache armed elements in the player structures (which is also an object).

2. Come up with a fast system for managing change. By big fear is that rooms will still be lit when a player or NPC carrying a torch leaves a room. Plamzi suggested the Diku method of caching that in the location which might be the best thing to do. But I'd still need a way to detect movement of light sources and to update that value.

3. I thought there was a 3, but I have lost track. Its early and I haven't had my coffee yet.

Thanks again for all the replies (and for all future ones). I really appreciate the time and the thought that goes into them.

Funny that someone should mention the 'enter a sword' thing - Alter Aeon actually allows this, and has since 1997 when I made object and mob structures derive from a base class called 'entity'. We now have a few other branches and layers in that inheritance tree, and quite a bit of generic infrastructure that lets us do neat if obscure things. However, my overall impression of the system is that in the end it caused more trouble and took more programming/debugging time than it was probably worth in gameplay.

I'm not about to rip it out though, now that it's been pretty thoroughly debugged.

So while I am in the midst of thinking about object design I am also having to think about object change notification. So there'll need to be a dependency graph to deal with change notification. It does seem like the more abstract a system is, the more maintenance is required to support it.

On the subject of notifications, I am of the mind that it's yet another popular place to over-engineer things. If an event is likely to have a limited number of listeners, and you know what those are, there really is no need to pass through a notification system to call the interested parties. In the case of a light source, I see nothing wrong with cascading down from the main "creature changed location" event to a hard-coded check on whether they have an active light source on them that needs to be handled.

Thanks Plazmi. I was leaning in that direction, especially, as you say for the "light" piece.

Follow up question: This is more of an implementation detail, so feel free to ignore if its too detailed of a question. I am trying to decide between have a single behavior for an object that handles registration for an action (verb) and contains the state. So.. lock/unlock/locked state would be a behavior which maps to "lock" and "unlock". Or, having a wider array of "behaviors" which do not contain state but which operate on a state stored in a separate list in the object. So an object would have a list of behaviors and states as well as a list of attributes. This would simplify the design for instances where there are potentially many actions which could set or unset a state on an object. But there is a satisfying feeling, too, with having a single behavior which handles the mapping to the parser semantics and also maintains the state.

There probably isn't a huge difference. I just wonder if there is an obvious sense of which is better than the other. Or there might even be a third option where the notion of which actions trigger a behavior is encoded in the command function and the behavior is dumb and just contains state.

On the idea of notifications, the first time I came across an event system like this was in the Amiga's OS. Prior to that, the general model was "check to see if something needs doing. if so, do it. If not, check the next thing and loop back."

The idea of having entities "register" themselves for various events, so they would only wake up and do stuff when one or more of those events happened was pretty cool.

With the light in the room example, I would think the light entering the room (or being turned on/created/etc) would be an event that the room might well be listening for. If it happens, and the room wasn't already lit, it would probably generate a "description changed" event which all the players and npcs would likely be listening for.

The players/npcs don't need to know that what changed was the light level (usually), but they may want to have the room description reprinted since the lit version is probably different than the unlit version. SOME things may care about the light event itself. Maybe a dark elf character might specifically want to react to the light directly. Maybe a light sensor that opens a gate might react.

Now, there are undoubtedly ways to optimize this, but I think that there are some benefits to enforcing barriers between things even if it might hinder implementing emergent behavior. For instance, merging item and thing might not be such a bad thing (even if I am choosing not to do so). After all, just because X could never lift a table or a metal safe does no one would ever be able to logically. I have it set up as the former since it helps to distinguish the two. There is something to be said for doing everything in attributes/properties, but I am not as fond of that approach.

Part of the trick to making the most of hierarchies is to avoid subclasses unless they can be generalized. Ideally, an Armor class would cover any kind of armor and not be limited to traditional medieval armor. There's no good reason why it shouldn't simultaneously handle futuristic power armor, medieval chain and plate armor, bits of material you can scrounge together into some kind of covering. The biggest advantage that I can see to attribute/property/entity systems is that they make it somewhat easier to construct "objects" without having to produce a well designed object hierarchy and the respective constructor and methods of the units that comprise it and also are much easier to extend with new features.

With regard to light sources, I think it would depend on whether you wanted a simple lit/unlit system that only required that someone in the room had a light source for it to be lit or something more complex. For a more complex system, you might have to track light for each player. Although if you had a notion of space & position then the room could be "lit" when just one light source exists (i.e. you can see), but different parts of it would have different amounts of light. So you could calculate how bright the room was for a player based on their closeness to one or more light sources. Of course, unless you're going to blank out the room if it's pitch black or decide what stuff in the room the player can see (whether that be objects or more descriptive detail or spawn monsters according to light (like Minecraft did/does) then there's not much point to having a complex system.

It would be nice if someone would commit some time to a document outlining these different strategies and analyzing overlap…

I see no special problem with hierarchies except that you have to be careful to keep them from growing out of control. My own code has this kind of thing:

I wouldn't mind spending time documenting my experiences, but I am not sure how useful it would be given my lack of deep knowledge of existing code bases / mud strategies. I have been out of mudding for about 25 years.. or so.

On hierarchies. I agree with your point in that they don't need to be (un)necessarily deep. Actually, I would prefer to have just one object and add allow behaviors / containment to define objects that are used in the system. But, as Plamzi points out, there could be performance issues with that and, so, it might be beneficial to have general categories of objects that have common fields that will be accessed frequently like.. armor class, hit points, offensive / defensive mods. Although, if the behaviors / attributes were hashed to the objects then that might not be such a big issue.

On the light issue, I don't plan to manage sub-location light values. I would like to be able to modulate what is viewable based on the total quantity of light available in a given location.

Yes.. I spend far too much time thinking about these things. It will be nice to get to a point where its not just thinking, but where I am tinkering with a somewhat viable system.

I'll chime in because I think there's an opinion here that hasn't exactly been addressed, although it's been touched upon. What is the motivation for creating highly factored models for object hierarchy? Presumably I think most people would agree (as someone else mentioned) that it's to improve the gameplaying experience. Obviously maybe not directly, as an easily-expanded system can itself catalyze a better game.

That said, I personally don't think that fundamental alterations to the typical MUD object inheritance are going to help anyone get anywhere particular in terms of content. A MUD's code is generally simple enough that issues of scale don't really come into play too much, and the scalability of design that you get from making everything a class might be outweighed by the effort of implementation plus the utility to players.

Thanks for chiming in Oliver. I think the motivation (for me) for making a flexible / extensible system is to

a. Make it easier to extend the game. Intuitively, it seems like a system that is more abstract and less "hard-code" allows for easier additions of new concepts to the game. And it might make it easier to simulate a "self-modifying" element to it. I might be wrong, that's just my sense.

b. Make a more enjoyable game. In some games I have played doors, for example, weren't really objects. You couldn't break them down, take them off their hinges, etc. You might see a description noting the presence of a door with a certain set of attributes and then when you go to touch it or part of it, "I can't see that here". Granted, I haven't played a mud in 20 years and it sounds like the technology has come a long way. It just seems to me that an abstracted object model composed of behaviors or building blocks that can individually be interacted with (to some degree) would lend to a greater sense of realism in the game. It could never be perfect, its just a goal. And there is, probably, also a satisfaction that comes from making an certain kind of design.

If you use a language like Java (or perhaps C++), I think it's important to this flexibility concept that you make some use of Interfaces (and whatever they call that sort of functionality in other similar languages) in addition to classes so that you can talk about groups of things with similar capabilities without worrying about their differences. Something that is easily seen to fall under this is mobiles/mobs as they are known sometimes in muds. Basically it's an object that can move, perhaps with some intelligence, but when you want something to move you don't really care if it is an npc or a creature or what kind of creature, only that it can move and that you can tell it, via some code mechanism to move.,

You might get more useful opinions if you choose some aspect and present what you want it to do so that there is a concrete issue to deal with. Abstraction is great, but too much design in search of a problem is a dangerous thing. The lighting topic seemed like an okay point to work around, but what it will be used for is important in how you set up such a system.

Emergent behavior (i.e. unintended or alternate actions/consequences) such as breaking down a door instead of picking the lock or finding the key is entirely absent when the system is not designed to handle anything but one particular solution/approach. Those sorts of things can make a game a lot of fun if they are allowed for.