I'm getting a Teleport 773 error, can you help me?

I’m actually designing a lobby, but more specifically, I’ll be sending 10 players to a single game via inter-server communication. However, the system I’ve designed only sends the players who created the server; other servers give a 773 error.

module.ServerCreate = function(number, MyServerid, Placeid)
	if MyServerid == 0 then
		return false
	end

	local privateServerCode
	local attempt = number or 1
	local maxAttempts = 4
	local playerList = Players:GetPlayers()

	if #playerList == 0 then
		return false
	end

	local successUpdate = pcall(function()
		ServerHeartbeat:UpdateAsync(MyServerid, function(olddata)
			if olddata and typeof(olddata) == "table" and olddata.Server then
				privateServerCode = olddata.Server

				return olddata
			end

			privateServerCode = TeleportService:ReserveServer(Placeid)

			return {Server = privateServerCode}
		end, 30)
	end)

	if not successUpdate then
		return false
	end
	
	Data:UpdateAsync(1, function(data)
		data = data or {}
		
		data[#data+1] = privateServerCode
		
		return data
	end)
	
	while attempt <= maxAttempts do
		local success, err = pcall(function()
			TeleportService:teleportToPrivateServer(Placeid, privateServerCode, playerList)
		end)

		if success then
			return true
		else
			warn("Teleport failed: "..tostring(err))

			local ok = pcall(function()
				ServerHeartbeat:UpdateAsync(MyServerid, function(olddata)
					olddata = olddata and typeof(olddata) == "table" and olddata or {}

					return {}
				end)
			end)

			if not ok then
				return false
			end

			attempt = attempt + 1
		end
	end

	return false
end

1 Like

he just edited it out a minute ago i saw for a split secon :eyes:
ok he edited it back in

ok turn this on :backhand_index_pointing_down:

I turned that setting on, but it still didn’t work.

ok try increase max players in server!

module.ServerCreate = function(number, MyServerid, Placeid)
	if MyServerid == 0 then
		return false
	end

	local privateServerCode
	local attempt = number or 1
	local maxAttempts = 4
	local playerList = Players:GetPlayers()

	if #playerList == 0 then
		return false
	end

	local successUpdate = pcall(function()
		ServerHeartbeat:UpdateAsync(MyServerid, function(olddata)
			if olddata and typeof(olddata) == "table" and olddata.Server then
				privateServerCode = olddata.Server

				return olddata
			end

			privateServerCode = TeleportService:ReserveServer(Placeid)

			return {Server = privateServerCode}
		end, 30)
	end)

	if not successUpdate then
		return false
	end
	
	Data:UpdateAsync(1, function(data)
		data = data or {}
		
		data[#data+1] = privateServerCode
		
		return data
	end)
	
	while attempt <= maxAttempts do
		local success, err = pcall(function()
			TeleportService:teleportToPrivateServer(Placeid, privateServerCode, playerList)
		end)

		if success then
			return true
		else
			warn("Teleport failed: "..tostring(err))

			local ok = pcall(function()
				ServerHeartbeat:UpdateAsync(MyServerid, function(olddata)
					olddata = olddata and typeof(olddata) == "table" and olddata or {}

					return {}
				end)
			end)

			if not ok then
				return false
			end

			attempt = attempt + 1
		end
	end

	return false
end
  1. Liste ögesi

The server’s player capacity is set to normal, which is 50, but I want to teleport 10 players.

ok ok hold on im trying to find your mistake

is your placeid corect? if one server is using a different place id (or a different exoerience) than another, the reserved acces code will be invalid from the other server! please check the exact number used on each server

I can tell you this: the system I’m currently using registers players using a table system established between servers. When the registration is complete, the first server to scan creates the server and assigns its code to the table. Although other servers have that code, they cannot teleport players to that server.

And I checked a few times, the placecode is correct.

ok ok try changing teleportToPrivateServer to TeleportToPrivateServer! (use capital T)

I’ll test it and be right back.

I got the same error again. If you want, I can send you the entire code so it’s clearer.

sure that would be great :grin: ​​​​​​​​​​​​​​​​​​​​​​​​

local MemoryStoreService = game:GetService("MemoryStoreService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TeleportService = game:GetService("TeleportService")
local Players = game:GetService("Players")

local DataStores = game:GetService("DataStoreService")
local Data = DataStores:GetDataStore("ServerData")

local RoundsData = MemoryStoreService:GetSortedMap("RoundsDatas")
local ServerHeartbeat = MemoryStoreService:GetSortedMap("LobbyHeartbeat")

local Modules = ReplicatedStorage:WaitForChild("Modules")

local RoundsDataId = require(Modules:WaitForChild("RoundsDataId"))

local module = {}

local function TableClone(orig)
	local Copy

	if type(orig) == "table" then
		Copy = {}

		for k, v in pairs(orig) do
			Copy[k] = TableClone(v)
		end
	else
		Copy = orig
	end

	return Copy
end

module.CreateMyGameAndDatas = function(Bool, Number)
	local NewIndex
	local WaitTime = 0.2
	local ServerCount = 0

	local success, result = pcall(function()
		return RoundsData:GetAsync(RoundsDataId)
	end)

	if success and result and typeof(result) == "table" and #result > 0 then
		if Bool and Number >= 0.1 then
			for i,v in pairs(result) do
				if v then
					ServerCount += 1
				end
			end

			WaitTime = math.clamp(ServerCount / 20, 0.5, 2) + math.random(0,30)/60
		end
	end

	task.wait(WaitTime)

	local success = pcall(function()
		RoundsData:UpdateAsync(RoundsDataId, function(old)
			old = old or {}

			local EmptyIndex = nil

			for i,v in pairs(old) do
				if v == nil or typeof(v) == "table" and #v <= 0 then
					EmptyIndex = i

					break
				end
			end

			if EmptyIndex then
				old[EmptyIndex] = {PlayerNumber = 0}
				NewIndex = EmptyIndex
			else
				table.insert(old, {PlayerNumber = 0})
				NewIndex = #old
			end

			return old
		end, 600)
	end)

	if not success or not NewIndex then
		return false
	end

	local NewData = {
		ATeam = 0,
		BTeam = 0,
		PlayerDatas = {}
	}

	local success2 = pcall(function()
		RoundsData:UpdateAsync(NewIndex, function()
			return NewData
		end, 600)
	end)

	if not success2 then
		return false
	end

	return NewData, false, NewIndex
end

module.GetMyGameAndDatas = function(ServerSize)
	local success, result = pcall(function()
		return RoundsData:GetAsync(RoundsDataId)
	end)

	local MyPlayersNumber = #Players:GetPlayers()

	local Games = {}
	local MyGame = {}
	local A_BTeamData = false
	local GameName = 0
	local ServerCount = 0

	if not success or not result or typeof(result) ~= "table" or #result <= 0 then
		return module.CreateMyGameAndDatas(false, 0)
	end

	for i,v in pairs(result) do
		if not v or not v.PlayerNumber or typeof(v.PlayerNumber) ~= "number" then
			continue
		end

		if v.PlayerNumber+MyPlayersNumber <= ServerSize then
			table.insert(Games, i)
		end

		task.wait()
	end

	for i,v in pairs(result) do
		if v then
			ServerCount += 1
		end
	end

	local waitTime = math.clamp(ServerCount / 20, 0.5, 2) + math.random(0,30)/60

	for i,Name in pairs(Games) do
		local success, v = pcall(function()
			return RoundsData:GetAsync(Name)
		end)

		if not success or not v then
			continue
		end

		task.wait(waitTime)

		if result[Name].PlayerNumber+MyPlayersNumber <= ServerSize then
			if v.ATeam+MyPlayersNumber <= ServerSize/2 then
				MyGame = v
				A_BTeamData = false
				GameName = Name

				break

			elseif v.BTeam+MyPlayersNumber <= ServerSize/2 then
				MyGame = v
				A_BTeamData = true
				GameName = Name

				break
			end
		end
	end

	if not MyGame or typeof(MyGame) ~= "table" then
		return module.CreateMyGameAndDatas(true, waitTime)
	end

	return MyGame, A_BTeamData, GameName
end

module.ServerCreate = function(number, MyServerid, Placeid)
	if MyServerid == 0 then
		return false
	end

	local privateServerCode
	local attempt = number or 1
	local maxAttempts = 4
	local playerList = Players:GetPlayers()

	if #playerList == 0 then
		return false
	end

	local successUpdate = pcall(function()
		ServerHeartbeat:UpdateAsync(MyServerid, function(olddata)
			if olddata and typeof(olddata) == "table" and olddata.Server then
				privateServerCode = olddata.Server

				return olddata
			end

			privateServerCode = TeleportService:ReserveServer(Placeid)

			return {Server = privateServerCode}
		end, 30)
	end)

	if not successUpdate then
		return false
	end
	
	Data:UpdateAsync(1, function(data)
		data = data or {}
		
		data[#data+1] = privateServerCode
		
		return data
	end)
	
	while attempt <= maxAttempts do
		local success, err = pcall(function()
			TeleportService:TeleportToPrivateServer(Placeid, privateServerCode, playerList)
		end)

		if success then
			return true
		else
			warn("Teleport failed: "..tostring(err))

			local ok = pcall(function()
				ServerHeartbeat:UpdateAsync(MyServerid, function(olddata)
					olddata = olddata and typeof(olddata) == "table" and olddata or {}

					return {}
				end)
			end)

			if not ok then
				return false
			end

			attempt = attempt + 1
		end
	end

	return false
end

module.GameRegister = function(index, A_B, ServerSize, Placeid)
	if not index then
		return false
	end

	local players = Players:GetPlayers()
	local playerCount = #players
	local MyServerid = 0
	local A_B_Bool = false
	local Started = false
	
	local Success, Errordata, UserIds = pcall(function()
		if playerCount == 0 then
			return false
		end

		local UserIds = {}

		for _, plr in ipairs(players) do
			UserIds[#UserIds + 1] = plr.UserId
		end

		table.sort(UserIds)

		return true, UserIds
	end)

	if not Success then
		return false
	elseif not Errordata then
		return false
	end

	local Bool = false
	local Registered = false
	
	local S, Err = pcall(function()
		RoundsData:UpdateAsync(index, function(data)
			if not data or typeof(data) ~= "table" then
				return data
			end
			
			print(data.PlayerNumber, data.ATeam, data.BTeam)

			data.PlayerNumber = data.PlayerNumber or 0
			data.ATeam = data.ATeam or 0
			data.BTeam = data.BTeam or 0
			data.PlayerDatas = data.PlayerDatas or {}
			
			for i = #data.PlayerDatas, 1, -1 do
				local group = data.PlayerDatas[i]

				for j = #group.Players, 1, -1 do
					for _, plr in ipairs(players) do
						if group.Players[j] == plr.UserId then
							if data.ATeam >= 1 and not A_B then
								data.ATeam -= 1
							elseif data.BTeam >= 1 and A_B then
								data.BTeam -= 1
							end

							data.PlayerNumber -= 1

							table.remove(group.Players, j)
						end
					end
				end

				if #group.Players == 0 then
					table.remove(data.PlayerDatas, i)
				end
			end

			if data.PlayerNumber + playerCount > ServerSize then
				return nil
			end

			data.PlayerNumber += playerCount

			A_B_Bool = A_B

			if A_B then
				data.BTeam += playerCount
			else
				data.ATeam += playerCount
			end

			data.PlayerDatas[#data.PlayerDatas + 1] = {
				Players = UserIds,
			}

			Registered = true
			MyServerid = index

			if data.PlayerNumber >= ServerSize then
				Bool = true
			end
			
			print(data)

			return data
		end, 600)
	end)
	
	if Bool then
		Started = module.ServerCreate(1, MyServerid, Placeid)
	end

	return Registered, MyServerid, A_B_Bool, Started
end

return module
local MemoryStoreService = game:GetService("MemoryStoreService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local Events = ReplicatedStorage:WaitForChild("Events")
local Modules = ReplicatedStorage:WaitForChild("Modules")

local RoundsData = MemoryStoreService:GetSortedMap("RoundsDatas")
local ServerHeartbeat = MemoryStoreService:GetSortedMap("LobbyHeartbeat")

local Functions = require(Modules:WaitForChild("Functions"))
local RoundsDataId = require(Modules:WaitForChild("RoundsDataId"))

local ServerSize = 10
local MyServerid = 0
local Placeid = 105676713454014

local ServerTeleported = false
local A_B_Bool = false
local LobyHost = nil

ServerSize = math.floor(ServerSize/2)*2

local function CleanupPlayerDatas(A_B)
	if MyServerid == 0 then
		return
	end

	local currentPlayers = Players:GetPlayers()
	local playerLookup = {}

	for _,plr in ipairs(currentPlayers) do
		playerLookup[plr.UserId] = true
	end

	pcall(function()
		RoundsData:UpdateAsync(MyServerid, function(data)
			if not data or type(data) ~= "table" then
				return nil
			end

			data.PlayerDatas = data.PlayerDatas or {}

			local removedPlayers = 0

			for i = #data.PlayerDatas,1,-1 do
				local group = data.PlayerDatas[i]

				if group and type(group.Players) == "table" then
					for j = #group.Players,1,-1 do
						local userId = group.Players[j]

						if not playerLookup[userId] then
							table.remove(group.Players,j)
							removedPlayers += 1
						end
					end

					if #group.Players == 0 then
						table.remove(data.PlayerDatas,i)
					end
				else
					table.remove(data.PlayerDatas,i)
				end
			end

			if removedPlayers > 0 then
				data.PlayerNumber = math.max(0,(OldPlayerNumber or data.PlayerNumber or 0) - removedPlayers)

				if A_B then
					data.BTeam = math.max(0,(data.BTeam or 0) - removedPlayers)
				else
					data.ATeam = math.max(0,(data.ATeam or 0) - removedPlayers)
				end
			end

			return data
		end, 600)
	end)
end

local function ServerClose()
	if MyServerid == 0 then
		return
	end

	local S, err = pcall(function()
		RoundsData:UpdateAsync(RoundsDataId, function(data)
			if not data then
				return {}
			end

			data[MyServerid] = nil

			return data
		end, 600)

		task.wait()

		RoundsData:UpdateAsync(MyServerid, function()
			return {}
		end, 600)
	end)
	
	print(err)
end

Players.PlayerRemoving:Connect(function(player)
	if LobyHost == player and not ServerTeleported then
		for i,v in pairs(Players:GetPlayers()) do
			v:Kick("Server Host has left the game")
		end
		
		CleanupPlayerDatas(A_B_Bool)
		
		OldPlayerNumber = #Players:GetPlayers()
		
		ServerClose()
	else
		CleanupPlayerDatas(A_B_Bool)
		
		OldPlayerNumber = #Players:GetPlayers()
	end
	
	if #Players:GetPlayers() == 0 then
		ServerClose()
	end
end)

Players.PlayerAdded:Connect(function(player)
	if not LobyHost then
		LobyHost = player
	end
	
	OldPlayerNumber = #Players:GetPlayers()
end)

game:BindToClose(function()
	ServerClose()
	
	task.wait(3)
end)

while task.wait() do
	local ServerCount = 0
	
	task.spawn(function()
		if MyServerid == 0 then
			local MyGame, A_BTeamData, GameName = Functions.GetMyGameAndDatas(ServerSize)

			if GameName > 0 then
				local R, M, AB, ST = Functions.GameRegister(GameName, A_BTeamData, ServerSize, Placeid)

				if R then
					MyServerid = M
					A_B_Bool = AB
					ServerTeleported = ST
				end
			end
		else
			local success, err = pcall(function()
				return RoundsData:GetAsync(MyServerid)
			end)

			if not success or not err or type(err) ~= "table" then
				MyServerid = 0
			else
				local success, Bool = pcall(function()
					return err.BTeam >= ServerSize/2 and err.ATeam >= ServerSize/2 and true or false
				end)

				if err.Server then
					ServerTeleported = Functions.ServerCreate(1, MyServerid, Placeid)
				elseif success and Bool then
					ServerTeleported = Functions.ServerCreate(1, MyServerid, Placeid)
				end
			end
		end
	end)
	
	for i,v in pairs(RoundsData:GetAsync(RoundsDataId) or {}) do
		if v then ServerCount += 1 end
	end

	local waitTime = math.clamp(ServerCount / 20, 0.5, 2) + math.random(0,30)/60
	
	task.wait(waitTime+math.random(1, 10))
end

ok ok give me time to analyze!! ill be back :eyes:

Okay, I’ll wait. Thank you also for your time.

here i am! i hope my solution is right

alright so the code you made lets any server that sees the reserved server access code attempt teleportorivateserver using that same code! in practice, reserved server access codes are fragile when muliple servers attempt to use the same code concurrently or when a server other than the one that created (reserved) the code tries to use it, so this is what causes that anoying 773 errors youre seeing!! also your ServerHeartbeat:UpdateAsync stores only Server = privateServerCode which means no owner info, so all other servers read the code and then try to teleport their players to it. no owner metadata in heartbeat (no owner nor jobid) means nothing prevents non owner servers from calling teleport

so my idea is to have a script that subscribes to messages whose ownerjobiid matches the game.jobid, so owner will resolve userIds to Player objects and then call the teleport thingy. alright, make a new script then put it in serverscriptservice ok!

local MessagingService = game:GetService("MessagingService")
local TeleportService = game:GetService("TeleportService")
local Players = game:GetService("Players")
local placeId = game.PlaceId
local TOPIC = "TeleportToOwner_" .. tostring(game.JobId)
local subMsg

local function TeleportToReserved(placeId, accessCode, players)
	 --playerobjs must be Player instancs from this server!
    local maxAttempts = 4
    local attempt = 1
    while attempt <= maxAttempts do
        local ok, err = pcall(function()
            TeleportService:TeleportToPrivateServer(placeId, accessCode, players)
        end)
        if ok then
            return true
        else
            warn("[OwnerSubscriber] teleport attempt", attempt, "failed:", tostring(err), "accessCode:", tostring(accessCode))
            attempt = attempt + 1
            task.wait(math.min(1 * attempt, 5))
        end
    end
    return false
end

local function onMessage(message)
    local payload = message.Data
    if not payload or not payload.userIds or typeof(payload.userIds) ~= "table" then
        return
    end

	--we rbuild Player objects that still exist on this server
    local playerObjs = {}
    for _, uid in ipairs(payload.userIds) do
        local p = Players:GetPlayerByUserId(uid)
        if p then
            table.insert(playerObjs, p)
        end
    end

    if #playerObjs == 0 then
        warn("[OwnerSubscriber] no local players to teleport for payload:", payload.serverIndex)
        return
    end

    local success = TeleportToReserved(payload.placeId or placeId, payload.accessCode, playerObjs)
    if not success then
        warn("[OwnerSubscriber] failed to teleport players for payload:", payload.serverIndex, "accessCode:", payload.accessCode)
    end
end

--subscribe once right here
local ok, subError = pcall(function()
    subMsg = MessagingService:SubscribeAsync(TOPIC, onMessage)
end)

if not ok then
    warn("[OwnerSubscriber] failed to subscribe to", TOPIC, "err:", tostring(subError))
else
    print("[OwnerSubscriber] subscribd to teleport topic:", TOPIC)
end

now back to the module script, what i see important is just the module.servercreate so now you first add messagingserivce on top of your scipt with the other services you got

--other services up there
local MessagingService = game:GetService("MessagingService")

i reworked your servercreate thing to actually use tht ownerid thing (and emssageservice) so in the end this may possibly make that teleport server possible

--add these 2 too
local msgPrefix = "TeleportToOwner_"
local maxRetries = 3
module.ServerCreate = function(number, MyServerid, Placeid)
    if MyServerid == 0 then
        return false
    end

    local privateServerCode
    local ownerJobId
    local attempt = number or 1
    local maxAttempts = 4
    local playerList = Players:GetPlayers()

    if #playerList == 0 then
        return false
    end

    --we do this to create heartbeat record ok
    local successUpdate = pcall(function()
        ServerHeartbeat:UpdateAsync(MyServerid, function(olddata)
            olddata = olddata and typeof(olddata) == "table" and olddata or {}

            --if record alresdy has a server (and posibly owner), we use it!
            if olddata.Server and olddata.Owner then
                privateServerCode = olddata.Server
                ownerJobId = olddata.Owner
                return olddata
            end

            privateServerCode = TeleportService:ReserveServer(Placeid)
            ownerJobId = game.JobId

            return { Server = privateServerCode, Owner = ownerJobId }
        end, 600) --longer ttl while setup is in progress
    end)

    if not successUpdate or not privateServerCode or not ownerJobId then
        warn("[ServerCreate] failed to reserve/read servr record for id:", MyServerid)
        return false
    end

    --safeguard
    pcall(function()
        Data:UpdateAsync(1, function(data)
            data = data or {}
            data[#data+1] = privateServerCode
            return data
        end)
    end)

    --here we check if instance is the owner then perform that teleport thing i hope no errors
    if ownerJobId == game.JobId then
        while attempt <= maxAttempts do
            local ok, err = pcall(function()
                TeleportService:TeleportToPrivateServer(Placeid, privateServerCode, playerList)
            end)

            if ok then
                print("[ServerCreate][Owner] Teleport succeeded. ownerJobId:", ownerJobId, "code:", privateServerCode)
                return true
            else
                warn("[ServerCreate][Owner] teleport failed attempt", attempt, "err:", tostring(err),
                     "ownerJobId:", ownerJobId, "code:", tostring(privateServerCode), "players:", #playerList)
                --clear heartbeat so other servers can try to recreate if needed
                pcall(function()
                    ServerHeartbeat:UpdateAsync(MyServerid, function(old) return {} end)
                end)

                attempt = attempt + 1
                task.wait(0.6 * attempt)
            end
        end

        warn("[ServerCreate][Owner] all attempts failed for owner:", ownerJobId, "code:", privateServerCode)
        return false
    end

    --if not the owner then we publish this server's player userids to the owner for teleportng
    local userIds = {}
    for _, plr in ipairs(playerList) do
        table.insert(userIds, plr.UserId)
    end

    local payload = {
        serverIndex = MyServerid,
        placeId = Placeid,
        accessCode = privateServerCode,
        userIds = userIds,
        fromJobId = game.JobId,
        timestamp = os.time()
    }

    local topic = msgPrefix .. tostring(ownerJobId)
    local published = false

    for i = 1, maxRetries do
        local ok, err = pcall(function()
            MessagingService:PublishAsync(topic, payload)
        end)

        if ok then
            published = true
            break
        else
            warn("[ServerCreate] publish to owner failed etry", i, "err:", tostring(err), "topic:", topic)
            task.wait(0.25 * i)
        end
    end

    if not published then
        warn("[ServerCreate] failed to handoff teleport to owner", ownerJobId, "code:", privateServerCode)
        return false
    end

    --successfully handedoff the teleport request, owner will perform teleport and we done!!
    return true
end

idk what i js did i tried my best :face_with_bags_under_eyes:
hope it works though!

1 Like

I appreciate your help, but my friend, you most likely misunderstood. What I wanted was a system that would teleport players from specific servers to a shared server, but you’ve designed a system that only accepts players from the server that created the server. But thank you very much for your help.