[MUD-Dev] [adv-mud] Spellbound Hierarchy and Keys (fwd)

J C Lawrence claw at kanga.nu
Sat Jan 29 12:46:15 CET 2000


> From: "phlUID" <phluid at mindless.com> 

> On Spellbound, every object in the game is given it's own database
> number. Help files, races, spells, objects, rooms, mobiles, exits,
> worlds, areas, classes, populations, etc.  There are generically
> two types of database numbers: Pure, which is just a simple unique
> number given to every object, and Hybrid, which is used in the
> case of Object's and Mobs. For example, a room is object #43,
> while the sword in my inventory is #45:1 and the same type of
> sword in my friend's inventory is #45:2. The second number is
> referred to as an Entity ID because they refer to specific
> Entity's instead of Entries. There is an Entry class for #45
> called ObjectEntry, and there is an associated Entity class for
> ObjectEntry called Object. This concept is the same as DIKU's use
> of OBJ_INDEX_DATA and OBJ_DATA.

Translation:

  You have ObjectIDs which are synonymous with their (single)
instance, and you have InstanceIDs which are synonymous with an
instance of a referenced ObjectID.  An ObjectID may have multiple
InstanceIDs referring to it as each one marks a duplicate object.

> Currently, Spellbound uses pointers directly to objects like
> normal DIKU mud.
...various complaints about pointer tracking...
> This is made worse by the object orientness of C++, so I began to
> think of alternate ways of storing pointers.

My first thought is using either an auto_ptr or some sort of simple
reference counting scheme.

> The first thing that I wanted to be able to do is validate
> pointers. 

Reference counting with a flag would work fine.  Put a reference
count on your object class, and add an internal object_deleted flag
that is checked on every reference.  That way you just delete the
object, the flag gets set, and at that point when its reference
count falls to zero you call the destructor.

There's actually a rather nicely written grim_reaper class floating
about the net that handles this elegantly as a base class.

> This started my thinking into the idea that it would be possible
> to replicate this system to make sure that what I am referencing
> is actually there. My database uses a regular array to return
> pointer's to DB numbers, so there is no CPU time involved looking
> through tables or linked lists. If I want object #43, I just call
> Database.getEntry( 43 ) and it returns a pointer to that entry.

You might like to hit the archives for discussion of my ObjectID
format, and how it supports re-use and collision detection.

> This identifier consists of a count of exactly how many nano or
> milliseconds from the epoch. 

Remember that the high resolution timer on non-hard realtime systems
(and not even most of those) is _not_ reliable or accurate.
Furhter, you are relying on general clock accuracy.  Consider the
simple case where you have something like an NTP client or a SysAdm
resetting the system clock: there is a definite chance for two timer
calls to return the same value as the system clock passes the same
value twice.

> Assuming that no two object's can be created at the exact same
> time, this gives each object ever created a unique identifier.

Object A created at time X.

System clock set back by NTP client to time X-Y.

Y time later Object B created at time X.

Both get the same ID.

> If the database couldn't find #23, entity 0, or the time
> identifier was wrong, I would end up with a NULL pointer, which
> will just stop my action and inform Fred that Bob is no longer
> there. Simple, effecient error control.

I tend to be a big fan of exceptions (you might notice that my
initial internal language used exceptions for all call returns, with
a normal non-error return merely being a flavour of exception that
defaulted to always being caught by the caller).

Why use exceptions here?  With your scheme ever piece of code that
has to reference an object has to be prepared to find it
non-existent.  This is both a lot of duplication of effort and puts
the load on the programmer for a task that the system can generally
take care of instead (in the general case you just want events to
fail that reference deleted objects, not try to manage the error).

> The only real question that I had is if anyone can see ways to
> improve this process. 

As above.  For what you're doing (runtime checks only with no
storage collision requirements) a refernece count etc seems cheaper
and simpler.

> On the technical side, I need a way of grabbing the time() in an
> extremely precise manner...

The syscall required tends to vary by OS: setitimer()/getitimer()
are typical.

--
J C Lawrence                                 Home: claw at kanga.nu
----------(*)                              Other: coder at kanga.nu
--=| A man is as sane as he is dangerous to his environment |=--


_______________________________________________
MUD-Dev maillist  -  MUD-Dev at kanga.nu
http://www.kanga.nu/lists/listinfo/mud-dev



More information about the mud-dev-archive mailing list