A discussion about the status() DGD call and object issue numbers turned into a discussion about recompiling a game on the fly and persistent MUDs. As background, make sure you know the basics of DGD inheritance and on-the-fly upgrades:
http://phantasmal.sf.net/DGD/Kernel/Inheritance.html
Here's some discussion from that thread:
RobertForshaw? wrote:
I'm wondering how useful having a persistant MUD is. I think of it as a
luxury, since most MUDS don't have 100% persistance. I also think of it as a
luxury to be able to clone and inherit from an object. One situation might
be to have a collection of standardized objects which you can clone or
inherit. For instance, you might want to load your orc in your room like
this:
create()
{
object m;
m = clone_object("/obj/orc");
m -> set_name("my customized orc");
....etc.
}
But on the otherhand, you might want to do a seperate file for your
customized orc:
inherit "/obj/orc";
create()
{
set_name("my customized orc");
....etc.
}
Isn't that also a luxury?
I have to admit, I've not had experience with running a MUD before, only a
stint as a wizard on another MUD, and I don't have the foresight to see how
useful 100% persistance can be. It can't hurt to reboot once every few
weeks, can it? Anyone have advice?
NoahGibbs replied:
Robert Forshaw wrote:
I'm wondering how useful having a persistant MUD is. I think of it as a luxury, since most MUDS don't have 100% persistance.
Very true. It's a very
useful luxury, but a
luxury. Kind of like a washing machine and dryer
I also think of it as a luxury to be able to clone and inherit from an object.
I assume you mean from the same object. That is, I
assume you're referring to that thing that you can't
do in the Kernel Library.
One situation might be to have a collection of standardized objects which you can clone or inherit. [... orc example ...] Isn't that also a luxury?
Yes it is. That one you can do with or without the
Kernel Library. Phantasmal allows something like it,
though it's not standard.
It can't hurt to reboot once every few weeks, can it? Anyone have advice?
Nope, doesn't hurt to reboot every few weeks.
Does hurt to reboot every time you need to make a
bug fix or minor code change. That's the big deal --
if you do the full-persistence thing, you can change
the code in place. And that makes releasing the code
far less painful since you don't need to be 100% sure
that it will work for weeks before you deploy.
It's actually really useful to have a bunch of
friends log into your MUD and debug *as they do
things*. In a normal MUD you rarely do this because
every time you fix a bug, they need to all log out
while you restart the server. In a DGD MUD you can
recompile the server from the command line (Phantasmal
has a "%full_rebuild" command which lets you do this),
incorporating (and testing!) the bug fix instantly.
It's a fine debugging technique, especially if
you're doing things that require several people to
test. Saves you typing and headache, and keeps your
testers from getting mad at you after the third
reboot.
Not that that's the
only use of full persistence,
but it's one of my favorites.
Par Winzell chimed in:
I'm wondering how useful having a persistant MUD is. I think of it as a
luxury, since most MUDS don't have 100% persistance. I also think of it
as a luxury to be able to clone and inherit from an object.
It's almost impossible to convey the experience of running a truly
persistent Mud to somebody who has never done it. So many assumptions
disappear. The way objects are created, areas designed, everything changes.
In traditional LPMud, virtually everything is an initialization script,
like the create() function in your example. Half the code in a wizard's
directory is startup code. In a persistent world, rather than write a
lot of startup code, you tend to write behaviour code, and configure
objects.
Most code in a traditional LPMud isn't real code, it's just a cumbersome
configuration (set_this and set_that) technique. That pretty much goes
away in a persistent game.
The cumulative effect is that if you design your mudlib to be fully
persistent from scratch, you will find yourself making subtly different
decisions on pretty much every single design question that comes up, and
you end up with something drastically different than LPMud.
ChristopherAllen? and
ErwinHarte contributed:
On Wed, Jan 07, 2004 at 10:35:13PM -0800, Christopher Allen wrote:
Par Winzell wrote:
[...Persistent games...]
It might be more specific or useful to give him a Skotos
example. How long has Marrach been running persistently?
The statedump that we're using was started in May '99, the current
virtual uptime is over 1600 days.
Erwin
RobertForshaw? responded:
From: Par Winzell
It's almost impossible to convey the experience of running a truly
persistent Mud to somebody who has never done it. So many assumptions
disappear. The way objects are created, areas designed, everything changes.
Specifically what changes?
In traditional LPMud, virtually everything is an initialization script,
like the create() function in your example. Half the code in a wizard's
directory is startup code. In a persistent world, rather than write a lot
of startup code, you tend to write behaviour code, and configure objects.
I don't appreciate what you're saying (you did say it would be difficult :),
as I understand it setting attributes to an object is part of configuring
its behaviour? What exactly do you mean by 'behaviour code' ?
Most code in a traditional LPMud isn't real code, it's just a cumbersome configuration (set_this and set_that) technique. That pretty much goes away in a persistent game.
How so? You still need to set attributes on an object, do you not?
How does persistance change this?
The cumulative effect is that if you design your mudlib to be fully persistent from scratch, you will find yourself making subtly different decisions on pretty much every single design question that comes up, and you end up with something drastically different than LPMud.
That much I understood, but I'm not sure what you are refering
to specifically...
NoahGibbs said:
Robert Forshaw wrote:
The way objects are created, areas designed, everything changes.
Specifically what changes?
I'll note that I'm not running a truly persistent
MUD. Phantasmal's sort of an amphibian -- keeps all
the machinery for full persistence, but also keeps an
object load/save mechanism for everything as well.
That keeps me from having to write all the upgrade
code, but means I still have a lot of configuration
code left.
I get a little insight into these things as well,
though not like Skotos.
As for how areas are designed, imagine a world with
no zone resets. Stuff doesn't pop back into place a
few moments after you kill it or steal it. You might
say "that seems stupid. How would you get more
opponents and money?" But if you think it through,
you wind up with something subtly more like the real
world. It's a nice change, or so I believe. That
changes area design completely. It also makes an
economy possible, since it allows for the possibility
of scarcity. Zone resets are the #1 source of runaway
inflation since new "valuables" come into the economy
constantly, thus destroying any actual value they may
otherwise have had.
Anyway, MUD-Dev has addressed these questions, and
I'm not going to be able to do better in one message.
Go read about it there
as I understand it setting attributes to an object is part of configuring its behaviour? What exactly do you mean by 'behaviour code' ?
Imagine that you created an object once, and it
stayed. But imagine you didn't create it as a regular
occurrence. You'd never write any initialization code
for it, not once it had its attributes (which could be
done in some other way, as Skotos does, or with a data
file, as Phantasmal does).
There's no reset, no respawn, no destruction and
remaking. It's just, y'know, there. So you don't
write code for routine destruction, nor code for
initialization. You just set some attributes (some of
which may involve code, naturally) and away it goes.
State dumps allow you to bring everything back to
the way it was pre-reboot, and to do so without
writing a single line of save/load code. So you can
get by without init code, without object destructors
(well, sort of). No load/save. It saves a lot of
code. I know it's a lot -- Phantasmal
has all that
code
In return, when you change object code, you have to
write a little piece of code to update the existing
object(s). That can be nontrivial, sadly. But it
runs to turn the old object into the new object, not
to make the new object from scratch.
Most code in a traditional LPMud isn't real code, it's just a cumbersome configuration (set_this and set_that) technique.
That pretty much goes away in a persistent game.
How so? You still need to set attributes on an object, do you not?
How does persistance change this?
For one thing, you can make the object and shape it.
You can change the attributes dynamically and they
stay. Kind of like how you don't need to extrude a
sculpture whole, but can start with a lump of clay.
So you never have to write the initialization code,
but you
do have to set data somehow.
RobertForshaw? said:
From: Noah Gibbs
As for how areas are designed, imagine a world with
no zone resets. Stuff doesn't pop back into place a
few moments after you kill it or steal it. You might
say "that seems stupid. How would you get more
opponents and money?" But if you think it through,
you wind up with something subtly more like the real
world. It's a nice change, or so I believe.
I'm not quite sure what this has to do with persistance. It seems to me that
resets and respawning are a design consideration, and can exist regardless
of whether the MUD gets rebooted or not...
That changes area design completely. It also makes an economy possible, since it allows for the possibility of scarcity. Zone resets are the #1 source of runaway inflation since new "valuables" come into the economy constantly, thus destroying any actual value they may otherwise have had.
What you are describing is the theory of game balance. What does this have
to do with persistance? It can still be achieved with a non-persistant MUD
can it not?
Imagine that you created an object once, and it stayed. But imagine you didn't create it as a regular occurrence. You'd never write any initialization code for it, not once it had its attributes (which could be done in some other way, as Skotos does, or with a data file, as Phantasmal does).
There's no reset, no respawn, no destruction and remaking. It's just, y'know, there.
This sounds drastically different from the conventions I've grown accustomed
to. What's the point of storing configuration in a datafile? Setting
attributes isn't difficult and having a datafile just makes it harder to
alter the possible attributes an object may have.
So you don't write code for routine destruction, nor code for initialization. You just set some attributes (some of which may involve code, naturally) and away it goes.
Hmm. I thought that was how it was always done?
scratches head
State dumps allow you to bring everything back to the way it was pre-reboot, and to do so without writing a single line of save/load code. So you can get by without init code, without object destructors (well, sort of). No load/save. It saves a lot of code. I know it's a lot -- Phantasmal has all that code
It sounds like you could get away with just doing state dumps, but that does
cause lag, no? I'm thinking of preserving user configuration, etc. with
savefiles in case there is a crash (you never know what might happen).
In return, when you change object code, you have to write a little piece of code to update the existing object(s). That can be nontrivial, sadly. But it runs to turn the old object into the new object, not to make the new object from scratch.
Do you mean writing the code to update objects is non-trivial? I thought it
was all there in the kernel lib?

I never have thought that writing an
object manager will be hard.
For one thing, you can make the object and shape it. You can change the attributes dynamically and they stay.
They stay on a non-persistant MUD also though, except when there is a
reboot...
NoahGibbs replied:
Robert Forshaw wrote:
From: Noah Gibbs
As for how areas are designed, imagine a world with no zone resets. Stuff doesn't pop back into place a few moments after you kill it or steal it.
You might say "that seems stupid. How would you get more opponents and money?" But if you think it through, you wind up with something subtly more like the real world. It's a nice change, or so I believe.
I'm not quite sure what this has to do with
persistance. It seems to me that
resets and respawning are a design consideration,
and can exist regardless
of whether the MUD gets rebooted or not...
Yes. Perhaps this wasn't what Erwin (I think?) was
talking about, though it's what you usually hear
called a "persistent MUD".
[...] It also makes an economy possible, [...]
What you are describing is the theory of game balance.
Well, sort of. Not that I've heard any real theory on that topic put forward
What does this have
to do with persistance? It can still be achieved
with a non-persistant MUD can it not?
This is a consequence of the deal with zone resets.
It can't be done with zone resets, no. At least, not
without an exponentially-expanding player base or
serious money drains. One isn't practical for most
MUDs, and the other is so unpopular with the players
that essentially nobody does it.
Imagine that you created an object once, and it stayed. But imagine you didn't create it as a regular occurrence. You'd never write any initialization code for it, not once it had its attributes (which could be done in some other way, as Skotos does, or with a data file, as Phantasmal does).
There's no reset, no respawn, no destruction and remaking. It's just, y'know, there.
This sounds drastically different from the conventions I've grown accustomed to. What's the point of storing configuration in a datafile?
There isn't. You'd never
write to the datafile. You'd just read from it, once, to make the object.
Setting attributes isn't difficult and having a datafile just makes it harder to alter the possible attributes an object may have.
I think you're giving datafiles too little credit,
but that's neither here nor there. Here's something
that Skotos seems to consider a feature (and I
certainly do), though you may not: you can make
objects entirely without having to write code. While
that approach doesn't scale to really complicated
objects, it's a good way to make 95% of the objects in
a given MUD.
For the other 5%, you can either write code your way
or write little scripts that attach to the objects.
At that point it's kind of an academic distinction.
However, the first approach works much better for
the other 95% of objects. Plus you can alter the
objects more easily after creation since your changes
stick, and you don't have to make changes to the code.
Doing the equivalent of '%set_obj_weight "sword" "9
lbs"' is really hard when the sword object is a .c
file and you'd have to rewrite the code to change that
So you don't write code for routine destruction, nor code for initialization. You just set some attributes (some of which may involve code, naturally) and away it goes.
Hmm. I thought that was how it was always done? scratches head
Here's the different bit -- you don't have to set
the attributes in a way that's reproducible. Your way
involves writing code that knows how to set
attributes. Our way involves setting the attributes
in any way
once, then never worrying about it again.
Not even to save or restore it.
State dumps [...] save a lot of code. I know it's a lot -- Phantasmal has all that code
It sounds like you could get away with just doing
state dumps, but that does
cause lag, no?
Not a lot, no. Skotos does it this way. For that
matter, so does
EverQuest? if memory serves. Everquest
doesn't use DGD statedumps, but their periodic backups
are just as large and just as laggy.
Also, you never have to statedump until shutdown, so
actually, it
never has to cause any lag.
I'm thinking of preserving user
configuration, etc. with
savefiles in case there is a crash (you never know
what might happen).
Yup. Statedumps would give you that for free.
Like, you'd have to write only about ten lines of
code, and
no code specific to particular kinds of
objects, ever.
In return, when you change object code, you have to write a little piece of code to update the existing object(s). That can be nontrivial, sadly. But it runs to turn the old object into the new object, not to make the new object from scratch.
Do you mean writing the code to update objects is non-trivial?
Yes. When you change the definition of an object to
have new data fields, you have to put something in the
new data fields. When you change how things get
stored, you massage the data into the new forms. For
instance, I might change my objects to stop storing a
"brief description" string and instead store offsets
into my arrays of nouns and adjectives to make a
description. So if you see a "broad green tabard"
then you're guaranteed you can "look broad green
tabard" since it uses nouns and adjectives in the
object.
However, when I take add the new data field (let's
say an array of integer offsets, so it'll be an int
pointer), I'll need to fill in decent values. I could
make it default to saying the first two adjectives,
then the first noun. So I'd set the array to [0, 1,
0], where the last element is the offset into the
array of nouns.
So far, so good. But where do I put the code to
fill in all those fields? One answer is "in the
ObjectD?". My favorite answer is to have the
ObjectD?
call a function called "upgraded" if it exists on
every object that gets upgraded. That's what
Phantasmal does.
So I could put that code I mentioned above into the
upgraded() function of my object type, then type
"%full_recompile" at the command line, and my objects
would all start being described as "big brown table"
and "flat checkered floor" and things, all according
to the first nouns and adjectives on their current
lists. Then I'd go fix all the descs, 'cause that
would look funny
But I've had to write specific upgrade code for the
specific change I made to my objects. In a standard
MUD, I'd make the change to the object loading code,
then shutdown the MUD and restart it. Then all my
objects would be appropriately altered, but I'd also
have to drop everybody's network connection to do it,
and generally disrupt things. Not nearly as
convenient. Plus, it's slow to do all that loading
and saving of LPC objects using LPC code. Much faster
to use a statedump.
I thought it was all there in the kernel lib?
Not the stuff specific to the change you just made
to an object type, no.
I never have thought that writing an object manager will be hard.
Look at the existing ones before you decide that. Please. There are some subtleties you're not considering. Seriously.
For one thing, you can make the object and shape it.
You can change the attributes dynamically and they stay.
They stay on a non-persistant MUD also though, except when there is a reboot...
Yes. Do you want all those objects to go away every
time you add a bugfix? You suggested "every few
weeks". Even on that timeframe, that's noticeable
disruption. You're right, not doing it is a luxury.
But why turn away that luxury?
Also, bear in mind that altering objects in these
ways is actually a good way for builders to do stuff.
That's harder if it all goes away every couple of
weeks
Par Winzell returned with:
changes area design completely. It also makes an economy possible, since it allows for the possibility of scarcity. Zone resets are the #1 source of runaway inflation since new "valuables" come into the economy constantly, thus destroying any actual value they may otherwise have had.
What you are describing is the theory of game balance. What does this have to do with persistance? It can still be achieved with a non-persistant MUD can it not?
Anything can be achieved with anything else. DGD's style of persistence
just means that things naturally stay around forever. Old style MUDs
reboot so often that everything tends to be built around it.
Modern MMORPGs are a good example of hybrids; most of the world state is
transient and disappears, but select things are stored in a database. Of
course, even LPMud does this to some degree with player.o files and
whatever. Everything has -some- persistence. The word can mean almost
anything.
Imagine that you created an object once, and it stayed. But imagine you didn't create it as a regular occurrence. You'd never write any initialization code for it, not once it had its attributes (which could be done in some other way, as Skotos does, or with a data file, as Phantasmal does).
There's no reset, no respawn, no destruction and remaking. It's just, y'know, there.
This sounds drastically different from the conventions I've grown
accustomed to. What's the point of storing configuration in a datafile?
Setting attributes isn't difficult and having a datafile just makes it
harder to alter the possible attributes an object may have.
I can't help but feel that you're spending your effort arguing the
precision of these descriptions rather than trying to harvest the fruit
of the experience behind them.
In LPMud, if you create a room, you create a hallway.c file that, when
compiled, sets the description and such of the room. In a persistent
game, you clone a room object, configure it during runtime (e.g. using
some kind of editor, or by calling set_description, or whatever). And
then it is always there, until eternity.
You're right, this is not a shocking "oh my GOD, you can do that with
persistence!?" thing, but you asked an open-ended question, and you must
be satisfied with vague answers.
So you don't write code for routine destruction, nor code for initialization. You just set some attributes (some of which may involve code, naturally) and away it goes.
Hmm. I thought that was how it was always done? scratches head
No. If the game reboots from no state, then there must be something that
recreates the state. This can be instructions in a datafile or an LPC
object or whatever.
It sounds like you could get away with just doing state dumps, but that
does cause lag, no? I'm thinking of preserving user configuration, etc.
with savefiles in case there is a crash (you never know what might happen).
I have no idea what this means.
In return, when you change object code, you have to write a little piece of code to update the existing object(s). That can be nontrivial, sadly. But it runs to turn the old object into the new object, not to make the new object from scratch.
Do you mean writing the code to update objects is non-trivial? I thought
it was all there in the kernel lib?
I never have thought that writing
an object manager will be hard.
Good, you'll have no trouble with it then. But Noah was probably talking
about the problem that when you never have a reboot, you never get to
start from scratch, and so every time you e.g. change the implementation
of a datastructure, you have to also write code that transforms the data
in the existing instances from the old form to the new.
For example, if you decide after 6 years of running the game that
inventories should be stored using mappings rather than inventories to
avoid certain laggy situations, you'd have to write a patch function in
your inventory code to mutate the array to the right mapping format and
then run that patch function in every one of the possibly millions of
objects that constitute your world at that point.
In LPMud, you'd just reboot.
For one thing, you can make the object and shape it. You can change the attributes dynamically and they stay.
They stay on a non-persistant MUD also though, except when there is a reboot...
Uh.
ErwinHarte chimed in:
On Thu, Jan 08, 2004 at 12:45:32AM +0000, Robert Forshaw wrote:
[...]
I'm not quite sure what this has to do with persistance. It seems to me
that resets and respawning are a design consideration, and can exist
regardless of whether the MUD gets rebooted or not...
Yes. But then you also need to design something that makes items
'wear', so that you don't, after a few months of running, have 200
swords of utter destruction or something along those lines.
In a persistent game uniqueness is important to avoid inflation, so
you don't want to clone the same things over and over and over, which
is what typically resets do.
On
IgorMUD? this was already an issue after over a month or so of
uptime, imagine a game that runs for years without a cold start?
[...]
That changes area design completely. It also makes an economy possible, since it allows for the possibility of scarcity. Zone resets are the #1 source of runaway inflation since new "valuables" come into the economy constantly, thus destroying any actual value they may otherwise have had.
What you are describing is the theory of game balance. What does this have
to do with persistance? It can still be achieved with a non-persistant MUD
can it not?
Yes. I don't think anyone is saying you have to write a persistent
game, but I think a lot of us are convinced it's one of the best ways
to make your game environment more appealing, more `real' if you wish.
[...]
State dumps allow you to bring everything back to the way it was pre-reboot, and to do so without writing a single line of save/load code. So you can get by without init code, without object destructors (well, sort of). No load/save. It saves a lot of code. I know it's a lot -- Phantasmal has all that code
It sounds like you could get away with just doing state dumps, but that
does cause lag, no? I'm thinking of preserving user configuration, etc.
with savefiles in case there is a crash (you never know what might happen).
If you work with a persistent game, you will keep previous a (few)
previous statedump(s) around and make those statedumps regularly. If
you crash because of some bug in DGD or something else going haywire,
you go back to the most recent statedump with which you can avoid that
problem, in most cases that'll be the most recent one. Thereby losing
only a few hours or so of 'state'.
[...]
Do you mean writing the code to update objects is non-trivial? I thought it
was all there in the kernel lib?
I never have thought that writing an
object manager will be hard.
The support is in the kernel-lib, and there is an example object-db
out there (I think) that shows you how you can track inheritance and
clone lists/counts.
For one thing, you can make the object and shape it. You can change the attributes dynamically and they stay.
They stay on a non-persistant MUD also though, except when there is a reboot...
Indeed. I remember the first time I walked into a room on the mud I
ran a couple of years ago and realized that it was quite possible that
the equipment I found 'on the floor' there could quite possibly have
been there for over a year (it wasn't a very busy mud). I quite liked
that idea and if I ever (hah!) write a game again, I'll definitely
make it persistent.
--
ErwinHarte - 21 Jan 2005
to top