Hey, thank you for taking the time to look into this.
Are you sure you were on the correct team? The Test Subject team has no morph (meaning it only has the default Roblox avatar parts). Whenever someone activates their night vision goggles, they move down and you can feel this lag in any team.
Furthermore, we have checked the Red Wolves team morph and it is 76,253 vertices and 49,489 tris. If we take that the average morph has 80k vertices and the average gun has 20k (the most used weapons are all already optimized to this standard, some even below 10k), that is 100k vertices. How did you obtain 86 parts and 158776 vertices? Perhaps this could be some area we missed and need to optimize in.
Unfortunately most meshes that are split are this way because it is needed from a gameplay perspective, such as for effects of radio equipping / unequipping, mag dropping, attachments being attached, etc. This is the case with most morphs and weapons, at least those used the most. We are aware some are still in serious need of reworking and optimizing, but those are mostly unused due to being outdated.
We will be using PBR on new assets, thank you for the tip.
The lag observed with night vision goggles mostly comes from the fact that the avatar update spans multiple frames rather than a single one, due to the Motor6D not having achieved its goal. Is there no way to have it so Roblox only invalidates the character once it has reached its target, or have it be throttled such as is normally the case where updateInvalidatedFastClusters usually only happens every so frames?
This is a really tricky problem for us because our game is already a result of massive optimization work over its development time, and issues like this are mostly out of our control, with solutions that are not really applicable for us (without completely degrading the entire game).
The main issue I’m trying to point out here is not even updateGeometry anymore, it is the fact this is being called every frame when Motor6D is actively changing the part - it truly kills the frames.