How to fix laggy physics in a localscript?

I currently have a system that detects when the player activates a proximity prompt, after that unanchor parts inside of a model. How do I make it so that the physics is less laggy when the parts are unachored?

--local script
OpenLootCrate.OnClientEvent:Connect(function(itemName, crate: Model)
	local ItemConfigs = require(game.ReplicatedStorage.Configs.Accessories)[itemName]
	local model = ItemConfigs.Model:Clone()
	model:PivotTo(crate.ItemSpawn.CFrame)
	crate:WaitForChild("InteractBox").ProximityPrompt.Enabled = false
	local position = crate:GetPivot()
	
	model.Parent = crate
	
	for _,v in crate:GetDescendants() do
		if not v:IsA("BasePart") or v.Name == "ItemSpawn" then continue end
		v.Anchored = false
	end
	
end)
-- server script
LootCrateEvent.OnServerEvent:Connect(function(player, CrateInQuestion)
	local CrateConfigs = require(RepS.Configs.Crates)
	
	if DM.GetData(player).money < CrateConfigs[CrateInQuestion.Name].Price then return false end

	DM.SubtractValue(player,"money",CrateConfigs[CrateInQuestion.Name].Price)
	
	local item = RandomizeChance(CrateConfigs[CrateInQuestion.Name].LootPool)

	LootCrateEvent:FireClient(player,item, CrateInQuestion)
	
	for _,v in CrateInQuestion:GetDescendants() do
		if not v:IsA("BasePart") or v.Name == "ItemSpawn" then continue end
		v:SetNetworkOwner(player)
	end

end)

Unanchor them from the server.

If you’re looking to have it be visible/simulated on the client only, clone the parts and unanchor the clones, and hide or remove the original.

1 Like

How do I make it so that only the player who fired the remote can see the parts, and it would appear normally to everyone else in the server?

Clone the parts and unanchor them on the client that fired it, and hide the original parts.

1 Like

This is incorrect, nothing should ever be done from the server if it’s a client-sided effect.

OP should not clone all the parts and then unanchor them on the client. The crate should be created on the client in the first place, which then you can unanchor the parts. Anything that is a strictly client sided effect, should only be done on the client side if only one client is affected.

3 Likes
OpenLootCrate.OnClientEvent:Connect(function(itemName, crate: Model)
	local ClientCrate = crate:Clone()
	ClientCrate:PivotTo(crate:GetPivot())

	for _,v in crate:GetDescendants() do
		if v.Name == "InteractBox" then v:Destroy() continue end
		if not v:IsA("BasePart") then continue end
		v.Transparency = 1
	end

	local ItemConfigs = require(game.ReplicatedStorage.Configs.Accessories)[itemName]
	local model = ItemConfigs.Model:Clone()
	model:PivotTo(crate.ItemSpawn.CFrame)
	
	model.Parent = ClientCrate
	ClientCrate.Parent = workspace.ClonedCrates
	
	for _,v in ClientCrate:GetDescendants() do
		if not v:IsA("BasePart") or v.Name == "ItemSpawn" or v.Name == itemName then continue end
		v.Anchored = false
	end
	
end)

I rewrote the client script according to this, the server script remains unchanged except I removed the setownership. Is this a good implementation?

No, do not clone the crate on the client. Add in a system to spawn the crates where they need to spawn on the client.

Naturally if the crate is spawned on each client individually they will all see the crates, it’s just not a server-sided crate. Cloning the crate and hiding the server crate just adds unnecessary parts. There’s no point in doing that and it’s bad practice.

Create the crates initially on the client, at run-time, not on the server. This way the crate is always owned by the client and will most likely never lag.

1 Like

If I’m following you correctly here, I would have to write a module script, and every crate function should be inside that crate, and then when a player joins the game, the crate will spawn only for that player. The server should only retain information about the crate configs, am I right?

Easy replication that is also eligible for instance streaming.

If you re-use the crate a lot, then it would be better to store it in ReplicatedStorage and have the client create them, and parent it to an object that is eligible for streaming. But for a majority of cases, it doesn’t really matter that much.

2 Likes

Yes, exactly, always develop in a way that you would if you expect the game to be big. If you miss out on important optimizations early on, you’re going to run into issues in the future.

1 Like

I decided to follow tannnxr’s way here since I thought some OOP practice could do some good. Really, many thanks to you both though, because of you, I got this working in a short time. Many thanks, once again.

1 Like

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