Reserve Server (Help)

I want to fix the code for a reserve server teleportation system that I have created. It uses a Gamepass, two module scripts, two RemoteEvents, and a unique JoinCode.

I’ve tried coding it myself initially, fixed a lot of bugs and got really close to having a working system, however, I am now lost. When I play test on Roblox everything works as usual, however, I get an error that the reserver servers id is incorrect (but it is not). The only script that you’d really need is the handler, the other scritps are for communicating to guis and to the server.

My reserve server handler:

local Gamepass = 176407715
local JoinCodeDataStore = game:GetService("DataStoreService"):GetDataStore("JoinCodes")
local CheckJoinCodeEvent = require(script.Parent.Parent.ReplicatedStorage:WaitForChild("CheckModule"))
local CreateJoinCodeEvent = require(script.Parent.Parent.ReplicatedStorage:WaitForChild("CreateModule"))

local EmptyServerLifetime = 300 -- 5 minutes in seconds

local function CreateServer(player, joinCode)
	local success, errorMessage = pcall(function()
		local playerHasGamepass = game:GetService("MarketplaceService"):UserOwnsGamePassAsync(player.UserId, Gamepass)
		if playerHasGamepass then
			print("You set up a server with join code: " .. joinCode)

			-- Check if the join code is already associated with a server
			local success, storedJoinCode = pcall(function()
				return JoinCodeDataStore:GetAsync(joinCode)
			end)

			if success and storedJoinCode then
				warn("Join code is already associated with another server.")
				return
			end

			-- Save join code to the data store
			local success, saveError = pcall(function()
				JoinCodeDataStore:SetAsync(joinCode, player.UserId)
			end)

			if not success then
				warn("Failed to save join code:", saveError)
			end
		else
			warn("Player does not have the required gamepass.")
		end
	end)

	if not success then
		warn("Error occurred while creating server:", errorMessage)
	end
end

CheckJoinCodeEvent.OnServerEvent:Connect(function(player, joinCode)
	if joinCode ~= "" then
		local success, serverOwner = pcall(function()
			return JoinCodeDataStore:GetAsync(joinCode)
		end)

		if success and serverOwner then
			print("Joining a server with the join code: " .. joinCode)
			local tp = game:GetService("TeleportService")
			local server = tp:ReserveServer(13432346530)
			tp:TeleportToPrivateServer(13432346530, game.PlaceId, { player })
		end
	end
end)

CreateJoinCodeEvent.OnServerEvent:Connect(function(player, joinCode)
	CreateServer(player, joinCode)
end)

-- Periodically check and delete empty servers
while true do
	wait(EmptyServerLifetime)

	local success, storedJoinCodes = pcall(function()
		return JoinCodeDataStore:GetAsync(100)
	end)

	if success and storedJoinCodes then
		for joinCode, serverOwner in pairs(storedJoinCodes) do
			local player = game.Players:GetPlayerByUserId(serverOwner)
			if not player then
				local removeSuccess, removeError = pcall(function()
					JoinCodeDataStore:RemoveAsync(joinCode)
				end)

				if removeSuccess then
					print("Empty server with join code " .. joinCode .. " found. Join code removed.")
				else
					warn("Failed to remove join code " .. joinCode .. ":", removeError)
				end
			end
		end
	elseif not success then
		warn("Failed to fetch join codes:", storedJoinCodes)
	end
end

All help is appreciated!

2 Likes

This is what you have:

CheckJoinCodeEvent.OnServerEvent:Connect(function(player, joinCode)
	if joinCode ~= "" then
		local success, serverOwner = pcall(function()
			return JoinCodeDataStore:GetAsync(joinCode)
		end)

		if success and serverOwner then
			print("Joining a server with the join code: " .. joinCode)
			local tp = game:GetService("TeleportService")
			local server = tp:ReserveServer(13432346530)
			tp:TeleportToPrivateServer(13432346530, game.PlaceId, { player })
		end
	end
end)

Specifically local server = tp:ReserveServer(13432346530) and tp:TeleportToPrivateServer(13432346530, game.PlaceId, { player })

The params for TeleportToPrivateServer are:

local code = TeleportService:ReserveServer(game.PlaceId)
TeleportService:TeleportToPrivateServer(game.PlaceId, code, players)

The reserved server code that you’re using is the game’s place id.
I did pull these two lines off of the documentation site

2 Likes

Oh shit so it was that simple? I just typed it in wrong???

1 Like

Well, do a little test, but it’s alright happens to everyone.

2 Likes

I’d also like to add, while you may have the join code, you’ll probably need to associate the reserved server token along with it, since otherwise when someone joins off this join code, they might not join the same server since it’ll just create a new server.

local join_data = {
    OwnerId = player.UserId,
    ServerToken = TeleportService:ReserveServer(game.PlaceId)
}
local success, saveError = pcall(function()
	JoinCodeDataStore:SetAsync(joinCode, join_data)
end)
3 Likes

Alr, I’ll get back to you once I test it out. Appreciate the help.

Ok, so I added the correct params for the private server teleportation, but I get this error when I attempt to teleport to the server:
Capture

Also another quick question unrelated to this issue. I have the datastore editor plugin, what key would I use for JoinCodes datastore to view the created codes? or would the key just be the code that the user inputs as their unique joincode?

Honestly, I’m not too sure completely. There’s many different ways people go about it, and personally I’ve never made a private server script alike.


This isn’t based on expert advice in the slightest

But for an idea, I do believe having one key for a whole list of code’s would be more convenient, less datastore calls and all the data is right there. Alongside that, having the unique code as the Key itself would be fine, but you’d probably need a method of allowing the player who ‘owns’ that unique code to be able to remember what they had in their own stored data. (Easy to forget these things)

While saving it to a datastore is nice, something that kind of annoys me about datastores is how the Key:Data still persists if it’s Key:nil so even if you can look through it using the datastore plugin, it can become quite messy to look in. Not saying this next idea is any better, but it removes the bloat key:nil situation.

Using MemoryStoreService, which should technically be better for these server to server type of jobs, main difference is that it persists until the provided duration is up. But at that point you can create a new code. I’ve never personally dived into using this service, but pretty sure it says somewhere within the documentation that that is one of the better/more recommended uses of this service.

1 Like

Alright, I figured out that the key for my datastores was the unique joincode and the value was the players userid.

I think my original issue is due to something with Roblox and it’ll just take a few days for the teleportation to authorize.

Again, thank you for helping me out man.

1 Like

I have figured out a solution and I am unsure why the previously mentioned system did not work.

If you are also struggling with getting something like this to work, I suggest approaching it a different way. For me, putting the teleportation system into a pcall function resolved the issue.

Didn’t work:

local TeleportService = game:GetService("TeleportService")
local code = TeleportService:ReserveServer(13432346530)
TeleportService:TeleportToPrivateServer(game.PlaceId, code, { player })

Did work:

local TeleportService = game:GetService("TeleportService")
local success, result = pcall(TeleportService.TeleportAsync, TeleportService, 13432346530, { player })

Hope this helps someone in the future.

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