How to teleport in Roblox scripting

Learning how to teleport in Roblox scripting is great for those with large game worlds. You can create a massive world by separating them into separate places. This separation creates the best player experience as you’ll soon learn.

In this post, you’ll learn:

  • Why teleporting players is needed and useful
  • How to teleport all players or certain players
  • Important things to consider with player data
  • How to use custom load screens
  • Lots of code examples to use
  • How Robox services work with events

Why we need to teleport players

Teleporting players helps a lot with your game’s performance by making it feel seamless and immersive. 

As a beginner you might create your entire world in a single map or place, but this will also affect the load time of your game. No one wants to play a game that takes several minutes to load.

You can teleport all players to a fun mini-game or teleport only specific players when they reach a certain point in your world. If you’re looking to create a game with random group mini-games then it makes the most sense to use separate places. 

You might even want to teleport players that have bought a game pass to exclusive levels or servers!

How to teleport players

Keep this in mind when designing your player teleporting scripts

  • TeleportService must use a server-side Script
  • TeleportService does not work during playtesting in Roblox Studio
  • Your game must be published before testing teleportation
  • Large worlds should use a custom load screen

First, it’s recommended to use a ModuleScript since teleporting may fail. Within this module, the script will retry several times when a teleportation fails.

Since TeleportService only works in a server-side Script, we’ll use a RemoteEvent to trigger this action. If you’re not familiar with RemoteEvent, check out my post on how Roblox games work.

Now, let’s make sure we have everything we need to create a working example.

How to get place id in a game

  1. Open Roblox Studio
  2. Open your game for editing
  3. Within Asset Manager, select places
  4. Right click within asset manager and select “Add New Place”
  5. Right click your new place and select “Copy ID to Clipboard”
  6. Paste your place id into your script

Module Example

Calling TeleportService:TeleportAsync may fail to run, so it’s recommended to use a recursive function that will call this function several times. 

local teleportService = game:GetService(“TeleportService”)
local replicatedStorage = game:GetService(“ReplicatedStorage”)

local TeleportModule = {}

local DELAY = 2
local RETRY_LIMIT = 10
-- attempts made = RETRY_LIMIT / DELAY
-- 10 / 2 = 5 attempts over 10 seconds

local teleportEvent = Instance.new(“RemoteEvent”)
teleportEvent.Name = “TeleportEvent”)
teleportEvent.Parent = replicatedStorage

function TeleportModule.teleportPlayers(target, players, options)
  local delayElapsed = 0

  teleportEvent:FireAllClients(players, true) -- triggers loading screen

  local function doTeleport(players, options)
    If delayElapsed < RETRY_LIMIT then

      local completed, error = pcall(function ()
        return TeleportService:TeleportAsync(target, players, options)
      end) -- end of lambda
    
      if not completed then
        wait(DELAY)
        delayElapsed = delayElapsed + DELAY
        doTeleport(players, options)
      end
    else
      -- update all players that teleporting completed
      teleportEvent:FireAllClients(players, false)
      return false
    end
  end

TeleportService.TeleportInitFailed:Connect(function (player, result, error)
  if result ~= Enum.TeleportResult.Success then
    warn(error)
    wait(DELAY)
    delayElapsed = delayElapsed + DELAY
    doTeleport(players, options)
  end
end)

end -- end of module

return TeleportModule

This module will try 5 times over a 10 second period before it returns an error.

When and how to use pcall function

The pcall function (protected call) is a core Lua function. It allows your script to handle any errors in your script. Without using pcall, any errors get returned within the core Roblox code; code that we don’t have direct access to. The pcall function will return a completed boolean value and any error messages. 

We can use the error message to handle them for each special case too.

How to use module scripts

When you find yourself writing the same code in your scripts then you should use module scripts. Module scripts allow us to reuse common code in any script. This concept follows the best practice known as the DRY principle or “don’t repeat yourself”.

Be careful with how you set up your module dependencies. You might find yourself in a chicken or egg situation (which comes first?). This happens when modules depend on one another, otherwise known as a circular dependency..

Example

  • Module A requires Module B
  • Module B requires Module A

In this scenario, neither module can complete itself and will cause your scripts to fail.

The key here is to keep it simple and avoid any extra cleverness in these dependencies. 

Keep modules self contained to one logical set such as:

  • Graphics functions
  • Math functions
  • Player functions
  • Marketplace functions
  • Teleporting functions
  • CFrame functions

To use a module script in another script, simply follow this pattern:

local moduleObject = require({location of module})

In Roblox scripts, your modules get stored in ReplicatedStorage.

local replicatedStorage = game:GetService(“ReplicatedStorage”)
local someModule = require(replicatedStorage:WaitforChild(“INSERT_MODULE_NAME”))

In Roblox Studio, your module name will use the name you set on the script itself.

Examples

Let’s look at some examples of how to use the TeleportService.

Teleport when a part is touched

If you have a starting room when players join your game, you can have different teleportation pads that take players to different areas. Your script will handle events for when a player touches the pad and leaves the pad. 

From the BasePart class, we’ll use two functions

  • Touched
  • TouchEnded
Code example
local replicatedStorage = game:GetService(“ReplicatedStorage”)
local players = game:GetService(“Players”)

local teleportPad = script.Parent -- this script is part of the teleportation pad model
local placeId = <add your place id>

local TeleportModule = require(replicatedStorage:GetChild(“TeleportModule”)
local function teleportPadTouched(playerPart)
  local player = players:GetPlayerFromCharacter(playerPart.Parent)
  if player and not player:GetAttribute(“is_teleporting”) then
    player:SetAttribute(“is_teleporting”, true)
    local result = TeleportModule.teleportPlayers(placeId, {player})
    player:SetAttribute(“is_teleporting”, false)
  end
end

teleportPad.Touched:Connect(teleportPadTouched)

Of course you can modify this to work with anything that needs to teleport players when touched.


To add a small delay before players teleport, we’ll use the wait function.

local replicatedStorage = game:GetService(“ReplicatedStorage”)
local players = game:GetService(“Players”)

local teleportPad = script.Parent -- this script is part of the teleportation pad model
local placeId = <add your place id>

local TeleportModule = require(replicatedStorage:GetChild(“TeleportModule”)
local function teleportPadTouched(playerPart)
  local player = players:GetPlayerFromCharacter(playerPart.Parent)
  if player and not player:GetAttribute(“is_teleporting”) then
    player:SetAttribute(“is_teleporting”, true)
    wait(3) -- wait 3 seconds
    If player:GetAttribute(“is_teleporting”) then
      local result = TeleportModule.teleportPlayers(placeId, {player})
      player:SetAttribute(“is_teleporting”, false)
    end
  end
end

-- updates player’s attributes when leaving teleport pad
-- player will have 3 seconds to leave the pad before they’re teleported
local function teleportPadNotTouched(playerPart)
  local player = players:GetPlayerFromCharacter(playerPart.Parent)
  if player
    player:SetAttribute(“is_teleporting”, false)
  end
end

teleportPad.Touched:Connect(teleportPadTouched)

Here we reset the is_teleporting attribute to false when the player leaves the pad. When the part is touched, we wait 3 seconds and teleport the player if the player still has is_teleporting set to true.

Teleport by player action

Instead of using parts to teleport players, we could instead use a Gui screen for a player to select a location. For this we’ll need to use a RemoteEvent in a server script.

Code example
-- server Script
local replicatedStorage = game:GetService(“ReplicatedStorage”)
local TeleportModule = require(replicatedStorage:GetChild(“TeleportModule”)

local teleportEvent = replicatedStorage:WaitForChild(“TeleportEvent”)
teleportEvent.OnServerEvent:Connect(function(player, target)
  local result = TeleportModule.teleportPlayers(target, {player})
end)

-- client LocalScript
local replicatedStorage = game:GetService(“ReplicatedStorage”)
local button = script.Parent
local target = {your target place id}

local teleportEvent = replicatedStorage:WaitForChild(“TeleportEvent”)
local function buttonPressed()
  teleportEvent:FireServer(target)
end

button.Activated:Connect(buttonPressed)

Data considerations

Secure data such as a player’s currency balance or inventory must use data stores. With a data store you can reload the player’s data once they’ve reached their next destination. Secure data allows the game to restore the player’s properties and inventory when they return later for another gaming session.

Other data such as player health or other replaceable attributes should use TeleportOptions. Before calling your TeleportModule, create an instance of TeleportOptions and set the data using the SetTeleportData function. This type of unsecured data only lasts as long as the player is in the game.

Example

-- server Script
local options = Instance.new(“TeleportOptions”)
options:SetTeleportData({ health = player.health })
local result = TeleportModule.teleportPlayers(target, {player}, options)

-- client LocalScript
local teleportService = game:GetService(“TeleportService”)
local players = game:GetService(“Players”)

local player = players.LocalPlayer
local character = player.Character
if not character or not character.Parent then
  Character = player.CharacterAdded():Wait()
end

local teleportData = TeleportService:GetLocalPlayerTeleportData()
if teleportData and teleportData.health then
  local humanoid = character:WaitForChild(“Humanoid”)
  humanoid.Health = teleportData.health
end

Custom load screens

Using a custom screen built in a script

Teleportation can appear near instantaneous or take as long as it needs to load the target destination. Once we’ve defined our Gui, we can attach the screen using the SetTeleportGui function on the TeleportService.

Example

-- client LocalScript
local teleportService = game:GetService(“TeleportService”)
local replicatedStorage = game:GetService(“ReplicatedStorage”)
local players = game:GetService(“Players”)

local player = players.LocalPlayer
local playerGui = player:WaitForChild(“PlayerGui”)

local teleportEvent = ReplicatedStorage:WaitForChild(“TeleportEvent”)

local screen = Instance.new(“ScreenGui”)
screen.IgnoreGuiInset = true
screen.Enabled = false
screen.Parent = playerGui
local textLabel = Instance.new("TextLabel")
textLabel.Size = UDim2.new(1, 0, 1, 0)
textLabel.BackgroundColor3 = Color3.fromRGB(0, 30, 60)
textLabel.Font = Enum.Font.GothamSemibold
textLabel.TextColor3 = Color3.new(0.5, 0.5, 0.5)
textLabel.Text = "Teleporting to new adventures..."
textLabel.TextSize = 32
textLabel.Parent = screenGui
 
TeleportService:SetTeleportGui(screenGui)
 
teleportEvent.OnClientEvent:Connect(function(playersTable, enable)
  if table.find(playersTable, player) then
    screenGui.Enabled = enable
  end
end)

Using a pre-built screen

You can also do the same for any pre-built screens you have under StarterGui.

Example

local teleportService = game:GetService("TeleportService")
local replicatedStorage = game:GetService("ReplicatedStorage")
local players = game:GetService("Players")
 
local player = players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
 
local teleportEvent = replicatedStorage:WaitForChild("TeleportEvent")
 
local screen = playerGui:FindFirstChild("TeleportScreen")
screen.IgnoreGuiInset = true
 
TeleportService:SetTeleportGui(screenGui)
 
teleportEvent.OnClientEvent:Connect(function(playersTable, enable)
 
  if table.find(playersTable, player) then
    screen.Enabled = enable
  end
end)

What’s Next?

Now that you’ve learned how to teleport in Roblox scripting. This should guide you to explore other services Roblox has available in their creation engine. You should now understand a bit more how services work and how they interact with screens, events, and other classes. 

Coming up next we’ll go over how to create a sequence of events in your game.

Let’s continue your journey by reviewing how Roblox games work.

Stay curious!

Leave a Reply

%d bloggers like this: