NPC CFrame movement replicates wrong on clients

hello, i’ve recently come with a big problem in custom character movement replication,
i’m not sure if this is a bug or just how it’s supposed to work, but NPC movement doesn’t replicate very well on other clients when i use CFrame math on runservice.Stepped or runservice.Heartbeat (serverside)

here is some footage, first video is what the server sees (during test mode, studio)
red character is our guy


as you can see, it runs super smooth, no problems at all.
but when you look at the client side, how others see the same red character:

it replicates wrong, it has lag, it stutters sometimes, lags behind, in front… the problem is noticable only when modifying cframe serverside in stepped or heartbeat (renderstepped is not available on server)
is this a bug? am i doing something wrong?

this is a custom scripted NPC character not assigned to a player, but controlled by its inputs. in my game character auto loading is disabled and theres no default roblox character, all custom, treated like NPC’s

What solutions i have tried so far?

  • changing stepped / heartbeat / wait() loop
  • setting network owner of every part ( and only root) to nil (server)
  • removing everything other than CFrame modifications from the loop, concluding that the problem comes from that.
2 Likes

From other DevForum posts, it looks like the server replicates to the client at a rate of 20Hz. I don’t know if the exact value is correct, but in any case, it is much lower than the client’s render rate–60Hz.

In order to achieve smooth movement, you simply have to handle this sort of movement on the client. You would be best to send the CFrame to the client (i.e. by RemoteEvent) every certain interval (e.g. 20Hz), and have the client interpolate between these CFrames to allow smooth movement. To optimise network usage, you could increase the time between information. If you have set animations, like a CFrame jump animation, you can avoid sending all the position data to the client, and instead tell the client to play the animation locally for the NPC.

I think the replication logic might be different for NPC humanoid movement (i.e. with MoveTo), because that obviously replicates smoothly to the client, and assumedly ROBLOX animations wold as well.

3 Likes

tho i agree with what you said, i have some research done and according to this thread:
https://devforum.roblox.com/t/npc-movement-cframe-or-physics/19256/7
many people are saying that using cframes on npcs are much more efficient, and i’ve never noticed any problems with them myself, the whole character is server sided and clients have no effect on them. still very curious about other responses, its like a new thing i’ve never seen, shouldnt this be handled just like any other character controlled by the server?

There is a difference between your custom NPC’s and a ROBLOX character that is being replicated by the server. With your custom NPC’s, the server is simply treating the model as a collection of Bricks. When you change the CFrame of one of these Bricks, it just directly updates the CFrame. This happens at roughly 20Hz (best case). Nothing more, nothing less. On the other hand, character replication is different. This is because when the server replicates a character (that is walking around for example), it sends the character position as well as velocity. This velocity data is used to interpolate the character locally so that it looks smooth (as well as do some lag compensation).

So while the data received is at 20Hz, your client is able to display the movement at 60Hz, thanks to cool ROBLOX character scripts!

(also pretty sure that when a character animation happens on the server, it simply replicates the animation start frame instead of continuously updating CFrames… the client then runs the animation locally) (also bodymovers at a scale of 500 NPCs is probably has the same performance impact as CFrames… at that scale, using BodyMovers vs CFrames doesn’t matter, the biggest performance impact is going to be due to improper implementation)

3 Likes

Makes sense… im going to try and move the system more towards robloxs defaul character api

It’s really not ideal, which is painful. I’m dealing with the same stuff by trying to make my own complex NPCs. It looks like humanoid functionality improvements are on their way in the nearish future though, judging by RDC–it’s desperately needed.

1 Like