(Big worlds) Will ever a Built-In solution for Float Precision Loss be?

At least in some 2030, will we get an out-of-the-box solution for huge worlds?
Is something about this is planned?
Upd:
(Like combination of all 4 well-known solutions of this, like Unreal did)
(upd 2. changed to General, World-Building is probably more about existing things anyways)

With AI assist
(I would’ve said it did entire job, but it was acceptable only with voxel terrain, chunks, terrain tool, material assign.
Then after 2 days of beating it wrongly, I started doing direct architecture tips)

managed to make work voxel terrain + floating origin properly + not ruining FPS to hell with empty objects (it was idiotic but lower LoC).

The general plan is: (of my idea of rather Infinite Procedural World)

  • FastNoiseLite Unity adapter: com.shniqq.fast-noise-lite (it’ll be Jordan Peck)
  • (Easily AI gen’d parts with dumb requests, vaguely describing the end result, etc)
  • Awaitables to make it compatible with Web + performant (AI handles but DS new chats lean to coroutines)
  • AI gen’d custom char contr moving with lerps to exclude FloatingOrigin messing with it wrongly
  • Store chunks in pure data
  • Accumulate FloatingOrigin shifts (offset) in them
  • Render, etc them to real GameObjects on demand (when close) in a pool (much < than Dictionary <Vector3Int, ChunkData> chunkDataMap)

Extra:

Then I (mostly AI) will need to restore (or do better) biomes, caves (because it got erased by copy-paste mania and was from AI and commited anyways) and my “genius” idea of smooth biome geometry transitions by just adding linear gradient on each side of a huge cell of a biome grid.

FloatingOrigin took as basis:

Old archived:

(P.S
Actually when using proper (at least robust in my current vision) ideas it is easier than though, just AI by itself is indeed very bad at working solutions in narrow topics. I would have programmed current 2000 LoC myself for 40 days at best, given that own inventory system with saves of 1000 LoC took 20 days.
Also “my” version kinda is 3/4 things of Huge worlds, except Double, though considering stuff around is close and other is pure data I.g, carefully, offset can be accumulated in Double (or even Decimal).

upd 3.
Okay, I remembered how annoying (but fast) it was to finish small game with 6000 LoC with current AI, it is only good as a starting point for any idea, but not polishing the product into a complete state,

quickly making own code ignoring quality as hard as possible sacrificing to speed of iteration is still better quality than AI does, it can’t keep up when connections get too complicated
(probably because under hood it is stupid predictor actually, even if context memory were infinite),

after 2000 LoC errors are way too often as its will to cut content, despite fixing bugs.

40 days it would have been if I was trying to Middle it.
(Sprints with AI is easier, can relax while it generates, but result feels more soulless, though for player “soulles” is more noticeable in using bunch of assets for the visuals, at the same time if own is worse general response is worse (okay this one is complete off-topic))

In case someone curious I’m AI fooling around 10 days (+3 if adding not related things, not all in a row).
I guess after restoring lost functional I should start doing refactors, fine-tuning myself, but given no one will play the game after a week, two, it doesn’t matter, ultimate goal is get things done.)

upd 4.
I forgot that I could’ve pasted every message the entire system to make output less error prone and feature lost.

Technically, the closer you get to zero the higher absolute precision you have with floats. About half the floats that exist are in the range of (-1,1) and the exact benefit depends on your specific use case, so you’ll need to test it. But the issues with floating point precision start to become apparent at really big numbers, 10,000 units is not a very big number, at about 8,000 units the precision gap is about 0.001 units (1 millimeter) which shouldn’t even be noticeable. The jitter in movement will start becoming noticeable on numbers greater than 60,000 units so if you notice issues in your game start looking for other things that can cause any visible jitter because floating points are not the reason.

When you say “work”, it depends on what you mean. The above examples work fine for the movement as 1 mm isn’t noticeable, but if you have physics calculations that want millimeter precision at 8-10 Km of the origin then they are not.

In summary:

  • This cannot be “fixed” in the absolute sense, higher precision will only increase the distance of where the issues will start appearing.
  • What is considered “fixed” is highly contextual. For movement and rendering, issues are not noticeable with fp32 up to 8000 units, as they still offer millimeter precision, if there are issues with movement appearing jittery in your game at that distance look for the cause somewhere else.
  • For physics it depends on what you are doing. Checking collisions for characters at 10Km needs lower precision than checking collisions for the balls in a 10Km pool table.
  • Absolute precision gets higher the closer you get to zero, but as I mentioned above at 10Km you mention, any noticeable problems in movement are not because of fp32 precision errors and you should look for solutions in other parts of your code that cause the problem

nope you are wrong in some places, at least if you constantly Update() transform.position to the raycast hit, the issue become apparent at 1000 already (it can’t find where exactly to place and it jitters slightly, but noticeable, though standing still it will stabilize, but any movement/mouse will result in jitters of Preview object), and at 10000 any world position even Unity itself will start giving errors about Frustum, ScreenSpace, Camera etc.

P.S.
And at 9000 of course the issue with updating transforms will get mad.

The renderer gets distorted at much higher values, but who cares if we already have bunch of issues and Unity errors at 10000 already?

I doubt that I’m wrong since this is simple math. At 1000 units the precision error is less that 0.06 millimeters. This cannot even be shown in a normal monitor.

The highest power of 2 less than 1000 is 9. The precision error is 2^(9-23) = 2^(-14) = 0.00006103515.
At 9000 units, the calculation is 2^(13-23) = 0.0009765625 or 0.9 millimeters. Less than a millimeter is not a noticeable distance in any monitor.

But I’d love you to show me where the error is in my math.

if you really wish i can show a video where the preview jiggles about 1cm or even more, pretty noticeable, and that happens on 1000 any x y z.

Character controller works though, but still 10000 is Unity errors, not from custom scripts

I don’t doubt that it jiggles, but it’s not caused by floating-point precision errors. Something else is responsible. If FP32 produced noticeable rendering precision issues at such small distances like 1000 units, most games would be unplayable.

Check your Unity settings and your code for the source of the jitter, FP32 precision is not the issue.

it is a part of the issue, i cant just ditch the raycasts at 1000 meters already

Unless you believe the math is wrong, review your settings and your code.

First, rendering is different than physics and no jitter exists because of fp32 precision at 1000 units.
Second, a Raycast is physics, but still 1000 units has a precision of 0.06mm which is far below the 1cm default contact offset of Unity physics. There might be edge cases where this 0.06mm makes a difference but generally no, it doesn’t.

I know it is tempting to always find an external reason for why our code won’t work as we believed it would, but math doesn’t lie. Check your settings and your code, fp32 precision IS NOT the reason of your problems.

Math is math, and when things work in engine it is different behavior in the end or there wouldn’t be bunch of FloatingOrigin.cs (which is threshold origin shifting actually) scripts that does shift origin on 1000 and even 200 sometimes.

That doesn’t even make sense.

I suggest reading about the basics before starting projects that require more advanced concepts otherwise, you will keep drawing incorrect conclusions about your results. This will prevent you from actually making a game, as it will lead you to reasoning like this, which is very common for beginners: thinking that the issues in your game are caused not by your code, but by external sources such as a library or the game engine.

This is a common problem for beginners and will only stop you from finishing your projects, as it encourages constantly making excuses instead of taking responsibility.

Debug your code. Find your mistakes. Fix them. Stop blaming external sources and start taking responsibility for your work.

"

Ray ray = playerCamera.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2));
if (Physics.Raycast(ray, out RaycastHit hit, reachDistance, terrainLayer))
{
    brushPreview.SetActive(true);
    brushPreview.transform.position = hit.point;
}

"

Is in:
FixedUpdate() (should satisfy raycast more on long distances? nope) or just Update(), results are the same.

It is literally the whole code for the positioning, and the jitters is the same, both on terrain or freshly created plane.
It is like the couple lines from bult-in Unity itself, it can’t be solved just looking into code base and ESPECIALLY by just seeing some BASICS.

Didn’t record as i fairly shown how it looks on a plane, and of course its not 3 at the same time visually but just one jittering fast between positions.

If you think it is still not actually what is happening at least as the end result which is caused by engine, you can easily replicate it yourself.

1000 gives same jitters, just less

P.S.
Was wrong about Frustum Error distance, it is 99999 not 10000:
“and on 99999 we get unity errors:
Screen position out of view frustum (screen pos 410.000000, 231.000000) (Camera rect 0 0 821 462)”

Only reason to blame my code is for not implementing at all any FloatOrigin.cs or other methods for solving big worlds.

But this topic is about will be something like Unreal and Godot did or anything,
to not encumber devs when they want something big and robust not a prebaked cells of scenes approach-likes to solve jitters with any logic at least on 10000 (even if it’s faking that distance technically) or manually making solutions that are badly compatible sometimes.

Updating your brush in FixedUpdate will result in jitter because it only updates at 50hz by default. Or if you update the brush from within Update then make sure the code runs after the camera has been updated or the brush will jiggle around. LateUpdate may be a better place for your brush code.

And that you’re also moving an object by setting its transform.position inside FixedUpdate, and enabling it before moving it.

This is exactly what I meant about blaming external sources. For small distances like the 1000 units you mentioned, fp32 precision is irrelevant. This code however, is not.

Setting transform.position in FixedUpdate teleports the object during the physics cycle, not the rendering cycle. With the default physics timestep of 0.02 seconds, this happens 50 times per second. Rendering framerate depends on hardware and workload, and even when capped it almost never matches 50 fps. This mismatch causes jitter and stutter because physics and rendering fall out of sync. Enabling Rigidbody interpolation might smooth it slightly, but any position changes using the transform should be done in Update. Raycasts, of course, should remain in FixedUpdate.

Enabling the object before moving it will also affect your game, depending on how often you do it. When you enable before moving, the object effectively exists in two positions within the same frame. It begins at its original position, so anything triggered in OnEnable applies there, and then it is moved afterward. The engine must then process what happens at the final position as well. If many events or calculations occur, this can slow down your game and cause collision glitches due to the instantaneous teleportation and the calculation of the physics collisions.

This is the only code you’ve shown so far, so there may be more issues elsewhere.

Now, when it comes to fp32 distance precision, there are huge differences between 1.000, 10.000, and 100.000 units that you mention in your posts.

At around 1.000 units, fp32 precision errors don’t cause noticeable jitter.

At around 10.000 units, everything should still behave fine unless you need high precision physics. Rendering is generally unaffected.

At around 100.000 units, problems start to become significant. That’s why Unity warns you.

In short:
8,192 – 16,384 units (2^13-2^14): Maybe issues with high precision physics.
16,384 – 32,768 units (2^14 - 2^15) : Maybe some minimal jitter.
32,768 – 65,536 units: (2^15-2^16): Noticeable problems in both
65,536 – 131,072 units (2^16-2^17): Here the real problems that can make the player experience bad begin.

To calculate the precision error, find the largest power of two that is smaller than your distance, take its log₂ value, and subtract the number of mantissa bits (23 for fp32). For example, if your distance is 1,000 units, the largest power of two less than 1,000 is 512, which is 2^9. Subtracting 23 gives 9 − 23 = −14, so the precision error is 2^(-14) = 0.00006103515 units. If one unit represents one meter, this corresponds to 0.006103515 millimeters.

Noticeable issues begin when the precision error reaches the millimeter range and worsen from there, the severity in each distance range depends on whether we are talking about physics or rendering.

As you can see the biggest encumbrances devs have are usually because of their code. Yes, having a higher precision will help with large worlds, but in this case it wouldn’t because you are moving your transform during the FixedUpdate.

This piece of code was one of the reasons. Good job showing it. Now inspect the rest of your codebase for anything else affecting rendering or movement and fix those as well.

Still putting everything (both character controller and the brush) in LateUpdate, which must have the less jitter possible, results in jitter for brush preview at 9000 anyways at cliffs, it is not possible to fix the issue by default means and just debugging existing code, knowing theory and stuff - I just trying to tell that this one is not the case, refactoring it (if it isnt meaning adding completely new logic like FloatingOrigin).

I can only admit that it is now smoothed jitter, especially on default plane (with rot X 90), but the same thing in random positions happens and probably if i would raycast some bullet rays with decals - they would not hit the same place.

Maybe this solves the problem of brush previews at 1000, but it probably still not fixing raycast precision even at that value (but okay, even with ~1 cm which would be in real world, given player doesnt see it - fine)

Why it is about floats, precisions also
(hell what kind of code needs to be imagined that breaks only with distance, both player and brush logic for transforms is a few lines),
people can just look up in similar topics or test themselves,

nothing except:
Floating origin
(for some reason it usually means orign-rebasing after threshold), Real Floating Origin (moving entire world around 0 0 0? Ultra-ugly, but most performant, expected behavior?),
Chunk-Based, Local Space, or ideally just having similar built-in combined solution of float + double + origin shift - like Unreal, Godot will fix this issue, not crutch-patch it.
(though in huge space-setting world still some extra solution(s) can be needed, but I’m satisfied with the scale of the solar system, lol)

It is definitely not about existing codebase it is about lack of needed implementations.

Anyways I guess I will just pregenerate entire map
(if quickly aligning FastNoiseLite made final “map” after shifts will be painful),
then kinda LOD, occlude/entirely disable far distance parts and will try to properly put/modify/integrate FloatingOrigin.cs from unity wiki (exact old ~2022 link isnt working), that was modified on GitHub by users:
Floating origin to handle large worlds in Unity. · GitHub

P.S.
(and if after 2 days of messing, breaking existing to the point of revert to commit, will just go midget /10 mode on player collision/cam pos, world length: 790 units + “walls”.
Fake 7900 leaves space for exploration (its the only way to keep the Unity default stuff intact, expectable?
(look at bunch of edge-cases in GitHub link)))

I know about Updates, this case is mostly problem of need to be at 9000 without any problems.

LateUpdate isn’t solving, it is smoothing things, can read reply above this one, if interested in result.

You keep insisting that at 1,000 units the problem is caused by floating point precision rather than your code.

Here are the facts:

  • It’s mathematically proven that fp32 precision errors do not cause issues at 1,000 units.
  • You fixed the snippet you showed, but it was three lines of code and two of them were responsible for the jitter. Focusing only on that snippet makes no sense. If most of a tiny sample is flawed, you should assume similar issues may exist elsewhere in your code.

Edge cases do exist, such as rays that are nearly parallel to a surface or rare situations where a ray can slip between triangles of a mesh collider far from the origin. But even those are programming errors, they should use a spherecast instead of a ray.

For some reason, you still believe your code isn’t responsible for the jitter, even after you demonstrated a snippet where two out of three lines caused it. After fixing them, you continue to assume everything else is fine.

Finding problems in two out of three lines should make you reevaluate the rest of your code. Instead, you patch those lines and repeat the same mistake: assuming the rest is correct and blaming something that is mathematically impossible.

I’ll repeat this one last time, because it’s a common hallmark of new programmers:

Thinking that the issues in your game are caused not by your code, but by external sources such as a library or the game engine.
This is a common problem for beginners and will only stop you from finishing your projects, as it encourages constantly making excuses instead of taking responsibility.
Debug your code. Find your mistakes. Fix them. Stop blaming external sources and start taking responsibility for your work.

Of course, you can also keep doing what you’ve been doing: blaming external sources for your problems and giving yourself an excuse for why you never finished your game: Your code was fine, it wasn’t your fault, and the blame always belonged to someone else.

I don’t think there’s anything more for me to say, and there’s no point repeating the same arguments. This is just another discussion where people blame Unity for not supporting double precision and claim that’s the reason they can’t finish their game.

This is the thing you’re arguing about, btw:

I quote from above:

This gives from 6 to 9 significant decimal digits precision.

So… at 100km your precision is about 1m

Not really, that would only give us 5 digit accuracy. From that page:

  • Decimals between 2n and 2n+1: fixed interval 2n−23
    and
  • Integers between 2n and 2n+1 round to a multiple of 2n−23

The precision at 100Km is 7.8 millimeters.

In general we find the highest number that is a power of 2 and less than the number we care about. In the case of 100.000 it is 65536 or 2^16. After that we subtract the 23 (number of mantissa bits for 32bit fps) from the log2 of that number: 16-23 = -7. Finally the precision is 2 in the power of that number, in this case: 2^(-7) = 0.0078125 or 7.8 millimeters. That’s a precision of 8 digits (100,000.00XXX…)

The 1m precision happens after 8,388,608 (around 8.000Km) which is 2^23. That’s 6 digits precision.

In general at single digits millimeter precision issues start to appear first in physics and progressively to rendering. From 1 centimeter precision the game jitters so much that becomes unplayable.

Over 65Km we have almost 0.8 centimeters precision, which is the Unity warning (100Km) even if physics may start jittering for small objects much sooner around 10Km.

But 1Km is very low limit for things starting to break. 1,000 meters, has a precision of at least 0.061 millimeters, only in very edge cases like the ones I describe above issues may appear and even then a spherecast should do the job.

i don’t need to prove anything, you saw everything - you can replicate, also you didn’t suggest even proper things, it is just assigning transform to hit point, both things that move player, camera and simple gameobject with half transparent mesh is in LateUpdate, you can’t smooth it out more than this.

It seems it is possible to move brush by terrain coordinates only, but that is not a classic approach at all and will result in snapping the brushPreview object, instead of intended smooth movement. (and probably if they gonna be tight - still we will get similar jitter)

About why it jitters noticeably already on 1000 when you want to precisely smoothly change position:

Maybe the “Simple math” as you said works, but:

What you expected in that (Simple math) reply at least, is a small sequence of calculations, when engine then external code do multiple calculations to finally give result of moving.

Even the code i presented much above does division for screen, then cast a ray, that gets hitpoint, then we assign that hitpoint position to the transform, and as result we get A BUNCH of actions already, that everytime calculates only approximately, so that is why it is noticeable at 1000 and at 9000 in Unity it is total crap.

Your simple math answers with one word itself why it isn’t what actually happening in my raycasting case, i dont deny that character controller work without noticeable problems almost on any distance, but raycasting + transform.position assign gets jittery MUCH EARLIER.

Shortly:
It is not Simple math given Unity engine context, it is at least bunch of simple maths happening.

Or do i need now to say about basics here and reading before starting projects, you do know how float works, right? It literally supposed at high values after adding small value to the second be == to the first, it literally craps a little everytime you work with it, it is also probably a problem with UGUI hating being at 0 0 0 constantly.

k, read entire this reply:

First i dont blame Unity purely, i am talking about a single issue especially at 9000 AND IT IS PARTLY DUE TO ENGINE LIMITS. I dont deny your philosophy, I deny you being oblivious to practical situations:

Also i did make work FloatingOrigin (requires thinking kinematically etc), so the brush problem isn’t with me at least now.

How you can really prove your point that it is possible to make responsive movement not jittery of gameobject by mouse even at 9000 is very easy (or that it is still “small” distortion), given length and amount of your replies:

  1. OBS, .mkv
  2. Scale the Desktop area to fit only the thing with object and world positions in inspector (in case you anonymous about your win/mac panel)
  3. Any “player” movement script, any implementation
  4. Any “object” movement by where camera looks script, any implementation
  5. Ideal end goal: Even at 9000 - You move mouse±player and object moves smoothly, doesnt jitter, doesnt use crutch snapping that isnt smooth, the object is always at center of screen, not noticeably fast/slow moving towards it

if you still think that magically in a separate single responsible code there something that breaks stuff exactly only by distance and Float doesnt have to do anything with it - I can’t do anything, this is TLDR and off-topic anyways and kinda obsessive (just as me continuing it) with “1000” still works fine for everything, when most people prefer to shift origin at that value already in infinite worlds.

Practice != Theory

And i guess you too just TLDRed or mind-skipped everything read i tried to say, and completely gone to point “boo-hoo those noobs just run away because it is hard”.

I regularly return to Unity and don’t use other engines, but it is time for it already to proof something for big worlds, given their Unity 6 philosophy is next-gen that isn’t requiring crutching your way out of floats or any other problems even if they’re caused not by floats but after distance anyways