CONCEPT
        driver modes / native driver mode

DESCRIPTION
        During the evolution of LPMud there has been a hiatus as the
        old driver became too restricting for the demands of modern
        muds: it did a lot of things the mudlib could do better or
        completely different. Removing these things from the driver
        weren't a problem, but to keep compatible with the existing
        mudlibs (namely the well-known 2.4.5 lib), it was possible to
        undo these changes. First by setting a runtime option, then
        by compiling the driver either in 'compat' or in 'native' mode.

        Starting with 3.2.1, the distinction between compat and native
        mode is more and more transferred into the mudlib, with the
        future goal of having a modeless driver.

        Starting with 3.2.7, native mode no longer exists as such,
        only 'plain' (quasi a superset of 'native' and 'compat')
        and 'compat' mode, and since 3.2.9 the mode selection can be
        made via commandline option.

        The main mode of the driver is determined at compile time
        by preprocessor symbols to be defined/undefined in config.h:

          COMPAT_MODE: when defined, the compat mode specifics are activated
                       by default.

        Additional modifications can be achieved by the specification
        of commandline arguments (most of them have a default setting
        entry in config.h as well):

          strict-euids: when active, euid usage is enforced.
          compat:       when active, the compat mode is used.

        Following is the description of the changes (de) activated by
        these defines. A shorthand notation is used: 'compat' means
        'if compat mode is active' and '!compat' means 'if
        compat mode is not active', etc.


        Predefined Preprocessor Symbols
          If compat, the symbols COMPAT_FLAG and __COMPAT_MODE__ are
          defined for all LPC programs.
          If strict-euids, the symbol __STRICT_EUIDS__ is defined
          for all LPC programs.
          For compatibility reasons, the symbol __EUIDS__ is defined
          for all LPC programs all the time.


        Preloading Of Objects
          The driver has the possibility to preload objects before the
          game is actually opened to the world. This is done by
          calling master->epilog(), which has to return 0 or an array.
          If its an array, its elements (as long as they are strings)
          are given one by one as argument to master->preload() which
          may now preload the objects (or do anything else).


        Initialisation Of Objects
          It is task of the mudlib (through the driver hooks) to call
          the initialisation lfuns in newly created objects. The
          following table shows the traditional calls:

                  mode        : init call : reset call
           --------------------------------------------
            !compat & !native :  create() :  reset(1)
            !compat &  native :  create() :  reset()
             compat & !native :  reset(0) :  reset(1)
             compat &  native :  reset(0) :  reset(1)

          If INITIALIZATION_BY___INIT was defined, the lfun __INIT()
          is called first on creation to initialize the objects
          variables.


        Movement Of Objects
          The efun move_object() is implemented in the mudlib through
          driver hooks and the set_environment() efun.
          move_object() itself exists just for convenience and
          compatibility.

          In original native mode, move_object() could applied only to
          this_object() as the object to move, and it called the lfun
          exit() in the old environment if in compat mode. As a side
          effect, the lfun exit() may not be target of add_action()s
          in compat mode.

          In compat mode, objects may be moved using the transfer()
          efun. It does make assumptions about the design of the
          mudlib, though, as it calls the lfuns query_weight(),
          can_put_and_get(), get(), prevent_insert() and add_weight().


        Efuns In General
          creator(), transfer()
            These exist only in compat mode (creator() is
            identical with getuid()).

          object_name(), function_exists()
            In !compat mode, the returned filenames start with a
            leading '/', in compat mode they don't.

          parse_command()
            This command exists in two versions: the old is used with
            compat, the new with !compat. However,
            SUPPLY_PARSE_COMMAND must be defined in config.h in both
            cases (this efun is not very useful at all).

          process_string()
            If this_object() doesn't exist, it defaults to this_player()
            and receives the backbone uid (returned by master->get_bb_uid())
            as euid. If strict-euids, this uid must not be 0.

        Userids and Effective Userids
          This is probably the most important difference between the
          modes.

          LPMud always had userids (uids) attributing the objects,
          though they were called 'creator names' in compat mode.
          Internally, the compat mode uses the 'creator names' as
          (e)uid.

          With the introduction of native/plain mode, additionally
          'effective userids' (euids) were introduced to improve
          security handling (which was only a partial success).
          The hardcoded handling of euids and uids was quite complex
          and too mudlib-insensitive, so most of it got moved from the
          driver into the mudlib with 3.2.1.

          In strict-euids mode, only objects with a non-zero euid may load
          or create new objects.

          --- In Detail ---

            Userids of the Master
              The master's (e)uid is determined by a call to
              master->get_master_uid().

              In strict-euids mode, the result has to be a string,
                otherwise the driver won't start up at all. If the result is
                valid it is set as the master's uid and euid.

              In !strict-euids mode, the result may be any value: 0 or a
                string are treated as the uid to set, a non-zero integer
                leads to the use of the uid set in the default 'global'
                wizlist entry, and any other value defaults to 0.
                The euid is either set to the returned string (if any),
                or to 0.

              The master's uid is determined only on startup this way;
              at runtime the uids of a reloaded master determined as
              for every object by a call to the appropriate driver
              hooks.

            Userids of New Objects
              To determine the (e)uids for a new object (loaded or
              inherited, or cloned), the appropriate driver hook is
              evaluated (H_LOAD_UIDS, H_CLONE_UIDS) and the result set
              as (e)uid. The result may be a single value, in which case the
              euid is set to 0, or an array ({ uid, euid }).

              In strict-euids mode, both uid and euid must be 0 or a string,
                any other value causes the load/clone to fail.

              In !strict-euids mode, the uid (however returned) may also be
                a non-zero integer to use the uid of the global
                wizlist entry as uid. The euid is then
                set to either 0 or the second entry of the returned
                array if it's a string.

          --- ---

SEE ALSO
        hooks(C), uids(C), move_object(E), initialisation(LPC)
