Should I move the player's character on the client or server?

On this section of the documentation about optimizing performance, it talks about instance streaming. Here it states:

If you move a player’s character by setting its CFrame, do so from a server-side Script and use streaming requests to more quickly load data around the character’s new location.

However, I’m wondering if that’s the case because I thought that moving the player’s character on the client would’ve been the best approach no?

1 Like

If you’re just teleporting the player to a new location, do that on the server. If you’re changing velocity or making a custom movement system, do that on the client.

Well, I’m moving the client in a temporary loop where I move the CFrame. Client?

If you’re just moving the character, you can do so on the client. Streaming requests are used to load the data before moving the character so when they are moved, everything is loaded.

What type of data? Does roblox mean everything in the game? Like scripts, stuff in workspace, etc?

Things like terrain and parts that make up the environment around the area.

Moving the character on the client was the best approach before streaming was introduced (moving in this context means teleporting so a position/cframe change). The issue with doing it on the client now is that sometimes when you teleport the player, not everything is “streamed in” so they might have certain things not loaded and fall through the map.

That’s why roblox introduced player:RequestStreamAroundAsync() before you teleport the player. Basically what it does is request the server to load in the area where you want to tp. It’s basically preloading the zone before the player teleports, so the experience is smooth and they don’t get send to an empty baseplate while assets are loading in around them.

1 Like

So should I call this on the client before I move them?

Yes exactly, so the area can be streamed around the player before they tp.

Function that you can use below. It takes the player as the first argument and a Vector3 (position) for the second. Also added a timeout on the RequestStreamAroundAsync so max time it waits before the player is teleported is 5 seconds.

--[[
	Function that handles preloading the players upcoming area
]]
local function _preloadTeleportAreaFromClient(player : Player, preloadArea : Vector3)
	local character = player.Character
	player:RequestStreamAroundAsync(preloadArea, 5)
	player.Character:PivotTo(preloadArea)
end
2 Likes

Ah I don’t move the character with pivot to, I just set the HumanoidRootPart to a new CFrame. Or is this usually bad?

PivotTo and setting the primary part to a new cframe is pretty much the same thing. I just use PivotTo because it works even if a primary part is not set for a model and moves the whole model

Oh alright good, ok thank you for your help again. You’re always helping me datasigh. I’ll mark you as the solution.

Okay wait so moving the character on client + requeststreamaroundasync best approach right?

Everything on the server. If the client needs to teleport send a remote event request

Problem is, I will be setting the CFrames in a temporary while loop which would mean I’d be sending alot of remote requests to the server. So…?

maybe change the design of that feature? don’t imagine a cframe needing to be repeatedly set in a while loop tbh

Trust me it’s needed, anyway can you not call requeststreamasync on the client? Or can you?

You can’t call it on the client :frowning:

1 Like

Meh alright then, I’ll just move the character on the client.

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