I don't need to test my programs. I have an error-correcting modem.


From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search
UT2003 :: Actor >> Info >> GameRules (Package: Engine)

The GameRules class handles game rule modifications for the GameInfo such as scoring, pickups, death, kills, finding player starts and damage modification.

GameRules modifies the play laid out by the GameInfo. GameRulesModifier is the instance of this class inside GameInfo. GameRules is a linked list of GameRules. Every time an function is called in GameInfo it searches through every GameRules in the list that override the any of the below functions. So GameRules augments the gameplay in a modular fashion by applying rules to an already existing game behavior.


GameRules NextGameRules 
The next GameRules actor in the linked list of GameRules.


AddGameRules (GameRules GR) 
Adds a GameRules to the end of the GameRules linked list.
bool CheckEndGame (PlayerReplicationInfo Winner, string Reason) 
Called when the EndGame conditions have been met.
bool CheckScore (PlayerReplicationInfo Scorer) 
Augments the score and returns whether the EndGame conditions have been met.
bool CriticalPlayer (Controller Other) 
Returns whether a player should be concidered a "critical player". E.g the flag or bomb carriers in CTF and Bombing run respectively are considered critical players.
NavigationPoint FindPlayerStart (Controller Player, optional byte InTeam, optional string incomingName) 
string GetRules ( ) 
Returns a string of information that contains the information about what this game rule does.
GetServerDetails (out GameInfo.ServerResponseLine ServerState) 
Like in Mutator.GetServerDetails() you can add information to the server information displayed in the server browser, however unlike mutators GameRules are not added to the server details by default. GameRules.GetServerDetails() is called after Mutator.GetServerDetails().
bool HandleRestartGame ( ) 
Augments whether the game is restarted or not.
int NetDamage (int OriginalDamage, int Damage, Pawn injured, Pawn instigatedBy, vector HitLocation, out vector Momentum, class<DamageType> DamageType) 
Allowes the GameRules to modify the damage (return value) and momentum. The OriginalDamage parameter should be passed to the next GameRules without any modifications.
bool OverridePickupQuery (Pawn Other, Pickup item, out byte bAllowPickup) 
Can be used like Inventory.HandlePickupQuery() to modify the way the item gets (not) picked up. Returning True means that the value of the bAllowPickup variable determines whether the item may be picked up. Otherwise the Inventory.HandlePickupQuery() is called for the player's inventory to possibly handle the pickup query.
bool PreventDeath (Pawn Killed, Controller Killer, class<DamageType> damageType, vector HitLocation) 
Called right before the pawn dies. Returning True prevents the death and sets the pawn's health to at least 1. Usually you will want to set it to a higher value, though.
bool PreventSever (Pawn Killed, name boneName, int Damage, class<DamageType> DamageType) 
Augments the action taken when a player would normally lose a limb. Returns true to prevent the severing of the boneName or false to allow the limb to be severed.
ScoreKill (Controller Killer, Controller Killed) 
Augements the action taken when a player scores a kill. Not the score itself, but having to do with the Controllers involved in the Kill.
ScoreObjective (PlayerReplicationInfo Scorer, Int Score) 
Augments the action taken when a player scores in the game.

Known Subclases[edit]

Example: Adding a GameRule[edit]

I was able to add a GameRule to my gamplay through the GUITabPanel that I wrote. Inside GUITabPanel there is a Play function that is called when the user has selected the gameplay to begin. When this happens the GUIComponents that make up the GUITabPanel are queried for their state and setting to determine how the game should proceed.

function string Play()
    LastAutoAdjustSkill = moCheckBox(Controls[15]).IsChecked();
    return Super.Play()$"?AutoAdjust="$LastAutoAdjustSkill$"?GameRules=MyPackageName.MyGameRule";

Above, I simply created a new subclass of TabInstantActionBaseRules, copied Tab_IADeathMatch and then edited the Play function. I added:


$ concatenates the existing string with what follows. Then I use the ? to add a new option to the Play string. GameRules= is an important keyword that GameInfo looks for when parsing this Play string. If I had more than one GameRules I would use a comma , to seperate each one.

MyPackageName is the name of package that the GameRules, that you've created and named MyGameRule, is located.

Burtlo: I thought that I would include a sort of how-to to set up the GameRule. However there might be anothe way to set it up through defaultproperties in the GameInfo class. Someone should double-check my work.

Wormbo: Please be careful when the wiki tells you there's a conflict. You can loose information added by other contributors if you simply copy over your own edited version. Also you don't need to link a class name if that class is described on the same page, i.e. you don't need to link the NextGameRules variable's type because it's "GameRules" and that's this page already.

burtlo: I apologize, I thought that it gave me that error because I had it opened in another browser window.

porkmanii: Alternatively, you can add a GameRules actor after gameplay begins by doing this:


Working with other GameRules[edit]

Tarquin: What's the correct way to work with the other GamesRules in the linked list? IN code, I see things like:

function foo {
  if(NextGameRules != None)
      return NextGameRules.foo();

but I don't quite understand how to handle it if I want my foo() to return something else – how do I combine my result with the other GameRules that might want to customize foo() ?

Mychaeel: Simple: If you want your GameRules to override whatever other GameRules might want to say about this, just return that value. Otherwise, return the result of Super.foo() (which should call foo() of the next GameRules actor in the chain). Like this:

function bool foo() {
  if (bByAllMeansReturnTrue)  return True;
  if (bByAllMeansReturnFalse) return False;
  return Super.foo();

Tarquin: So the flow of functions is:

  • super calls...
    • first child in list, calls...
      • super, calls...
        • 2nd child in list

... and so on?

Mychaeel: Yes – the chain of GameRules actors is followed recursively. (That's not very efficient for very long linked lists, but for a list with only a couple of objects it works well enough.)

Argon: This is my first post, so hopefully I don't screw anything up... I'm building a mutator that uses NetDamage to modify damage based on a variety of factors, and it seems to work in most gametypes, but not in Invasion. Whenever monsters get damaged, they take normal damage and none of my code in Netdamage runs on them. Debugging shows that Netdamage isn't even being called when monsters take damage. I've been looking through the Skaarjpack.u code, but the only thing I can find is a reducedamage function, which is based on the same function in TeamGame, but that doesn't seem to be what I'm looking for, as it doesn't explain why this isn't being passed to NetDamage. Anyone have any insights?

Related Topics[edit]