hello everyone i’m making a client-sided collecting system for my game
the problem is that each cube collected make bigger and bigger lag spike
i’ll appreciate help
-- server code
remotes.CubeCollected.OnServerEvent:Connect(function(player, cube: string)
local data = RS.Data:WaitForChild(player.Name)
local Stats = data:WaitForChild("Stats")
local TotalStats = data:WaitForChild("Total Stats")
Stats.Cubes.Value += CubesModule[cube.Name].Value
TotalStats["Total Cubes"].Value += CubesModule[cube.Name].Value
Stats.XP.Value += CubesModule[cube.Name].Value/10
end)
local function parseVector3(str)
local x, y, z = string.match(str, "([^,]+), ([^,]+), ([^,]+)")
if x and y and z then
return Vector3.new(tonumber(x), tonumber(y), tonumber(z))
end
return nil
end
local function isPositionTaken(pos, takenPositions, tolerance)
for _, taken in takenPositions do
if (pos - taken).Magnitude <= tolerance then
return true
end
end
return false
end
local spawnDebounces = {}
remotes.CubeData.OnServerInvoke = function(player)
if spawnDebounces[player.Name] then return end
table.insert(spawnDebounces, player.Name)
local data = RS.Data:WaitForChild(player.Name)
local spawnSpeed = data["Cube Stats"].Speed.Value
local spawnLimit = data["Cube Stats"].Limit.Value
if #data.Cubes:GetChildren() >= spawnLimit then return end
spawn(function()
task.wait(1/spawnSpeed - 0.001)
spawnDebounces[player.Name] = nil
end)
local chosedCube = CubesModule.ChooseCube()
local cube = Instance.new("StringValue")
cube.Name = chosedCube
local takenPositions = {}
for _, existingCube in data.Cubes:GetChildren() do
local pos = parseVector3(existingCube.Value)
if pos then
table.insert(takenPositions, pos)
end
end
local maxAttempts = 20
local found = false
local cubePos
local tolerance = 1
for attempt = 1, maxAttempts do
local randomX = math.random(-spawnArea.Size.X/2+ 0.5, spawnArea.Size.X/2 - 0.5)
local randomZ = math.random(-spawnArea.Size.Z/2+ 0.5, spawnArea.Size.Z/2 - 0.5)
local tryPos = spawnArea.Position + Vector3.new(randomX, spawnArea.Size.Y/2 + 0.5, randomZ)
if not isPositionTaken(tryPos, takenPositions, tolerance) then
cubePos = tryPos
found = true
break
end
end
if not found then
return nil
end
cube.Value = tostring(cubePos)
cube.Parent = data.Cubes
return cube
end
-- client code
local function spawnCube()
local cubeValue = Remotes.CubeData:InvokeServer()
if not cubeValue then return end
local cubesTemplates = RS:WaitForChild("Cubes")
local cubeTemplate = cubesTemplates:FindFirstChild(cubeValue.Name)
if not cubeTemplate then return end
local cube = cubeTemplate:Clone()
local x, y, z = string.match(cubeValue.Value, "([^,]+), ([^,]+), ([^,]+)")
if x and y and z then
cube.Position = Vector3.new(tonumber(x), tonumber(y), tonumber(z))
end
local connection
connection = cube.Touched:Connect(function(hit)
if debounce then return end
debounce = true
if hit.Parent == player.Character then
cubeValue:Destroy()
game.Debris:AddItem(cube, 0.6)
Remotes.CubeCollected:FireServer(cubeValue)
AnimateCollect(cube)
if connection then
connection:Disconnect()
connection = nil
debounce = false
end
end
end)
cube.Parent = playerCubesFolder
end
RS.Remotes.LoadCubes:FireServer(playerCubesFolder)
while task.wait(1/CubeStats.Speed.Value) and playerCubesFolder do
spawnCube()
end
video: