Round 3 Manager

Nodes used within this script

med_riot_05_script – the overall controller script of this round
med_riot_05_vstore – what tells the round when to start and finish
med_riot_05_vstore_counter – what keeps track of the character count

Figure 1

Figure 2

Round 3 overview

This is a technical breakdown of one of the rounds within the Riot Control game mode. Since Riot Control is based on a rounds system, it’s quite easy to control the sequence of events that happen within the round. There are a few basic rules to follow…

  • It must start
  • It must finish
  • It cannot get stuck anywhere
  • It is easy to adjust for quick iteration

If you look at figure 1 above, you will see it is broken down into 7 separate sections. It contains 1 starting area, 5 group stages and a finishing section. (This will be broken down later in this document).

Now have a look at figure 2. This is an overview of the world tree. Concentrate on the med_riot_05 area. The other rounds are present in the picture but you can see that each round is completely separate from the next, and is a self contained unit.

  • The top node of the round is a group node. It was chosen to be a group node as you can call functions upon it when required that assist the flow of the round.
  • Below the parent node are the three controlling nodes of the round. Then following those you have the sub groups (med_riot_05a, b, c, d, and e) which are called upon during the round at a specific time.
  • And finally you have the characters that reside under the sub groups. Each character has a script on them. This is the random_entry_point_script (and will be covered elsewhere).

Every round is setup in the same way, parent group\sub groups\characters. This helps debugging problems later in development where everything is the same and less design time wasted using different systems to achieve the same result. This has proven to be a robust and manageable system for tweaking and adjusting just a few details that can completely change the flow of the round.

Round 3 Breakdown
Part 1

Figure 3

This is the starting position for all the round scripts. They all work the same way for every round.

  • First up is the starting block, then moving into a blank holding state.
  • Now we have our first condition for the round. This checks to see if it is its turn to run. It is looking for the med_riot_05_vstore to be set to a value of 1. What tells which round script to run is the riot_full script (covered in another document). Once it has reached a value of 1 the script can progress.
  • Now we stream in any relevant packages required to run. It could be animation / sector or character data tables, or all three. Riot control – Danvers Island only needed to swap out the character data tables once (to replace Riggs with Redwater).
  • The 2nd condition block checks to see if everything you have told it to stream in is loaded before continuing the script. (safety check)
  • Now the last state block in figure 1 starts the round timer. This keeps track of how long it took you to play this individual round.
Part 2

Figure 4

In part 1 we did all of the setup & configuration of the round. Now we get into the part that deals with bringing the characters into the world (going clockwise).

  • First up I’ll give a brief description of what is going on within these 4 state machine blocks.
  • The first block tries to bring 1 character in at a time from the specified sub group A (med_riot_05a). (See part 4 for a more detailed breakdown).
  • Then it asks how many people there are in the active sub group A (med_riot_05a). Here you set how many people you want alive / in game (tie this in with how many characters you have actually placed in sub group A (med_riot_05a)).
  • Then a blank state for a frame delay.
  • Then the last condition is checking for how many characters you have spawned from this group.
  • Now if the number above is less than what it is asking for, it feeds off of the NO and back into the first spawning block, to bring another character from the same group into the world. This will cycle around inside this loop until you have reached the correct number of characters spawned from the sub-group A (med_riot_05a).
  • When the required amount of characters has been reached, it can feed off of the YES of the last condition block to continue the script / round.
Part 3

Figure 5

This is the next part that follows the previous section, in figure 4. So previously we spawned all the required characters from group A and are now testing how many are alive and active before we spawn the next group.

  • First block is just a blank state.
  • The 2nd is a condition block that will test for the active characters in group A. By controlling the amount of characters here before the next group is spawned, we can definitely make sure that we are spawning a reasonable amount of characters that the game can handle at once.
  • As you all should know, DTR can have a maximum of 15 active characters at once, but in practice, I would suggest that 10 – 12 should be the absolute maximum running around at any one time (CPU & GPU overhead).
  • So, the simple calculation we do here is… How many are alive now? + How many do I want to bring into the world? If the combined total of the previous group and the next group are less than 10 -12, continue.
  • In this particular situation, I spawned 6 characters from group A, and then test for 5 active characters in group A, before I bring in the next group (which has a total of 3 characters in group B). This now means that the active character count will be 8.
PART 4

This deals with the next sub group, group B. Technically this system will be a repeat of the group A actions and for every sub group after. All that I have changed is the amount of active characters that are within that group and the supporting code to back it up.

Figure 6

  • The first action that we call is fasetvaluestorenodename. This works on the node spawn_name_vstore. What it does, is it changes the name of that node to the name of the group that you are currently trying to spawn. (This requires its own tutorial, but this will do for now).
  • This node is referenced within the spawn_point_script so the two systems are independent of each other and all the other rounds use this without interfering with any other.
  • Basically, every time you spawn someone from a different group, you have to set the name of this node to the name of the group you want to spawn from.

Figure 7

  • Now look at figure 7. The second action we call upon is famodifyvaluestore. This node is also referenced within the spawn_point_script. This is what tells it to pick a spawn point for this character you are enabling. It does this by increasing the value of the spawn_request_vstore by 1.
  • Now we know from the previous tutorial that the spawn_point_script is constantly waiting for a spawn request to come in, and this is where those requests come from.
  • Then last of all in this action list is a fawait command to just add a little time buffer into the looping script.

Ok, so to save repeating myself I won’t go through all of this again for each sub group, since they all work in exactly the same way. I will now move onto how we finish the round.

Part 5

Now we are coming to the end of the round and we need to tie up all the loose ends and bring the script to a close.

Figure 8

  • First off I call a faaiscriptcommandmove command on all of the characters within the round to make them move to the player. I do this because it is a timed based scoring system, and the player would appreciate not having to hunt down the last few remaining stragglers to end the round.
  • Then the next condition asks if there are only 3 active characters left in the round. You do this by calling the function activecharactersincharactergroup on the top node of the round in the world tree.
  • This is where it helps by having the parent node of the round a character group node. We know there has to be no-one left alive to end the round, so rather than calling the above function on every individual sub group you only have to do it once on the parent.

Figure 9

  • Now I can start calling on a few special functions. First I call a special function to highlight all the remaining enemies (the remaining 3) so you can see them easier.
  • Then it plays an audio line for 3 enemies remaining, then tests for 2 enemies remaining and finally 1, each time playing the specific audio for the remaining characters.
  • Also on the last character I specify an action to run on the last man standing. If you do a takedown on the last person, bonus points are awarded.
  • At this time I also call on the function to put the last takedown camera back into normal game mode (instead of the full speed Riot Control camera).
  • Then in the last condition in figure 9, we test if all characters in the overall round are dead. Now following this it is safe to start to shutdown the round script and reset all of the game functions back to default for the next round.

Figure 10

  • Here in the first state block, we are resetting the nodes back to their default names and values that the game had changed over the course of the round.
  • I.e. round timer, spawn_name_vstore, quick takedowns re-enabled, play round end audio and call the function to shutdown the round for the scores to be totalled up and added to your overall score.
  • The last condition block is testing if the player has skipped the end of round stats screen so we can early out and start the next round.
  • Last of all we modify the value store that controls the entire round so the game knows it has finished. By increasing this by 1 again, the riot_full script will move onto the next round in its list of things to do.
  • And finally we call an action to clear away all of the guns left lying about the place from the round. The player has a few seconds to run about and find the best weapon before it times out and the next round starts.

So to round up…

That is how the Riot Control round system works. By dividing up the script up into specific sections, the start / the sub groups / the end, we can control the flow and intensity of the combat within.
Tweaking of the rounds happens via adjusting when to bring in the next sub group by increasing or decreasing the active character count on the previous group.
If you find a dead spot where there is a lull in the combat, increase the active character count to bring on the next sub group earlier. Or if you find it too difficult, reduce the number. By adjusting this float alone can make a big difference to the pacing of the game.

BACK TO THE BEGINNING