Best practices for waiting for number of players teleporting?

Hey all,

I want some guidance on the best way to know how many players are expected to teleport to a reserved server.

I’ve already read the following related post:

However, I am not satisfied with using teleportData because it relies on the client to hold the data. I need to server to have it, otherwise the number can be fabricated.

When looking into MessagingService, it also looks as if the client needs to be subscribed to receive any messages. Am I just misunderstanding something here?

My guess of what the code might look like for the start place:

-- Services
local MessagingService = game:GetService("MessagingService")

-- Variables
local PLAYER_COUNT_TOPIC = "PlayerCountEvent"

-- Just after teleporting the Players:
MessagingService:PublishAsync(PLAYER_COUNT_TOPIC, #playersTeleporting)

And the code that would exist on the receiving place:

-- Services
local MessagingService = game:GetService("MessagingService")

-- Variables
local PLAYER_COUNT_TOPIC = "PlayerCountEvent"

-- Private functions
local function init()
    local subscribeSuccess, subscribeConnection = pcall(function()
		return MessagingService:SubscribeAsync(PLAYER_COUNT_TOPIC, function(playerCount)
			print(playerCount.Data)
		end)
	end)

    return subscribeSuccess
end

However, how would I then ensure only the server that is just now being reserved receives that data? Wouldn’t any server subscribed receive that data?

Could I somehow bake in the code from TeleportService:TeleportToPrivateServer() into the messaging topic? What about if I am using TeleportService:TeleportAsync() with teleportOptions to reserve the server?

Lastly, do I need to wait for the reserved server to be created before I publish my message? In theory, no one will be subscribed if it’s baked with the code or whatnot. Any insight is appreciated.

2 Likes

exactly, every server would get that data, so MessagingService isn’t a good fit here.

MessagingService is better for things like global announcements or general cross-server messages, not for sending data to one specific server.

A better way is to use MemoryStoreService with the reserved server code from TeleportService. You can save the player count using that code before teleporting, and then read it in the new server using game.PrivateServerId.

This keeps everything on the server and not the client.

1 Like

Hey Bloxy,

This sounds like a good option in theory, however, the code I am getting returned from TeleportService:TeleportAsync()'s TeleportAsyncResult does not match the game.PrivateServerId in the other place. Any idea why?

What I have now in the start place:

local teleportOptions = Instance.new("TeleportOptions")
teleportOptions.ShouldReserveServer = true

local MAX_TRIES = 3
local RETRY_DELAY = 3

local attempt = 0
local success, result

repeat
	attempt += 1
	success, result = pcall(function()
		return TeleportService:TeleportAsync(placeId, contestants, teleportOptions)
	end)

	if not success then
		task.wait(RETRY_DELAY)
	end
until
	success or attempt == MAX_TRIES

if not success then
	s_warn(`Error: {result}`)

	-- TODO: implement something here in case the teleport fails
else
	local pid= result.PrivateServerId -- Used to be result.ReservedServerAccessCode
	print(pid)
	
	local memStoreQueue = MemoryStoreService:GetQueue(pid)
	memStoreQueue:AddAsync(#contestants, 5 * 60)
end

And on the other place:

local function readPlayerCount()
	local pid = game.PrivateServerId
    print(pid )
	if string.len(pid ) < 4 then
		return false
	end
	
	local memStoreQueue = MemoryStoreService:GetQueue(pid )
	local data = memStoreQueue:ReadAsync(1, false, 10)
	print(`EXPECTED PLAYER COUNT: {data]1]}`)
	
	return data[1]
end

EDIT: I see my mistake, I was comparing the TeleportAsyncResults ReservedServerAccessCode, when I should have used the PrivateServerId.

1 Like