That is incorrect, private servers can be joined at any time as long as you have the private server ID that was generated when calling :ReserveServer. Pretty sure you can teleport to the game using the game’s JobID as well (not 100% sure about this one though) (update, you can’t).
UPDATE 3/15/22
This post was marked as a solution because I gave OP help in discord but it used unreliable methods so don’t use this. There now exists a way to do a safe implementation that doesn’t rely on the client, by using MemoryStoreService.
Further, I helped that user out on discord so that code really isn’t the actual solution.
What I’d do in this case is the following:
1- use TeleportService:ReserveServer which returns two strings:
- the ReservedServerAccessCode
- the JobId
So, by using the game’s PrivateServerId, we can use this as the key, and we can use the AccessCode as the value:
So on server 1, the “matchmaking” server:
local reservedServerAccessCode, privateServerId = teleportService:ReserveServer(placeId)
local memoryStoreQueue = memoryStoreService:GetQueue(privateServerId, 120) -- should return a queue object, second parameter, realistically we shouldn't need this available for more than 2 minutes and that's in some extreme circumstance where servers are abnormally slow. really, the teleport should error before it takes 120 seconds but yeah
memoryStoreQueue:AddAsync(reservedServerAccessCode, 120) -- 120 for the same reasons as above
teleportService:TeleportToPrivateServer(placeId, reservedServerAccessCode, {player})
Now, on the second server:
local privateServerId = game.PrivateServerId
local memoryStoreQueueForThisServer = memoryStoreService:GetQueue(privateServerId, 120)
local thisPrivateServerAccessCode = memoryStoreQueueForThisServer:ReadAsync(1) -- now, we have given the private server its own access code
thisPrivateServerAccessCode = thisPrivateServerAccessCode[1]
Now, I’d suggest using the private server ID’s first 6 or so characters as the access code for readability and management sake.
local thisServerAccessCode = thisPrivateServerAccessCode:sub(1,6) -- this will be the access code that needs to be shown to the player
-- now, we need to use MessagingService to create a connection that will use a GUID to return the access code to the main server:
messagingService:SubscribeAsync(thisServerAccessCode, function(message) -- this will be a table with 2 items: RequestedServerCode and a GUID which will be used to "return" the value to the main server
message = message.Data
if message.RequestedServerCode == thisServerAccessCode then -- technically don't have to check this but just in case
messagingService:PublishAsync(message.GUID, thisPrivateServerAccessCode)
end
end)
Now, back on the “main” server:
local guid = httpService:GenerateGUID(false) -- false because we don't want to wrap in brackets
local tempConnection
tempConnection = messagingService:SubscribeAsync(guid, function(returnCode)
teleportService:TeleportToPrivateServer(placeId, reservedServerAccessCode, {player})
tempConenction:Disconnect()
end)
messagingService:PublishAsync(codeInputtedByPlayer, {RequestedServerCode = codeInputtedByPlayer; GUID = guid})
That should give you an idea to approach this.
Old reply
TeleportService | Roblox Creator Documentation
You could probably formulate some type of return system using MessagingService by doing something like this:
Server 1/“main” server:
local messagingService = game:GetService('MessagingService')
local teleportService = game:GetService('TeleportService')
local requestedID = a1b2c -- change this to whatever
messagingService:PublishAsync(requestedID, 'GetJobId')
local connection
coroutine.wrap(function()
wait(5) -- timeout
if connection.Connected then
connection:Disconnect()
-- return to client that the server with that ID doesn't exist
end
end)()
connection = messagingService:SubscribeAsync(requestedID, function(message) -- this is going to act as our "returned" value which would be the access code
local accessCode = message.Data
connection:Disconnect() -- we want to disconnect so no further messages are received
teleportService:TeleportToPlaceInstance(123456, accessCode, game:GetService('Players').user)
end)
Server 2:
local messagingService = game:GetService('MessagingService')
local teleportService = game:GetService('TeleportService')
local partyID = a1b2c -- the 5-digit code
local connection = messagingService:SubscribeAsync(requestedID, function(jobId) -- this is going to act as our "returned" value which would be the job id
messagingService:PublishAsync(partyID, game.JobId)
end)