Results 1 to 15 of 15

Thread: Generating Solar Systems

  1. #1
    Member Hrafna's Avatar
    Join Date
    Jan 2017
    Posts
    37
    Post Thanks / Like

    Generating Solar Systems

    So, I'm bored. I only work 25% of the time now due to health reasons, and spend the majority of my time at home, where I enjoy coding at times. This is my first time using Visual Studio and first time coding C#, as I've coded procedural PHP most of my life for personal use. I try to avoid OOP as much as possible because I feel lost in a mess of OOP the more complex the code gets, forgetting where I am, what I've done, and where things are at.

    I have access to Unity engine where perhaps the easiest method would be use 2D tools to generate a visual representation, but so far I'm not familiar enough with Unity to use it efficiently. Knowledge of libraries have never been my strong suit. So, I'm just using Windows Console, echoing feedback to represent generation.

    But, if anyone is interested, either in programming or, well, this type of stuff, this is what I've done so far.

    The purpose of the StringBuilder is self-explanatory if you're familiar with the language. I'm just using it to write to the console.
    PHP Code:
    StringBuilder sb = new StringBuilder(); 
    Random is used repeatedly throughout this instance, in this manner, because I fail to comprehend non-primitive types and OOP. Random is used in everything, from generating placeholder IDs to generating celestial bodies and their properties. I feel that I might be using this too much (in my experience with PHP it can take a toll on performance).
    PHP Code:
    Random random = new Random(); 
    GAIA is the value used to divide space. It turns the real Earth into a miniature 65 km diameter version of itself, and the moon into a 20 km diameter version of itself. The multiplier is used to make the sun smaller, and to make the distance between planets and the asteroid belt relative to the sun smaller.
    PHP Code:
    const byte GAIA 175;
    const 
    byte GAIA_MULTIPLIER 2// 1 is default 
    An AU is an Astronomical Unit. It is basically just a neater way of saying kilometers. For now, it is only used to determine the asteroid belt's position relative to the sun. It will be used to determine the position of planets relative to the sun as well.
    PHP Code:
    const float AU = (149597870.7f / (GAIA GAIA_MULTIPLIER)); 
    The following calculates the number of suns that the solar system will have. No statistics have been found regarding the commonality of multiple suns; some sources claim (undocumented) that 85% of solar systems are binary or more, whereas other sources claim (undocumented) that 85% of solar systems are singular, like our own solar system. Thus it is left almost entirely up to chance.
    PHP Code:
    int numberOfSuns random.Next(13);
    sb.AppendLine("Number of Suns:\t" numberOfSuns);
    sb.AppendLine(); 
    Suns might not have to behave in the same manner as other celestial bodies that the player can interact with (e.g. dig into voxels). The sun could perhaps be a cubemap object, be of almost any small size and memory-efficient shape, and use low quality textures, which can be hidden by strong lighting effects, and distance limitations. The cube, terrain, or sphere that makes up the sun's texture will then have no collision and will delete any group of objects (a ship) or an object (a part of a ship) that comes into contact with it. This is to make sure that JUNKASAURUS cannot bounce off the sun in his suicidal attempt to touch the sun. I haven't written this in because it serves no purpose in this representation. However, suns have to contain information such as size, from where distances can be calculated.

    I have found no statistics regarding the size of suns in our galaxy (yet) so calculation is made using the size of our own sun, with some leeway to chance.

    I've also made it so that if the sun is very small, then the color is orange, and the planets are all much closer to the sun. And if the sun is very large, then the sun is blue, and the planets much farther away. Blue suns are very rare. I would improve upon this more, but I'm afraid that if the generation sequence is too complex that it becomes redundant for something that is supposed to be a random occurance anyway. So, I'm staying away from red supergiants, for instance, but mostly because they're too huge to fit in a game, presumably.
    PHP Code:
    int sunDistanceFromCenter 0;
    for (
    int i 0numberOfSunsi++) {
        
    sb.AppendLine("Sun ID:\t\t\t#" random.Next(10000009999999));
        
    float actualSunRadius_Min 696000 0.5f;
        
    float actualSunRadius_Max 696000 1.25f;
        
    float actualSunRadius random.Next((int)actualSunRadius_Min, (int)actualSunRadius_Max);
        
    int sunRadius = (int)Math.Ceiling(actualSunRadius / (GAIA GAIA_MULTIPLIER));
        if (
    numberOfSuns 1) {
            
    sunDistanceFromCenter sunDistanceFromCenter + (sunRadius 50);
            
    sb.AppendLine("Off-center:\t\t" sunDistanceFromCenter " km");
        }
        if (
    actualSunRadius < (actualSunRadius_Min 1.5f)) {
            
    // Small orange sun (We want them to be rare, even though they are the most common)
            
    sb.AppendLine("Surface color:\t\tOrange (near), Orange (far)");
            
    sb.AppendLine("Emits color:\t\tOrange (near), Orange (far)");
        } else if ((
    actualSunRadius > (actualSunRadius_Max 0.8f)) && numberOfSuns == 1) {
            
    // Big blue sun (Lowest chance of appearing)
            
    sb.AppendLine("Surface color:\t\tBright-Blue (near), Bright-Blue (far)");
            
    sb.AppendLine("Emits color:\t\tWhite (near), Bright-Blue (far)");
        } else {
            
    // Average yellow sun (Highest chance)
            
    sb.AppendLine("Surface color:\t\tOrange (near), Bright-Yellow (far)");
            
    sb.AppendLine("Emits color (near):\tBright-Yellow (near), Bright-Yellow (far)");
        }
        
    int sunLethalHeatRadius sunRadius 10;
        
    int sunLethalRadiationRadius sunRadius 100;
        
    sb.AppendLine("Radius:\t\t\t" sunRadius " km");
        
    sb.AppendLine("Heat radius:\t\t" sunLethalHeatRadius " km");
        
    sb.AppendLine("Radiation radius:\t" sunLethalRadiationRadius " km");
        
    sb.AppendLine();

    The existence of an asteroid belt and its properties is determined before the existence of asteroids and planets. Planets should not be generated inside asteroid belts, and asteroids should be generated much more frequently inside the asteroid belt. Asteroids are normally quite rare; there's only a couple of hundred thousand in the entire inner region compared to the asteroid belt which contains millions upon millions of asteroids. All of these numbers of course will be reduced by GAIA when we get that far.

    Again, I have found no information about asteroid belts other than our own. Its position and size is loosely based on what we know about our own asteroid belt.
    PHP Code:
    float actualBelt_Inner 0;
    float actualBelt_Outer 0;

    // 50% chance that an asteroid belt exists in the solar system
    if (random.NextDouble() >= 0.5) {
        
    float actualBelt_Inner_Min = (AU 2.2f) * 0.75f;
        
    float actualBelt_Inner_Max = (AU 2.2f) * 1.25f;
        
    float actualBelt_Outer_Min = (AU 3.2f) * 0.75f;
        
    float actualBelt_Outer_Max = (AU 3.2f) * 1.25f;
        
    actualBelt_Inner random.Next((int)actualBelt_Inner_Min, (int)actualBelt_Inner_Max);
        
    actualBelt_Outer random.Next((int)actualBelt_Outer_Min, (int)actualBelt_Outer_Max);
        
    sb.AppendLine("Asteroid belt:\t\t" actualBelt_Inner " km - " actualBelt_Outer " km");
        
    sb.AppendLine();

    I have written asteroids and planets but it started to get a bit tangled up when I wrote the asteroid belt. It's one of the issues with coding procedurally, I guess. I found some cool statistics about how much carbons, silicates and metals occur on asteroids, in some cases dependent on their location in the solar system, and I was about to write something on that when I got all sidetracked with the asteroid belt.

    This is for instance all I've got on planets so far.

    PHP Code:
    /*
        NUMBER OF PLANETS    Calculates the number of planets that a solar system has, excluding moons.    Numbers taken from https://en.wikipedia.org/wiki/List_of_multiplanetary_systems
        1 planet      =   1:402
        2 planets      =   301:402
        3 planets      =   102:402
        4 planets     =   34:402
        5 planets      =   16:402
        6 planets      =   4:402
        7 planets      =   3:402
        8 planets     =   1:402
     */
    List<intindex = new List<int>();
    int[] planets = { 1301102341643};
    index.AddRange(planets);int num 0;foreach (int planet in planets) {
        if (
    random.Next(planets.Min(), planets.Max()) < planet) {
            
    int P planet;
            if (
    random.Next(planets.Min(), P) < planet) {
       
    num index.IndexOf(planet);
            }
        }
    }
    int numberOfPlanets num 1;sb.AppendLine("Number of Planets: " numberOfPlanets);
    sb.AppendLine();for (byte i 0numberOfPlanetsi++) {
        
    sb.AppendLine("Planet ID:\t\t#" random.Next(10000009999999));

    What are your thoughts on the subject?
    Last edited by Hrafna; 11-02-2017 at 02:10 AM.

  2. #2
    Member Hrafna's Avatar
    Join Date
    Jan 2017
    Posts
    37
    Post Thanks / Like
    Ok, so I figured out how to use Unity, to some extent. I had to spend some time learning how things work (I'm still in the process of learning), and I had to figure out how to solve the float precision problem. I decided to solve it by ripping the universe into tiny pieces, so that I could proceed to use small numbers. World position is only used now to determine where the sun is, whereas everything else is relative to that, multiplying and multiplying. Due to this, I can now potentially create several hundred thousand solar systems next to one another without float precision issues. Yay!

    The original idea was to divide the size of the solar system by a common value so that everything would be relative to the size of the earth which would be around 50km, and that's why I wanted the solar system to be so big, or at least have the ability to make it big, but after having played No Man's Sky and felt the atmosphere of having planets much closer to the camera all the time, I decided on making the solar system no larger than 90 000 units, that way everything looks all neat and cozy.

    I didn't bother to add more than one sun, though. I changed my mind, because either it takes up way too much space, or it just becomes way too complex to code, and it includes having to make the suns spin, not once, not twice, but three times. That's just not feasible, I think, at least not for my abilities in C#. But there can be between 1-6 planets like this which is more than enough. There are moons to account for, as well.

    So, yeah, I'm gonna fine tune the random placement of planets some more, and then I'm gonna, hopefully, start working on some asteroids. I want to find out how to position the asteroid field. The asteroid field won't be created upon start of the game, like the planets are, but the information that the solar system has an asteroid is there; it's just a matter of where now.

    This is so much fun

    Is no one else interested in this type of stuff?



  3. #3
    Super Moderator Wazbat's Avatar
    Join Date
    Jun 2015
    Posts
    395
    Post Thanks / Like
    Very cool! I really want to get into coding myself and it's really interesting seeing how people managed to do things.

  4. #4
    Member Hrafna's Avatar
    Join Date
    Jan 2017
    Posts
    37
    Post Thanks / Like
    It really is a lot of fun if you're into solving problems.

    Like, the problem in Unity Engine, or any engine for that matter, isn't that Vector3() uses float, but that float has a maximum range, like any primitive type. And what I mean by that is that it doesn't matter whether Vector3 uses float (32 bit), double (64 bit), or decimal (128 bit), the end result will be the same when using precision types, which is that the player will lag and bug out eventually as soon as the player is positioned over the 99 999 unit mark, because there's just not enough decimal points to position the player accurately.

    Now, the good thing, is that the player does not have to be bound to the world position, which will always have to start at Vector3(0, 0, 0), and which will always have a problem at Vector3(99999, 99999, 99999) and beyond. The player can be bound to a GameObject instead, and said GameObject's position does not have to be a precision value. It can use whole numbers. It's just an invisible box to which the player is bound, and from which the player gets their position (a local position) so as to make sure that the player doesn't lose the precision values it needs to move around smoothly without having to lag and bug out.

    So, how many whole numbers can a float contain? Don't be intimidated by the math. I had to google my way to this formula, myself.

    1 + ((2^23 - 1) + 105 * (2^23)) * 2 = 1 778 384 895 units.

    Of course, if you were allowed to use a long value instead of a float value, this number would be seemingly infinite in comparison, because a long value is faster to execute and can contain 9 223 372 036 854 775 807 units, but 1.7 million units is already more than enough, or at least I think so.

    I mean, that's over 17 783 km worth of space to work with, and I only need 900 km for one solar system. I mean, 900 km from the center. It's 1800 km in diameter.

    I decided to solve this problem by chopping the universe into what I call solar bits. Each solar bit is 90000*2 units large, can contain a celestial body, and more importantly, a player. The player is tied within the boundaries of this bit, thus never lose precision. When the player moves outside the confinement of this bit, another bit is generated where the player is at so that the player will have a new parent from which they can get their local position. So the player can move on and on and on for 17 783 km, instead of just 90 km.

    I forgot that the asteroid belt's position from the sun is already in the math, so I don't have to-- more important don't want to create the asteroid belt, per se. I want to create asteroids randomly throughout the whole solar system, but increase the density of asteroids as the player is inside the boundaries of the asteroid belt.

    All the planets are now scattered randomly around the sun. I had to start working on a camera that could be created upon start of the game and moved to the nearest habitable planet, and in the process learn how to create movement, and a HUD that can feed information back to me about how fast I'm moving. This way I can start working on asteroid creation, and asteroid belt, and generating solarBits as the player moves around in the universe.

    As you can see here, it warns about floating point precision because it's all very much out of bounds, but its using whole numbers, so it's ok; the warning is shallow. The player is not using any value that is out of bounds, nor is anything else, so nothing can be lagging due the solarBits being out of bounds. The biggest square box, the parent of everything, has no value what so ever. It's just there to visually represent the total size of a solar system. Those planets down there are between 35 and 51 km in size. The one in the middle, the sun, is 15 km. Their sizes are random. The player (camera) was created near a random habitable planet as seen in the window below.





    Man, I had no idea that I would like working with Unity so much. It's like working with PHP, only, with even more options available to me because it's a freakin game engine not a web server!
    Last edited by Hrafna; 14-02-2017 at 04:11 AM.

  5. #5
    Kickstarter Unique Nomad Nomad Dave's Avatar
    Join Date
    Mar 2016
    Location
    53į38'01.3"N 1į50'30.1"W
    Posts
    272
    Post Thanks / Like
    i like reading through these posts of yours Hrafna. but i have no freaking clue what your on about. it looks good though, keep it up and al try my best to follow what your on about.
    Wazbat say's "Oh Nomad Dave isn't affiliated with Planet Nomads or Craneballs" witch is very true all I have is the game

  6. #6
    Member Hrafna's Avatar
    Join Date
    Jan 2017
    Posts
    37
    Post Thanks / Like


    Each of those little green square boxes are 180 000 meters in size (90 000 meters from the center).

    When the player moves outside the boundaries of the green box (90 000 meters), a new one appears in the direction the player was headed, unless a box already exist in that position.

    Every time the player moves within the confinements of a box, the player's local position is moved from the old box to the new box to preserve the player's camera float precision (so that the player doesn't suffer from lag when moving around).

    In theory, the player can move 1 778 384 895 meters away from the center of the world. But, if my calculations are wrong, the player can move twice as far away from the center (using int), or several thousand times away from the center (using long). It's currently using whole numbers in Vector3(float, float, float), as far as I'm aware, even though the variables are calculated as int before being placed in the Vector3().


  7. #7
    Super Moderator Wazbat's Avatar
    Join Date
    Jun 2015
    Posts
    395
    Post Thanks / Like
    Oh right I see what the main problem is. As you were saying, floating point precision, or floating point errors. I know games like no man's sky suffer from that when you fly for about 2-3 hours in a straight line. Many people encountered it when trying to fly to the sun.

  8. #8
    Member Hrafna's Avatar
    Join Date
    Jan 2017
    Posts
    37
    Post Thanks / Like
    That's right!

  9. #9
    Member Hrafna's Avatar
    Join Date
    Jan 2017
    Posts
    37
    Post Thanks / Like
    I've made some improvements to the camera so that I can move around in all directions relevant to the position the camera is pointing in, and I've created a 3D skybox that copies the positions and sizes of the planets so that the sun and planets can be viewed from extreme distances.

    To show off the random generation of planets, I clicked on the play button a few extra times in the beginning of the video.



    One issue with this 3D skybox is that, currently, I'm not creating "Mini Bits" as the player moves into new Solar Bits. The result is that the actual size of the planets and the 3D skybox overlap when I get to close to planets. But I would have to get really-- really up-close to the planet to see that. I mean, I need to get up all up in the planet to see it, at which point the 3D skybox is supposed to be turned off anyway.

    Ps. I think what I said about the max range earlier might be nonsense. Now I'm just unsure as to how far away from the center I can be. I get bugged out past the 999,999 mark now, but I think it might be because of the 3D Skybox. At least I hope it's the 3D Skybox. The bugging stops when I turn the 3D skybox off, but the error persist, hopefully because the script keeps trying to pass float values to it. I didn't write automatic Mini Bit generation though, that's probably it. Hopefully it.
    Last edited by Hrafna; 17-02-2017 at 10:18 PM.

  10. #10
    Member Hrafna's Avatar
    Join Date
    Jan 2017
    Posts
    37
    Post Thanks / Like
    I'm done testing, and it seems the 3D skybox is not at fault.

    Unity's limitation is, as I've come to terms with:

    1. that, you cannot use anything other than float in Vector3, and
    2. the view frustum is calculated from world position, not local position (a solar bit).

    which results in a smaller and limited maximum range, and means that even if I can expand the universe, and I can, there's no point in doing it because the camera is still tied to world position. So the jittering and staggering and bugging and lagging will start at 1 million units regardless of what is done to prevent it.


    I'm fine with using float as a precision value, but I really don't need to position static objects like solar bits with precision values, so I wish I had the alternative to set Vector3 from float to long (whole numbers rather than precision) where it was needed, and that the view frustum could be calculated in local position rather than world position. This would result in little to no coding required to make a seemingly infinite universe.

    I've been reading up on some various methods that people have used to solve this predicament, and from what I can tell, an alternative solution would be to push objects out of the view frustum rather than move the view frustum. I personally don't want to do this, for obvious reasons, being that it would be a nightmare to code the multiplayer-side of things.

    So, what I'm going to look into, to save myself the trouble of having to deal with unnecessary complexities, is to apply a method that generates/loads new scenes in the background. A galactic bit can still be 1800 km in diameter. The remaining 99 km that the player can travel before hitting the jitter bug can then be spent loading an empty space scene.

    If the first scene, the scene that the solar system is in, is called X0:Y0:Z0, and the player moves outside the 900 km range in direction X of said scene, a new scene begins loading and is called X1:Y0:Z0. This way, if it was ever to be multiplayer, players can still find each other, in theory.

  11. #11
    Member Hrafna's Avatar
    Join Date
    Jan 2017
    Posts
    37
    Post Thanks / Like
    I haven't posted in this thread for a while, and the reasons are plentiful. One of the reasons being that I've spent a lot of time learning about networking in Unity, and in doing that I decided to redesign my entire project. But, the most important reason is that I've somehow unexpectedly managed to transcend this project into something resembling an actual game, and that is not something I should be posting about here on Planet Nomads website.

    But, to finish my thread off, for those wondering, I was able to make the universe infinite in scale. It is similar to my original design, yet different. So different, that a player can now move 1,7 billion x 1,7 billion x 100,000 meters away from the center of the universe. This distance can be expanded upon indefinitely, but I've decided to cap it at 50 x 50 x 100,000 meters. Don't get me wrong. A player can still move 1,7 billion x 100,000 meters away from the center of a solar system, but I've made it so that planets are not generated past a certain point because it's no fun when things are so far apart that it takes forever to find things and each other. Beyond the limits of the solar system, players will but move into the vast emptiness of space where they will encounter nothing, not even float precision issues. And all of this works in multiplayer, without desync issues.

    I wrote a lot of other things, but I won't get into that.

    Right now I'm learning how to use Blender so I can try something I've always wanted to try with the GUI, kind of. I will eventually create some models for Planet Nomads with it, like oxygen tanks and air vents so that when the time comes that we can create mods for Planet Nomads I can maybe create an oxygen mod or something, I don't know. Maybe when I start playing I'll want to do something else entirely with it Maybe.... a female character? Dun-dun-dun!

  12. #12
    Member
    Join Date
    Jul 2017
    Location
    UK
    Posts
    180
    Post Thanks / Like
    You do all this when you're bored?

  13. #13
    Member
    Join Date
    Oct 2017
    Posts
    1
    Post Thanks / Like
    Very cool! I really want to get into coding myself and it's really interesting seeing how people managed to do things. i am loving it...






  14. #14
    Kickstarter Alpha Nomad
    Join Date
    May 2016
    Posts
    11
    Post Thanks / Like
    Random random = new Random(Random random 2 = new Random(Random random 3 = new Random(Random random 4 = new Random(Random random 5 = new Random();););););

    INCEPTION!!!!

    but aye, looks great man! Depending on how things are going later in development you may be able to make a mod to do such things within the game.

  15. #15
    Senior Member
    Join Date
    Apr 2018
    Posts
    236
    Post Thanks / Like
    Very cool stuff. Very technical stuff too. Iím afraid Iíve never delved this much into Unity. Iíve dabbled a bit in the Unreal engine but thatís close to the extent of what Iíve done. Whatís the grand plan for all this when youíre done?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •