Adding a Pause / Continue Action
From C4 Engine Wiki
This article explains how to add a "Pause / Continue" action to the demo game module MGGame that ships with C4 Engine.
Overview
Here are the steps to add the Pause action to the demo game:
- Implement the Pause action in the Game World class
- Define the Pause action type in the Input Manager class
- Add the Pause action handler to the GameWorld class
- Register the Pause action with the Input Manager
- Bind a new keyboard input to the Pause action
- Add a user-friendly action name to the Input string table
Here are the four files from the demo game module that will be modified:
- MGGame.h
- MGGame.cpp
- MGInput.h
- MGInput.cpp
The Pause action also requires some minor additions to the Input.txt file located in the Import/txt directory as well as the Engine.cfg file, which is located in the Data/cfg directory, to add the user interface that allows the user to discover and remap the Pause action's keyboard input binding.
Many of the code snippets in this article have comments that are tagged with the name of the original author of this article, "Huidafa". Please feel free to remove those tags or change them to something else. The original author of this article tags his custom code changes to make it easy to find them in older builds of C4 Engine when he integrates his changes into new builds of C4 Engine as they are released by Terathon Software.
Implement the Pause action in the Game World class
In MGGame.h, declare a boolean member field isPaused:
bool isPaused; // Pause action for single-player mode. [Huidafa]
The GameWorld interface will look something like this:
class GameWorld : public World
{
private:
long spawnLocationCount;
List<Marker> spawnLocationList;
List<Marker> spectatorLocationList;
List<Marker> benchmarkLocationList;
SpectatorCamera spectatorCamera;
FirstPersonCamera firstPersonCamera;
ChaseCamera chaseCamera;
EntityCamera *playerCamera;
bool isPaused; // Pause action for single-player mode. [Huidafa]
While still editing MGGame.h, define the Pause action method as follows:
void TogglePause(void); // Pause action for single-player mode. [Huidafa]
Next, in MGGame.cpp initialize the isPaused member field to false:
GameWorld::GameWorld(const char *name) : World(name), spectatorCamera(kCameraFocalLength, 1.0F, 0.3F), isPaused(false) // Pause action for single-player mode. [Huidafa]
Add the implementation of GameWorld::Pause as the last method in the GameWorld class (just before the Game::Game constructor):
// Pause action for single-player mode. [Huidafa]
void GameWorld::TogglePause(void)
{
if (isPaused)
{
TheSoundMgr->ResumeAllSounds();
TheTimeMgr->SetWorldTimeMultiplier(1.0);
}
else
{
TheSoundMgr->PauseAllSounds();
TheTimeMgr->SetWorldTimeMultiplier(0.0);
}
isPaused = !isPaused;
}
Define the Pause action type in the Input Manager class
Near the top of MGInput.h define a new action type for the Pause action:
kActionPause = 'paus', // Pause action for single-player mode. [Huidafa]
Here is the complete enumeration:
// Action types
enum
{
kActionForward = 'frwd',
kActionBackward = 'bkwd',
kActionLeft = 'left',
kActionRight = 'rght',
kActionUp = 'jump',
kActionDown = 'down',
kActionFirePrimary = 'fire',
kActionFireSecondary = 'trig',
kActionBlaster = 'blst',
kActionGrenadeLauncher = 'gren',
kActionRocketLauncher = 'rock',
kActionPlasmaGun = 'plas',
kActionProtonCannon = 'cann',
kActionNextWeapon = 'next',
kActionPrevWeapon = 'prev',
kActionFlashlight = 'lite',
kActionCameraView = 'camr',
kActionPause = 'paus', // Pause action for single-player mode. [Huidafa]
kActionScoreboard = 'scor',
kActionChat = 'mess',
kActionLoad = 'load',
kActionSave = 'save'
};
Add the Pause action handler to the Input Manager class
In MGInput.cpp add the following case to the switch statement in the SwitchAction::Begin method:
case kActionPause: // Pause action for single-player mode. [Huidafa]
if (!TheMessageMgr->Multiplayer())
{
GameWorld *world = static_cast<GameWorld *>(TheWorldMgr->GetWorld());
if (world) world->TogglePause();
}
break;
Register the Pause action with the Input Manager class
First, define the Pause SwitchAction in the Game class header MGGame.h:
SwitchAction pauseAction; // Pause action for single-player mode. [Huidafa]
The section where it is added should look like this:
WeaponAction blasterAction; WeaponAction grenadeLauncherAction; WeaponAction rocketLauncherAction; WeaponAction plasmaGunAction; WeaponAction protonCannonAction; SwitchAction nextWeaponAction; SwitchAction prevWeaponAction; SwitchAction flashlightAction; SwitchAction cameraViewAction; SwitchAction pauseAction; // Pause action for single-player mode. [Huidafa] SwitchAction scoreboardAction; SwitchAction loadAction; SwitchAction saveAction; ChatAction chatAction;
Next, in the Game::Game constructor (in MGGame.cpp), initialize the Pause action as follows:
pauseAction(kActionPause), // Pause action for single-player mode. [Huidafa]
The section where this is done should look like this:
forwardAction(kActionForward, kMovementForward, kSpectatorMoveForward), backwardAction(kActionBackward, kMovementBackward, kSpectatorMoveBackward), leftAction(kActionLeft, kMovementLeft, kSpectatorMoveLeft), rightAction(kActionRight, kMovementRight, kSpectatorMoveRight), upAction(kActionUp, kMovementUp, kSpectatorMoveUp), downAction(kActionDown, kMovementDown, kSpectatorMoveDown), primaryFireAction(kActionFirePrimary), secondaryFireAction(kActionFireSecondary), blasterAction(kActionBlaster), grenadeLauncherAction(kActionGrenadeLauncher), rocketLauncherAction(kActionRocketLauncher), plasmaGunAction(kActionPlasmaGun), protonCannonAction(kActionProtonCannon), nextWeaponAction(kActionNextWeapon), prevWeaponAction(kActionPrevWeapon), flashlightAction(kActionFlashlight), cameraViewAction(kActionCameraView), pauseAction(kActionPause), // Pause action for single-player mode. [Huidafa] scoreboardAction(kActionScoreboard), loadAction(kActionLoad), saveAction(kActionSave)
Now we are ready to register the Pause action with the Input Manager:
TheInputMgr->AddAction(&pauseAction); // Pause action for single-player mode. [Huidafa]
The section where this is done should look like this:
TheInputMgr->AddAction(&forwardAction); TheInputMgr->AddAction(&backwardAction); TheInputMgr->AddAction(&leftAction); TheInputMgr->AddAction(&rightAction); TheInputMgr->AddAction(&upAction); TheInputMgr->AddAction(&downAction); TheInputMgr->AddAction(&primaryFireAction); TheInputMgr->AddAction(&secondaryFireAction); TheInputMgr->AddAction(&blasterAction); TheInputMgr->AddAction(&grenadeLauncherAction); TheInputMgr->AddAction(&rocketLauncherAction); TheInputMgr->AddAction(&plasmaGunAction); TheInputMgr->AddAction(&protonCannonAction); TheInputMgr->AddAction(&nextWeaponAction); TheInputMgr->AddAction(&prevWeaponAction); TheInputMgr->AddAction(&flashlightAction); TheInputMgr->AddAction(&cameraViewAction); TheInputMgr->AddAction(&pauseAction); // Pause action for single-player mode. [Huidafa] TheInputMgr->AddAction(&scoreboardAction); TheInputMgr->AddAction(&loadAction); TheInputMgr->AddAction(&saveAction);
Bind a new keyboard input to the Pause action
We're almost done. Bind a keyboard input to the Pause action so that the player can use it in the game. This example uses the Tab key as the factory preset shortcut.
- Open C4\Data\cfg\Engine.cfg
- Add the following entry above the keybinding for the scoreboard:
bind "Tab" %paus;
- The whole thing will look something like this (yours may be different if you have customized your key shortcuts):
$device = "Mouse"; bind "Button 0" %fire; bind "Button 1" %trig; $device = "Keyboard"; bind "1" %blst; bind "2" %gren; bind "3" %rock; bind "4" %plas; bind "5" %cann; bind "-" %prev; bind "=" %next; bind "W" %frwd; bind "T" %mess; bind "A" %left; bind "S" %bkwd; bind "D" %rght; bind "F" %lite; bind "G" %trig; bind "K" %camr; bind "Tab" %paus; bind "X" %scor; bind "C" %down; bind "Space" %jump; bind "F6" %save; bind "F9" %load; $device = "XBOX 360 For Windows (Controller)"; undef $device;
Add a user-friendly action name to the Input string table
Finally, add "Pause / Continue" to the game's Input string list and import it into C4's internal string table.
- Open C4\Import\txt\Input.txt
- Add this entry just before the "Show Scoreboard" entry:
'paus' "Pause / Continue"
- The whole thing should look like this:
'frwd' "Move Forward" 'bkwd' "Move Backward" 'left' "Move Left" 'rght' "Move Right" 'jump' "Up / Jump" 'down' "Down / Crouch" 'fire' "Primary Fire" 'trig' "Secondary Fire" 'blst' "Blaster" 'gren' "Grenade Launcher" 'rock' "Rocket Launcher" 'plas' "Plasma Gun" 'cann' "Proton Cannon" 'next' "Next Weapon" 'prev' "Previous Weapon" 'lite' "Toggle Flashlight" 'camr' "Change Camera" 'paus' "Pause / Continue" 'scor' "Show Scoreboard" 'mess' "Send Message" 'save' "Quick Save"
- Open C4 and access the console by hitting the tilde key.
- Type istring and press Enter.
- Select Input.txt from the list and press OK.
- Quit C4
Using the Pause action
- Start the sample game and enter the Demo game world.
- Pause the game by pressing the Tab key.
- Continue the game by pressing the Tab key once again.
The "Pause / Continue" action is a toggle.
Although you can rotate the camera while the game is paused, you cannot move about within the world until you continue the game.
This example disables the Pause action in multi-player mode. A multi-player version of the Pause action might be workable if the game host could broadcast a Pause command to all of the players in the game.

