Server Hub - Duplication & not fetching server name

Hi!

I am trying to achieve a Server Hub, basically you go in the Server Hub and press Create Server (you can also type a name, or a passcode to enter that server)

What it is doing is:

  • When you are teleported to the server you made, it sends a heartbeat to the hub but then creates a new server named “Unknown Server” as defined, and sends the heartbeats to that Unknown Server instead of the one I made.

I do not think the name is getting stored properly, or retrieved properly but honestly stuck right now.

Here is my Hub Server Script:

local function updateAllClients()
	updateList:FireAllClients(localServerList)
end

local function publishServerUpdate(server)
	pcall(function()
		MessagingService:PublishAsync(SERVER_UPDATE_CHANNEL, {
			action = "update",
			server = server
		})
	end)
end

local function publishServerRemoval(code)
	pcall(function()
		MessagingService:PublishAsync(SERVER_UPDATE_CHANNEL, {
			action = "remove",
			code = code
		})
	end)
end

local function saveServer(server)
	local success, err = pcall(function()
		serverStore:SetAsync(server.code, server, SERVER_EXPIRATION)
	end)
	if not success then
		warn("[Hub] Failed to save server:", err)
	else
		print("[Hub] Saved server data:", server.serverName, "Code:", server.code)
		publishServerUpdate(server)
	end
end

local function removeServer(code)
	for i, srv in ipairs(localServerList) do
		if srv.code == code then
			table.remove(localServerList, i)
			break
		end
	end
	pcall(function()
		serverStore:RemoveAsync(code)
	end)
	publishServerRemoval(code)
end

local function onServerUpdateReceived(message)
	local data = message.Data
	if not data then return end

	if data.action == "update" then
		local updatedServer = data.server
		local found = false
		for i, srv in ipairs(localServerList) do
			if srv.code == updatedServer.code then
				localServerList[i] = updatedServer
				found = true
				break
			end
		end
		if not found then
			table.insert(localServerList, updatedServer)
		end
		updateAllClients()

	elseif data.action == "remove" then
		for i, srv in ipairs(localServerList) do
			if srv.code == data.code then
				table.remove(localServerList, i)
				break
			end
		end
		updateAllClients()
	end
end

local function subscribeToMessaging()
	pcall(function()
		MessagingService:SubscribeAsync(SERVER_UPDATE_CHANNEL, onServerUpdateReceived)
	end)
end

Players.PlayerAdded:Connect(function(player)
	updateList:FireClient(player, localServerList)
end)

createServer.OnServerEvent:Connect(function(player, serverName, serverPassword)
	if player:GetRankInGroup(GROUP_ID) < 86 then
		warn(player.Name .. " tried to create a server without permission.")
		return
	end

	local reservedCode = TeleportService:ReserveServer(PRIVATE_SERVER_PLACE_ID)
	local newServer = {
		code = reservedCode,
		owner = player.Name,
		serverName = (serverName and serverName ~= "") and serverName or ("Server #" .. tostring(#localServerList + 1)),
		playerCount = 0,
		maxPlayers = DEFAULT_MAX_PLAYERS,
		creationTime = os.time(),
		isLocked = false,
		password = (serverPassword and serverPassword ~= "") and serverPassword or nil,
		lastActive = os.time(),
	}

	print("[Hub] Creating new server:", newServer.serverName, "Code:", newServer.code)

	saveServer(newServer)

	local exists = false
	for i, srv in ipairs(localServerList) do
		if srv.code == reservedCode then
			localServerList[i] = newServer
			exists = true
			break
		end
	end
	if not exists then
		table.insert(localServerList, newServer)
	end

	updateAllClients()
	TeleportService:TeleportToPrivateServer(PRIVATE_SERVER_PLACE_ID, reservedCode, {player})
end)

joinServer.OnServerEvent:Connect(function(player, code, enteredPassword)
	if not code then return end

	local serverInfo
	for _, srv in ipairs(localServerList) do
		if srv.code == code then
			serverInfo = srv
			break
		end
	end

	if not serverInfo then
		local success, stored = pcall(function()
			return serverStore:GetAsync(code)
		end)
		if success and stored then
			serverInfo = stored
		end
	end

	if serverInfo then
		if serverInfo.password and serverInfo.password ~= "" and enteredPassword ~= serverInfo.password then
			accessDenied:FireClient(player)
			return
		end

		TeleportService:TeleportToPrivateServer(PRIVATE_SERVER_PLACE_ID, code, {player})
	else
		accessDenied:FireClient(player)
	end
end)

deleteServer.OnServerEvent:Connect(function(player, code)
	if player:GetRankInGroup(GROUP_ID) >= 86 and code then
		removeServer(code)
		updateAllClients()
	else
		warn(player.Name .. " attempted to delete server without permission.")
	end
end)

local function fetchServersFromMemoryStore()
	local success, result = pcall(function()
		return serverStore:GetRangeAsync(Enum.SortDirection.Descending, 50)
	end)

	if success then
		for _, entry in ipairs(result) do
			local exists = false
			for i, srv in ipairs(localServerList) do
				if srv.code == entry.value.code then
					localServerList[i] = entry.value
					exists = true
					break
				end
			end
			if not exists then
				table.insert(localServerList, entry.value)
			end
		end
	else
		warn("[Hub] Failed to fetch servers:", result)
	end

	updateAllClients()
end

fetchServersFromMemoryStore()
subscribeToMessaging()`

Whereas here is my Heartbeat (the PS Server Script)

local Players = game:GetService("Players")
local MessagingService = game:GetService("MessagingService")
local MemoryStoreService = game:GetService("MemoryStoreService")

local SERVER_UPDATE_CHANNEL = "ActivePrivateServers3_Heartbeat"
local PRIVATE_SERVER_CODE = game.PrivateServerId
local SERVER_EXPIRATION = 300 

local serverStore = MemoryStoreService:GetSortedMap("ActivePrivateServers3")

print("[Heartbeat] Starting for PrivateServerId:", PRIVATE_SERVER_CODE)

local function getValidServerInfo()
	if not PRIVATE_SERVER_CODE or PRIVATE_SERVER_CODE == "" then
		warn("[Heartbeat] Invalid PrivateServerId")
		return nil
	end

	local success, storedData = pcall(function()
		return serverStore:GetAsync(PRIVATE_SERVER_CODE)
	end)

	if not success then
		warn("[Heartbeat] Failed to read MemoryStore:", storedData)
		return nil
	end

	if not storedData then
		print("[Heartbeat] No server data found, creating minimal server entry for", PRIVATE_SERVER_CODE)
		storedData = {
			code = PRIVATE_SERVER_CODE,
			serverName = "Unknown Server",
			playerCount = #Players:GetPlayers(),
			maxPlayers = 75,
			lastActive = os.time()
		}
		local successSet = pcall(function()
			serverStore:SetAsync(PRIVATE_SERVER_CODE, storedData, SERVER_EXPIRATION)
		end)
		if not successSet then
			warn("[Heartbeat] Failed to create minimal server data in MemoryStore")
			return nil
		end
	end

	storedData.playerCount = #Players:GetPlayers()
	storedData.lastActive = os.time()
	return storedData
end

local function updateMemoryStore(serverData)
	if not serverData or not serverData.code then return end

	local success, err = pcall(function()
		serverStore:SetAsync(serverData.code, serverData, SERVER_EXPIRATION)
	end)

	if success then
		print("[Heartbeat] Updated MemoryStore for:", serverData.serverName)
	else
		warn("[Heartbeat] Failed to update MemoryStore:", err)
	end
end

local function sendHeartbeat()
	if not PRIVATE_SERVER_CODE or PRIVATE_SERVER_CODE == "" then
		warn("[Heartbeat] Missing PrivateServerId")
		return
	end

	local playerCount = #Players:GetPlayers()
	print("[Heartbeat] Player count:", playerCount)

	local serverData = getValidServerInfo()
	if not serverData then
		warn("[Heartbeat] Skipping heartbeat — server not registered or invalid")
		return
	end

	updateMemoryStore(serverData)

	pcall(function()
		MessagingService:PublishAsync(SERVER_UPDATE_CHANNEL, {
			action = "update",
			server = serverData
		})
	end)

	print("[Heartbeat] Sent update for", serverData.serverName, "(Code:", PRIVATE_SERVER_CODE, ")")
end

Players.PlayerAdded:Connect(function(player)
	print("[Heartbeat] Player joined:", player.Name)
	task.delay(1, sendHeartbeat)
end)

Players.PlayerRemoving:Connect(function(player)
	print("[Heartbeat] Player leaving:", player.Name)
	task.delay(1, sendHeartbeat)
end)

local function initialSetup()
	print("[Heartbeat] Initializing for server:", PRIVATE_SERVER_CODE)
	sendHeartbeat()
end

initialSetup()
task.spawn(function()
	while true do
		sendHeartbeat()
		task.wait(15)
	end
end)

print("[Heartbeat] Script running for private server:", PRIVATE_SERVER_CODE)```

Any guidance would be appreciated or assistance.