How to Teleport Players in Roblox (TeleportService)
Last updated:
Quick answer: To teleport players inside one place, move the character on the server with character:PivotTo(targetCFrame); to move players to a different place in the same experience, call TeleportService:TeleportAsync from a server Script with the destination place ID.
A Roblox teleport script does one of two jobs. Inside a single place, it repositions a character by pivoting the model to a new CFrame on the server. Between places — lobby to minigame, hub to arena — it calls TeleportService, which hands the player off to a server running the destination place. Both are simple calls; the details that matter are running them on the server, handling the physics so players do not get flinged, and validating every request so exploiters cannot teleport themselves where they should not be.
How do you teleport one player to a part with CFrame?
Move the whole character model with PivotTo. It takes any CFrame and repositions the model and everything welded to it, so held tools and accessories come along:
local function teleportCharacter(character, targetCFrame)
character:PivotTo(targetCFrame)
-- Zero the leftover velocity so a mid-air teleport cannot fling the player
local rootPart = character:FindFirstChild("HumanoidRootPart")
if rootPart and rootPart:IsA("BasePart") then
rootPart.AssemblyLinearVelocity = Vector3.zero
rootPart.AssemblyAngularVelocity = Vector3.zero
end
end
-- Example: send a player five studs above a target part
local target = workspace:WaitForChild("TeleportDestination")
local character = player.Character
if character then
teleportCharacter(character, target.CFrame * CFrame.new(0, 5, 0))
end
Setting HumanoidRootPart.CFrame directly also works — it is the same anchor point PivotTo uses under the hood — but PivotTo keeps the whole model consistent and is the call to reach for first. Learn the CFrame maths in the CFrame and Vector3 guide if the offsets above are unfamiliar.
Two rules make this reliable. Offset the destination upward (CFrame.new(0, 5, 0)) so the character is not teleported inside the floor. And run the teleport in a server Script, not a LocalScript: the server is authoritative over character positions, and a client-side teleport is exactly what an exploiter can fire at will to skip walls or jump to a locked area.
How do you make a teleport pad with Touched?
The classic teleport pad is a part whose Touched event moves whoever steps on it — with a debounce so one touch does not fire the teleport ten times:
local Players = game:GetService("Players")
local pad = workspace:WaitForChild("TeleportPad")
local destination = workspace:WaitForChild("TeleportDestination")
local cooldown = {}
pad.Touched:Connect(function(hit)
local character = hit.Parent
local player = Players:GetPlayerFromCharacter(character)
if not player or cooldown[player] then
return
end
cooldown[player] = true
character:PivotTo(destination.CFrame * CFrame.new(0, 5, 0))
task.delay(2, function()
cooldown[player] = nil
end)
end)
The debounce matters because Touched fires constantly as limbs brush the part — without the cooldown table, a single step triggers the handler several times over. task.delay releases the lock after two seconds so the player can use the pad again. The event itself is covered in depth in the Touched event guide, including why passing a character check through GetPlayerFromCharacter beats checking for a Humanoid alone (NPCs have Humanoids too).
How do you teleport every player to a map at once?
Round-based games teleport the whole server to an arena when a round starts, then distribute players across spawn points:
local Players = game:GetService("Players")
local function teleportEveryoneToMap(mapSpawns)
local players = Players:GetPlayers()
for index, player in players do
local character = player.Character
if character and character.Parent then
local spawnPart = mapSpawns[(index - 1) % #mapSpawns + 1]
character:PivotTo(spawnPart.CFrame * CFrame.new(0, 5, 0))
end
end
end
The modulus spreads players over the spawn parts no matter how many join. In a real round flow this call sits between "intermission over" and "round starts": teleport everyone in, then arm the round logic. Player counts, spectating players who joined mid-round, and respawns during the round are all handled by the surrounding round state machine — see the round system tutorial for the full loop. For two players who should share an exact spot (a duel, a co-op puzzle), give each their own spawn part rather than reusing one CFrame and fighting over it.
How does TeleportService move players between places?
When the destination is a different place in the same experience, no CFrame can help — the player has to load a new place on a new server. That is TeleportService's job. The modern call is TeleportAsync, which takes a place ID and a list of players:
local TeleportService = game:GetService("TeleportService")
local MINIGAME_PLACE_ID = 123456789 -- replace with your place ID
local function sendToMinigame(player)
local success, err = pcall(function()
TeleportService:TeleportAsync(MINIGAME_PLACE_ID, { player })
end)
if not success then
warn("Teleport failed for " .. player.Name .. ": " .. tostring(err))
end
end
The older TeleportService:Teleport(placeId, player) still works but the official docs mark it as not intended for new work, having been folded into TeleportAsync — use TeleportAsync (or TeleportPartyAsync below) in anything you write today. Wrap the call in pcall like every other network-facing Roblox API: teleports can fail on bad place IDs or service hiccups, and Roblox also fires TeleportService.TeleportInitFailed with a reason and retry information when a teleport does not start.
Useful variations of the same call:
- Send the whole party to one server.
TeleportService:TeleportPartyAsync(placeId, players)moves a table of players together, keeping the group on the same server — the natural call for a party leaving a lobby for a co-op map. - Reserve a private server with
TeleportService:ReserveServer(placeId)andTeleportToPrivateServer, or aTeleportOptionsobject withShouldReserveServer = true, when the group needs a fresh empty instance (a raid, a private match). - Pass context along with
teleportOptions:SetTeleportData({ ... })and read it on the other side withTeleportService:GetLocalPlayerTeleportData(). Fine for presentation hints like which spawn to arrive at. Do not trust it for anything valuable — Roblox explicitly notes teleport data can be spoofed, so currencies and progress must travel through your own DataStore save flow instead.
How do you stop teleport exploits?
Every teleport path has to be server-authoritative, because each one is a door an exploiter will try to open:
- Never teleport from a LocalScript. If a player should request a teleport (a menu button, a "go to lobby" key), the client fires a RemoteEvent and the server decides. That is the standard server-side validation pattern applied to teleports.
- Validate the request, not just the caller. Check the player is actually in the state that allows the teleport: in the lobby, in the round, on the pad. An exploiter firing your RemoteEvent directly is otherwise "teleport to the arena five rounds early" for free.
- Whitelist destination place IDs. If the client can suggest a destination at all, the server compares it against a fixed table of your own place IDs. Never feed a client-supplied ID straight into
TeleportAsync. - Treat teleport data as decorative. Anything read from
GetLocalPlayerTeleportDatamust be re-verified server-side or ignored.
Common mistakes that make teleports misbehave
- Flinging instead of teleporting. Moving a falling character without clearing
AssemblyLinearVelocityleaves the old momentum in place — the character arrives at speed and launches. Zero both velocities right afterPivotTo. - Teleporting into geometry. A destination CFrame exactly on a part's surface lands the character inside it. Offset upward by a few studs.
- No debounce on Touched pads. The handler fires per limb contact and re-teleports the player mid-arrival.
- Testing TeleportService in Studio. This one is not your bug: the official docs state TeleportService does not work during playtesting in Studio. Publish the experience and test in the Roblox app.
- Forgetting pcall around TeleportAsync. A bad place ID then throws instead of warning, killing the surrounding round logic.
Learn Luau by doing
Teleport scripts are small enough to write from memory once the pieces click — but the pieces only click through practice. On Luablox you can write Luau in the browser through the free course on /learn/roblox-scripting-for-beginners, drill specific mechanics on /problems, and browse the API notes in /theory while you build. Start with the pad, break it on purpose, and fix it: that loop teaches more than any single teleport snippet.
Frequently asked questions
Why does my teleport fling the player in Roblox?
Usually leftover velocity. When you set a character CFrame or call PivotTo, the old AssemblyLinearVelocity and AssemblyAngularVelocity survive, so a character that was falling or moving arrives at the new spot still carrying that momentum and launches. Zero both velocities on the HumanoidRootPart right after the teleport, and offset the destination a few studs above the floor so the character is not spawned inside geometry.
How do I teleport all players at once in Roblox?
Iterate Players:GetPlayers() and call character:PivotTo() for each one on the server, distributing them over your map spawn parts — this is the standard round-start teleport. If "at once" means a different place in your experience, call TeleportService:TeleportAsync(placeId, players) with the whole player list, or TeleportPartyAsync to keep the group on the same server.
Can Roblox TeleportService teleport players between two different games?
TeleportService is built for places and servers within the same experience — teleporting to a completely different experience is blocked by default and requires cross-experience teleportation to be enabled on the experience. The normal design is multiple places under one experience: a lobby place plus minigame places, connected with TeleportAsync.
Does TeleportService work in Roblox Studio?
No. The official documentation states that TeleportService does not work during playtesting in Studio — to test teleports you must publish the experience and play it in the Roblox application. In-place CFrame teleports via PivotTo do work in Studio, so develop and debug those locally and test place-to-place teleports on the published experience.
Should I teleport the player from a LocalScript or a server Script?
Always from a server Script. Character positioning and TeleportService are server-authoritative, and a client-side teleport is trivially fired by an exploiter to skip walls, locked areas, or round restrictions. If the player initiates the teleport, fire a RemoteEvent and let the server validate the request before moving anyone.
Learn core Roblox scripting and Luau programming concepts, including: roblox teleport script, teleport service roblox, TeleportService tutorial, roblox teleport player to part, teleport pad roblox.