[Gtkradiant] Draft for implementing multiple game support V1.0

Hydra gtkradiant@zerowing.idsoftware.com
Thu, 27 Sep 2001 14:24:45 +0100

Version 1.0 - 2000-09-27

This document currently a draft for the basis of implementing multiple game
support into GTKRadiant 1.2.

 - Hydra (contact me via the gtkradiant mailing list or IRC)

First, before we get onto game configurations, there's a couple of things I
think we could do with in Radiant before we get into it, I'm not attaching
any kind of priorities to these ideas at the moment, obviously there are
alot of low priority things here, but as long as I show you guys what I'd
like to do, you'll go ahead and do your stuff and will know what I'm working



Currently, radiant uses VFS for loading maps, textures, shader scripts,
and shaderlist.txt (if it is used for anything other than that, let me know)

VFS lets us read files from the computers native filesystems as well as
reading files stored in compressed files


If I'm using Quake3 and I have a pk3 file with a map (.bsp) in it, and have
the same file in "maps/". Quake3 will use the files stored in pk3's first,
before it uses files that are not contained within pk3 files.
Even with /sv_pure 0

According to SPoG (not verified this) Quake 2 does the opposite, in that
it will use files outside PAK files before it uses files inside them.

What we want is a way to emulate the game engine's method of loading files
so that the files used by the editor are the same files that will be used
by the game engine itself.

We need to extend VFS system (or rather, the plugin system itself) so that
more than one VFS module can be loaded and extend the functions in
pluginmanager.cpp like QERApp_LoadFile() so they behave like
QERApp_LoadImage() (which uses CPlugInManager::LoadImage() to try
each image module loaded)

When this is done, we can move the code in vfspk3 that deals with loading
files via the OS into a new filesystem module called vfsstdio (or whatever)

Then, we can let the user change the order that the VFS systems are used so
that the editor emulates the way the engine works!

Now, in doing that we also open up the possibility of having other VFS
loaded at the same time, and the possibilities there are endless. (I'm not
saying all the possibilites will be useful, just that extra functionality
will then be possible.  you could for example have a VFSCVS module)

And, I'm not sure this would work yet, i need to check the code a bit
further, if VFS used itself to open files then you could open PK3 files
from inside PK3 files, or you could open PK3 files on a CVS server.
OMG! Now *that* would be cool.

Entity Modules

Instead of having the code for loading .DEF files in the core, we move it
into a seperate module and define an interface for such modules.

This gives us the ability to expand the editor so that it can read entity
information from other games and new games as they appear by just creating
a new plugin.

Build Modules

Instead of having the code for kicking off a BSP compile built into the
core we move it into a seperate module (kinda like the exisiting Q3Build
module that exists for 1.1).  We would also define an interface for these
special kind of plugins.

Thus, the code for BSP Monitoring would be moved into that.

This also gives us the opportunity to actually make Q3MAP itself into a

It also gives us greater flexibility than having the project file storing
the commands used to build the BSP file from the map file.

A universal module could do something like this:
make Radiant save the map to a file that the compiler tool understands
run pre-build commands
run build tools
run post-build commands

Game configuration files

Game configuration files will REPLACE .qe4 project files (and will
probably have an option to import one too).

The idea with a game config is to keep the list of things that Radiant
needs to know down to a minimum.  And if you think of a modularised system
this list quickly becomes quite small.

Game config also stores plugin configs in the same file, so if you are using
the BUILDALL plugin to compile maps for Q3, then configuration for Q3MAP.EXE
command lines would be in here (thus making stuff like "rshcmd" in the main
config irrelvevant).  Plugins should still be able to have their own GLOBAL
config files, preferably stored as something like plugins/<myplugin>.cfg.

The format for the game configuration files will be XML, the file extension
for them will be .xgc (XML Game Config) (unless anyone knows of a common
extension that conflicts with that idea)

They will be saved in a configs/ subdirectory of Radiant itself (so you
loose them when you add/remove games to and from your system)

Once we've decided on what information goes into a game configuration, I'll
draft up the XML game configuration config file format itself.

Items stored in game configuration file:
note: all paths and filenames in config are absolute, unless specified below
note: Should support for UNC paths on WIN32 should be allowed for some

Profile File Name
        The name of this game configuration profile

        I envisage that people will want more than one configuration
        profile for each game that Radiant supports, much like we have
        different project files at the moment.

        This gets round the problem of GTKRadiant creating lots
        of .qe4 files without the user knowing which one they're
        currently using.
        A comment for the profile

        This is for display only, and has NOTHING to do with
        anything else at all.

        String can be upto 100 chars or so long, so it can be
        reasonably descriptive.

        Possible uses:
        It could used when displaying a list of profiles to the user
        Displayed in the title bar after the map filename.

        Quake III Arena
        Quake III: Team Arena
        Quake III Arena test mod 1

Base path of game
        The path the user installed the game to.

Game Executable
        The executable file of the game itself. e.g. quake3.exe or

Base path(s) of game data
        Multiple paths for this allows support for a) common shared
        areas and b) cd-rom/network drives.

        Searched IN ORDER when looking for files.

        (e.g, basepath1, basepath2...)

        Paths seperated by ,'s or ;' in the view presented to the
        user, or as a list that they can add to/remove from.

Base path(s) of mod data
        For support of game mods, like missionpack or cstrike

        Multiple paths for this allows support for a) common shared
        areas and b) cd-rom/network drives.

        Searched IN ORDER when looking for files.

        MOD Dirs are searched for files BEFORE game data paths so that
        things like shader scripts / shaderlist.txt / textures are picked
        up from the MOD dir, rather than the game dir, thus allowing
        mod developers/mappers to use updated.

        (e.g, modpath1, modpath2, then basepath1, basepath2...)

        Paths seperated by ,'s or ;' in the view presented to the
        user, or as a list that they can add to/remove from.

Map Source Path
        The path that GTKRadiant loads and saves map source data to
        and from.

        Not necessarily used by the map compiler tools.

Prefab path
        The path that GTKRadiant loads and saves map prefabs to and

MAP Module(s)
        Plugin(s) that this game/mod uses for loading and saving map files.

        Needs to be a list of modules, and the one at the top of the
        list should be the primary module (which would be the default
        file/load, file/save)  file/export would let you use the
        other modules.

        We can't just load one MAP module, or we won't be able to
        import prefabs and or maps of other kinds or convert between them.

VFS Module(s)
        Module(s) that this game/mod uses for loading files (of any kind)
        from PK3/PAK/etc files.

        Needs to be a list of modules, files are located using the VFS
        module list in order (e.g. VFSSTDIO then VFSPK3 then VFSetc...)

Shader Module
        Module that this game/mod uses for loading files (of any kind)
        from PK3/PAK/etc files.

Image Module(s)
        Module(s) that this game/mod uses for loading image files.

        Needs to be a list of modules, no specific order as images
        are loaded on demand, there might be a performance increase
        if the order can be prioritized however.
        (e.g. looking for PCX files first when editing Q3 maps would
        not be a great idea)

        This list can also be empty, as an image module is NOT required
        to EDIT a map. (It sure won't look pretty though!)

        Having no image module loading should have the same effect as
        a brush that the texture cannot be found for.

Entity Module(s)
        Module(s) that this game/mod uses for loading entity defintion

        Needs to be a list of modules, no specific order as entity
        definitions are loaded at startup.  Though having said that
        letting the user change the order might be useful, but
        certainly not required.

        This list can also be empty, as an entity module is NOT required
        to EDIT a map.

Build Module(s)
        Module(s) that this game/mod uses for to call the map compiler tools

        (Because Q1/Q2/Q3/HL can all use different compiler tools
        and some of the tools provide additional features like

        Needs to be a list of plugins, and the one at the top of the
        list should be the primary plugin (which a hotkey might call)

        This list can also be empty, as a build module is NOT required
        to EDIT a map.

        Additional map compiler plugins may be useful, rather than
        just one. (Don't know what for yet, but... :)

        List of additional plugin(s) that this game/mod uses for to
        do other stuff.

        This list can also be empty, as additional plugins are NOT
        required to EDIT maps.

        The idea here is that you can have a bunch of plugins sitting
        in plugins/ but some are only useful to you if you're editing
        Q3 maps (autocaulker..), and some only useful if you're editing
        HL maps (a .RAD file creator/editor for example).  So you don't
        want to load HL plugins if you're editing Q3 and vice-versa,
        and this takes care of that.

version_name's currently tend to be either the extension of the filename
that the plugin supports, or game engine names but are not limited to this.

VFS (interface_name: "filesystem module")
VFSSTDIO  loads files using normal OS calls (see extra topic below)
          proposed version_name's:

VFSPK3    loads files from PK3 files
          handled by vfspk3.dll
          current version_name's:
          "quake3", proposed: "pk3"

VFSPAK    loads files from PAK files
          proposed version_name's:

VFSWAD    loads files from WAD/WAD3 files
          proposed version_name's:

MAP (interface_name: "map module")
XMAP      loads and saves XMAP files
          proposed version_name's:

MAP       loads and saves Q1,Q2,Q3 and Q3BP files
          proposed version_name's:
          "wolf" ? unless Wolf map format == quake3 map format
          "stvef" ? unless STV:EF map format == quake3 map format

HL        loads and saves HalfLife .MAP files
          (probably be incoporated to MAP module, above)
          proposed version_name's:

RMF       loads and saves Worldcraft .RMF files
          proposed version_name's:

BUILD (interface_name: "build module")
BUILDQ3   shows a GUI and lets you compile Q3 maps with q3map monitoring
          OR it could be the actual BSP compiler itself. (i.e. instead of
          having Q3MAP.EXE it could be built into BUILDQ3.DLL)
          proposed version_name's:
BUILDALL  shows a GUI that lets you run various programs in sequence
          (which can be used for Q1,Q2,etc..)
          proposed version_name's:

ENTITY (interface_name: "entity module")
ENTITYDEF loads entities from Q*.DEF files
          proposed version_name's:
ENTITYFGD loads entities from HalfLife FDG files

IMAGE (interface_name: "image module")
IMAGE     loads TGA/JPG images
          handled by image.dll
          current version_name's:
IMAGEPCX  loads PCX images
          proposed version_name's:

SHADER (interface_name: "shader module")
SHADER    handles shaders and shader scrips for q3
          currently handled by shader.dll
          proposed new name of shader.dll: "shaderq3.dll"
          current version_name's:
          NULL, proposed: "quake3"

Overview of which which interfaces need to be able to support more that one
loaded module/plugin, which ones are REQUIRED by radiant and which
ones are prioritizied

Interface     Multiple?, Prioritized?, Required?, Example List
VFS              YES         YES          YES     VFSSTDIO, VFSPK3
SHADER           NO          N/A          YES     SHADERQ3
IMAGE            YES         NO           YES     IMAGE, IMAGEPCX
MAP              YES         YES          YES     XMAP,MAP
BUILD            YES         YES          NO      BUILDQ3, BUILDALL
ENTITY           YES         NO           NO?     ENTITYDEF, ENTITYFGD

Changes to GUI
Have an amalgamated GUI for editing preferences, with a tree view on the
and a blank area on the right that is filled by whatever item in the tree
view is being configured.  Much in the same way that the Gnome control
center does.

The core sets up the actual list of items on the tree view

The idea being that plugins/modules add items to the preferences tree view
on the left and then display their preferences in the blank area on the

Here's a list of things that could be in the tree view.

+ User Input
|  |- Mouse                    (2/3 button, invert in camera, etc)
|  |- Keyboard Shortcuts       (provide gui to change them)
|  |- Toolbars                 (patch toolbar)
+ Editor
|  |- Layout                   (views, floating z)
|  |- Rendering                (Open GL this that and the other)
|  |- Camera                   (Slow <-> fast, update XY)
|  |- Texturing                (Quality, subset, scrollbar, tex increment
|  |                            matches grid)
|  |- Options                  (Alt + multidrag, vertex editing splits face,
|  |                            display size info)
|  |- Misc                     (Use Win 32 file dialog, autosave every, load
|                               last config/map, etc)
+ Modules
|  <interface name>
|  |-<module name>             <module prefs>
|  Shader Systems
|  |- ShaderQ3                 (Startup Shaders)
|  File System
|  |-VFSPK3
|  Image Loaders
|  |-Image
|  Build / Compilers
|  |-BuildQ3                   (BSP Monitoring config)
+ Plugins
   <plugin name>               about info and plugin prefs

Not looked too much at GTK stuff yet, so don't know how hard
this would be, but it makes sense for everything to be configured in the

Module priority must be configurable by clicking on the <interface name>
in the tree view, and then re-arranging a list of modules with the same
<interface name> via way of UP and DOWN buttons.

Each plugin and module should be able to enabled and disabled by ticking a
checkbox either a) next to the plugin name in the treeview (dunno if GTK can
do that) or b) via a checkbox on the right hand side when that plugin
is selected.  Whether or not this requires a restart of Radiant or not
would be up the the plugin iteself, but the user should be informed if that
is the case.
The plugin's enabled/diabled state would have to be stored in the game
And, obviously you wouldn't be allowed to disable all required modules (so
could say, disable XMAP and MAP by themselves, but not have them BOTH

Not sure wether the game configuration dialog should be included in this
yet,  it'd be better if it was, but making changes to the game config would
possible change the list of plugins that are uses, and then the tree view
would change. So, thinking about it'd be easier if it was a seperate dialog
much like project preferences and editor preferences are now.

Operation of Radiant

Radiant startup
Radiant loads up, and as part of it's initialization process it does this:

Radiant scans modules/ dir for modules

Loads each module, and builds a list in memory of what each module does but
DOES NOT activate the modules YET!

After it has scanned the modules and verified all the .dll files are
actually all valid modules (correct for this radiant version, etc..) it
will end up with a list like this:

  module filename, **interface_table (GUID, interface_name, version_name)
  shaderq3.dll,   (* , "shader module"     , "quake3")
  image.dll,      (* , "image module"      , "tga")
                  (* , "image module"      , "jpg")
  buildq3.dll     (* , "build module"      , "quake3")
  map.dll         (* , "map module"        , "quake3bp")
                  (* , "map module"        , "quake3")
                  (* , "map module"        , "quake2")
                  (* , "map module"        , "quake1")
  xmap.dll        (* , "map module"        , "xmap")
  entity.dll      (* , "entity module"     , "def")
  vfspk3.dll      (* , "filesystem module" , "pk3")
  vfsstdio.dll    (* , "filesystem module" , "stdio")

Radiant scans plugins/ dir for plugins and makes a list in memory, plugins

Searches configs/ subdirectory for .xgc files (XML Game Config)
Checks saved settings (radiant.ini) for last .xgc file used and loads
it if:
  a) the user told us to "load last config on open"
  b) the file exists

If we've not loaded a game config, then prompt the user to
  a) create one (see below)
  b) load one
  c) quit

Game config now in memory

The game config then determines which modules are to be used and activates
the ones to be used and unloads the ones that are not to be used.

Radiant activates all plugins that are ENABLED in the users config.
(meaning users would have to actually activate all plugins manually,
and for each game configuration file)
Radiant activates all plugins that are NOT DISABLED in the users config.
(meaning that new plugins placed in the plugins/ dir are enabled for
each game configuration until manually disabled)

Note: I'm not sure which one to go for here, as there implications either
way.  I think, for ease of use I'd go with the second option, but if the
user was required to enable each new plugin we'd have less problems, and
also configurations would say the same if you copied the game config file
to another machine that had more plugins than the machine the config came
from.  So thinking about it like that I think I'd go for the first
option: "activate plugins that are ENABLED", comments ?)

The intention here is not to load plugins/modules that don't need to be
loaded.  For instance, if you're doing Quake3 mapping then it makes no sense
to activate the shader and vfs modules for Quake1, and vice versa.

There must also be at least one plugin for each core type of plugin for each
interface listed in the REQUIRED interfaces table (above), radiant cannot
start if there is not.

If any plugin requires configuration then the plugin calls a function
in radiant that shows a preferences dialog and allows the user to configure
the plugin and any other plugins or preferences.

Check that all plugins are actually configured, if not exit.

If any changes to a plugin's config are made then they are saved into the
game configuration file now.

If changing a plugin's config requires a restart then exit now.

DO NOT free the list of available plugins and modules so that new game
configs can be created after Radiant has finished loading up.

Carry on with GTKRadiant initialization.

Creating a game config
A dialog will pop up asking the user to create a new game config.
This dialog should let the user import example game configs as well
as import .QE* files or other editor config files (as we see fit)

The user will then be presented with a list of available modules from which
they can chose which ones to use and will be able to set the order those
modules are loaded via way of lists and up down buttons just like in the
prefs (see above).

The user will also be also be enable (or disable, see above) plugins
that are available to them.

The user will then be able to configure the items that are stored in the
main game configuration (filename, comments, etc..)

Information required for configs

Example config for Team Arena (A Quake 3 mod)
Hard Drive = C:, CDRom's on drives D: and E:

GameName        Quake III: Team Arena
BasePath        C:\Games\Quake3
GameExecutable  C:\Games\Quake3\Quake3.EXE
DataBasePath    C:\Games\Quake3\BaseQ3,D:\Quake3\BaseQ3
DataModPath     C:\Games\Quake3\MissionPack,E:\Quake3\MissionPack
MapSourcePath   \\MyServer\MapDevelopment\Quake3
PrefabPath      \\MyServer\MapDevelopment\Quake3\Prefabs
MapModules      XMAP,MAP
ShaderModule    SHADERQ3
ImageModules    IMAGE
EntityModules   ENTITYDEF
BuildModules    BUILDQ3,BUILDALL

Example Config for CounterStrike (a Half-life mod)
Hard Drive = C:, CDRom's on drives D: and E:

GameName        Counter-Strike
BasePath        C:\Games\HalfLife
GameExecutable  C:\Games\HalfLife\HL.EXE
DataBasePath    C:\Games\HalfLife\Valve,D:\HalfLife\Valve
DataModPath     C:\Games\HalfLife\CStrike,D:\HalfLife\CStrike
MapSourcePath   \\MyServer\MapDevelopment\CStrike
PrefabPath      \\MyServer\MapDevelopment\CStrike\Prefabs
MapModules      XMAP,MAP,RMF
ShaderModule    SHADERHL
ImageModules    IMAGEPCX
BuildModules    BUILDALL
Plugins         BOBTOOLZ,GENSURF

Planned list of support for games:
Quake3 and it's mods
STV:EF and it's mods
WOLF and it's mods
Quake2 and it's mods
Quake1 and it's mods
Halflife and it's mods