Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

...

As you might have noticed, Chivalry has a separate PlayerController, Game, and sometimes Pawn class for every game mode. If I wanted to do the same thing in every PlayerController, the naïve way to do it would be to create a separate child PlayerController for every mode and put the same code in every one. This would become a maintenance nightmare with more complex PlayerController classes as you have to make sure you make the same changes to every one of them (unless you don't want the change in question in that class). Bleh.

Instead, we use include files which contain common functionality.

The `include macro is evaluated before the code is compiled. It copies the file in question into this script before compiling this script. Using this, we can keep common code in one file that's `included from every script that needs it.

If you're just making a single, brand new game mode you don't need to do this! Instagib is doing this because it subclasses and replaces several vanilla Chivalry game modes. If, say, you wanted to just add a "Last Man Standing" mode that derives from free-for-all, you only really need one GameInfo, one PlayerController, and maybe one Pawn (see: Tutorial: Creating the "Giant Slayers" mod)

PlayerController include files

Open up

Instagib/Include/InstagibPlayerController.uci

...

Code Block
languageactionscript3
titleInstagibPlayerController.uci
reliable client function ShowDefaultGameHeader()
{

Exists in AOCPlayerController.uc, so when it's overridden in the Instagib classes, this overridden version is used instead. The overridden version calls its super class' version (that is, the function that's in AOCPlayerController):

Code Block
languageactionscript3
titleInstagibPlayerController.uci
	super.ShowDefaultGameHeader();

Before then doing its own, special thing.

Code Block
languageactionscript3
titleInstagibPlayerController.uci
	ReceiveChatMessage("",Localize("ChatMessages", "Welcome", "Instagib"),EFAC_ALL,false,false,,false);
	SetTimer(3.0f, false, 'ShowInstagibHeader');
}
 
function ShowInstagibHeader()
{
	ReceiveLocalizedHeaderText(Localize("ChatMessages", "Welcome", "Instagib"),5.0f);
}

GameMode include files

Let's look at a game mode. Open up InstagibCTF.uc.

Code Block
languageactionscript3
titleInstagibCTF.uc
class InstagibCTF extends AOCCTF;
`include(Instagib/Include/InstagibCTF.uci)
`include(Instagib/Include/InstagibGame.uci)

The first `include you see in Instagib's PlayerControllers, Pawns, and Games looks like

Code Block
languageactionscript3
titleInstagibCTF.uc
`include(Instagib/Include/InstagibCTF.uci)

If you open that file, you'll notice it just has

Code Block
languageactionscript3
titleInstagibCTF.uci
`define GAMEMODE InstagibCTF

This defines the GAMEMODE macro to be InstagibCTF. This means that anywhere in code that

Code Block
languageactionscript3
`{GAMEMODE}

shows up, it's replaced with InstagibCTF. We use this in a clever bit of trickery in our common Game code so that every game mode automatically knows which PlayerController and Pawn it should use. We're going to use it in Step 3 in your new mod's PlayerControllers and Pawns to do something interesting.

Open up the second include, Instagib/Include/InstagibGame.uci. This is the common GameMode code. You'll notice that at the bottom, there's

...

Code Block
languageactionscript3
titleInstagibGameexcerpt from InstagibCTF.uci uc after the preprocessor gets to it (during the script compiling processcompilation)
PlayerControllerClass=class'InstagibCTFPlayerController'
DefaultPawnClass=class'InstagibCTFPawn'

...