There have been a lot of threads asking “how do I patch exploiters”. A lot of common methods keep on getting mentioned, but one I haven’t seen used may be able to catch the most common time-saving exploit: teleport exploits. Since some games benefit by teleporting, like The Labyrinth where you could teleport from the lobby to the end and save between 20 minutes and 1 hour, it is an incentive for exploiters to get resources faster. Depending on how the game is set up, teleport exploits can be mitigated by visualizing the game as a state machine.
As a note going forward, the goal is to stop players from drastically speeding up resource gathering beyond what was intended; not stop them from teleporting altogether. Teleport can still be done at a slow enough pace and over short enough distances where it can be indistinguishable from a player with a lot of practice on a slow connection.
What is a State Machine?
When designing software, you may need to have specific function work in only certain conditions, or a “state”. As an example, a plane’s landing gear should only be able to go up if they are flying. It is possible to do it with just basic inputs, but it can be difficult. As an example, here is where the state is defined implicitly (needs to be calculated):
local IsTaxiing = (Speed <= STALL_SPEED and VerticalSpeed == 0)
local IsStalling = (Speed <= STALL_SPEED and VerticalSpeed ~= 0)
local IsFlying = (Speed > STALL_SPEED and not IsStalling)
This example doesn’t seem that bad, but more modifications will be required if more states are needed, like IsReversing
and IsDescending
. The solution to this is a “Finite State Machine” (or just “State Machine”), which is a system that contains several explicit states with specific conditions that allow the state to move from one state to another. At any given time, the system has only one state. For the original example, checking the states become a lot easier with explicitly defined states:
local IsTaxiing = (PlaneState == “Taxiing”)
local IsStalling = (PlaneState == “Stalling”)
local IsFlying = (PlaneState == “Flying”)
Diagrams
There are several different methods of diagramming state machines. For this tutorial, I will be using the UML State Diagram method. States are defined as rectangles with the state name, with the arrows (aka transitions) using the format of action that causes state change [condition] / additional action
. A circle is also used to define the initial state. For the plane example, here is a possible state machine to represent it:
Tools For Diagrams
There are tools for creating various UML diagrams. If you have an EDU email account or are willing to pay for a premium plan, I would recommend LucidChart for the user experience and support. If you don’t get a premium account, you will be limited to 60 objects (rectangles, text, and arrows). If you want something that a bit inferior in terms of user experience for creating diagrams, but is accountless and can interface with many cloud storage options, I would recommend draw.io. For this thread, I used draw.io.
Using State Machines To Catch Teleporters
Character Position States
The simplest method that you can use to catch these exploiters is to use either region checks or part collisions. As an example with zones A, B, and C, where A is connected to B and B is connected to C, A to B and B to C are valid transitions while A to C is not. If a transition from A to C is attempted, the player can be considered exploiting. The valid transitions can be pictured as the following, with invalid transitions (dashed) considered as exploits:
Additional Checks
The simple approach may work for a while, but eventually, exploiters will figure out a way around it (ex: teleport from A to B and B to C). To combat this, additional requirements for transitions can be added. These include:
- Time requirements: If a zone takes time to cross, being lower than this time can detect teleporters. Be aware that if the player gets flung, this may cause a false positive.
- Path requirements: If zone C has a door, the door being open can be a condition to check for.
- Tasks requirements: If zone C requires a button to be pressed, checking if the player activated a button can be a condition to check for. This may be redundant with the path check since tasks typically unblock a path.
- Tool requirements: If zone C requires a key, checking if the player has a key can be a condition to check for.
More options exist depending on what the game or system is.
Planning Intended Teleports
If your game intentionally teleports players for specific events, it will need to be worked into your system. A simple way to get around this is having a temporary state that allows teleportation and having the transition out of the state being the teleportation.
Example: Escaping in The Labyrinth by Nitenity Studios
The Labyrinth is the first game I thought of for applying this type of system because of how common teleporting was. When I entered one day, the changelog showed that the coins reward was removed from escaping the maze (commonly 20 minutes - 1 hour) because of people teleporting and causing an increase in the number of lootbox items into the trading system.
Overview of Escaping in The Labyrinth
The Labyrinth is composed of four main sections: the lobby, the maze, the labyrinth, and the escapes (4 different escapes exist, each with different obstacles). To escape the maze, you need to exit the lobby through a door into the maze, exit the maze through a door into the labyrinth, exit the labyrinth through a door to the exit sections, and getting to an escape. The first door opens during the day, and the others open at night, with days and nights being 6 minutes apart. Each in-game night, only 1 of the 4 doors for the exits open. If you die, you return to the lobby.
Escaping in The Labyrinth as a State Machine
Since the sections involve passing through doors, those can be used as transactions rather than having to do constant region checks on a non-rectangular shape. The map is also very large, so a time requirement can also be built into the sections. Using this, the state machine looks like this (ignoring player deaths):
Example: Jewelry Store Robbery in Jailbreak by Badimo
Jailbreak is a very well known game on the Roblox platform based on being a criminal or a police officer. There are several different robbery types, but the Jewelry store has been targeted a lot recently. Typically it takes 2-3 minutes, but current teleport exploits allow it to be done in less than 10 seconds. This doesn’t have an effect on the game’s economy since there is no trading and donations are very limited, but it does prevent other players from being able to complete the robberies.
Overview of Robbing the Jewelry Store in Jailbreak
When the Jewelry Store opens, one of two glass windows needs to be breached. After entering the store and breaking a glass display with jewelry, a security wall will block off the window entrance. After the player collects as much as they want, they need to complete 3 floors of obstacles and exit through a door on the roof, then go to the criminal base to redeem the reward. If a player doesn’t enter the glass window before the robbery starts, they can enter through the roof exits but have to complete the obstacles.
Robbing the Jewelry Store as a State Machine
Depending on the implementation, there can be as many as 6 states (Outside, Floor 1, Floor 2, Floor 3, Floor 4, Roof). To keep the diagram small, only the 5 states will be used:
Example Implementation
About a month ago, I created a demo for The Labyrinth to decrease the number of exploiters flooding the trading system with coins. The code is now open sourced and can be demoed in Studio. It doesn’t fully match the state diagram above, but it is close.