tmi2_fluffos_v2/
tmi2_fluffos_v2/bin/
tmi2_fluffos_v2/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/ChangeLog.old/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/Win32/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/simuls/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/clone/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/command/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/data/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/master/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/log/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/compiler/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/efuns/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/operators/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/u/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/tmp/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/windows/
tmi2_fluffos_v2/lib/
tmi2_fluffos_v2/lib/adm/
tmi2_fluffos_v2/lib/adm/daemons/languages/
tmi2_fluffos_v2/lib/adm/daemons/network/I3/
tmi2_fluffos_v2/lib/adm/daemons/virtual/
tmi2_fluffos_v2/lib/adm/daemons/virtual/template/
tmi2_fluffos_v2/lib/adm/news/
tmi2_fluffos_v2/lib/adm/obj/
tmi2_fluffos_v2/lib/adm/obj/master/
tmi2_fluffos_v2/lib/adm/priv/
tmi2_fluffos_v2/lib/adm/shell/
tmi2_fluffos_v2/lib/adm/tmp/
tmi2_fluffos_v2/lib/cmds/
tmi2_fluffos_v2/lib/d/
tmi2_fluffos_v2/lib/d/Conf/
tmi2_fluffos_v2/lib/d/Conf/adm/
tmi2_fluffos_v2/lib/d/Conf/boards/
tmi2_fluffos_v2/lib/d/Conf/cmds/
tmi2_fluffos_v2/lib/d/Conf/data/
tmi2_fluffos_v2/lib/d/Conf/logs/
tmi2_fluffos_v2/lib/d/Conf/obj/
tmi2_fluffos_v2/lib/d/Conf/text/help/
tmi2_fluffos_v2/lib/d/Fooland/adm/
tmi2_fluffos_v2/lib/d/Fooland/data/
tmi2_fluffos_v2/lib/d/Fooland/data/attic/
tmi2_fluffos_v2/lib/d/Fooland/items/
tmi2_fluffos_v2/lib/d/TMI/
tmi2_fluffos_v2/lib/d/TMI/adm/
tmi2_fluffos_v2/lib/d/TMI/boards/
tmi2_fluffos_v2/lib/d/TMI/data/
tmi2_fluffos_v2/lib/d/TMI/rooms/
tmi2_fluffos_v2/lib/d/grid/
tmi2_fluffos_v2/lib/d/grid/adm/
tmi2_fluffos_v2/lib/d/grid/data/
tmi2_fluffos_v2/lib/d/std/
tmi2_fluffos_v2/lib/d/std/adm/
tmi2_fluffos_v2/lib/data/adm/
tmi2_fluffos_v2/lib/data/adm/daemons/
tmi2_fluffos_v2/lib/data/adm/daemons/doc_d/
tmi2_fluffos_v2/lib/data/adm/daemons/emoted/
tmi2_fluffos_v2/lib/data/adm/daemons/network/http/
tmi2_fluffos_v2/lib/data/adm/daemons/network/services/mail_q/
tmi2_fluffos_v2/lib/data/adm/daemons/network/smtp/
tmi2_fluffos_v2/lib/data/adm/daemons/news/archives/
tmi2_fluffos_v2/lib/data/attic/connection/
tmi2_fluffos_v2/lib/data/attic/user/
tmi2_fluffos_v2/lib/data/std/connection/b/
tmi2_fluffos_v2/lib/data/std/connection/l/
tmi2_fluffos_v2/lib/data/std/user/a/
tmi2_fluffos_v2/lib/data/std/user/b/
tmi2_fluffos_v2/lib/data/std/user/d/
tmi2_fluffos_v2/lib/data/std/user/f/
tmi2_fluffos_v2/lib/data/std/user/l/
tmi2_fluffos_v2/lib/data/std/user/x/
tmi2_fluffos_v2/lib/data/u/d/dm/working/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/smtp/
tmi2_fluffos_v2/lib/doc/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/interactive/
tmi2_fluffos_v2/lib/doc/driverdoc/concepts/
tmi2_fluffos_v2/lib/doc/driverdoc/driver/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/arrays/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/buffers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/compile/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/ed/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/filesystem/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/floats/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/functions/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/general/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/mappings/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/numbers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/parsing/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/constructs/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/preprocessor/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/types/
tmi2_fluffos_v2/lib/doc/driverdoc/platforms/
tmi2_fluffos_v2/lib/doc/mudlib/
tmi2_fluffos_v2/lib/ftp/
tmi2_fluffos_v2/lib/include/driver/
tmi2_fluffos_v2/lib/log/
tmi2_fluffos_v2/lib/log/driver/
tmi2_fluffos_v2/lib/obj/net/
tmi2_fluffos_v2/lib/obj/shells/
tmi2_fluffos_v2/lib/obj/tools/
tmi2_fluffos_v2/lib/std/adt/
tmi2_fluffos_v2/lib/std/board/
tmi2_fluffos_v2/lib/std/body/
tmi2_fluffos_v2/lib/std/fun/
tmi2_fluffos_v2/lib/std/living/
tmi2_fluffos_v2/lib/std/object/
tmi2_fluffos_v2/lib/std/shop/
tmi2_fluffos_v2/lib/std/socket/
tmi2_fluffos_v2/lib/std/user/
tmi2_fluffos_v2/lib/std/virtual/
tmi2_fluffos_v2/lib/student/
tmi2_fluffos_v2/lib/student/kalypso/
tmi2_fluffos_v2/lib/student/kalypso/armor/
tmi2_fluffos_v2/lib/student/kalypso/rooms/
tmi2_fluffos_v2/lib/student/kalypso/weapons/
tmi2_fluffos_v2/lib/u/l/leto/
tmi2_fluffos_v2/lib/u/l/leto/cmds/
tmi2_fluffos_v2/lib/www/errors/
tmi2_fluffos_v2/lib/www/gateways/
tmi2_fluffos_v2/lib/www/images/
tmi2_fluffos_v2/old/
tmi2_fluffos_v2/win32/
  The MudOS driver comes with the ability to create and use virtual objects.
A virtual object is one that was NOT created from an existing file: thus,
it doesn't take up any disk space. They're ideal for making a large number
of similar but not identical objects: historically they've usually been
used to make rooms, creating large areas without wasting a lot of disk space.
However, they are applicable to any situation where you need a lot of
similar but not identical items which can be customized based on a single
string argument (which can be sscanfed into multiple arguments if needed.)
   Virtual objects get created in the following way. Whenever the driver
tries to load a file that doesn't exist, it calls compile_object() in the
master object, passing the name of the nonexistant file as an argument.
This function can return an object to the driver, or it can return 0,
in which case the driver will report that the file cannot be loaded.
If the function returns an object, then that object is handed back to
the driver and treated as if it had been loaded from the file name. The
virtual object can be customized based on the file name that was loaded,
so that virtual objects need not be exactly alike, and can have as much
variation as you can code base on a string argument.
   Exactly where that object comes from depends on the mudlib. You can alter
the code of your mudlib to do different things. In the TMI-2 mudlib, the
master object calls compile_object() in the virtual object daemon, which is
the file /adm/daemons/virtual_d.c, passing the name of the file as an argument.
This file passes control to a virtual object handler. The virtual object
handler will parse the file name and determine which base object should
be cloned to supply a virtual object. Which of the various virtual object
handlers gets called depends on the file name supplied. If the file name is
of the form /u/x/xyzzy/*, then it tries to pass control to the handler
/u/x/xyzzy/virtual/server.c. If the file name is of the form /d/Foo/*,
then it tries to pass control to /d/Foo/virtual/server.c. If the file
name is not of these forms, or if the requested handler doesn't exist,
then control is instead passed to /adm/daemons/virtual/server.c. By
altering /adm/daemons/virtual_d.c, you can direct control to other
places, if you would want to do that.
   The virtual object handler parses the file name, and decides what object
should be cloned in response to the attempted load. You can code your own
handlers, or you can use the default server. If you use the default server,
then things go like this. First, the server attemps to parse the name
of the file in the following form: args.tmp.c, where both args and tmp
are strings (seperated by a .). For example, if the cloned file was
/u/m/mobydick/3,3.ocean.c, then args would be "3,3" and tmp would be
"ocean". Next, the handler looks for a base object to clone, based onthe
file name requested and the tmp string. If the original file name was of
the form /u/x/xyzzy/*, then it looks for a file called <tmp>_server.c,
in the directory /u/x/xyzzy/virtual. In the above example, the handler
would look for an object called /u/m/mobydick/virtual/ocean_server.c.
If the file name is of the form /d/Foo/*, then it looks for the file
<tmp>_server.c in the directory /d/Foo/virtual. If neither of these
servers exists or the file name is not of those forms, then it tries
to find /adm/daemons/virtual/<tmp>_server.c. If it can't find that, or
if the parse attempt fails, then it returns 0, and the driver reports
that the original object doesn't exist.
If, however, the object server is found, then the handler calls the
function compile_object() in the server, passing args as an argument
to that function. All virtual object servers should #include the file
/std/virtual/compile.c which defines this function. It creates a clone of
itself using the clone_object() efun, and calls the initialize() function
in the new object, passing <args> as an argument. This information is
used by the initialize() function to customize the new object before
giving it to the driver. For example, in the grid_server file which comes
with the mudlib, <args> is equal to the room's coordinates on the grid,
eg. "3,3" from the file "3,3.grid.c". The grid server uses sscanf() to
break the string apart into two integers, and supplies terrain and exits
to the room based on those two coordinates.
  By writing your own virtual object servers and handlers, you can do
much more than this with the virtual object facility. First, you can
start with a different base object: the existing servers are all rooms
but you can do other things as well. For example, you could start with
a weapon as the base object: then, you can treat the argument as the
specific weapon type and customized the weapon based on whether the
requested file was "sword.weapon.c", "pole-arm.weapon.c", or whatever.
You can write the initialize function yourself to do the customization
in whateever way you like.
  If you want to, you can also rewrite the object handler to pass different
arguments. For example, you can rewrite the handler to pass the entire
file name to the object server, instead of parsing it and only passing the
arguments. You can then call restore_file() to restore an object's data
from the supplied file name. This has been used to create a room system
where instead of each room being coded, they only exist as save files, and
the virtual object system is used to restore the appropriate save file
to the default room.