So, I’m working on a 3d space combat game, and recently I found some problems with floating point precision, as the difference in scale between a spaceship and the orbit of Neptune is… large. And because this will be a multiplayer game, I don’t really want to use a floating point origin, as that could mess things up server-side.
So, I’m considering letting each ship/planet/moon have it’s own scene, letting me play with scale a bit more, and having most, if not all, of the scenes loaded at a time, so I can pass data between them, and not ruin immersion with loading screens every time you zoom into an object. It would also let me have much finer control over what is being rendered at a time.
Most of these scenes would be very small (just, say, a large ship, a single planet/moon, the sun, and some UI stuff), and I could play with perspective to make things much closer to each-other than they should be, while keeping all of the actual physics stuff in it’s own scene, with a, say, 10 billion to 1 scale, as I don’t need to worry about the player zooming too far in.
Is this a good idea, a terrible idea? What’s the cost of having so many scenes actively running at a time? How hard will it be to pass data between them? Is there any extra overhead to the scene itself other than what is inside it? Lots of questions xD.
Thanks in advance for your help!
Since you are a new member on these forums, you might not yet be familiar with a strikingly similar project being discussed here. Coincidentally, another developer is working on a large-scale, 3D multiplayer space game and much like yourself, has opted against using a floating-point origin. They claim to have bypassed the limitation by rewriting their own physics engine within Unity to utilize double-precision, reportedly maintaining performance through an ECS based rendering pipeline.
I haven’t seen a formal proof of concept for these claims yet, but your mileage may vary. You might find it useful to reach out via DM to compare notes. After all, when two different people tackle the exact same niche problem, solutions tend to surface much faster than when working in isolation.
You can find the discussion here: Looking for Information on Customisations pertaining to 64 bit floats - #68 by Father_Sweepus
2 Likes
Thanks for pointing me over there!
Yes, I’m new to the forum (and Unity in general), trying to make sure I don’t spend months working on something that will not be able to actually work before I get too deep into it.
My project will (ideally) be a lot more performant then what Sweepus is working on, so I would rather not use double-precision unless absolutely necessary. If I can get away with some camera fakery, I would much rather do that then try and rewrite Unity (probably best not to try and rewrite the entire engine as my first project xD). Great read regardless.
So far I’m thinking about having the authoritative server only know your position relative to whatever body you are orbiting, with appropriately scaled units, and then generate a new scene for each body, using what it knows about those bodies relative to the central star, so I can get away with single precision. To avoid loading screens though, I would need to have a scene loaded for every planet and moon simultaneously, so I’m just trying to figure out if that would be a feasible direction to go in. (These scenes probably wouldn’t be very large, just 3-4 objects and a bunch of 2d icons for anything considered too small or far away for the scene to bother with, and I’m not planning to go crazy and make fully detailed planets either)
I’m also not actually using Unity’s physics, I have a script that finds the orbital path of the smaller mass, and just moves it around that path using transforms, so I shouldn’t have to worry too much about physics issues from one scene to another.
Thanks for the help!
Pretty much the same as having all the content in a single scene.
Not any different than having everything in a single scene. Consider that all the scenes must be loaded in a networked game if you are using Netcode for GameObjects. Other networking frameworks may allow clients having loaded separate scenes (NGO doesn’t out of the box). But on the server (host!) side all those scenes would have to be loaded all together - meaning your multi-scene idea doesn’t actually solve the problem.
Then your game needs to be entirely within the acceptable scale ie 4k or 8k units distance from origin at most.
Solving this requires elaborate engineering efforts far beyond loading multiple scenes. Most games would either have all players forced to the same planet or solar system, or they would employ separate server instances for each planet or solar system as implemented by MMOs like EVE Online.
For a “regular” multiplayer game ie when we’re talking 4 to 16 players and this being a combat/action game the scale of your world is beyond reason! Keep them together in close areas so they can have fun shooting each other rather than getting bored trying to locate one another, and then closing in on each other for minutes (if not hours, days, …).
Physics will break if you scale it down to one ten billionth. The floating point accuracy issue exists in both dimensions so whether it goes from 1 to 10 billion or 1 to 1/10 billionth simply does not matter.
One option would be to use coherence, since it supports world origin shifting.
One user made a discord post about a multiplayer large map proof of concept with some additional details.