Teleport several players to a private server

Hey all! I have this code and I need to teleport all the players who touch the same part to the same private server but
this code teleports each player to a different server.
Ive tried doing that via a loop but it didn’t work…

local TS = game:GetService("TeleportService")
local Part = workspace.Part

Part.Touched:Connect(function(otherPart)
    if otherPart.Parent:FindFirstChildWhichIsA("Humanoid") then
        local success,err = pcall(function() -- to get the error incase it does error
            local code = TS:ReserveServer(game.PlaceId)
            local plr = game.Players:GetPlayerFromCharacter(otherPart.Parent)

            TS:TeleportToPrivateServer(game.PlaceId,code,{ plr })
        end)

        if not success then -- it errored, print the error
            warn("Could not teleport " .. otherPart.Parent.Name .. "! Error : " .. err)
        end
    end
end)```
1 Like

I would try something like this using the SafeTeleport module too.

The Touch script:

local TPS = game:GetService("TeleportService")
local Players = game:GetService("Players")

-- SAFE TELEPORT MODULE
local SafeTeleport = require(game:GetService("ServerScriptService"):WaitForChild("SafeTeleport"))

local idPlace = 0000000

local Part = workspace.Part

-- RESERVED SERVER DATA
local code
local pvSVid

-- DEBOUNCE IF SERVER ALREADY EXIST
local isServerExist = false

Part.Touched:Connect(function(partTouched)
	if partTouched.Name == "HumanoidRootPart" then
		local isPlayer = Players:GetPlayerFromCharacter(partTouched.Parent)
		if isPlayer then
			if Players:GetPlayerByUserId(isPlayer.UserId) then
				if not isServerExist then
					code, pvSVid = TPS:ReserveServer(idPlace)
					isServerExist = true
				end		
				if code and pvSVid then
					local teleportOptions = Instance.new("TeleportOptions")
					teleportOptions.ReservedServerAccessCode = code

					local isTPDone, TPresult = SafeTeleport(idPlace, {isPlayer}, teleportOptions)
					warn("TP done?", isTPDone)
					warn("PrivateServerId?", TPresult.PrivateServerId)
					warn("ReservedServerAccessCode?", TPresult.ReservedServerAccessCode)
				end
			end	
		end
	end
end)

The SafeTeleport Module:

local TeleportService = game:GetService("TeleportService")

local ATTEMPT_LIMIT = 21
local RETRY_DELAY = 1
local FLOOD_DELAY = 15

local function SafeTeleport(placeId, players, options)
	local attemptIndex = 0
	local success, result -- define pcall results outside of loop so results can be reported later on

	repeat
		success, result = pcall(function()
			return TeleportService:TeleportAsync(placeId, players, options) -- teleport the user in a protected call to prevent erroring
		end)
		attemptIndex += 1
		if not success then
			task.wait(RETRY_DELAY)
		end
	until success or attemptIndex == ATTEMPT_LIMIT -- stop trying to teleport if call was successful, or if retry limit has been reached

	if not success then
		warn(result) -- print the failure reason to output
	end

	return success, result
end

local function handleFailedTeleport(player, teleportResult, errorMessage, targetPlaceId, teleportOptions)
	if teleportResult == Enum.TeleportResult.Flooded then
		task.wait(FLOOD_DELAY)
	elseif teleportResult == Enum.TeleportResult.Failure then
		task.wait(RETRY_DELAY)
	else
		-- if the teleport is invalid, report the error instead of retrying
		error(("Invalid teleport [%s]: %s"):format(teleportResult.Name, errorMessage))
	end

	SafeTeleport(targetPlaceId, {player}, teleportOptions)
end

TeleportService.TeleportInitFailed:Connect(handleFailedTeleport)

return SafeTeleport
1 Like

the first script is a server script and the second one is a module script?

Yes, the first one is a Server Script, referencing the part to touch, it creates the ReservedServer and stores it in a variable, and its calling the SafeTeleport module script too, to handle the Teleport with retries if it fails. Both are in ServerScriptService

I think the Players touching the part needs another lock so they dont trigger it more than once, edit of the first script with a table:

local TPS = game:GetService("TeleportService")
local Players = game:GetService("Players")

-- SAFE TELEPORT MODULE
local SafeTeleport = require(game:GetService("ServerScriptService"):WaitForChild("SafeTeleport"))

local idPlace = 0000000

local Part = workspace.Part

-- RESERVED SERVER DATA
local code
local pvSVid

-- DEBOUNCE IF SERVER ALREADY EXIST
local isServerExist = false

-- PLAYERS WHO ALREADY TRIGGERED THE TOUCH
local PlayersActivatedTouchTP = {}

Part.Touched:Connect(function(partTouched)
	if partTouched.Name == "HumanoidRootPart" then
		local isPlayer = Players:GetPlayerFromCharacter(partTouched.Parent)
		if isPlayer then
			if not table.find(PlayersActivatedTouchTP, isPlayer) then
				table.insert(PlayersActivatedTouchTP, isPlayer)
				if Players:GetPlayerByUserId(isPlayer.UserId) then
					if not isServerExist then
						code, pvSVid = TPS:ReserveServer(idPlace)
						isServerExist = true
					end		
					if code and pvSVid then
						local teleportOptions = Instance.new("TeleportOptions")
						teleportOptions.ReservedServerAccessCode = code

						local isTPDone, TPresult = SafeTeleport(idPlace, {isPlayer}, teleportOptions)
						if isTPDone then
							table.remove(PlayersActivatedTouchTP, table.find(PlayersActivatedTouchTP, isPlayer))
						end
						warn("TP done?", isTPDone)
						warn("PrivateServerId?", TPresult.PrivateServerId)
						warn("ReservedServerAccessCode?", TPresult.ReservedServerAccessCode)
					end
				end					
			end
		end
	end
end)
1 Like

ive tested this script but all thе players get teleported to different servers

help please. I’ve been trying to edit this script so all the players got teleported to the same server this whole day but I couldn’t. im really exhausted. can u please try to edit it or at least suggest something…?

1 Like

The issue happens because, when players got teleported the main place gets empty, causing that server to close, next time a player joins the main place, and touch the teleporter, it will create a new ReservedServer different from the one the first group of players got teleported.

Its an easy fix, just save the Password of the ReservedServer into a Datastore.

When main place server starts, it will run a check of the Datastore, if no server exist it will create a new ReservedServer, and save it into Datastore. Next time a new Main Place server starts it will perform the Datastore check, but, this time the Datastore has data in it, the password of the previous ReservedServer, and it will use those values to teleport the players there. So this function will only run once, and it will never save data of a different ReservedServer, unless you change it manually.

Heres a code that will perform everything I told you:

local idPlace = 000000 -- Change it to your secondary place ID
local Part = game.Workspace:WaitForChild("Part") -- The part to touch

local DSS = game:GetService("DataStoreService")
local TPS = game:GetService("TeleportService")
local Players = game:GetService("Players")

-- DATASTORE TO SAVE A RESERVED SERVER
local ReservedServerDSS = DSS:GetDataStore("ReservedServerDSS")

-- SAFE TELEPORT MODULE
local SafeTeleport = require(game:GetService("ServerScriptService"):WaitForChild("SafeTeleport"))

-- RESERVED SERVER DATA
local code
local pvSVid

-- RUN A FUNCTION TO FIND IN DATASTORE IF A SERVER ALREADY EXIST
local success, Server = pcall(function()
	return ReservedServerDSS:GetAsync("Reseveds")	
end)

-- IF DSS GETASYNC WORKED, CHECK THE DATA, IF NO DATA CREATE A SERVER AND SAVE IT
if success then
	if Server then
		warn("A Server already exist in DSS")	
		code = Server["ServerPassword"]
		pvSVid = Server["ServerID"]
		warn("Server Password:", code, "Server ID:", pvSVid)
	else
		warn("No Server in DSS create one")
		local pass, SVid = TPS:ReserveServer(idPlace)
		if pass and SVid then
			warn("Server Reserved Sucessfully, proceeding to Save it in DSS")
			local s, err = pcall(function()
				return ReservedServerDSS:SetAsync("Reseveds", {ServerPassword = pass, ServerID = SVid})
			end)	
			if s then
				warn("Server successfuly saved")
				code = pass
				pvSVid = SVid
			else
				warn("DSS failed to save the server, do retries", err)	
			end
		end
	end
end

-- PLAYERS WHO ALREADY TRIGGERED THE TOUCH
local PlayersActivatedTouchTP = {}

Part.Touched:Connect(function(partTouched)
	if partTouched.Name == "HumanoidRootPart" then
		local isPlayer = Players:GetPlayerFromCharacter(partTouched.Parent)
		if isPlayer then
			if code and pvSVid then
				if not table.find(PlayersActivatedTouchTP, isPlayer) then
					table.insert(PlayersActivatedTouchTP, isPlayer)
					if Players:GetPlayerByUserId(isPlayer.UserId) then
						warn(isPlayer, "gonna be teleported to this Reserved Server", code, pvSVid)

						local teleportOptions = Instance.new("TeleportOptions")
						teleportOptions.ReservedServerAccessCode = code

						local isTPDone, TPresult = SafeTeleport(idPlace, {isPlayer}, teleportOptions)
						if isTPDone then
							table.remove(PlayersActivatedTouchTP, table.find(PlayersActivatedTouchTP, isPlayer))
						end
						warn("TP done?", isTPDone)
						warn("PrivateServerId?", TPresult.PrivateServerId)
						warn("ReservedServerAccessCode?", TPresult.ReservedServerAccessCode)
					else
						table.remove(PlayersActivatedTouchTP, table.find(PlayersActivatedTouchTP, isPlayer))
					end
				end					
			end
		end
	end
end)

Players.PlayerRemoving:Connect(function(isPlayer)
	if table.find(PlayersActivatedTouchTP, isPlayer) then
		table.remove(PlayersActivatedTouchTP, table.find(PlayersActivatedTouchTP, isPlayer))
	end
end)
2 Likes

The output says passed value is not a function

where? the line?
I tested that code in a game and works nicely, give me more information of the error

2 Likes

oh. nvm, my bad. it works but it teleports players to the same private server. I mean… I have different gameteleporters with a cool down. as soon as the cool down reaches 0 it teleports players to the game. so im using private servers to prevent players from joining a game which has already started.

I use doors like game teleporting elevators.

I make a story game so I just can’t let players to join in mid game

1 Like

So, players touch the teleporter and after a countdown the players will get teleported to the reserved server, then a another party of players will get teleported to a different reserved server?

With the scripts I gave you, you have all the required tools to implement it and edit it as you like, it totally depends on your needs, use the datastore and rewrite on it after the cooldown, or the teleport, maybe teleport a party of players instead of just one, maybe save multiple reserved servers on the datastore, idk the possibilities are endless, depends on what you are trying to achieve

2 Likes

you’re right, but ive been trying to do that yesterday for the whole day long and im exhausted… I have no idea how to make a different server every time

I tried doing that today too with the new script but I didn’t reach anything.

You should have a clear idea of what you are trying to do.

You need to explain or decide more details on how your teleporters going to work…
Players touch the teleporter, after a certain amount of seconds they get teleported to a reserved server, after that create a new server for the next wave of players?

  1. So you have some teleporters in the Starting Place? How many?
  2. All those teleporters are for the same subPlace ID?
  3. What means a “started game”? The subPlace has a timer? and the players will go back after that? (Honestly, you would be asking me to tune the teleport system for you, cause theres lot of information about your game that I dont know, and probably you should found how to use the scripts I gave you to adapt it to your needs, or explain fully what is the goal with details)
  1. I have 12 teleports. here’s the full code btw

local Part = workspace["Elevator 2p left"].Teleport.Telepart

workspace["Elevator 2p left"].Teleport.Telepart.Touched:Connect(function() local Part = workspace["Elevator 2p left"].Teleport.Telepart end)
workspace["Elevator 3p left"].Teleport.Telepart.Touched:Connect(function() local Part = workspace["Elevator 3p left"].Teleport.Telepart end)
workspace["Elevator 4p left"].Teleport.Telepart.Touched:Connect(function() local Part = workspace["Elevator 4p left"].Teleport.Telepart end)
workspace["Elevator 5p left"].Teleport.Telepart.Touched:Connect(function() local Part = workspace["Elevator 5p left"].Teleport.Telepart end)
workspace["Elevator 6p left"].Teleport.Telepart.Touched:Connect(function() local Part = workspace["Elevator 6p left"].Teleport.Telepart end)
workspace["Elevator 1p left"].Teleport.Telepart.Touched:Connect(function() local Part = workspace["Elevator 1p left"].Teleport.Telepart end)

workspace["Elevator 2p"].Teleport.Telepart.Touched:Connect(function() local Part = workspace["Elevator 2p"].Teleport.Telepart end)
workspace["Elevator 3p"].Teleport.Telepart.Touched:Connect(function() local Part = workspace["Elevator 3p"].Teleport.Telepart end)
workspace["Elevator 4p"].Teleport.Telepart.Touched:Connect(function() local Part = workspace["Elevator 4p"].Teleport.Telepart end)
workspace["Elevator 5p"].Teleport.Telepart.Touched:Connect(function() local Part = workspace["Elevator 5p"].Teleport.Telepart end)
workspace["Elevator 6p"].Teleport.Telepart.Touched:Connect(function() local Part = workspace["Elevator 6p"].Teleport.Telepart end)
workspace["Elevator 1p"].Teleport.Telepart.Touched:Connect(function() local Part = workspace["Elevator 1p"].Teleport.Telepart end)
local idPlace = 11873076445

local DSS = game:GetService("DataStoreService")
local TPS = game:GetService("TeleportService")
local Players = game:GetService("Players")

-- DATASTORE TO SAVE A RESERVED SERVER
local ReservedServerDSS = DSS:GetDataStore("ReservedServerDSS")

-- SAFE TELEPORT MODULE
local SafeTeleport = require(game:GetService("ServerScriptService"):WaitForChild("SafeTeleport"))

-- RESERVED SERVER DATA
local code
local pvSVid

-- RUN A FUNCTION TO FIND IN DATASTORE IF A SERVER ALREADY EXIST
local success, Server = pcall(function()
	return ReservedServerDSS:GetAsync("Reseveds")	
end)

-- IF DSS GETASYNC WORKED, CHECK THE DATA, IF NO DATA CREATE A SERVER AND SAVE IT
if success then
	if Server then
		warn("A Server already exist in DSS")	
		code = Server["ServerPassword"]
		pvSVid = Server["ServerID"]
		warn("Server Password:", code, "Server ID:", pvSVid)
	else
		warn("No Server in DSS create one")
		local pass, SVid = TPS:ReserveServer(idPlace)
		if pass and SVid then
			warn("Server Reserved Sucessfully, proceeding to Save it in DSS")
			local s, err = pcall(function()
				return ReservedServerDSS:SetAsync("Reseveds", {ServerPassword = pass, ServerID = SVid})
			end)	
			if s then
				warn("Server successfuly saved")
				code = pass
				pvSVid = SVid
			else
				warn("DSS failed to save the server, do retries", err)	
			end
		end
	end
end

-- PLAYERS WHO ALREADY TRIGGERED THE TOUCH
local PlayersActivatedTouchTP = {}

Part.Touched:Connect(function(partTouched)
	if partTouched.Name == "HumanoidRootPart" then
		local isPlayer = Players:GetPlayerFromCharacter(partTouched.Parent)
		if isPlayer then
			if code and pvSVid then
				if not table.find(PlayersActivatedTouchTP, isPlayer) then
					table.insert(PlayersActivatedTouchTP, isPlayer)
					if Players:GetPlayerByUserId(isPlayer.UserId) then
						warn(isPlayer, "gonna be teleported to this Reserved Server", code, pvSVid)

						local teleportOptions = Instance.new("TeleportOptions")
						teleportOptions.ReservedServerAccessCode = code

						local isTPDone, TPresult = SafeTeleport(idPlace, {isPlayer}, teleportOptions)
						if isTPDone then
							table.remove(PlayersActivatedTouchTP, table.find(PlayersActivatedTouchTP, isPlayer))
						end
						warn("TP done?", isTPDone)
						warn("PrivateServerId?", TPresult.PrivateServerId)
						warn("ReservedServerAccessCode?", TPresult.ReservedServerAccessCode)
					else
						table.remove(PlayersActivatedTouchTP, table.find(PlayersActivatedTouchTP, isPlayer))
					end
				end					
			end
		end
	end
end)

Players.PlayerRemoving:Connect(function(isPlayer)
	if table.find(PlayersActivatedTouchTP, isPlayer) then
		table.remove(PlayersActivatedTouchTP, table.find(PlayersActivatedTouchTP, isPlayer))
		Part.CanTouch = false
	end
end)

  1. yes
    3.the place is like a story game, so I don’t need other players to join by game if it has already started, otherwise they will join in mid-games without understanding what’s going on.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.