So I came across this replication issue that I still don't fully understand but it finally works now

TL;DR: If you instead want to skip the contexts you can watch the video to get a visual representation.

Quick Context:
I currently made a shield that is welded to a characters Torso. I originally used TweenService (On the serverside after firing a remote event from the client whenever the client right click’s) to not only repeatedly change the color of this welded shield but also the size of it.

The Issue:
After experimenting with my testers, for some reason we noticed that whenever we used our shields, on our ends, it would look and work perfectly fine from our own perspectives. However, it wasn’t being properly replicated to every other client. It was though, and I confirmed this, being properly replicated to the server but with the exception of it replicating for every other client. On every other clients end it would appear as if the player, that is using the shield, is always anchored from their perspectives and it is only until they stop using the shield that the server finally replicates where they are really positioned, and them properly moving.

My Attempts To Fix It:
After I removed the tween that was resizing the part indefinitely and left only the tween that was changing the color of the shield, it was finally replicating correctly to everyone else. I tried to make my own indefinite tween by creating the resize script manually through RunService like this. Keep in mind that I am using the HEARTBEAT event.

	        local switch = true
		shieldSize = RNS.Heartbeat:Connect(function()
			local add = Vector3.new(0.04,0.04,0.04)

			if switch then
				if shield.Size.Magnitude >= Vector3.new(9,9,9).Magnitude then
					switch = not switch
				end
				
				shield.Size += add
			else 
				if shield.Size.Magnitude <= Vector3.new(7,7,7).Magnitude then
					switch = not switch
				end
				shield.Size -= add
			end

		end)

Unfortunately because I used Heartbeat, it was still causing the same issue as if i was using the TweenService to resize this part. It was until I used PreSimulation that everything was finally replicating as it should be. Here’s the updated code:

	if isBlocked then	
		local switch = true
		shieldSize = RNS.PreSimulation:Connect(function()
			local add = Vector3.new(0.04,0.04,0.04)

			if switch then
				if shield.Size.Magnitude >= Vector3.new(9,9,9).Magnitude then
					switch = not switch
				end
				
				shield.Size += add
			else 
				if shield.Size.Magnitude <= Vector3.new(7,7,7).Magnitude then
					switch = not switch
				end
				shield.Size -= add
			end

		end)
		shieldColor:Play()
		
		script.Parent.Parent:WaitForChild("Shield").Transparency = 0.5		
	else
		shieldSize:Disconnect()
		shieldColor:Pause()
		script.Parent.Parent:WaitForChild("Shield").Transparency = 1
	end

Video Using TweensService To Resize (Same as Heartbeat): < Doesn’t Work :x:

Video using PreSimulation via Runservice (Finally Works!). < Works :white_check_mark:

Can any advanced programmer tell me why this is working :sweat_smile:.

1 Like

try sending a remote event and tween the shield on client. Maybe it will be an optimization and more accurate

SetNetworkOwner(BasePart)
1 Like

Heartbeat (and PostSimulation) run after the physics simulation has completed, while PreSimulation (and Stepped) run before the physics simulation runs

Personally, I don’t remember encountering an issue like this before, so to tell you the truth I’m unsure as to why this is happening, but I mentioned what I did above because the type of RunService loop you use does matter depending on what you’re trying to do


@soultroulowlman Out of curiosity, does the shield have CanCollide enabled? If so, do you still experience the issue if you set it to false, then try tweening the shield’s size afterwards?

3 Likes

If i tween the size on the client it wont replicate to others

2 Likes

Nope it does not have cancollide enabled.

3 Likes

Also theres a moment in the second fixed video that proves collision is off as the shield goes through the other player btw

2 Likes

can you share the .rbxl project? Your heartbeat code looks okay, it shouldn’t cause the problem, there’s probably something else causing it

1 Like

I checked my projects, and I did make a shield system that works similar to this one, but what I did was I made the shield follow the character’s RootPart rather than connect it to them using a weld

Changing an object’s scale also affects its CFrame (how much depends on the difference between the object’s original size and its new size), and therefore affects its physics

When you connect an object to an assembly using a joint or constraint such as a weld, that object becomes part of the assembly, so any modifications done to the object’s physics will have an effect on the assembly

Welds try to maintain a fixed offset between each part, so I wouldn’t be surprised that this behavior is either responsible or related to the issue, although I still don’t really know why using PreSimulation fixed the problem. My theory is that, since PreSimulation runs before the physics simulation, it’s giving the physics engine enough time to compensate for the shield’s new size