From: dlrozend@cs.vu.nl (Rozendaal DL)
Subject: Re: The horrors of native mode (Was: Re: Gamedriver survey [LONG])
Organization: Fac. Wiskunde & Informatica, VU, Amsterdam
Date: Fri, 16 Oct 1992 12:10:46 GMT

behrends@arctecws-12.dfki.uni-kl.de (Karl Reimer Behrends) writes:

[lots of stuff deleted...]

>First, reset(arg) vs. create()/reset() without arguments.
>As may be noticed, there are inherently three parts to reset(arg), one
>consisting of the commands executed when arg == 0, one of the commands
>executed when arg == 1 and one consisting of the commands executed independent
>of whether arg == 0 or arg == 1. create() covers the first of them, i.e.
>arg == 0. This so far is logical since this is by far the part used most
>by objects. However, there is no special routine to cover the last case
>(the part independent of the value of arg), but it is the second most used
>part, e.g. for cloning monsters in a room or similar things. This leads to
>unnecessary duplication of code in the case of native mode. And reset() in
>native mode is rarely ever used except for simulating the old behaviour
>of reset(arg). Thus we may conclude that although create() may be nice,
>the new reset() is a total failure and a considerable drawback. And we
>don't actually need create() if we already have reset(arg) - but this is
>a matter of taste. The necessity to duplicate code however, is not a matter
>of taste. Consider, for example, cloning a treasure within a room: You will
>have to do it in create() AND in reset(). This is not only an inconvenience
>when coding but also when debugging code as you'll have to check BOTH cases.

Instead of duplicating code, why not just call reset() from create() ?
The only problem with that is the case where arg == 1. As far as I know,
no one uses that one. Even that problem can be solved by using an extra
function that does all the cloning/etc.. and then call that function from
both create() and reset().
Personally I do not mind much about what scheme. create()/reset() seems
a little clearer to me though.

>Second, concerning lfun move().
>Instead of getting right down to the problems associated with move() I
>will first sketch two possible clean solutions how the idea of getting
>more control over object movement may be implemented.
>a) Consider move_object() as some kind of low level instruction. We may
>   now add a layer of abstraction and additional security against careless
>   weight manipulation and similar problems by creating a simul_efun
>   move_object() which in turn calls efun::move_object() to perform the
>   actual move. This can easily be implemented in compat mode, btw.
>b) We can implement all the environment/inventory/move stuff in the object
>   that is moved on mudlib level instead in the gamedriver. Thus each
>   object would have as variables one denoting its environment and an
>   array holding its contents. Moving object A from B to C would then
>   involve removing it from the inventory list in B, adding it to the
>   inventory list in C and updating the environment variable. Thus
>   weight and light updates (for example) could easily be done alongside
>   the actual move, which makes it easy to keep them consistent.
>   This could be done in nomask functions in a class which MUST be inherited
>   by any object, thus forestalling manipulation.
>Now we have the native mode implementation, having move_object() with
>only one or a fixed first parameter, allowing only to move this_object().
>Other objects have to call move() in the object to be moved. Although this
>looks a lot like b) at first sight, it is more of a hybrid implementation,
>taking ideas from both a) and b). This has the following disadvantages:
>While for objects other than this_object() we've got an additional abtraction
>layer as in a), there is no such restriction for this_object(). Programmers
>may feel encouraged to use move_object() instead of move() because it seems
>perfectly legal, whereas in a) the use of efun:: makes clear that this is
>a sort of hack (which may even be disabled with a little gamedriver patch).
>Then, there's the problem that if consider the example from b) again,
>objects B and C are completely at the mercy of A. That is, if A accidentally
>or intentionally forgets to notify B and C about the changes we're left
>with the same problems as in old 2.4.5 mudlibs. We don't have the same neat
>parallelism of moves and updates as in b) - I may confess I think the native
>mode solution looks kludgy at best. Even a) is cleaner in spite (or perhaps
>because of?) its simplicity.

Personally I like the native mode scheme. Scheme b) can also be implemented,
as long as you make sure an object can't just disappear, without updating
B and C. But that might be too slow, all coded in LPC. I agree that for
the native mode scheme, move_object should only be allowed to be used from
the move() lfun. And yes, this all can be coded using a simul_efun
(altough ob->move(dest) looks nicer to me than move_object(ob, dest) ;)

>[stuff about uids deleted...]

No real opinion. Uids can be both very handy or a curse. Maybe I would
really like them if I fully understood them :-)

>These are my reasons to consider native mode a drawback. Of course, none
>of them will render the gamedriver useless, but I consider them design flaws.
>And since the intention of native mode was to get rid of design flaws, I
>question whether this goal has been achieved.

I think native mode is basically better than compat mode, not much though.
Much depends on the mudlib, not on the driver. And as far as I am concerned,
2.4.5 is simple and easy, but a big kludge. The CD mudlib is complex, and
sometimes hard to understand. Anyone volunteered to write a simple, consistent
3.1.2 native or compat mode mudlib (from scratch...) ? :-)

>Well, Johan Anderson asserted in a recent article that most experienced
>LPmud wizards disagreed with me. I'd be interested if besides opinions they
>have also reasons - reasons that invalidate my arguments.

>					Reimer Behrends

Erik Rozendaal <dlrozend@cs.vu.nl>
Newsgroups: rec.games.mud.lp