Ending Matches

Ending Matches

Player cheering after winning Roblox battle royale game

Learning Objectives Students will be able to:
  • Practice modular programming by coding functions and events to end the game under two possible conditions: the timer running out or a winning player being found.
  • Use for loops and pairs() to iterate through a table and remove specific players from a game.
  • Respawn defeated players using anonymous functions and events.

Managing Defeated Players

Right now, defeated players respawn in the arena. Instead, send them back to the lobby to wait for the next match.

Code a Respawn Function

  1. In PlayerManager, create a local function named respawnPlayerInLobby().
Then, in that function:
  • Set the player's RespawnLocation property to the lobbySpawn.
  • Reload the character with player:LoadCharacter(). Remember, LoadCharacter() recreates the player at their spawn, removing any tools they had.

Connect to Player Event

To teleport defeated players to the lobby, the respawn function will have to be connected to the player’s Died event.

There is a problem though. If you connect the event as we have in the past, for example: myPlayer.Died:Connect(myFunction) - there’s not a way to get the name of the player from the Died event. The script needs that name to remove a defeated player from the table tracking active players.

To get the name of the player that triggered the Died event, use an anonymous function. Anonymous functions don’t have their own names, and can be created directly within Connect() rather than separately.

Anonymous Function Coded In Connect()
local player

Separate Named Function
local player

local myFunction()
  print(player.Name .. " is defeated")


Code an Anonymous Function

  1. To get access to the player’s Died event, in PlayerManager > preparePlayer(), add a variable for the player’s humanoid.
  1. Create an anonymous function that connects to the Died event.
  • Start by typing humanoid.Died:Connect().
  • Inside Connect(), type function(), press Enter to autocomplete end, and delete the extra parenthesis.
Check Your Function Before Moving On

Make sure the function looks exactly like above, with the correct amount of parentheses in each part.

  1. In the anonymous function, call respawnPlayerInLobby() .
Pass in player, a variable storing the player getting ready to enter a match.
  1. Start a server and play a match. Test that when a player dies, they respawn in the lobby. To defeat players, walk up to them and use your weapon until you can confirm they’ve respawned in the lobby.
Attacking Player2
Player2 in Lobby after respawning

Depending on on your game, you can test in a few different ways:

  • To kill a player, in the Server > Output Window > Command Bar, copy and paste: workspace.Player1.Humanoid.Health = 0. Press Enter to run the command. To remove other players, use Player2, Player3, etc.
  • Setting GameSettings > matchDuration to a longer time can give you more time to find and take out all players.
  • To have quicker tests, change GameSettings > minimumPlayers to smaller number, like 2.

Ending the Game

Now that defeated players respawn, start working on ending the game. Remember creating the MatchEnd event? It’ll be fired when either the timer runs out or a winner is found.

To tell other scripts which condition ended the game, create a table with variables for TimerUp and FoundWinner. When the match end event fires, it’ll pass in a variable so other scripts can respond.

  1. In GameSettings, create an empty module table named endStates.
  1. Create two variables named TimerUp and FoundWinner. Set each to a string matching their name. These strings will be used to test the code.

Time Up Ending

When the timer ends, fire the Match End event and send the matching end state variable. That way, other scripts listening for that event can respond accordingly. Remember that while events fire signals, that can also send data that’s received by listening scripts, like TimerUp or FoundWinner.

  1. In GameManager, in the while true do loop, find the line matchEnd.Event:Wait().
At the start of the line, add local endState =.
  1. To confirm that the correct state was received, add a print statement including endState.
  1. In MatchManager, find timeUp() and remove the print statement.
To fire the match end event:
  • Type matchEnd:Fire().
  • Pass in: gameSettings.endStates.TimerUp.
  1. Test a match. Once the timer runs out, check that the print statement includes the string stored in the TimerUp variable.
  • Check that wherever the end state variables are called, that they’re written exactly, like here: gameSettings.endStates.TimerUp
  • Make sure to use : (colon operator) with the Fire() instead of the dot operator, like in matchEnd:Fire()

Winning Player Ending

Matches will also end if one player is left. To see if the FoundWinner condition is met, you’ll need a function that checks the number left in the table tracking players in a match.

Check Player Count

  1. In PlayerManager, define the following variables:
  • ModuleScripts folder
  • GameSettings module - Used to access end state variables.
  • Events folder and the MatchEnd event - Fires event.
  1. Above respawnPlayerInLobby(), add a new local function named checkPlayerCount().
  • Remember, to be in scope, this function needs to come before the functions that will use it later in the script.
  1. Within that function, use an if then statement to check for a winner.
  • Check if the size of the activePlayers table is 1.
  • If so, fire matchEnd and pass in gameSettings.endStates.FoundWinner.

Remove a Player

When a player is defeated, keep an accurate player count by removing them from the player table. Then, check the size of the active player table to see if there’s a winner.

  1. Under checkPlayerCount(), create a new local function named removeActivePlayer() with a parameter named player.
  1. To find the player in the activePlayers table:
  • Use a for loop with pairs() that goes through the activePlayer table.
  • Then, add an if statement that runs if a player matching the name passed into the function is found.
Keep Similar Variable Names Different

As you code, may sure you don’t have overlapping variable names, like the above function which includes two versions of player: player and whichPlayer.

For instance, adding which to a variable name in an iterating table is a good convention to avoid confusion, such as whichPlayer or whichPart.

  1. To remove the player, in the if statement:
  • Call table.remove(). Remember remove() takes two parameters, the table to access, and the index of the item to remove. Pass in:

    • activePlayers - the table to look in.
    • playerKey - the player to remove from the table.
  • Set the value of the playersLeft object to #activePlayers.
  • Check for a winning player by running checkPlayerCount().

Connect and Test

To use the function just created, call it from within the anonymous function connected to the player’s Died event.

  1. Find preparePlayer(). In the anonymous function with the Died event connection, call removeActivePlayer().
Then, pass in the player as the parameter.
  1. To see if a winning player is found, start a test server. When there is only one player left you should see FoundWinner in the output window.
  1. Continue testing and let the match end. Notice as a new match starts, an error appears in the Output Window:

This error is because the timer wasn’t stopped, which will be fixed in the next section.

Stopping the Timer

Whenever a match ends with a winning player, the timer should stop as well. To halt the timer before time is up, have the timer stop whenever the match end event fires. This is one of the benefits of creating events. They can be reused in multiple situations to script cause and effect relationships.

  1. In MatchManager, create a new local function named stopTimer()
Inside, type myTimer:stop() to halt the timer.
  1. To stop the timer when the match ends, connect the matchEnd event to stopTimer().
  1. Test that the previous error no longer appears by starting a test server. Eliminate all but one player and then wait a few seconds once the match ends.

Next Steps

While the two win conditions are finished, there are still some tasks left to finish the game loop. For instance, the winning player isn’t ever teleported to the lobby. In the next lesson, you’ll display how the match ended to players and reset the game, finally completing the whole loop.

Using your knowledge of how to create end state variables and events, code a different way to end the game. Some examples include getting to a specific part in a race or touching a trap part.

  1. Code a new variable in GameSettings.endStates.
  2. Add a gameplay element that fires the Match End event. When firing the event, send the newly created end state variable through.

Finished Project Sample

Project File

Download the finished project.


Previous Creating a GUI Next Cleanup and Reset