Attempted to teleport to a place that does not exist

Background:

I’m working on a game with infinite world generation.
I have a world generator that generates the map based on a TerrainKey string I feed it.
When the player gets to the edge of the map, they get teleported to another reserved server with a different TerrainKey. I’m basically trying to create a grid of reserved servers that players can walk through.
image :point_left: Each box is a Reserved Server
The ReservedServer’s grid coordinates are the TerrainKey. For example, a TerrainKey of “0,0” would be the center of the universe.


Problem:

image

It’s saying the place doesn’t exist. :boom:
The place I’m trying to teleport to is under the same game as the place I’m teleporting from.
It’s a group place.

This works perfectly fine:

game:GetService('TeleportService'):Teleport(5907815608,game.Players.dispeller)

For some reason, this doesn’t:

local reservedCode = WorldPosService.getReservedCodeAndID("0,0")
TeleportService:TeleportToPrivateServer(5907815608,reservedCode,Players)

Same exact PlaceId, but it’s telling me the place doesn’t exist.

Is this an internal bug with Roblox?


Thought process

These are the steps of how I’m trying to get things to work:

Player needs to teleport to specific TerrainKey

  1. Get ReservedServer Access Code based off TerrainKey
    a. If Access Code is cached, grab cached code
    b. If not cached, grab from datastore
    c. If not in datastore
    Reserve new server
    – Store Reserve Server Access Code in datastore under TerrainKey
    – Store TerrainKey in datastore under PrivateServerId
    – return Reserve Server Access Code

  2. Teleport player to Terrain place Reserved Server using Access Code

When a new server starts up in the Terrain place:

  1. Get current TerrainKey based off game.PrivateServerId
    a. Check datastore using PrivateServerId as key
  2. Generate terrain based off TerrainKey
  3. Use TerrainKey when players get to edge of map
    (teleport to specific adjacent TerrainKey)

Code:

This is a module for reserving servers, storing data to datastore, and teleporting players

-- WorldPosService
-- dispeller 2020

WorldPosService = {}

--[[

TerrainKey = "1,2"

function WorldPosService.getReservedCodeAndID(TerrainKey: string)
	returns string ReservedCode, string ServerId

function WorldPosService.getTerrainKeyFromServerIdAsync(ServerId: string)
	returns string TerrainKey

function WorldPosService:Teleport(Players,key)

]]

local Players = game:GetService("Players")
local TeleportService = game:GetService("TeleportService")
local DatastoreService = game:GetService("DataStoreService")
local DataStore = DatastoreService:GetGlobalDataStore()

local getReservedCodeAndIDCache = {}
function WorldPosService.getReservedCodeAndID(TerrainKey: string)
	assert(type(TerrainKey)=="string","TerrainKey must be a string!")
	
	if getReservedCodeAndIDCache[TerrainKey] then
		return unpack(getReservedCodeAndIDCache[TerrainKey])
	end
	
	local data = DataStore:GetAsync(TerrainKey)
--	local reservedCode = data[1]
--	local serverID = data[2]
	if data then
		getReservedCodeAndIDCache[TerrainKey] = data
		return data[1],data[2]
	else
		local code,serverID = TeleportService:ReserveServer(game.PlaceId)
		DataStore:UpdateAsync(TerrainKey, function(oldData)
			-- Returning nil cancels the write
			if oldData then 
				code = oldData[1]
				serverID = oldData[2]
				return nil 
			end
			-- Returning a value attempts to use this as the TerrainKey's new value
			return {code,serverID}
		end)
		warn'did update!'
		
		-- Make TerrainKey obtainable via game.PrivateServerId
		local datastoreSetSuccess = false
		local err
		for tries=1,30 do
			if not datastoreSetSuccess then
				datastoreSetSuccess,err = pcall(function()
					DataStore:SetAsync(serverID,TerrainKey)
				end)
				if not datastoreSetSuccess then
					warn("DATASTORE ERROR: ",err)
					wait(tries)
				end
			end
		end
		if not datastoreSetSuccess then
			error("FAILED TO SET DATASTORE SERVERID ",serverID," TO TerrainKey ",TerrainKey)
		end
		
		return code,serverID
	end
end

local getTerrainKeyFromServerIdAsyncCache = {}
function WorldPosService.getTerrainKeyFromServerIdAsync(ServerId: string)
	
	if getTerrainKeyFromServerIdAsyncCache[ServerId] then
		return getTerrainKeyFromServerIdAsyncCache[ServerId]
	end
	
	local TerrainKey = nil
	for tries=1,5 do
		TerrainKey = TerrainKey or DataStore:GetAsync(ServerId)
		if not TerrainKey then
			wait(tries)
		end
	end
	
	if TerrainKey then
		getTerrainKeyFromServerIdAsyncCache[ServerId] = TerrainKey
		return TerrainKey
	else
		warn("Server with id ",ServerId," has not been generated!")
		return false
	end
end

function WorldPosService.getTerrainKey()
	return WorldPosService.getTerrainKeyFromServerIdAsync(game.PrivateServerId)
end

function WorldPosService:Teleport(Players,key)
	if type(Players)~="table" then
		Players = {Players}
	end
	local reservedCode = WorldPosService.getReservedCodeAndID(key)
	TeleportService:TeleportToPrivateServer(5907815608,reservedCode,Players)
end

return WorldPosService

I have a simple script that calls the actual teleportation for testing purposes:

TS = game:GetService('TeleportService')
WorldPosService = require(game.ServerStorage:WaitForChild("WorldPosService"))

script.Parent.Touched:Connect(function(hit)
	local Char = hit.Parent
	local Player = game.Players:GetPlayerFromCharacter(Char)
	if Player then
		WorldPosService:Teleport(Player,"0,0")
		--TS:Teleport(5530161763,Player)
		Char.Humanoid:UnequipTools()
		Char:Destroy()
		wait(5)
		if Player then
			Player:LoadCharacter()
		end
	end
end)

Reply with any questions.
If you took the time to combe through the code yourself, but haven’t found any problems, reply anyway telling me so.

There’s always a small chance this is an internal bug with Roblox. It’s either that, or the Teleport Failed message is misleading; It says the place doesn’t exist, even though you can still teleport to the place without ReservedServers.

1 Like

Hey, just letting you know I looked through the code and was able to reproduce this in my own place.

1 Like

Make sure the place you’re trying to send the player to has API on. (I think its API)

Some additional help.

I have made a discovery :face_with_monocle:
But first, here are some tips:

  • You should use a debounce for your test script so you’re not making multiple requests to teleport.
  • Use F9 and look at the Client and Server logs whenever you have issues

And now, the discovery: the logs revealed that the access code was invalid. The reason is because you need to use the PlaceId for the place you want to teleport TO in the function ReserveServer. So if you’re teleporting to 5907815608 then instead of
local code,serverID = TeleportService:ReserveServer(game.PlaceId)
you should write
local code,serverID = TeleportService:ReserveServer(5907815608).

Note: you’ll need to clear your datastore data after fixing the code so it doesn’t use the old bad codes.

1 Like

UGH I can’t believe I didn’t catch that yesterday!
It’s funny actually; In the middle of church service today, I remembered that I might not have changed the input PlaceID.
It’s cool that someone else caught it before I did.

Thanks for your help! PM me if you want this badge:
Bug Slayer Badge - Roblox
(It’s not much, but it’s something)

Also, I do normally use debounces. The .Touched script was just for testing.
Plus, I think a queuing system would be more appropriate in this situation.

1 Like