[MUD-Dev] FW: Article on Data Inheritance

Christopher Allen ChristopherA at skotos.net
Thu Feb 8 22:31:22 CET 2001


Christopher Allen wrote:

> I thought that you might enjoy this week's article from Shannon
> Appelcline's ongoing series "Trials, Triumphs & Trivialities" at
> http://www.skotos.net/articles/TTnT_19.html and comments at
> http://www.skotos.net/ubb/Forum4/HTML/000019.html
>
> In the article he discusses:
>
>    * Global Verbs vs Local Verbs
>    * An amusing bulk bug

This is a sequel to last week's article -- this time on data
inheritance. As it talks about some things of interest to mud
developers, I thought that you'd be interested in it.

The full article is at http://www.skotos.net/articles/TTnT_20.html and
comments are at http://www.skotos.net/ubb/Forum4/HTML/000019.html

-- Christopher Allen

P.S. There are now quite a few articles at
http://www.skotos.net/articles -- we are adding about 4-5 new ones a
week, and we are looking for more (and we pay.)

------------------------------------------------------------------------
.. Christopher Allen                                 Skotos Tech Inc. ..
..                           1512 Walnut St., Berkeley, CA 94709-1513 ..
.. <http://www.Skotos.net>               o510/647-2760  f510/647-2761 ..


#20: Hobgoblins, Part Two

by Shannon Appelcline

February 8, 2001 - "Lack of consistency is the hobgoblin of online
games."  That's the conclusion that I came to last week, and you can
put it in your quotes dictionary right next to Emerson.

Though I have some other things that I'm dying to write about
(including dreams, plots, change, self-sacrifice, identity, and
redemption), I'm going to be good and follow my mantra. I'm going to
talk about consistency again this week, consistently staying to the
course I laid out. We'll get to that other stuff in seven days, I
promise.

So, consistency. If you haven't already read my last article go do so
now, to get the ground work on this topic. As a quick reminder, last
week I talked about the weird implementation of verbs in online prose
and how it can lead to inconsistency. There's another place where
consistency really matters in online prose games, and that's in
inheritance. This week I'm going to explain exactly what inheritance
is, how it works, and how we can be inconsistent in its use. I hope
the whole exercise will be eye opening for potential StoryBuilders? 
and interesting for everyone else, because I'm going to expose a
little bit of the guts of our system.

If you're bored by the technical details, go ahead and skip to my
general thoughts. And then, next week I'll be back to substantially
less techie topics.

The Problem with Definitions

So what is inheritance? It's a creation method that's related to
objects.  Which I'll need to take a step back and explain.

(For the tech heads out there, let me say that the objects I'm
referring to here aren't quite the same thing as the objects you'd
find in OOP.)

In the Skotos StoryBuilder? Server every discrete thing is an
object. That's to say each thing is an individual unit that's defined
in certain, common terms and can be interacted with by certain, common
methods.

Everything you see in Castle Marrach is an object. A sword, a pin, a
dress--all objects. A cat, a rat, a shadow--all objects. The Dining
Hall, the Grand Hall, your Guest Room--all objects. Sir Launfal, the
Queen, you--all objects.

Beyond these physical objects, we have a lot of intangible objects
too.  Social verbs like hug, kiss, and cry are objects. So are adverbs
such as slyly, happily, and merrily. So are the help files and the tip
files and even the error messages for action verbs.

Each object is made up of certain individual attributes. A sword, for
example, has a look description and a brief description and a weight
and a length. It has details too, like a guard and a hilt and a
pommel.

Making everything in the world into an object lets us view things in a
much more abstract way. We can now look at two objects, say Sir
Launfal and Sir Boreas, and see that they actually have a lot of
attributes in common. They both have feet and legs and knees, for
example. And, the descriptions of those particular details might be
identical for these two characters.

When considering how much similar objects have in common, we begin to
realize that its pretty silly to rewrite all of those common details
every time you create a new object (in this case, every time we create
a new person). So, we try and figure out a way to link together
similar objects.

And that is where inheritance comes in.

With inheritance, we would create a parent object that's used by all
"Men" (maybe; there's variations as we'll see below). We'd put all of
the common information in that parent object. Then, we'd create
children objects which inherit from that object. In our above example
we'd create Launfal and Boreas as children of our "Men" object. They
inherit all of the common information from the parent object. If "Man"
has "ordinary" knees, then both Boreas and Launfal have "ordinary"
knees.

A little restrictive it seems. What is Launfal or Boreas should have
"unordinary" knees? There's more.

Each child object can "overload" data it inherits from its
parent. This means the child can replace some specific information
with its own local data. Say Boreas had "hairy" knees. We'd put the
"hairy knees" attribute in Boreas, the child object, and that would
overload the "ordinary knees" in the "Man" object.

Easy. We get all of the standard information from the parent, then we
change any information we want in the child.

Much of what we've talked about so far is called "data
inheritance". This is when you inherit some attribute or other
information from a parent. In our games, you might inherit a
description or a detail.

There's another type of inheritance too: "method inheritance". This is
when you inherit how to do something. In a prose game like ours, an
object could inherit how to do something via method inheritance (a
person might inherit the "walk" and "talk" methods; a frying pan might
inherit the "cook" method) or how to react to something via method
inheritance (a log could inherit the how-to-react-to-burning method; a
trombone could inherit the how-to-react-to-playing method).

Whew. Summary:

  * Two types of inheritance. Data and Method.

  * Via inheritance children objects can get data or methods
    from parent objects.

  * Data inheritance means an object inherits specific
    information, such as a description, a weight, or some other
    attribute.

  * Method inheritances means an object inherits how to do
    something, such as a verb or reaction to external stimuli.

So, how can inheritance cause inconsistency?

The Problem with Inheritance

Before I try and answer this question, I want to talk about how
inheritance has been done in MUDs. The problems will quickly become
obvious.

Traditionally there have been two inheritance methods in MUDs: none
and chaotic. I'll briefly run through each of these, then talk about
how we're doing it at Skotos and what challenges we still face.

The oldest MUD, including MUD and AberMUD?, didn't do inheritance at
all.  Each object was totally separate. If you wanted to make two
similar objects you'd do it by copying the attributes and methods from
a similar object and changing them ... or more likely you'd just
ignore older objects all together and just create what made sense to
you.

EARLY MUD INHERITANCE
(No Inheritance)

+---------+         +----+          +----------+         +------+
|Longsword|         |Dirk|          |Frying Pan|         |Teapot|
+---------+         +----+          +----------+         +------+

This way of doing things provided for zero consistency. Players would
have no guarantees that similar items would look or work the same. You
might be able to cook with frying pans but not pots. Likewise, since
the correlation between items was so poor, you had no guarantee that
similar items would be related in the correction proportions. Daggers
might be more damaging than swords (And, in fact, when I used to play
AberMUD? this was a noticable issue.)

C++ and OOP started becoming popular among programmers in the 1980s
and they brought with them the whole idea of objects and
inheritance. Thus later MUDs, starting with LPMUD, started to make
good use of inheritance. In fact, they dove headfirst into inheritance
without looking back. You could build trees of objects, with each
object inheriting appropriate methods and attributes from its parents.


LATER MUD INHERITANCE
(Data and Method Inheritance)

           WEAPONS
          /   |   \
   DAGGERS  BLUNT  SWORDS
    |         |         \
  Dirk      Club    Longsword


                 FOOD 
                /    \
           MEATS      GRAINS
            / \          \ 
         COW   PIG      Cereal
         /     /  \
  Hamburger  Ham  Bacon

                    SMITHERY
                   /    |   \
        KITCHENERY   Nails SWORDS
        /      \              \
  Teapot   Frying Pan         Broadsword

As you can, huge trees would developed, and they'd offer a lot of very
useful correlation. It makes sense that Ham and Bacon are very closely
related and that Ham and Hamburger are fairly closely related and that
Hamburger and Cereal have some features in common. That's all
represented by this tree and thus by the methods and attributes
inherited.

But, unfortunately, the structure of the tree is totally arbitrary. We
gain some consistency because similar objects will usually have
similar attributes and methods, but we don't resolve the issue
totally, because similar objects might actually end up far apart on
our inheritance tree--just by chance or by people thinking about
things in different ways.

In my example above, Weapons is a class that describes what its
children do (hurt people) and Smithery is a class that describes what
its children are made of (metal). The classes were probably created by
different people with different ideas of how the world works ... and
we ended up with a situation where swords could be found in two
locations. Because they're far apart in the inheritance tree, a
longsword and a broadsword may actually be very different items. And,
they may work in very different ways. The inheritance of both data and
methods begin to fall apart as our inheritance tree increases in size.

This isn't just a terrible example that I'm demonstratating. This
always happens in inheritance trees of objects, particularly when you
have a bunch of designers all working together on the same tree. In a
real inheritance tree for a real game you might end up with weapons in
a half-dozen places, with most people not knowing where most of the
weapons are. Thus, not only do you end up with massive inconsistency,
but you also end up with lots of redundant work.

In Skotos games, we've done our best to start resolving the issue of
inconsistent inheritance while still maintaining the power of the
concept.

Our first attempt to fix the consistency problems with inheritance
isn't particularly inventive. We did two things:

  * We restricted data inheritance to one level.

  * We largely got rid of method inheritance. We defined huge
    classes of objects (e.g., all physical objects, all help
    files, etc.) and determined that all objects in that class
    would use the same methods.

SKOTOS 1-D INHERITANCE
(Data Inheritance Only)

            SWORD              DAGGER         PAN             POT
           /     \               |             |               |
  Longsword       Broadsword    Dirk       Frying Pan        Teapot

This resolves several problems.

First, it allows us to use the global verbs that I mentioned last
week.  Methods are global (to a very large class of objects) and thus
verbs for interacting with objects are global. Even better, all
objects will react to all stimuli. You could use a teapot as a weapon
(though an ineffective one).  You could try and burn your dirk
(unlikely) or eat your longsword (ouch!).

Restricting data inheritance to one level resolved much of the problem
of inconsistent trees--because those inconsistencies usually happen
when you get a few levels into a tree. However, it also creates
inconsistencies because we have to constantly remake items. Sure, our
longsword and broadsword will be guaranteed similar because they both
descend from Sword, and sure all of our weapons will have the same
methods for reacting to combat, but our Broadsword and Dirk aren't
guaranteed to be consistent in detail because they don't have a common
parent.

Let me offer an in-game example. All male characters have the same
parent that they inherit from. It's called the UrMale? ("Ur" is a word
meaning generic; it's kind of like a platonic ideal). Likewise, all
the female characters have the same parent that they inherit
from. It's (cleverly) called UrFemale?. All characters of both sexes
can do the same things, because verbs are global, and they can all
react to the same things, because methods are global.

But there's no link between the attributes and details of UrMale? and
UrFemale?.

Just because a man has a waist doesn't mean a woman will have a waist
(or an arm, or a head, or an eye.)

Oh, we're very careful to keep the UrMale? and the UrFemale? synced,
but there's no system that enforces it. And I know that we've already
gotten sloppy with some of our others parallel Ur objects, such as the
UrOutside?  and UrInside? objects that we use as parent objects for
some of our rooms in Marrach. (Want to know why you can almost always
find the "center" or a room inside or why you can almost always
interact with the "wind" outside? It's because they're built into Ur
rooms.) These two Ur objects should be very similar because they both
represent rooms ... but again there's no guarantee that they'll stay
synced.

To better resolve some of these issues we're in the process of
expanding our data inheritance system into two-dimensional
inheritance, or property-based inheritance. The idea is that all
inheritance is only one-level deep, as in the diagram above, but that
we inherit the basic form of the object from an Ur object "above" and
that we inherit certain properties of the object--like color,
substance, and quality--from attribute descriptions "to the left".
(In a certain sense, an object can have lots of different parents that
it inherits from, each offering attributes of very specific types).

SKOTOS 2-D INHERITANCE
(Data Inheritance Only)

                   POT
                    |
  Brass ------> +--------+
                |        |
  New --------> | Teapot |
                |        |
  Well-made --> +--------+

It's a little more complicated then the one-dimensional inheritance tree,
but it allows for some more complex possibilities.

So, looking at our earlier problems:

  * We have no problems with methods inheritance because we make those
    method global.

  * We can maintain a high level of data consistency by carefully
    inheriting the shape and important attributes of an object.

  * By keeping inheritance to one-level we avoid complex structures
    that hurt consistency.

  * But we still have some problems with maintaining relationships
    between our objects. There's no guarantee that a longsword will be
    better than a dirk.

So again I have to offer the same advice I did to StoryBuilders? last
week: Be aware of consistency problems (regarding inheritance) and try
and keep your inheritance clean and consistent.

And that is the end of my delving into highly technical issues in
order to make a point ... for now at least.

The Problems with StoryBuilding?

Over the last two weeks I've investigated two systems that interested
me--verbs and inheritance. In each case the systems highlighted
consistency problems.

In truth there can be consistency problems in anything you do with
online game design, so it's a problem that you have to be constantly
aware of.

Here's a few more places where inconsistency can hamper your online games:

  * Room descriptions. Is everything written in the same voice? Is the
    level of description the same for all briefs / looks / examines?

  * Language. Is your use of language the same throughout or do armor
    and gray mix with armour and grey?

  * Danger level. Is similar warning always given for similar danger? 
    Or, might an ancient red dragon be a pussycat in part of your
    world and a deadly opponent in another?

  * Reward level. Within reason, does similar danger usually result in
    similar reward? Or, can killing a cow give you 100 gold while
    killing that ancient red dragon (the mean one) only gives you a
    few coppers?

  * StoryTelling. Do different StoryTellers have the same criteria for
    doing things? Do some StoryTellers give out tons of help to
    players while others ask them to get along on their own?

The list goes on. Some may even be worthy of future columns on their
own.

Just be aware of the basic maxim which I already suggested last week:
Consistency matters.

See you in 7 when I'll tell you about my second dream of Castle
Marrach ...  and what it got me thinking about.


_______________________________________________
MUD-Dev mailing list
MUD-Dev at kanga.nu
https://www.kanga.nu/lists/listinfo/mud-dev



More information about the mud-dev-archive mailing list