User Tools

Site Tools


This is an old revision of the document!


Game Development Overview

The Cafu Engine can be used both for developing single- or multiplayer games that ship as individual products, as well as for products that support multiple, independent games in a single program that the user can select from at runtime.

For example, after starting the program, the user might choose from a list of online game servers (each possibly running not only different game maps, but entirely different games), or a list of available single-player games, and join one seamlessly without restarting the program.

The fact the multiple games can be present at the same time makes it worthwhile to keep all related files and program code well organized, so that games can be developed and shipped to end users modularly and independently of each other and of the Cafu core engine.

One directory per game

In order to achieve these goals, all files, data and program code for a game are stored in one common directory, which in turn must be a subdirectory of Games/.

For an example, see the Games/DeathMatch/ directory of the DeathMatch example game that ships with Cafu:

(Also see How do I start a new game (MOD) project? for help about creating a new game directory.)

Although you're largely free to organize the contents of the game directory as desired, per convention some of the resource files must be kept under fixed names or in given directories, so that the Cafu Engine can find and load them when it is newly initializing the game.

The following sub-sections list and explain most of these “fixed” files and directories.

EntityClassDefs.lua

File EntityClassDefs.lua defines all entity types that can occur in the game. The file is read both by the world editor CaWE and the actual game code. For each entity type, it specifies details like names, dimensions, properties, etc.

Code/

Directory Code/ contains the source code for the implementation of this game.

The source code is compiled into a program library that is linked to the Cafu Engine executable when the software is built. Multiple game libraries can be linked to the Cafu Engine at the same time, so that the user can choose at runtime which one should be used.

When SCons builds the game library, it places the generated binary files into subdirectory

  Code/build/...

where ... is a path that is automatically created by the build system according to your platform, compiler and build variant. When it proceeds, SCons will automatically pick up the generated files from there to link them to Cafu, so normally you never have to deal with them yourself.

See section The game source code for more details about the game source code.

GUIs/

The graphical user interfaces that are used in a game are kept in GUIs/.

GUIs are used both

  • in “2D”, e.g. for the main menu, the console window, the “HUD” (head-up display) in the game, etc., as well as
  • in “3D”, as parts of the game worlds, that the player can use e.g. to call lifts, to unlock doors, to activate teleporters, or to control any other game script action.

The GUIs kept in GUIs/ are usually “2D” GUIs, and “3D” GUIs that are universally used in multiple maps. “3D” GUIs that are specific to a single map can either be stored in GUIs/ as well, or along with the map in the same directory as the map.

At this time, the following GUIs are automatically loaded by the Cafu Engine:

  • GUIs/ChatInput.cgui – implements the text input when the player presses T to talk in the game.
  • GUIs/Console.cgui – implements the in-game command console, opened with F1.
  • GUIs/MainMenu/MainMenu_main.cgui – implements the main menu that is shown after program start.

In addition, the DeathMatch game code in DeathMatch/Code/HumanPlayer.cpp loads

  • GUIs/HUD_main.cgui – implements the players head-up display (cross-hair, ammo count, etc.).

You can replace all these GUIs by providing your own editions in their place, or just copy them from the DeathMatch example game and modify them as you like.

Maps/

Contains the map files as saved by the CaWE Map Editor.

You don't actually have to save your map files in this directory, but we may merge Maps/ and Worlds/ sometime in the future, and thus Maps/ is still the recommended place to save .cmap files.

Materials/

All material definitions for the game maps are kept in Materials/. Materials are often reused in several maps of a game, and thus Materials/ is where all map materials are centrally stored.

The CaWE Map Editor loads the material definitions from this folder in order to provide the map designer with the choices in the Material Browser dialog. The Cafu Engine loads the material definitions from Materials/ as well in order to render the materials in the game.

Music/NextTitle.txt

Whenever the player enters a new map, the client calls console function StartLevelIntroMusic(), that in turn is defined in file config.lua in the Cafu top level directory and that uses file Music/NextTitle.txt in order to play the next title from the list of files in Music/.

Textures/

The texture images that the materials in Materials/ are referring to are stored here.

Worlds/

Maps from Maps/ must be “compiled” in order to be used with the Cafu Engine. Compiling turns a map file (suffix .cmap) into a world file (suffix .cw) and is documented at Compiling Maps for Cafu.

The world files generated by compiling are stored in Worlds/, where the main menu GUI (MainMenu_main.cgui in the DeathMatch example game) looks for .cw files that the player can choose to enter. It also looks for a matching screenshot image to show with the maps list.

The game source code

The source code for the game library is in Code/, inside which you can organize and arrange the source files at will.

To get familiar with the code, a good start is to check out the cf::GameSys::GameI interface, and its implementation in GameImplT, and to continue from there.

The core engine will call the methods of the cf::GameSys::GameI interface, e.g. those to have new entities created after a map file has been loaded or when another player joins the game, and it's the job of the game code to provide implementations for these methods. See the code for class GameImplT in order to see how it was done for the DeathMatch game.

With the GameEntityI pointers to newly created entities, the engine will also call the virtual methods in the GameEntityI interface, in order to let entities know about events or to have them carry out tasks. These methods too are supposed to be overridden by the concrete entity implementation, and are in fact the essence of implementing a game: An entity is considered a state machine that lives in a virtual world, interacting with the world and other entities, and for example its GameEntityI::Think() method is expected to update it over a small amount of time whenever the method is called (by the server code inside the engine).

Exploring the code

This document is not complete, and we will continue to improve it.

The class hierarchy is shown in

If you have questions about anything that is mentioned in this document (or is missing and should be mentioned), please let us know! We will be happy to answer you questions and use the answer to improve this text.

cppdev/gamecodeoverview.1351773169.txt.gz · Last modified: 2013-01-07 12:07 (external edit)