What is the most optimal way to hold and display a part that the player will be moving around in a multiplayer game?

Hi, I’m currently in the midst of coding a game as a side project but I’m unsure which way I should go about this. Currently, what I have is this.

It looks okay and gets the job done decently, aside from slight choppiness. However, I went through a few steps to get there and I think there’s a MUCH more optimal way to do this, but I can’t think of it.

Things to note:

  • I’m using a LocalScript in StarterPlayerScripts to give the player their controls and move their part locally inside their CurrentCamera(which I’m unsure is the best way to do it). This means that the player can only move their part locally.
  • writeModule is a RemoteEvent that tells the server to input the position into the positionKey of the positionsTable of a ModuleScript.
  • readModule is a RemoteFunction that asks the server for the positionsTable so it can read the data of all the other players’ parts.

Currently each player’s part is replicated in their own CurrentCamera in workspace. All of the other players’ parts are cloned into that as well, but each player can only move their own. Using the following code, I locally send the position of a player’s part to the server where the other clients can then read from it and position the other players’ parts in the correct location in their own view.

runService.RenderStepped:connect(function()
	local partInQuestion = workspace.CurrentCamera:FindFirstChild(player.Name.."Part")
	local position = partInQuestion.Position
	
	writeModule:FireServer(position)
	
	local positionsTable = readModule:InvokeServer()
	local numPlayers = #positionsTable
	
	for i = 1, numPlayers do
		if positionsTable[i].playerKey ~= Players.LocalPlayer.Name then
			workspace.CurrentCamera[positionsTable[i].playerKey.."Part"].Position = positionsTable[i].positionKey
		end
	end
end)

I feel like there’s clearly something I’m missing and I could do this so much more easily by just putting all the player’s parts in workspace so I don’t have to do this extra step, but the way I have it right now, since the control script is a LocalScript, players can only manipulate their parts locally. The only other solution I can think of is to send a RemoteEvent to the server for each frame to tell the server where to move the part, but I’m not sure if that’d be taxing on the server.

2 Likes

A good way to slightly improve the communication would be to set up a loop on the server that would invoke all clients, send the last positions and receive the current positions and wait until requests returned or timed out. The way you are doing it right now piles up requests which come out in bursts.

Make sure to make the loops independent for each player to avoid throttling others when one is lagging.

1 Like

You could just get rid of the remote communication altogether. Create the part on the server (the player’s character) and place it in the Workspace. After, give NetworkOwnership of it to the appropriate client. Let the client control their part and the position will automatically replicate to other clients.

At that point, you don’t need to handle replication yourself. The remote becomes unnecessary and you won’t need a module to track the positions of others.

2 Likes

Thank you, I’ll look into this and see if it works once I make some modifications; the part I was cloning was anchored and these parts were moving along the X and Y axes, so I’ll have to experiment with making the game X and Z axis based instead, because I can’t give NetworkOwnership to a player if the part is anchored.