Im making a farming game where you harvest LOTS of crops. There can be up to 30k crops in a feild at once. Im telling the server to harvest a crop with unreliable remote events, so lots of events are fired quickly. Most of the time, when a crop is collected it is instantly respawned with a new rarity, position, ect. When I regrow them, I just move them and change their values instead of making a whole new instance (to save performance) But still, with just one player the server can lag and get behind massively. Im willing to restructure all of my code to achieve server performance boosts if it is needed
Heres an old version of the game to provide some context: [3 DAYS] Farming Simulator 99 - PUBLIC ALPHA - Roblox
If anyone can provide tips or even ideas on how to boost server performance it would help
Has to be a way to let them build a bit … check what they have and fire less events.
Them mining programs come to mind. You fill the bag you have to move to a spot to get credit for what you got … All that cuts down on server pounding time.
Instead of firing the event 30k times (wich i don’t recommend) you could fire it once with a table containing all the crops, and then on the server you could loop thru them and to prevent lag you could wait(0.01) every for example 100 crops
just got around to implementing this, but the players movement (and therefore the tools position) is so badly delayed between the client and server that it looks laggy and the game becomes unsatisfying and i cant have that happen. It did improve performance, but i dont think its possible to use the clients position for doing touch on the server without remote events. if there is a way it would be greatly helpful, but for now theres no solution
local module = {}
local rs = game:GetService('ReplicatedStorage')
local events = rs:WaitForChild('events')
local values = rs.globalvalues
local cropsmined = 0
function module.cropmain(newcrop,feild)
local feilddimensionlist = require(rs.Dependencies.Dependencies)['FeildDimensions'][feild]
local feildcroplist = require(rs.Dependencies.Dependencies)['CropList'][feild]
local minx = feilddimensionlist['minx']
local maxx = feilddimensionlist['maxx']
local minz = feilddimensionlist['minz']
local maxz = feilddimensionlist['maxz']
local crops = values[feild..'Crops']
local newx = math.random(minx, maxx)
local newz = math.random(minz, maxz)
newcrop.Position = Vector3.new(newx, 2.2, newz)
local rarity
local raritynum = math.random(1, 100)
newcrop.Feild.Value = feild
if raritynum <= 81 then
newcrop.Type.Value = feildcroplist[1][1]
newcrop.BrickColor = feildcroplist[1][2]
elseif raritynum <= 95 then
newcrop.Type.Value = feildcroplist[2][1]
newcrop.BrickColor = feildcroplist[2][2]
elseif raritynum <= 99 then
newcrop.Type.Value = feildcroplist[3][1]
newcrop.BrickColor = feildcroplist[3][2]
elseif raritynum == 100 then
local randomChance = math.random(1, rs.globalvalues.DiamondRarity.Value)
if randomChance == 1 then
newcrop.Type.Value = feildcroplist[4][1]
newcrop.BrickColor = feildcroplist[4][2]
if math.random(1,150) == 1 then
newcrop.Type.Value = feildcroplist[5][1]
newcrop.BrickColor = feildcroplist[5][2]
newcrop.Material = Enum.Material.Neon
for k,v in pairs(game.ReplicatedStorage.spawnables.rare:GetChildren()) do
v:Clone().Parent = newcrop
end
end
else
newcrop.Type.Value = feildcroplist[3][1]
newcrop.BrickColor = feildcroplist[3][2]
end
else
--newcrop.Type.Value = 'wheat' -- Default value in case raritynum is out of range
end
newcrop.Parent = workspace
end
function module.harvest(part, multi, player)
local feild = player.Values.Feild.Value
local feilddimensionlist = require(rs.Dependencies.Dependencies)['FeildDimensions'][feild]
local feildcroplist = require(rs.Dependencies.Dependencies)['CropList'][feild]
local minx = feilddimensionlist['minx']
local maxx = feilddimensionlist['maxx']
local minz = feilddimensionlist['minz']
local maxz = feilddimensionlist['maxz']
local crops = values[feild..'Crops']
-- harvest main calculations
if part:FindFirstChild('Type') then
local amt = 1*multi
local special = 'None'
local special2 = ''
local totalspecial
if Random.new():NextNumber(1,100) <= player.Values.CritChance.Value then
amt = player.Values.CritPower.Value*multi
special = 'Crit'
end
if Random.new():NextNumber(1,100) <= player.Values.GoldenChance.Value then
amt = amt*5
special2 = 'Golden'
end
player.Values[part.Type.Value].Value +=amt
events.CalculateQuestProgress:Fire(player, part, part.Type.Value, special, special2)
local charmlist = require(rs.Lists)['Charms']
if math.random(1,rs.globalvalues.CharmRarity.Value) == 1 then
local charm = charmlist[math.random(1,#charmlist)]
game.ReplicatedStorage.events.Notification:FireClient(player, 'charm', charm)
player.Values.Charms[charm..'1Charms'].Value += 1
game.ReplicatedStorage.events.NewEnchant:FireClient(player)
events.CalculateQuestProgress:Fire(player, nil, 'Forage', nil, nil)
end
totalspecial = special..special2
player.PlayerGui.HarvestMarker.Start:FireClient(player, amt, part.Type.Value, part.BrickColor, totalspecial)
end
cropsmined += 1
if (values.InstaGrowback.Value == true or cropsmined/values.Growbackamt.Value == math.floor(cropsmined/values.Growbackamt.Value)) and (part.Type.Value ~= 'lavarock') then
module.cropmain(part, feild)
else
local insprinklerrange = false
for k,v in pairs(workspace.Sprinklers:GetChildren()) do
local distance = (part.Position - v.Main.Position).Magnitude
if distance <= v:GetAttribute('Range') then
insprinklerrange = true
end
end
if insprinklerrange == true and part.Type.Value ~= 'lavarock' then
module.cropmain(part,feild)
else
part:Destroy()
crops.Value -= 1
end
end
end
function module.main(tool)
local lastcollectedcrop = nil
tool.Equipped:Connect(function()
--game.ReplicatedStorage.events.CalculatePassives:FireServer()
player = game.Players[tool.Parent.Name]
tool:SetNetworkOwner(player)
tool.hb:SetNetworkOwner(player)
tool.Handle:SetNetworkOwner(player)
end)
tool.hb.Touched:Connect(function(part)
if part.Name == 'Crop' and part:FindFirstChild('Type') and part ~= lastcollectedcrop then
lastcollectedcrop = part
player = game.Players[tool.Parent.Name]
module.harvest(part, tool.hb.multiplier.Value, player)
end
end)
end
return module