Home General

How you managing the scale problem

I'm new to Godot, and not too experienced with programming in general, so I'm struggling a bit navigating the ivoyager project. I know from my past dabblings that all game engines can't deal with a solar system to scale, especially if human size objects are involved. How does iVoyager handle the extreme scales, and where in the code should I poke around for this?


  • Yeah, that was a problem to solve. There are 3 parts to this...

    1. Global.scale (find in singletons/global.gd) defines "engine units" per km. I think it's set to 1e-9 or something like that in last version. Some engine errors start to happen at 1.0 or maybe a bit above that.
    2. Dynamically adjusting near and far properties of the camera (tree_nodes/voyager_camera.gd) as the camera moves in and out from its parent object. You can't just set them to super small and super large (respectively) and leave it at that. But I found that it works if I adjust them together as the camera zooms closer or farther from its parent. I have some small moon models in the next version (coming soon I hope) and you can zoom to kilometers just fine. I believe smaller/closer models (even human scale) will work, but I have not tested this yet.
    3. The camera is always near the origin (i.e., has small global translation). As you move to Pluto, it's really the sun (and all its other children) that are moving away. This is done by a single line of code in voyager_camera.gd, just search for "CENTER_ORIGIN_SHIFTING". It looks a little obscure but I'm literally just moving the sun to the opposite translation of the camera's parent body (the camera re-parents itself when it moves from one body to another). If you set CENTER_ORIGIN_SHIFTING = false, then you will see Pluto shake wildly from imprecision errors.
    One thing that is weird is that Godot 3.x versions have *partially* implemented double precision float. GDScript vars and a lot of math works as double precision. However, most engine stuff is single precision. The Godot devs say we will have full double precision implementation in Godot 4.0.

    It just so happens I'm overhauling the scale system (and units in general) so it will look a little different in next version. Global.scale is gone. Instead, there is a static class UnitDefs that defines SI units like SECOND, METER, KG, etc. So now we have UnitsDef.METER = 1e-12 (or something like that) and that defines our simulator scale.
  • Thank you! When I was fiddling with Panda3D I did a lot of similar tricks. I kept the camera at the origin (or behind a ship at the origin) and translated object locations.
    For point 2 I struggled with the camera distance properties. Rendering a ship in LEO, the Earth, and the sun were really problematic. I ended up implementing the trick the original Elite did. I would scale down celestial objects and their distance from the camera so they had the same angular size on the screen.
    I kept planets on rails with the keplerian parameters (I found that csv!) and had to calculate the n-body physics on the ship separately. I hope Godot 4 will have physics compiled for doubles as well. My napkin math says that would give cm precision out to half a light year form the origin.
  • In early versions, I also "shrank" the universe as the camera moved out. But I found this wasn't necessary if I adjusted camera near and far together. They seem to have to be within a certain orders-of-magnitude of each other.

    Hope you're having fun with I, Voyager! I'd love to have some other developers involved.
  • I'm looking at making a FOSS and in-browser Simple Rockets/Kerbal Space Program like game for my physics students as we are going to be missing out on our rocketry unit this year. I'm going to clamp craft and celestial movement to 2d for their sake. I've been playing flight sims since wing commander 2, these kids can barely drive!

    I've been hemming and hawing between 3d rendering or 2d. I discovered the 2D engine chokes up when "zoomed out" to about 6000 units, so any power of 10 like zoom will needs 2d camera magic as well.

    Going with a 3D render would give a much better view in flight, even if controls are locked to 2D. I think I answered my own question writing this out.

    Next question: Any thoughts of adding some atmospheric effects/scattering?
  • edited April 2020
    Edit: I just opened a new discussion on your question: https://ivoyager.dev/forum/index.php?p=/discussion/38/i-need-your-help-with-graphics.
  • The goal is to recreate the effects of atmospheres during daytime and at the terminators. Earth is blue sky during the day, red at the terminator. Mars is reddish pink during the day, and blue skys during sunset/rise. Its a combenation of light scattering based on the composition of the atmosphere as well as rayleigh and mia scattering from particulates. This also colorizes and fuzzies surface textures when viewed from lower orbits.

    The two major families of atmospheric rendering is Sean O'Neil's work, which is older and simpler, and Bruneton's more complex method that involves calculated lookup tables. I also found this very large tutorial on the implementation and math.

    The best premade resource I found is this one. There is a shadertoy to play with the parameters. The only gotcha is that I do not know where to look up the reyleigh and mia parameters for different planets. How far into the spectrum light gets scattered is based on the polarization of the gases (or so my quick research shows). The ideal solution is that the parameters can be generated based on atmospheric composition, which makes it easier for procedural planets.

  • edited April 2020
    Thanks @croxis! I quoted your post in the other thread so I will have all of my sources in one place.
  • edited April 2020
    Should probably wait for my coffee to pick in. I've updated the source so scale is in unit_defs

    const METER := 1e-9
    Does that mean there are 1e9 meters per engine unit, or 1e9 engine units per meter?

    EDIT: tangential question: Is there a particular pathway (planned or existant) for importing assets like spacecraft into the engine?

  • const METER := 1e-9 means that our internal meter is 1e-9 engine units. (So 1e9 meters per engine unit.)

    Models that are (or will be) part of the core I, Voyager packages go in ivoyager_assets/models/. The current development ivoyager_assets has Phobos, Deimos, Hyperion and a couple asteroids in there. I'd like to add at least a few real spacecraft there as well: Voyager 1 & 2, etc. (Note: there is an issue posted about a graphics glitch, possibly related to some of my new models.)

    Models for your own project should go somewhere else. (The idea is to stay out of ivoyager & ivoyager_assets unless you intend to contribute changes to I, Voyager.) 
Sign In or Register to comment.