Part Position and NetworkOwner scripts: how to optimize?

Intro
I made a few scripts to move parts on the client (using bodypositions) and it works.
However, I’m failing to optimize my scripts and I was hoping one of you can help.

Goal of the script
I wanted to SetNetworkOwner() for the five moving parts in my game. This can only be done in (1) the workspace and (2) using a serverscript. Without SetNetworkOwner I can’t change the bodypositions on the client.

Script number 1: Server Script (ServerScriptService)

Script
local movefolder = game:GetService("ReplicatedStorage").Movefolder
local remote = game.ReplicatedStorage.Movement

game.Players.PlayerAdded:Connect(function(player)
	
	local Clonefolder = movefolder:Clone()
	Clonefolder.Name = player.Name
	Clonefolder.Parent = game.Workspace.movefolderstore
	
	local blueflower = Clonefolder.BlueFlower
	local movingflower = Clonefolder.MovingFlower
	local movingplanets = Clonefolder.MovingPlanets
	local movingplatform = Clonefolder.MovingPlatform
	local Redflower = Clonefolder.RedFlower
	
	blueflower:SetNetworkOwner(player)
	Redflower:SetNetworkOwner(player)
	movingflower:SetNetworkOwner(player)
	movingplatform:SetNetworkOwner(player)
	movingplanets:SetNetworkOwner(player)
	
	remote:FireClient(player)

	Clonefolder.Parent = game.ReplicatedStorage

end)

Explanation: Player is added. The ‘‘Movefolder’’ in the ReplicatedStorage is cloned (so each player can have ownership). Remote is fired so the Localscript can start working. Clonefolder (named as the player who joined) is sent back to the ReplicatedStorage.

Script number 2: Localscript (Starterplayerscripts)

Localscript
local Player = game.Players.LocalPlayer
local movefolderstore = game.Workspace.movefolderstore
local movefolder = game.ReplicatedStorage:WaitForChild(Player.Name)
local remote = game.ReplicatedStorage.Movement

local blueflower = movefolder.BlueFlower
local redflower = movefolder.RedFlower
local extraflower = movefolder.MovingFlower
local candyplatform = movefolder.MovingPlatform
local planets = movefolder.MovingPlanets

local timer = 4

remote.OnClientEvent:Connect(function()
	
	movefolder.Parent = movefolderstore
	
while true do
	planets.BodyPosition.Position = Vector3.new(-52.935, 8.321, 61)
	blueflower.BodyPosition.Position = Vector3.new(-307.369, 12.069, -63.031)
	redflower.BodyPosition.Position = Vector3.new(-278.362, 12.069, -50.031)
	extraflower.BodyPosition.Position = Vector3.new(-54.371, 2.303, -239.852)
	candyplatform.BodyPosition.Position = Vector3.new(170.308, 8.25, -56.95)

	wait(timer)

	planets.BodyPosition.Position = Vector3.new(-52.935, 8.321, 49)
	blueflower.BodyPosition.Position = Vector3.new(-278.362, 11.896, -63.437)
	redflower.BodyPosition.Position = Vector3.new(-307.369, 12.069, -50.031)
	extraflower.BodyPosition.Position = Vector3.new(-54.371, 1.948, -253.776)
	candyplatform.BodyPosition.Position = Vector3.new(151.308, 8.25, -56.95)

	wait(timer)

	end 
	
end)

Explanation: the server fired the remote. This script now starts doing what is needed: changing the bodypositions in a loop to make the parts move every x seconds. The ‘‘clonedfolder’’ (the folder where the localplayer is networkowner of) is moved to workspace to make it visible for the client only.

Thank you and please ask questions
This post is probably really confusing. I really hope one of you can help me out. Please ask me for anything if needed. I tried to be as clear as possible. Your help is appreciated!

1 Like

I forgot to mention that the ‘‘blueflower’’ ‘‘redflower’’ ‘‘candyplatform’’ etc. are the parts that are being moved in a loop. I also forgot to mention that the script works and does the job, however, the CPU and GPU are extremely high!

1 Like

First of all, consider changing wait() to task.wait().

Secondly, is it possible there are multiple while loops starting? You start a new one every event, is it possible the event fires more than one?

I’ve just had a quick glance at your code, but I don’t see anything client-side which should cause performance issues. Could you include a gif/video of this effect in-game? Might be able to spot potential issues then, probably not though.

Lastly, I see you are using BodyPosition, this has been deprecated, you should use AlignPosition (roblox.com) instead. Might help with performance, but probably won’t make a difference.

1 Like

Hi @ifkpop,

Thank you for taking your time to help me.

  1. I will read about task.wait() later.
  2. I think yes, there are multiple loops starting, one loop per player.
  3. If the issue is fixed (or I have found an alternative I will change it into AlignPosition
  4. Sure! I have made two videos showing the performance stats. I have no idea how to edit what I recorded, so forgive me for the low quality (Performance stats showing above).
Video 1: Performance stats when both scripts are active

robloxapp-20220316-1724591.wmv (786.7 KB)

Video 2: Performance stats when the scripts aren't active

robloxapp-20220316-1726397.wmv (435.1 KB)

Difference: CPU and GPU

Edit: uploaded the same video twice by accident. this is fixed now

I made a script that changes the BodyPosition on the server, so that only one script is required. It’s better than the performance stats in video 1: but not really good as well. That’s why I decided to make the script run on client (but the problem: you can’t change bodypositions on the client). Unless you make the player NetworkOwner (but that results in video 1). Do you know a way or a helpful article that makes it possible to achieve what I want without creating this much lag?

Well, I’m not quite sure.

A friend of mine wanted help with an obby, similar way to yours. I sadly don’t remember how we did it, nor where or if I still have the file saved.

This is just a guess, not sure if this will work or increase performance.

Would it not be possible to have the part (flower or whatever) on the server as usual (without BodyPosition). The client, without being NetworkOwner, adds a BodyPosition and then manipulates it that way.

I don’t think being a network owner is necessary for what you want to achieve, since you only need each client to control their own moving parts.

1 Like

Great idea! I’ll test it out and I will let you know if it works. If it does, that’d be amazing!

Sounds good! Feel free to come back here once again if you need further help.

1 Like

Right now, I’m testing the idea. There is one problem. The part needs to be unanchored in order for the bodypositions to work.

  • unanchoring the part on the client script works for the client, but the bodypositions don’t seem to have any effect on the part.
  • anchoring the part → no effect
  • unanchoring the part on the server: they fall down into the void before the script can use the bodypositions.

Do you have an idea why unanchoring the part on client doesn’t work…? I’m a little confused now.

robloxapp-20220316-1944378.wmv (1.3 MB)

This is the progress so far! I have a few questions to ask you.

  • If there is no grey platform as seen in the video, the flowers fall down and are gone. (is it possible to unanchor the moving part on the client, while it is anchored on the server?) → so it doesn’t fall down.
  • As seen in the video, the flowers start doing what they are supposed to do after around 10 seconds. I don’t see why. Do you know that?
Localscript that I use to make this work
local Player = game.Players.LocalPlayer

local movestorage = game.Workspace.Movestorage
local movefolder = movestorage.Movefolder

local timer = 4

local blueflower = movefolder.BlueFlower
local redflower = movefolder.RedFlower
local extraflower = movefolder.MovingFlower
local candyplatform = movefolder.MovingPlatform
local planets = movefolder.MovingPlanets

local clonedbodypos1 = game.ReplicatedStorage.BodyPosition:Clone()
local clonedbodypos2 = game.ReplicatedStorage.BodyPosition:Clone()
local clonedbodypos3 = game.ReplicatedStorage.BodyPosition:Clone()
local clonedbodypos4 = game.ReplicatedStorage.BodyPosition:Clone()
local clonedbodypos5 = game.ReplicatedStorage.BodyPosition:Clone()

clonedbodypos1.Parent = blueflower
clonedbodypos2.Parent = redflower
clonedbodypos3.Parent = extraflower
clonedbodypos4.Parent = candyplatform
clonedbodypos5.Parent = planets

while true do
	planets.BodyPosition.Position = Vector3.new(-52.935, 8.321, 61)
	blueflower.BodyPosition.Position = Vector3.new(-307.369, 12.069, -63.031)
	redflower.BodyPosition.Position = Vector3.new(-278.362, 12.069, -50.031)
	extraflower.BodyPosition.Position = Vector3.new(-54.371, 2.303, -239.852)
	candyplatform.BodyPosition.Position = Vector3.new(170.308, 8.25, -56.95)

	wait(timer)

	planets.BodyPosition.Position = Vector3.new(-52.935, 8.321, 49)
	blueflower.BodyPosition.Position = Vector3.new(-278.362, 11.896, -63.437)
	redflower.BodyPosition.Position = Vector3.new(-307.369, 12.069, -50.031)
	extraflower.BodyPosition.Position = Vector3.new(-54.371, 1.948, -253.776)
	candyplatform.BodyPosition.Position = Vector3.new(151.308, 8.25, -56.95)

	wait(timer)

end 

I don’t think this is the source, however if you want BodyPositions you can do this in different ways. For example:

local bodyPos = Instance.new("BodyPosition")
-- Configure the bodyPos to be how you want it
-- Clone this over and over and put it on each of the things.

This is probably faster than asking the server for the parts. Otherwise you can do this:

local clonedbodypos1 = game.ReplicatedStorage.BodyPosition:Clone()
local clonedbodypos2 = clonedbodypos1:Clone()
local clonedbodypos3 = clonedbodypos1:Clone()
local clonedbodypos4 = clonedbodypos1:Clone()
local clonedbodypos5 = clonedbodypos1:Clone()

Didn’t mean to send it at this stage, sorry for the confusion.

1 Like

Will do. I made another script that also seems to work. Can you check if there is something I should change to make it better?

Localscript
local movefolder = game.ReplicatedStorage.Movefolder
local movestorage = game.Workspace.Movestorage

local timer = 4

local clonemovefolder = movefolder:Clone()
clonemovefolder.Parent = movestorage

local blueflower = clonemovefolder.BlueFlower
local redflower = clonemovefolder.RedFlower
local extraflower = clonemovefolder.MovingFlower
local candyplatform = clonemovefolder.MovingPlatform
local planets = clonemovefolder.MovingPlanets

while true do
	planets.BodyPosition.Position = Vector3.new(-52.935, 8.321, 61)
	blueflower.BodyPosition.Position = Vector3.new(-307.369, 12.069, -63.031)
	redflower.BodyPosition.Position = Vector3.new(-278.362, 12.069, -50.031)
	extraflower.BodyPosition.Position = Vector3.new(-54.371, 2.303, -239.852)
	candyplatform.BodyPosition.Position = Vector3.new(170.308, 8.25, -56.95)

	wait(timer)

	planets.BodyPosition.Position = Vector3.new(-52.935, 8.321, 49)
	blueflower.BodyPosition.Position = Vector3.new(-278.362, 11.896, -63.437)
	redflower.BodyPosition.Position = Vector3.new(-307.369, 12.069, -50.031)
	extraflower.BodyPosition.Position = Vector3.new(-54.371, 1.948, -253.776)
	candyplatform.BodyPosition.Position = Vector3.new(151.308, 8.25, -56.95)

	wait(timer)

	end 

You could, rather than saving all the positions as Vector3’s, you could save them as a start and end part. You could then do something like this:

local movers = {
    ... -- All of your flowers and stuff
}

while task.wait(timer) do
    for _, mover in pairs(movers) do
        mover.BodyPosition.Position = mover.End.Position
    end

    task.wait(timer)

    for _, mover in pairs(movers) do
        mover.BodyPosition.Position = mover.Start.Position
    end
end

Not the best code, but it looks a bit neater and should probably do the trick. Wrote it in this text editor so I haven’t tested it, but I think this should work.

1 Like

Thank you for all the advice and help you have given! I appreciate it very much. The problem is solved!
Have a nice week,

Sven (@NinjaMinion101)

1 Like