Starship Simulator cover
Starship Simulator screenshot
PC Mac Steam
Genre: Role-playing (RPG), Simulator, Adventure, Indie

Starship Simulator

T-63 Days

Today's challenge has been in remapping the height ranges on the heightmap so that both the lava and the land go from 0-1 while maintaining their relative heights. Or to put it another way, making sure the upper boundary of the lava colour gradient matches the lower boundary of the landmass colour gradient. I'm still not completely happy with it yet, but we're just about there.

Here's an example of a lava world with a tenuous atmosphere and sulfuric clouds:



The landscape shader takes the relative height of the lava into account when defining its regions, and I'll be driving that value using the planet's kelvin temperature on the procedural generation. Here's what it looks like when you turn up the temperature on the same planet :)







I'm going to add a bit of heat haze to the lava next, and then I'm onto the final polish for all the various flavours of exoplanet generation. Oh, and I've also had a good idea for how we can create a single circular sea of lava for tidally locked worlds, so I'll take a quick look at that too :)

T-64 Days

We're now onto the icy bodies, which share a lot of the shader code from the barren worlds. Looking at the icy moons and dwarf planets around our solar system you'll find a fairly significant amount of Tholins giving those bodies their reddish brown hues. I've taken that into account with the colour palettes, so a lot of the icy planets will resemble variations on this:



I'm also using the generated heightmap data to drive the surface roughness values, so if we take away the Tholins and go with relatively pure ice you get some really breath taking sun reflections:



Next up is the lava worlds, which should be the last shader to polish up for a new alpha build :)

https://discord.gg/eDSQvpgdUX

T-66 Days

I've been flitting back and forth between different planet types today and also trying out various different approaches to generating the layers of detail we need. Each planet needs to be built (literally) from the ground up, applying layers of ever-increasing detail as we go. This is ultimately a much more flexible approach to planet generation, and it allows us to add/remove layers as needed.

Also, because we're already generating masks for each layer that means we can add "special overlays" for added flavour. For example, we could take the cloud mask and overlay an additional emissive texture for bioluminescent organisms living in the clouds. Or, do the same for the oceans and have a subtle blue glow around coastlines. I'm quite excited to see how far we can go with that to create some really unique worlds.

Here's an example of the new cloud function and an arid desert world :)



T-67 Days

I've been working on refining the terrestrial planet shader some more, with an emphasis on generating a series of masks for things like the oceans, clouds, etc. This will allow for adding other layers of detail more easily. I also added some turbulence to the surface noise to make it a bit more organic.

The continent detail is definitely less flat now, but I'm still not quite done with it. I'd like to add an additional overlay for reducing colour opacity closer to the poles, and I need to refine the colour palettes some more for better random generation.

Here's a concept shot of an Earthlike moon orbiting a Class I gas giant ːsteamhappyː

T-68 Days

Continuing with the planets refresh, I've been refining the system that generates Earthlike worlds. It was quite fiddly to get all of the various layers combined into a unified global normal map, but ultimately well worth the effort. I'm particularly pleased with how the ocean turned out because breaking up the flat specular response with waves really helps to ground the surface more.



The shader is also able to add lights from surface settlements in the low-lying areas, which I'll also use to add alien cities and things in a future update. That will all be tied into the system that defines whether or not life exists on the planet, and if so how advanced.



I still need to do some work on the actual continent details, because right now they're a bit too plain. I'll rough them up a bit with some noise variations, and again this will soon be tied into the actual galaxy system where it defines things such as "giant red-leaved forests". The surface textures will reflect that ːsteamhappyː


Tech Example - New Orrery Map and a K-Class star arrival

Approaching the system of a K-Class star.
The new Orrery Map is now centred on the player ship instead of the system's central star, which allows for much smoother movement and greater zoom levels. It is also now fully 3D, so you can easily see the inclination of any star system to the galactic plane.

Join us on Discord: https://discord.gg/eDSQvpgdUX



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

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! ːsteamhappyː




Tech Example - Mercury approach from ~0.5ly.

WIP
Approaching Mercury from outside of the Sol system on autopilot, demonstrating how you can now see large system objects moving in real-time while you're flying at FTL speeds.


Discord: https://discord.gg/eDSQvpgdUX

Now With 50% More Tasty Astrophysics! - Update

I've been on a bit of a mission this past week or so, firstly to learn more in-depth astrophysics so I can make an even more accurate galaxy, and secondly to future proof the galaxy generation code so that adding new locations won't mess up the old ones.

When you have a massive procedurally generated world driven by random streams, one of the dangers you face is changing the entire face of that world when a single variable is adjusted. Random streams increment by 1 whenever you reference them, so adding or removing a single step in the process means every other reference to that stream is suddenly 1 digit off, and therefore the random outcome is changed. This has happened before in other games, and you can imagine the angst from the community when hundreds of hours spent mapping an area is suddenly rendered meaningless overnight, or that cool thing you found doesn't exist anymore.

To help safeguard our galaxy from such an occurrence I've been changing the way its sectors are generated. Instead of generating all the stars at once, I'm now generating each class of stars independently. Not only does that give us more control over each type of star, but it also means we can add additional types of star (or other locations) to the end of the list without affecting anything that came before it in the chain. In short, we can add interesting new things without breaking the old things.

Speaking of having greater control over each class of stars, I really wanted to make sure our galaxy was as close to real-world astrophysics as possible. Being a mere armchair astrophysicist myself, I went on a journey of learning and discovery that is actually still ongoing this week. I've had to read more scientific papers than is good for a person, but the net result is something that looks like this:



That's how our galaxy is now organised, with each 100ly sector falling into one of those regions. A sector's region determines the number and type of stars it contains, and some have the chance to be a special sector for things like Open or Globular Clusters.

That's probably all a bit meaningless to someone who isn't familiar with such things, so here are the basics in a nutshell:

Galactic Core
This is a single 100ly sector right in the middle of the galaxy, and it will hold Sag A* (our supermassive black hole) and the stars surrounding it. This will be a special and dangerous place eventually.

Bulge Area
The central bulge surrounds the core, and it's populated with mainly low-metal Population II stars over 10 billion years old. This is actually why the centre of spiral galaxies are yellow/orange in colour, it's because of the type of stars generally found there. Low-metal stars have very few to no rocky worlds, due to the lack of heavier elements present.

Thin Disc - Arms and Inter-Arms
The thin disc is where all the Population I stars our found, being high-metal stars younger than 8-10 billion years. This is the only place you'll generally find O and B class stars, with O Class being limited almost exclusively to Open Clusters (star-forming dust clouds) as they are <100 million years old.

The inter-arm areas generally won't have any O/B class stars or Open Clusters, consisting mainly of older stars.

The thin disc sectors are where the bulk of high-metal stars and planets can be found, with this region being responsible for some 85% of the entire galaxy's mass. The edge of the thin disc extends to some 50,000ly from the galactic core, and the density per-sector is driven by our galactic density map.

Thick Disc
The thick disc contains mainly low-metal Population II stars, somewhat older and even less metal rich than the bulge region. Again, you won't find many interesting worlds in this area. They will predominantly be gas giants or icy worlds.

Galactic Halo
Getting less and less dense the further out you go, the Halo is a mix of very old Population II stars and dense globular clusters. The Halo is actually twice as wide as shown in the diagram, extending some 100,000ly away from the core in every direction.

Globular Clusters
These are dense regions of Population II stars, which can be found scattered throughout the Halo and in some of the Thick Disc.

Intergalactic Space
As you pass beyond 100,000ly away from the galactic core stars will cease to be generated, and you will truly be in Intergalactic Space. There's no hard edge and you can keep flying, but there's nothing out there except running out of fuel and resources.


In total, this means the actual area where stars are generated is 8,000,000,000,000,000 cubic lightyears. That's 8 Quadrillion, and you can fly the ship without any loading screens to every square cm of every one of those 8 quadrillion locations. Phew! mission accomplished!

The next task is now to fill those locations with interesting content, which is a whole new challenge :)

Back To The Galaxy - Dev Update

Having gotten the new player character working reasonably well on the UE5 build, I've gone back to getting the new 1:1 scale Galaxy System working smoothly as well. The first step in the process was generating the complete starfield around the ship using the new scale, but with a greater number of sectors than before so that we can use the same data to render a real-time, dynamic skybox (ie, the stars move outside while at warp).

Instead of the 8 sectors, we were generating before (a 2x2 cube), we now need to generate a whopping 27 (3x3 cube) to form a full sphere with a radius of 150ly. Given an average of 4000 stars per sector, that's over 100,000 star systems to manage. Efficiency is the name of the game here, so I've been carefully juggling just how much data to generate at set points in the process so as not to overload everything. For example, do I convert each star's Kelvin temperature to RGB colour at the time of generation, or do I perform that task after the data has been filtered? The jury is still out on that one, but that's an example of how carefully this needs to be managed.

Generating a full 3x3 cube of sectors means I only have to regenerate that data afresh when the ship moves into a whole new sector, and given that each sector is 100ly wide, it's not something that will be happening very often at all. As such, I can generate the data fairly slowly over a period of say 20 seconds so as not to cause any performance impact. All the real-time systems then simply reference the stored data and filter it as needed.

In case you were wondering (because surely you were), this is what 300x300x300 lightyears looks like when trimmed to a sphere:



The next step was harder though because the galaxy is now represented at a literal cm-scale and we need to translate the location of the ship within a given cubic lightyear from centimetres to more reasonable galactic coordinates. As you can see here, the local coordinates are massive:



With the power of math however I was eventually able to get my head around it, and I'm happy to say we now have a fully working system for traversing the entire 1:1 scale galaxy per centimetre. Don't just take my word for it though, here's a video of the ship moving at a very real 200,000,000 times the speed of light:



The flickering you see is where it's taking the 27 stored sector data and discarding anything further away than 50ly to render the holo-display. It's having to do that a couple of times per second, which is a mad amount of data processing, but the ship is never going to be moving anywhere near that quickly during normal gameplay, so it should be fine.

During normal gameplay the ship will have a max speed of around 2,000,000C, so the speeds show above are way, way faster than needed. What this does mean however is that we have a huge margin to play with in terms of ship upgrades etc. Even a tenfold increase in ship capability is still significantly slower than the speeds tested, so we can look forward to a wide array of alien bolt-ons and interesting new minerals to make getting around the galaxy a bit quicker :)

Discord: https://discord.gg/eDSQvpgdUX