The best way of extending BigWorld is to take advantage of its extension loading mechanism. When a CellApp, BaseApp or ServiceApp component of the system is loaded, it checks for executable objects in its extensions directory, and dynamically loads each one separately, in alphabetical order.
The extensions directory is located in the same folder as the component executable, and is named after it, with the -extensions suffix.
For example, the CellApp's extensions directory is
cellapp-extensions
, and is normally located under
folder bigworld/bin/$MF_CONFIG.
We recommend making serviceapp-extensions
a
symbolic link to the baseapp-extensions
directory, so
that both BaseApps and ServiceApps load the same extensions. These
directories should only be different if you want the two components to load
different extensions.
The file bigworld/src/build/common.mak
contains
Makefile rules to ease the compilation of server extensions, and it is
recommended that you make use of it.
The format of a Makefile for an extension is described below (italics indicate placeholders):
SO =extension_name
COMPONENT =component_name
SRCS =source files
include $(MF_ROOT)/bigworld/src/build/common.mak all::
The list below describes the Makefile entries:
-
SO
Name chosen for the extension.
-
COMPONENT
Name of the BigWorld component to extend (CellApp, BaseApp or ServiceApp).
-
SRCS
List of sources files to compile, separated by white spaces (excluding the suffix '.cpp').
There is no blueprint for what an extension must do, and there is no API that is called by the host component. In general, any functionality that does not damage the operation of the host component may be compiled into an extension, including launching threads, and sending network messages. However, extensions must take great care not to block the main thread of the component while running in the game.
Since an extension is a dynamic library, it does not have any standard
entry point such as main
(). Usually, an extension must
have static initialisers that call back into its host component to hook in
somewhere, or else the extension will have no way of being executed. Most
BigWorld systems have macros that create such static initialisers
automatically, such as IMPLEMENT_CHUNK_ITEM for a chunk
item type.
The BigWorld infrastructure is modular, and there are many ways to hook into it without changing the underlying code (which is fixed in the component binary).
Some examples of places to hook in are:
-
New chunk item types.
-
New ResMgr file systems.
-
Entity extras.
-
Controllers.
-
Loading thread jobs.
-
Network packet filters.
-
Game tick (and higher resolution) timer queues.
-
New Python functions or object types.
-
New basic entity data types.
These are all ideal candidates for compiling into extensions.
The following sections describe some of the most useful and sophisticated extensions.