Welcome to an all new episode of "Astrophysics with Dan!" :D

It's been a while but here is where we are with the galaxy system!

Posted by on

It's been an entire month since I last wrote a proper update, and that's easily the longest we've ever gone without a dev diary, but in my defense, I've spent a great deal of that time learning more in-depth astrophysics while working on the core galaxy and planet systems.

It's difficult to show anything pretty when everything I've been doing involves spreadsheets and math, but I thought it would be a good opportunity regardless to go into some more detail about how our galaxy actually works. I'm planning to make a proper in-depth video about this once the current build is live, but for now, here's the wordy version.

I've covered the nature of the galaxy quite a few times before so I won't go into too much detail on that, other than to remind everyone that it's a true 1:1 scale recreation of the Milky Way, with 8 Quadrillion cubic lightyears of explorable space when you include the Galactic Halo region. Also, because I'm particularly proud of this fact, every single square cm of that space is accessible in real-time.

So how do we organise and navigate such an immense area of space? Well, the galaxy is neatly split into thousands of 100ly sectors, and each of those sectors is further subdivided into single lightyears. Within each of those cubic lightyears, we navigate at a cm-scale, which is now possible thanks to native 64bit doubles in UE5.

Each Sector procedurally generates thousands of "Locations" based on its proper Galactic Region and a supplied density map. Each Location occupies 1 cubic lightyear within its Sector, and this can be anything from a star system to a black hole, to a rogue planet, or anything in-between. Each cubic lightyear in the galaxy represents a place where a Location can be generated. New types of Locations can easily be added over time without messing with the generation of existing Locations, and really the only limit is our imagination.

To actually navigate the galaxy you need to know the XYZ Galactic Coordinates of a Location (eg, a star system), and also the XYZ Local Coordinates for a specific point of space within that cubic lightyear (eg, a planet). This can now be accomplished with the new Nav Panel on the Helm:

You are free to enter any coordinates you want here (literally any point in space in the entire galaxy), and the autopilot will happily take you there, but fortunately, you can simply let the sensors do the hard work for you and press the "USE SNSR TARGET" button.

So that's how the galaxy itself is structured, and hopefully, you'll agree that it's pretty logical and straightforward, but what about the actual star systems themselves?

Now we're getting to the meat of what I've been up to all month! Because we now have a 1:1 scale galaxy, one of the things I needed to do was re-write how star systems are handled in the game. This was a necessary evil to make it all work at the new scale, but I also took it as an opportunity to finally make star systems exist properly in real-time.

Essentially when you leave one cubic lightyear the current Location is unloaded, and when you pass into a new cubic lightyear that contains a known Location, it will be loaded. This of course means you can just arbitrarily point the ship in any direction and hit warp. If you pass within 1ly of any star the Location will be automatically loaded and you'll see the star and its planets physically in space. This is actually a critical point because it means the galaxy is truly real-time and everything is driven by the ship's genuine location in space.

Ok, buckle up because now it's time for the Astrophysics!

One of the problems with our existing Orrery Map was that it was 2D. Space is very much not 2D, and squishing the ship's 3D movements onto a 2D plane just looked goofy. Plus, star systems have all sorts of weird and wonderful inclinations relative to the galactic plane, so the 2D map just had to go. I couldn't just flick a switch to make the map 3D though, because making it 3D required implementing real orbital mechanics.

This is where my rabbit hole truly began, and where it also became clear that no two sources of astrophysics data ever agree with one another. You'd think we'd have some hard data for our solar system by now, but depending on where you look the numbers are all different to some degree. The data is also nearly always incomplete, so while it might give you the Semi-Major Axis for a planet, it will leave you to work out the Focal Point and Semi-Minor Axis yourself. I ended up using the NASA data as a base and then wrote functions to populate the rest of the information.

The net result is we now have a true 3D Orrery Map, which is built using real orbital calculations. It is also centered on the ship now instead of the central star, so it will smoothly track the ship's location and can be zoomed in and out without any limitations.

But then the rabbit hole got deeper. In order to generate scientifically accurate star systems, we need to begin with accurate stars. We already had the basic spectral classes covered, but each class of star is further divided depending on its temperature. For example, Sol's full class is G2V, which is at the hotter end of the G Class scale, with the V referring to the fact it's a main-sequence star.

Having added additional detail to the stars, including their mass, I was then able to begin the long process of rebuilding the Procedural Star-System Gen code so that it can generate all the extra data that was now needed by the game. I of course took this as another opportunity to improve upon what we already had, so I re-designed the procedural algorithms to build star systems properly.

Once we have our star, we take its Mass and add a little bit more to define the gas cloud that formed our system. We then deduct the star's Mass from that cloud to give us the overall Mass of our system's Proto-Planetary Disk. Next, we use a few formulae to calculate the Equilibrium Temperature at various distances from the star and at various Bond Albedos. This defines the star's various temperature regions, such as the Habitable Zone and the Frost Line.

Now we pick a random location near the star for our first planet. A weighted random function will determine what the planet's Base Type is, depending on how far from the star it is. For example, Gas Giants are less common inside of the Frost Line due to lighter elements being blown further from the star.

After having looked at a lot of real exoplanet data, we can now give our planet a random amount of Mass relevant to its Base Type. (Working this out was another frustrating task because again a lot of scientific papers on the subject put forward different conclusions. I've gone with the overall consensus.)

Next, we need to define the planet's Density, and we do that by first deciding what percentage of the planet's Mass is Core, Mantle, and Crust. Heavier elements like iron tend to be more common nearer to the star, so the Core percentage is partially driven by distance. Once we've done that, we then calculate the Density of the Core, Mantle, and Crust regions based on the Mass of the planet, which takes into account compression due to gravity. And finally, by adding all three values together we get our overall Density figure for the planet.

Armed with our Mass and Density values, we can now easily calculate the planet's Radius.

Now we have everything we need to work out how thick the atmosphere is, based on the fact large high-mass planets hold onto a lot more atmosphere than small low-mass worlds like Mars or Mercury. We also decide how much surface water there is at this point too.

We can now work out the planet's Bond Albedo, and thus its Equilibrium Temperature at its distance from the star. Add to that the effects of any atmospheric heating and we have our final average surface temperature. At this point, we also decide what flavour a Gas Giant is too (Hot Jupiter, Ice Giant, etc).

Depending on the type of planet we'll then perform all the procedural work to determine if the planet has life, but that's not implemented yet.

And with that planet now finished we use the Blagg Formulation of the Titius-Bode Law to decide where the next planet will be and repeat the process.

I'm still working on the final niggly bits of the planet-gen code, but here's an example of the new level of detail the sensors are outputting:

Phew, that was certainly a giant wall of text, but I hope it sheds some light on just how detailed our galaxy is getting. The goal here is nothing short of being the most accurate galactic simulation in the genre, so there is still lots more detail to be added! :D