Before all the security checks to see if a player is allowed to do an action, can you help me first with the head cloning issue? The cloned heads only show on the local player and won’t show for anyone else.
That’s what I have been explaining, any action that involves heads, whether it be creating, cloning or selling, has to go through this system if you want no lag and all players to see it.
No I get that I have to use multiple RemoteEvents, but you never clearly explained how I can make it so the heads are cloned on the client side but still shows for everyone else. All you told me to use is Remote.OnClientEvent:Connect(function(player)
but that did nothing to help. It made it worse as it made the heads not even show for other players.
This is the same problem that Slither .io Simulator tries to solve, and it is hard. The max I can CFrame is about 2,500 parts per heartbeat before it drops below 30fps and there is a lot of tricks I used to tweak the performance.
Suggest to read this post on Lag Prevention and one key bit of information there is in the 3rd-to-last paragraph where it mentions that parts parented to Cameras, among other things, will not replicate any of the usual properties. Slither uses this technique to parent thousands of spheres to folders inside the Camera, which short circuits a lot of replication.
Careful what you wish for, because then without replication in place, you need to take over the positioning of the parts yourself. Each client will need to render hundreds of heads for themselves and all of the other players, every frame. Each client will need to upload their stream of heads position data to the server by firing a RemoteEvent. Server then aggregates all these feeds and publishes a feed of all of each players’ heads positions and fire a remote 20x per second. All clients will need to connect to that and reposition all of each players heads based on that feed. If the exact position isn’t important then you’ll be able to transmit much less information, perhaps just the initial position and velocity and size and theme for the heads might get you pretty far. Just send the minimum properties in your packets, and don’t ever send Part instances or references to huge Player or Character structures in your events.
Once you set up a heartbeat callback to process the positioning each frame, you can optimize it by careful use of task.defer()
to separate the heartbeat into a prepare and present phase. Do all the maths in your Heartbeat callback and use task.defer for your CFraming. Get familiar with the microprofiler and you’ll be able to tell that the CPU and GPU can optimize a large batch of only CFrame operations versus having to do maths CFrame maths CFrame maths CFrame which is how us human beings mostly like to write code.
One more trick I can give you is if you reach a threshold of say a thousand parts you can start skipping the rendering of certain parts on certain frames. Simple use of distance formula (Vector3.Magnitude) to filter out some parts from being rendered in some frames, can go a long way.