Jump to content
Sign in to follow this  

Gamemodes, Rulesets, and Capturezone documentation

Recommended Posts

This thread is intended to be a series of documentation posts on how the gamemode system works, how to create new gamemodes, rulesets, and other game-flow objects.
On the high level, Game Flow is broken down into 3 different objects:

  • Gamemode: The gamemode sets up the generic squad flow (respawns, team creation, putting players on teams), but delegates the match flow tasks off to the Rulesets, of which there can be many. 
  • Rulesets: The primary instigator of game flow.  Rulesets are 'mini gamemodes' that handle specific game events and allow for flow.  AAS, Insurgency, Flag Scoring... these are all handled by Rulesets.  Rulesets are Server Only, so they can be created on a per-server basis as well.  
  • Important Actors: Important Actors are objects that specifically notify the Gamemode (and by extensions, all of the Rulesets) of their existence.  These are objects that exist in the world and are very specifically intended to be objects the Rulesets can use to direct game flow.  This includes FOBs, Capture Zones, Insurgency Caches... stuff like that.  

Creating a Game Mode
Given that many of the important tasks of a gamemode are handled in C++, Creating a gamemode is mostly a task of creating a number of Rulesets and associating them with a gamemode.  You can also override some of the default classes for the gamemode, allowing you to create custom Controller actors and game states.  
Required Reading for how GameModes work: https://docs.unrealengine.com/latest/INT/Gameplay/Framework/GameMode/index.html
To create a new GameMode, create a child blueprint from BP_GameMode
Adding Rulesets
As mentioned above, Most of the actual match flow logic is delegated out to Rulesets.  These Rulesets can be sourced from 3 places:

  • Gamemode Config: Rulesets can be sourced directly from the gamemode blueprint.  This is the primary source for rulesets




  • World Settings: Rulesets can also be added directly to a world settings class, giving Mappers and Modders the ability to create map-layer specific rulesets.  This can be useful for map events or specific scoring for doing something (Blowing up a radio tower, for example).  


  • Holiday Events:  These are stored in the DefaultGame.ini and used to do holiday events.  They can be configured in the project properties.  Mods and Custom Servers can make use of these.  They require a date and time to start and end, and will only ever be active with matches started during that window.  


Share this post

Link to post
Share on other sites

Creating a Ruleset


Creating and changing Rulesets will be the core aspect of creating a mod.  They govern Game Flow, scoring, and the overall layout of a Squad match.


The first thing you will need to get familiar with is the Unreal Engine Blueprint Visual Scripting.  Many of the Squad rulesets are implemented in Blueprint, although some of the more involved ones (like AAS) are implemented in C++.  Blueprint documentation can be found here: https://docs.unrealengine.com/latest/INT/Engine/Blueprints/index.html




To create a Ruleset, create a new blueprint based off of SquadGameRuleSet





We've exposed a large number of game events to Rulesets.  To get find the full list, you can look at the Override drop-down menu in the Functions section.  This list will always be up to date when we add new functions to Rulesets (something we do often).  If there is a function missing that you need to do a mod, feel free to contact me (NOTE: Wait until mod support is actually out before you actually contact me)





Current Exposed Overridable Functions:

/* Called when a player joined the game */
void PlayerJoined(ASquadPlayerController* NewPlayer);	
/* Called when a player joins a team */
void PlayerJoinedTeam(ASquadPlayerController* Player, int32 TeamIndex);	
/* Called when a player is spawning into the world */
void PlayerSpawned(ASquadPlayerController* NewPlayer);
/* Called when a player puts another player into Wounded state */
void PlayerWounded(ASquadPlayerController* Killer, ASquadPlayerController* Victim);
/* Called when a player puts another player into Dead state */
void PlayerKilled(ASquadPlayerController* Killer, ASquadPlayerController* Victim);
/* Called when a player puts another player on his team into dead state */
void PlayerTeamKilled(ASquadPlayerController* Killer, ASquadPlayerController* Victim);
/* Called when a player goes into the Wounded state */
void PlayerWound(ASquadPlayerController* Victim);
/* Called when a player dies but has no killer */
void PlayerDied(ASquadPlayerController* Victim);
/* Called when a player kills themselves */
void PlayerSuicide(ASquadPlayerController* Victim);
/* Called when a player heals another player */
void PlayerHealed(ASquadPlayerController* Healer, ASquadPlayerController* HealedPlayer);
/* Called when a player heals themself */
void PlayerSelfHealed(ASquadPlayerController* Healer);
/* Called when a player bandages another player */
void PlayerBandaged(ASquadPlayerController* Bandager, ASquadPlayerController* BandagedPlayer);
/* Called when a player bandages themself */
void PlayerSelfBandaged(ASquadPlayerController* Bandager);
/* Called during the spawning of a soldier, after the soldiers inventory is spawned.  All inventory items are guanranteed to be valid at this point */
void ModifySoldierInventory(ASquadSoldier* Soldier);
/* Called every second when the game is playing */
void SecondPassed();
/* Called when the match starts */
void MatchStarted();
/* Called when an actor registers themselves with the gamemode.*/
void RegisterActor(AActor* actor);
/* Called when an actor leaves the world.*/
void UnregisterActor(AActor* actor);
/* Called after a player logs into the server, but before they fully join */
void PostPlayerLogin(class APlayerController* Controller);
/* Called when a player logs out of the server, but before they've fully left */
void PostPlayerLogout(class AController* Controller);

Helper Functions:

/* Returns the gamemode that is currently running */
ASquadGameMode* GetGameMode() const;
/* Sends a chat message to everyone in the server */
void SendChatMessage(ESquadChat::Type ChatType, FString Message, ESquadTeam::Type Team = ESquadTeam::Team_Neutral, int32 Squad = 0);
/* Notifies a player when they receive score */
void NotifyPlayerOnScoreEvent(ASquadPlayerController* Player, FScoreEvent ScoreEvent);
/* Notifies a player in the notification area */
void NotifyPlayer(ASquadPlayerController* Player, FString Message);

Tracking Actor Events


Rulesets really gain strength with being able to respond to Actor Events.  Most of the Squad Actors have a number of events that a Ruleset can subscribe to, allowing them to respond and control those actors when needed.  A good example of this is the AAS ruleset that responds to flag capture events and sets flags cappable or not. 


The Register Actor function is the primary place you want to do this.  From here you cast the input actor to whichever object you are looking for and bind functions to the actor's events.  







A simple notification when a player dies: 




Remove 20 points when a player Teamkills another player.





C++ Rulesets


There are a number of Rulesets defined in C++ to handle some standard tasks.  They contain many useful features that may not be used in a normal Squad match, but can be simply turned on or off.  


  • KillDeath Ruleset:  The K/D Ruleset handles many of the Kill-Damage-Death events in the game.  It's used for notifying players of events and scoring them.  



  • Flag Ruleset: Handles the scoring and reporting of flag events.  Useful for any gamemode that makes use of the Capturezone system



  • Game Event Ruleset: Handles game events, like player joining or leaving the game.  Right now this Ruleset is pretty thin, but future events (like notification on team switch) will be placed here.  '
  • AAS: AAS is implemented as a Ruleset.  Please view This Thread on how to configure AAS

Share this post

Link to post
Share on other sites

Creating an Important Actor


Creating an actor that interacts with the Ruleset system is the other half of setting up game flow.  In terms of Actor->Ruleset interaction, we make heavy use of Event Dispatchers and Delegates.  


To create an actor that interacts with the Ruleset system, you need to create a new Actor Blueprint.  See the Unreal Engine documentation linked above for how to do this.


Once you have an new Actor BP, on the Begin Play Node, get the Authority Gamemode and register the actor.  Make sure this only runs on the server by checking if you have Authority.  




This will then show up in every Ruleset, and only those listening for your object will be able to react to it (Note: In the example of listening for Important actors above, the Cast node checks for success.  That's how you filter out what actors you want to deal with). 


Example: A ruleset that does something when you interact with a box


Here is an example.  In the Ruleset, we want to broadcast 'Playername has touched the box' whenever a player presses 'F' on the box.  


To do so, we want to create a Ruleset and an Actor.  


In the Box actor, open it up in the blueprint editor and add a 'Cube Component' to it.  Scale it up however large you want it.  


On Begin Play, Add the blueprint nodes shown above.  


Add an Event Dispatcher for 'OnPlayerInteractedWith'.  Set the params to be itself and the player that touched it.  We'll bind to this later in the Ruleset.




In the Class Settings we want to add the Squad Usable interface.  This will allow players to press 'F' on this actor and we will get a callback when they do.  




After we do this, we want to override the new functions we have available to us.  Go to the Event Graph tab and right click.  Type 'Server On Used' and create a new event for Server On Used.  (Note: You may have to compile the blueprint before it shows up) (Note: We use the Server version here as Rulesets only exist on the server)


From here, we want to call the Player On Interact Event that we created earlier.  Drag it in from the sidebar and click 'Call'.  Fill in the Parameters (Self, and the user from the interact function).  




From here, our interact actor is done.  Now we want to go into our new Ruleset and bind to that event.  


In the function overrides, override the Register Actor function.  With the actor pin, we want to cast it to our ExampleActor class.  From the 'Succeeded' pin, we want to bind to the OnPlayerInteract event.  




From here, we want to drag out the red Event pin, and type 'custom' into the search bar to get the "Create Custom Event" option.  This will create a new function that will be called every time the OnPlayerInteract event fires.  


Add a 'Send Chat Message' function, and set the channel to 'Game Event'.  Create a 'Format Text' node, and set the text to be "{player} has touched the box!".  This will make the Format Text node create a 'player' pin.  


From the Player pin on the Event, we want to 'Get Player State', then from the player state, we want to 'Get Player Name'.  Connect that to the 'player' pin of the Format text box, and connect the output of that to the Message pin in Send Chat Message. You can ignore 'Team' and 'Squad' in the Send Chat Message node, as those are only relevant when sending to a team or squad channel. 




Now, put the box in your map, Add the Example Ruleset to your map's Rulesets, play in editor, and press F on the box.  






Share this post

Link to post
Share on other sites
This topic is now closed to further replies.
Sign in to follow this