Interfacing to the UI

To make our single player game workable we must interface it with our UI, scripted or unscripted. This will allow us to start a new game, load a saved game or save the current game from the menu.

One of the problems we have with the Quake 3 system is that the server is completely reset every time a map is loaded. This clears out all local variables and makes things ready to go again. The problem here is that we have no way of telling if we are starting a new game, loading a saved game, changing levels or restarting a level after dying, since any server variable we may have set will be reset when the map loads. To get around this we have to define a special cvar in the UI system and use that as our indicator variable. For the purposes of this tutorial we will create a cvar named Save_Loading that will be used to tell the server exactly what type of level load we are doing.

Save_Loading Value

Type of Level Load

0

Start of new game

1

Loading a saved game

2

Changing levels

3

Restarting after dying

Both the server and the UI can modify this cvar to indicate the type of level load taking place.

In order to properly handle changing level and restarting after dying the server also needs a cvar named persid which can hold the id number of the last saved persistant data. This cvar is also defined in the UI so it is external to the server.

Since much of the Quake 3 code deals with team based games we need to indicate to the server that the game is single player. The g_gametype cvar is used for this purpose. If this cvar is set to 2 then the game type is set to single player.

When loading a game from a saved game file we need to know the name of the file to load, since the loading takes place in the server code. The cvar ui_LoadGame is used to hold the name of the saved game file. The server uses it's contents to determine which file to read. This cvar must be cleared when starting a new game to correctly allow for restarting after dying.

When starting a new game or loading a saved game the menu system uses the spmap console command to load the map and start the server running. This command requires the name of the map to be loaded. This can be provided directly for a new game, since you know the name of the first level, but when loading a saved game the map name must be extracted from the saved game file. The following function does just that :

qboolean SP_LoadGame(char *load_game, char *loadmap)
{
char filename[150];
int i;
fileHandle_t f;
 Com_sprintf( filename, MAX_QPATH, "save\\%s.svg", load_game );
 if (trap_FS_FOpenFile( filename, &f, FS_READ ) < 0) {
   Com_Printf( "SP_LoadGame: savegame '%s' not found\n", filename );
   return qfalse;
 }
 trap_FS_Read (&i, sizeof(i), f); // version
 trap_FS_Read (loadmap, MAX_QPATH, f);
 trap_FS_FCloseFile( f );
 return qtrue;
}

The name of the saved game file (without extension) is passed in load_game and the name of the map is returned in loadmap. The function returns qtrue if it successfully read the map name and qfalse if not.

Summary

The UI must have the following cvars defined in it for use by the single player game code :

  1. Save_Loading
  2. persid
  3. ui_LoadGame

When starting a new game you do the following :

  1. set the g_gametype cvar to 2
  2. set the Save_Loading cvar to 0
  3. clear the ui_LoadGame cvar
  4. execute the console command spmap <map name> where <map name> is the name of the first level

When loading a saved game you do the following :

  1. set the g_gametype cvar to 2
  2. set the Save_Loading cvar to 1
  3. set the ui_LoadGame cvar to the name of the saved game file
  4. extract the map name from the saved game file using the SP_LoadGame function
  5. execute the console command spmap <map name> where <map name> is the name of the map from the saved game file

When saving the current game you do the following :

  1. execute the console command savegame <file name> where <file name> is the name of the saved game file without an extension.

In the scripted menu system we use the following commands :

uiScript "StartSPGame" <map name>

to start a new game and :

uiScript LoadSPGame

to load a saved game. It is assumed that the ui_LoadGame cvar already holds the name of the saved game file. The uiScript LoadGame command is used to load the ui_LoadGame cvar with the name of the file selected in the saved game list box.

To save the current game we use the following command :

uiScript SaveSPGame

It is assumed that the ui_SaveGame cvar holds the name of the file we are saving to. The uiScript SaveGame command is used to load the ui_SaveGame cvar with the name of the file selected in the saved game list box, if we are overwriting an existing file..

 

Return to Home Page