Need help with scripting a table for my obby

Hi, I’ve been hard at work trying to build my first obby and I’ve ran into an issue involving how the stages are updated.

A quick rundown of how I have this laid out: So per each world I keep all of the spawn / stage checkpoints in their own folders so I can easily put them all into a table for checking if they get touched by a player to update their stage, worked pretty well for a while.

The issue now? After I’ve gotten about 30+ stages into the obby, a lot of the instances in the table keep showing as ‘nil’ and just acting as duds when touched. I originally had the table created on the client side, and after that I made it so a server script would create the table and send it to each client as they joined, but that hasn’t fixed much either. I don’t know if there’s a more efficient or reliable way to do this that I just haven’t yet figured out since most of my work has just been based off trial and error (I only started scripting a few months ago).

A snippet of the code that updates the stage (LocalScript)

local spawns = {}
caster.OnClientEvent:Once(function(data)
	spawns = data
	print(spawns)
	for i, v in pairs(spawns) do -- turns spawns green when touched by the player
		for key, data in pairs(v) do -- checks each spawn through the nested table
			data.Touched:Connect(function(hit)
				if tostring(hit.Parent) == game.Players.LocalPlayer.Name then
					if tonumber(data.Name) and data.Parent.Name == tostring("W"..localplayer.leaderstats.World.Value) then -- Check if spawn is in current world
						if tonumber(data.Name) > game.Players.LocalPlayer.leaderstats.Stage.Value then
							data.BrickColor = BrickColor.new("Lime green")
							event:FireServer(data) -- fires server to update the stage
						end
					end
				end
			end)
		end
	end
end)

The code that sends the table to the client (Server Script)

local caster = game.ReplicatedStorage:WaitForChild("FailsafeServerLoad")
game.Players.PlayerAdded:Connect(function(player)
	task.wait(1)
	local spawns = {
		spawns1 = game.Workspace.W1:GetChildren(),
		spawns2 = game.Workspace.W2:GetChildren()
	}
	caster:FireClient(player, spawns)
end)

A screenshot from the console of the table showing ‘nil’
image_2024-05-21_155936451

Server side part

  1. Create the spawns table on the server.
  2. Listen for player touches on the server.
local caster = game.ReplicatedStorage:WaitForChild("FailsafeServerLoad")
local updateStageEvent = game.ReplicatedStorage:WaitForChild("UpdateStage") -- Create a RemoteEvent named UpdateStage in ReplicatedStorage

-- Function to initialize spawns table
local function initializeSpawns()
    local spawns = {}
    for i = 1, 30 do
        local worldSpawns = workspace:FindFirstChild("W" .. i)
        if worldSpawns then
            spawns["spawns" .. i] = worldSpawns:GetChildren()
        end
    end
    return spawns
end

local spawns = initializeSpawns()

game.Players.PlayerAdded:Connect(function(player)
    task.wait(1)
    caster:FireClient(player, spawns)
end)

-- Listen for stage updates from the client
updateStageEvent.OnServerEvent:Connect(function(player, touchedSpawn)
    if touchedSpawn and touchedSpawn:IsA("BasePart") then
        local playerStage = player.leaderstats.Stage
        local newStage = tonumber(touchedSpawn.Name)
        local currentWorld = "W" .. player.leaderstats.World.Value

        if newStage and touchedSpawn.Parent.Name == currentWorld and newStage > playerStage.Value then
            playerStage.Value = newStage
        end
    end
end)

Local Script

  1. Listen for spawns data from the server.
  2. Connect touch events to notify the server.
local spawns = {}
local caster = game.ReplicatedStorage:WaitForChild("FailsafeServerLoad")
local updateStageEvent = game.ReplicatedStorage:WaitForChild("UpdateStage")

caster.OnClientEvent:Connect(function(data)
    spawns = data
    print(spawns)

    for i, v in pairs(spawns) do
        for _, spawn in pairs(v) do
            spawn.Touched:Connect(function(hit)
                if hit.Parent == game.Players.LocalPlayer.Character then
                    if tonumber(spawn.Name) then
                        local currentWorld = "W" .. game.Players.LocalPlayer.leaderstats.World.Value
                        if spawn.Parent.Name == currentWorld then
                            local currentStage = game.Players.LocalPlayer.leaderstats.Stage.Value
                            if tonumber(spawn.Name) > currentStage then
                                spawn.BrickColor = BrickColor.new("Lime green")
                                updateStageEvent:FireServer(spawn)
                            end
                        end
                    end
                end
            end)
        end
    end
end)
1 Like

Someone had helped me out and now I’m all good.

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