TL;DR: We have just enabled a new CFrame replication implementation that significantly improves the precision of rotations for “data” updates (CFrame property setup, initial map replication). Please let us know if you see any issues in games that might be a result of that update. The hope is that you should see the rotational error (gaps between parts etc.) heavily reduced, and no negative effects.
The rest covers the update in more detail, feel free to skip if you aren’t curious.
Roblox has had several different method for CFrame replication over the years. In general they are split into “data” format that is used for property updates, and “physics” format that is used for physics updates.
Physics format is compressed relatively aggressively (although it’s still very precise - we’re planning to look into optimizing this even more) to save bandwidth on physics updates. Because of this, it doesn’t represent position or rotation or velocity exactly - but the error is pretty small. We’ve used a very inefficient representation for this data up until several months ago where the format was completely revamped to be more efficient & precise. The errors we get now are roughly as follows:
- position: 5, 7 or 9 bytes; maintains max absolute error of 0.01 studs up to ~40k studs, error is 0.03 studs at ~100k and grows linearly from there (~0.3 studs at 1M studs from origin, etc.)
- rotation: 6 bytes, max error 0.056 degrees, avg error 0.004 degrees
- compact rotation: 4 bytes, max error 0.261 degrees, avg error 0.085 degrees (not used atm)
- velocity: 1 byte for zero vectors, 5 bytes otherwise; length error max 0.3% avg 0.01%, direction error max 0.2 degrees avg 0.01 degrees
So as you can see we lose a bit of precision, but it’s pretty good and much smaller than uncompressed versions. We have some more compact representations that we might start using for physics in the future.
Data format is compressed less aggressively - it has to be more precise. Because of this, it’s using a fully precise storage for position (3 floats, 12 bytes). Unfortunately, using a fully precise rotational representation is not a very good tradeoff - this is too much data (it’s 9 floats, 36 bytes, and it’s not reducible to a simpler form without precision loss because the rotational matrix, while mathematically orthogonal, isn’t actually orthogonal numerically due to floating point errors). So rotational representation is also compressed with some error.
Note that we have a special case for “axis aligned” rotations - if a rotation is precisely 0, 90 or 180 degrees around a cardinal axis, we represent it very compactly and precisely; other rotations have an error introduced that can cause large parts to be visibly offset due to rotation being off.
Following a recent report (https://devforum.roblox.com/t/fix-parts-being-offset-in-online-mode-by-replicating-rotations-with-full-precision/), we’ve decided to take a closer look at the data format and found several significant numerical issues with that code - it was using 9 bytes for each rotation, and achieving pretty bad error rates - max 0.3 degrees, avg 0.02 degrees.
After analyzing the behavior, we found a few tweaks to our physics rotational implementation that made it better and decided to use a slightly more precise variant of that, that takes 7 bytes, achieves similar but slightly better error rates (max 0.04 degrees, avg 0.003 degrees) and still represents rotations around the cardinal axes that are multiples of 90 degrees exactly - we’ve also tweaked this logic to expand it to cases where rotation is almost-axis-aligned (and the error introduced by forcing it to be axis aligned is small than it would be if we didn’t do that).
This is what we shipped just now - so now parts take a tiny bit less space on the wire and should have much more precise rotation behavior. The change should be active in the new servers. Last time we tried to improve this we’ve found a bug in the legacy hinge code that was triggered by the more precise data coming through the replication code, but since we’ve fixed that hopefully nothing else gets broken - but please let us know if something does seem off!
Hopefully as a result the builds with rail tracks, long walls and the like get much closer in-game to what they look like in Studio.