Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Would updates every frame for all players on a server cause severe lag?

I'm making a shooter game, and I want everyone to see each other's head and arms follow their cursor. That means that on a server-side script, I would have to update everybody's head and arms' CFrames - every frame. Is that going to be a massive problem? If you have done something similar, what alternatives do I have?

Edit: I just want to thank everyone for their answers - they were all helpful!

4 comments

0

it would only lag a lot if the waiting time between frames is unusually short

0

well u could make it so only when the player moves the mouse u update??

0

on an FPS thats gonna be like... all the time.

0

conventionally in FPS games, the client's update time would be much greater than the servers. this means that the client will see a much cleaner view of their gun, their arms, etc. the server, however, does not need to see such great detail, so you can send less updates

3 answers

✓ Accepted answer

I don't have any metrics for that, but it's generally a bad practice and for the sake of this answer, we're just not gonna do that. Here's what I think you could do instead:

  1. Send updates to the server at a much lower frequency, say, 5 updates per second. This would ease the load on the network because you're not sending requests 30 or 60 times per second. Additionally, you could run a check to stop sending updates when there hasn't been any mouse movement for some period of time.

  2. Handle those updates by interpolating (tweening) the joints when rendered on other clients. This would make the movement seem smooth enough, despite not receiving updates at every frame. Note that doing this would also make up for latency issues or network/internet lag. This is necessary, without it, other characters would look... jittery.

  3. Make adjustments to the number of updates per second, to get that smoothing to look good enough while taking into account the performance levels. Maybe the network can handle more updates per second, maybe it can't, idk.

Oh, and another tip: your update function should ideally just send the angle of the camera tilt, instead of the joint CFrames. Sending just one value over a CFrame which has about 12 values(don't quote me on this, it's probably inaccurate, but the point is it's much smaller than a CFrame) is bound to make a difference when you're running the updates at high frequency times the number of players. Let the client handle the CFrame interpolation and offsetting of each joint based on the angle.

Normally I'd provide a code sample, but this one's a bit less simple than the other questions I've provided an answer for, so have some pseudo-ish code instead:

-- this is for updating your own character
-- skip this part if you're locked in FPS, you're not going to see this at all
RunService.RenderStepped:Connect(function(delta)
	local CameraTiltAngle = GetCameraTilt()
	for ("each joint you care to update") do
		Joint.C0 = offsetJoint() -- however you plan to offset based on camera tilt
	end
end)

-- this is your update loop
local updateFrequency = 1/5 -- updates per second
spawn(function()
	while true do
		wait(updateFrequency)
		if isPlayerMoving() then 
			JointUpdateRemote:FireServer(GetCameraTilt())
		end
	end
end)

-- this is your other character rendering listener
JointUpdateRemote.OnClientEvent:Connect(function(player, angle)
	local char = player.Character
	if not char then return end -- check if character still exists
	for ("each joint you care to update like neck, shoulders") do
		spawn(function()
			local targetC0 = CFrame.new("cframe of that joint offset by the angle")
			-- tween the CFrame
			local alpha = 0
			local tweenConnection = RunService.RenderStepped:Connect(function(delta)
				alpha = alpha + (delta * updateFrequency)
				Joint.C0 = Joint.C0:lerp(targetC0, alpha)
				if alpha >=1 then
					Joint.C0 = targetC0
					tweenConnection:Disconnect() -- break the loop
				end
			end)
		end
	end
end) 

If you'd like to learn more, you could read this guide from EgoMoose. It suffers from the same problem, though he did mention that he's updated the blog and is just waiting for the approval of the change.

Hope that helps!

You should not do the updates on the server:

  1. The server does not do anything with such information

  2. The new positions and orientations would be updated to the client that already has updated them causing odd looking stuttering effects

  3. It stops you from doing client-side optimizations

  4. It doesn't make sense in "the real world" and is an ugly Roblox-specific shortcut

What you should do instead is have the server forward these updates to the other clients. The clients can then decide if they want to update the parts in question. If the parts are really far away from the client's viewpoint, or are obstructed by something, there really is no reason to actually visualize the updates. They can then be forgotten about.

Sending 60 updates a second is not an issue unless you're sending tons of data. Sending one angle update only requires 8 bytes of extra data. That's 480 bytes of data per second. Sure, Roblox might internally be sending some other packets alongside your data, but the total will still stay around half a kilobyte. It might've been a lot a couple centuries back but modern internet connections can handle it easily. Your router is probably transferring much more at the very moment.

Having the "machines of today are powerful enough" mindset is often dangerous. Here however, there isn't much optimization you can do regarding the networking, yet games manage to perform these kinds of visual effects pretty easily.

first thing to do would be to minimize frequency of communication between the server and client. One such step u should take would be to only update the player server - side when the player moves its mouse, or once every few client - side frames. I know these things wont change the overall picture by much but every step along the way counts. Next u should minimize the magnitude of data transferred to run the function. In this case, it would be ideal to only pass where the cursor is pointing to, with any other items required to run the function derived by the server. This would mean u should place the server - side script where it could "see" all the items required(apart from all the client - side only stuff of course). These are the two prime steps u should take when u opt for the server and client to interact. I apologize if u wanted me to go further in to details(say, precise placement of all the scripts and objects for optimization of the game) but that would have to depend on the genuine structure of ur game. With the parameters that u gave me, this would be the best i can come up with.

1 comment

0

my hand got itchy ok?

This discussion is preserved as it was. New answers, comments, and votes are closed.