Difference between revisions of "Tutorial:Making Planets"

From Kerbal Space Program Wiki
Jump to: navigation, search
m (added caveat)
m
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
== Creating Your Own Planets ==
 
== Creating Your Own Planets ==
This tutorial is made for people who are getting bored with landing and collecting science on the stock planets, but if you could land on your own planets, that could be very interesting!
+
This tutorial is designed for those with a relentless, creative spirit. Those seeking a way to vent said creativity will be delighted to learn that, with the Kopernicus plugin's existence, it is now possible to modify the planetary system in Kerbal Space Program, allowing for new planets to be added and existing planets to be modified or removed entirely.
 
 
It is not  updated for modern versions of the game, and does not depict any good practices or techniques that Kopernicus modders should use when making actual mods. This tutorial should therefore not be used if you are intending to make planet mods, not even as a jumping off point.
 
  
 
=== Specifications ===
 
=== Specifications ===
 
*Length: 15-20 minutes
 
*Length: 15-20 minutes
*Difficulty: Easy - Somewhat Intermediate
+
*Difficulty: Advanced
*For Version: 1.0.4+
+
*For Version: 1.3.X (Planets will work in 1.4, but the map exporter won't, so we'll be using 1.3 for this tutorial)
  
 
=== Requirements ===
 
=== Requirements ===
*Ksp (Duh)
+
*[https://forum.kerbalspaceprogram.com/index.php?/topic/140580-142-kopernicus-release-1-march-30/ Kopernicus]
*[http://forum.kerbalspaceprogram.com/threads/114649 Kopernicus 0.3.3]
+
*[https://forum.kerbalspaceprogram.com/index.php?/topic/140581-13-kopernicus-kittopiatech-a-kopernicus-visual-editor-release-2-sep-27/ KittopiaTech]
*[http://forum.kerbalspaceprogram.com/threads/129186 KittopiaTech 0.2]
+
*A text editor. Notepad can do the job, but Notepad++ is highly recommended.
*A text editor (Notepad, Notepad++,Sublime Text, etc.)
+
*(No, you do not need textures or image editors of any kind. In fact, if you're going to be advising SpaceEngine, I'm glaring at you.)
*A place to get textures (This can be SpaceEngine)
+
* The only objects that require the use of image editors and such are gas planets and stars. Terrestrial planets do not require textures to function.
*A photo editor (Photoshop, GIMP, Paint.net, etc.)
+
 
*An online normal map creator, like the one [http://cpetry.github.io/NormalMap-Online/ here] (optional)
+
=== Config Files ===
 +
 
 +
The first step when making planets is knowing the basics of config files. Let's start by creating one! For Notepad users, simply open up Notepad, then head to File -> Save As. Navigate to a location that you will be creating your mod at. Recommended is to create a folder for your mod somewhere (your desktop, for example) and using that folder to store all of your planet pack's data. We'll go over organizing said data later, for now, let's focus on not cluttering the hard drive and storing all mod info in a similar location.
 +
 
 +
Once you have settled on a nice saving location, write the name of your planet and '''remove the .txt''' as we will not be saving in this format. Add .cfg behind it, and select ''All Files'' in the drop-down menu following ''Save as type''
 +
 
 +
For this tutorial, we will be making a planet called Tutora. So, in this case, we would write ''Tutora.cfg''. The file name is actually not that important, but it's recommended to name config files properly so that you know just from the name what it contains.
 +
 
 +
Now we should have a .cfg file. Let's get to editing it!
 +
 
 +
Firstly, there are two kinds of config entries that you must memorize. The first is called a 'Config Node'. These appear as follows:
  
== Rocky Planets ==
+
Orbit
=== Steps ===
+
{
==== 1. Getting Textures ====
+
...
 +
}
  
(I will use SpaceEngine in this example)
+
As you can see, the name of the node is followed up by an opening bracket, which is in turn followed up by the node's contents, then lastly - and this is very, very important - the closing bracket. (Notepad++ automatically highlights opening and closing bracket pairs, which is why it is pretty much industry standard when making planets.)
In order to get textures, open up SpaceEngine, find the planet you want to use, and click on export planet in the editor menu.
 
[[File:SpaceEngine_Planet_Export.png|thumb|center|This is how to export a planet from Space Engine]]
 
Make sure you uncheck the clouds and surface settings, and check the color map. All you need is color map, normal map, and height map. If you don't have SpaceEngine and you have a color and height map, use the online normal map. Just drag and drop the color and height map, and it will create your normal map. Save the files from SpaceEngine as .dds files, but if you have a .png file, open it up in your texture editor, and save another copy as .dds. Make sure you save all files as '''''YourPlanetName'''''. You should now have three files - '''''YourPlanetName''''' '''_Color.dds''', '''''YourPlanetName''''' '''_Normal.dds''', and '''''YourPlanetName''''' '''_Height.dds'''.<br />
 
  
 +
The other kind of config entry is called a 'Config Value', and these appear as follows:
  
==== 2. Creating The Config Files ====
+
semiMajorAxis = 19000000
  
Open up your text editor and copy this code into it.<br />
+
As you can see, a config value is always in the format of 'X = Y', where X is the name of the Config Value and Y is the data assigned to it. Y can be many different kinds of data, for example a line of text (a 'string', as it is called in programming languages), a whole number (also known as an integer), or a number with decimals (also known as a 'float' or a 'double', depending on the situation).
  
CODE:
+
Making planets is largely the product of simply placing the correctly named nodes in the right locations, and supplying the right config values with the right data.
@Kopernicus
+
 
{
+
=== Module Manager Syntax ===
    Body
+
 
    {
+
Contrary to what some might expect, we are not actually writing a piece of code for Kopernicus. Rather, Kopernicus internally has a config file, which we will be altering - and this is very important - ''indirectly''. We will be using the 'Module Manager' plugin to patch Kopernicus' config file instead. This way, users can add and remove planet packs at will without having to go into the config files and swapping things out manually.
        name =  //This will be the name of your planet.
+
 
        flightGlobalsIndex = 500 //You can make this any number, just not too big.
+
Although writing configs largely comes down to Nodes and Values, there are several handy commands that you can leave in your code for ModuleManager to use.
        Template
+
 
        {
+
Let's go over a few.
            name =  //This is the template for your planet. Put Tylo for rocky planets, Laythe for ocean planets, Jool for gas giants, or Sun for stars.
+
 
        }
+
@Orbit
        Properties
+
{
        {
+
...
            radius =  //The distance in meters from the surface to the planet's center.
+
}
            geeASL = //The planet's gravity. (Kerbin = 1)
+
 
            mass = //The planet's mass. Not that important.
+
The @ operator means 'edit'. In the above example, instead of declaring a node named 'Orbit', we are instead telling Module Manager to patch an already existing Orbit node. Note that this will not randomly edit an Orbit node - only one in the exact same location, in another file. (IE the parent nodes of the node marked for editing must match those of the target node in terms of name)
            tidallyLocked = true/false //Determines if the planet is tidally locked.
+
 
            rotationPeriod = //Duration in seconds for the planet to complete a single rotation.  
+
!Orbit {}
            description =  //The description of the planet. (Shows up in planet's Info panel)
+
 
            ScienceValues //The values for conducting experiments at the planet.
+
The ! operator differs in use. In the above example, we tell Module Manager to remove the Orbit node. We do not need to specify anything in the brackets, just add them to inform Module Manager that we are targeting a NODE, not a VALUE. Another case for the ! operator is conditioning:
            {
+
 
                landedDataValue =  
+
@Kopernicus:NEEDS[!OPM]
                splashedDataValue =
+
{
                flyingLowDataValue =
+
..
                flyingHighDataValue =
+
}
                inSpaceLowDataValue =
+
 
                inSpaceHighDataValue =
+
Above, you can see that we edit the 'Kopernicus' node. However, we have added the 'NEEDS' condition to it. The above code, when translated to English, basically means:
                recoveryValue =
+
 
            }
+
''Edit the config node Kopernicus with the below changes, BUT only do so if the tag named OPM is NOT present.''
        }
+
 
        Orbit
+
Note that 'not' is written in capital letters. This is because I would like to draw your attention to that word. Rather, the fact that, if we were to remove the ! operator from the above code example, we would have to remove the 'NOT' word in the translation. Ergo:
        {
+
 
            referenceBody =  //The celestial body the planet orbits.
+
:NEEDS[OPM] = only patch when the tag 'OPM' is present
            inclination =  //Value in degrees for how far above the orbital plane the planet's orbit goes. (Use >90-<270 for retrograde orbit)
+
:NEEDS[!OPM] = only patch when the tag 'OPM' is NOT present
            eccentricity =  //Value from 0-1 for how much an ellipse the planet's orbit is. (1 is a parabolic escape trajectory, 0 is circular, in between is elliptical, >1 is hyperbolic, infinite makes the planet fall straight into the Sun)
+
 
            semiMajorAxis = //This is the distance in meters your planet is away from the reference body.
+
But what are these 'tags' that I have mentioned thrice thus far? Tags can be targeted by Module Manager conditions, and can be declared in many ways:
            longitudeOfAscendingNode = //The rotation of the orbit from the Ascending Node
+
- Folders directly inside the GameData folder of your KSP directory can be targeted as a tag.
            argumentOfPeriapsis = 0 //The angle between the Ascending node and Periapsis, changing this essentially changes the orbits rotation about the axis perpendicular to its plane.
+
- Tags can be declared with the :FOR[X] condition, where X is the name of the tag
            epoch = 0 //The reference time elapsed for meanAnomalyAtEpoch since Universal Time = 0. This is typically 0, unless this is the orbit of a ship or forcibly relocated asteroid.
+
 
            meanAnomalyAtEpoch = //Changes the starting position of the body in its defined orbit. It is the time elapsed since the last periapsis, measured in seconds (in intervals of the orbital period, which is calculated by 2*Pi*sqrt(semiMajorAxis^3/G/mass of referenceBody))
+
And that brings us to the next condition: FOR.
            color = R,G,B,1 //The RGBA color code of your planet's orbit in the orbit map and tracking station. Divide each value by 255. The 4th value is Alpha, or the opacity of the color. Keep it at 1.
+
 
        }
+
@Kopernicus:FOR[Bob]
        ScaledVersion
+
{
        {
+
...
            Material
+
}
            {  
+
 
                texture = //This will be Kopernicus/Config/''YourPlanetName''/''YourPlanetName''_Color. Do NOT put .dds.
+
FOR on it's own does not do anything, it is merely a marker for other conditions, namely BEFORE, AFTER and NEEDS. Let's call the config file containing the above node 'File A'. In that case, making config edits with conditions will have the following effects:
                normals =  //This will be Kopernicus/Config/''YourPlanetName''/''YourPlanetName''_Normal. Do NOT put .dds.
+
 
          }
+
:BEFORE[Bob] = The patch is applied before the patch declared in File A (which is marked as 'FOR[Bob]', remember!) is applied.
      }
+
:NEEDS[Bob] = The patch is only applied if File A (or another file declaring the tag Bob through the use of FOR) is present.
 +
:NEEDS[!Bob] = The patch is only applied if the tag 'Bob' is not declared anywhere.
 +
:AFTER[Bob] = The patch is applied after the patch declared in File A (or any other file declaring the tag Bob through the use of FOR)
 +
 
 +
And lastly, a more advanced condition, especially handy when editing a specific node of which there are multiple.
 +
 
 +
!Atmo:HAS[#name[Duna]]{}
 +
(Taken from [https://github.com/Galileo88/StockVisualEnhancements/blob/master/GameData/StockVisualEnhancements/SVE_Scatterer/Planets/Duna/atmo.cfg here] with lots of thanks.)
 +
 
 +
As you can see, we are removing the config node named 'Atmo', but we have the HAS condition preventing the deletion of every single node named 'Atmo'. The HAS condition limits the effect of a patch to config nodes that meet the declared condition. In the above example, each Atmo node is checked if it contains a Config Value named 'name', with an assigned value of 'Duna'.
 +
 
 +
=== Planetary Nodes ===
 +
 
 +
Before we start making planets, let's go over the config structure.
 +
 
 +
The first thing that we want to do is edit the Kopernicus Config Node. So let's open up the config we made earlier. Remember that we will be making a planet called Tutora.
 +
 
 +
@Kopernicus:FOR[Tutora]
 +
{
 +
}
 +
 
 +
The observant among you have noticed that we are declaring this config with the tag 'Tutora'. This means that we can specify a loading order for config files (should we need this later) by marking patches with AFTER, BEFORE, and NEEDS.
 +
 
 +
Every celestial body has its data stored in a node called 'Body'. There can be multiple Body nodes per config, but only one planet per Body node.
 +
 
 +
Let's add the Body node to the above start.
 +
 
 +
@Kopernicus:FOR[Tutora]
 +
{
 +
    Body
 +
    {
 +
        name = Tutora
 +
    }
 +
}
 +
 
 +
I have also added the 'name' Config Value real quick. The 'name' Config value declares the name that the celestial body will wear, both internally and in-game (unless otherwise specified).
 +
 
 +
Inside the Body node of Tutora, we can add a variety of Config Nodes. Let's go over a few.
 +
 
 +
''Debug {}''
 +
Debug stores data for debugging planets, for example whether or not we want Kopernicus to generate a cache file.
 +
 
 +
''Properties {}''
 +
Properties stores most of our planet's physical properties (mass, radius, gravitational acceleration, rotation period, whether or not our planet is tidally locked, et cetera) as well as some miscellaneous items such as the in-game description, the science multipliers, and the timewarp altitude limiters.
 +
 
 +
''Orbit {}''
 +
Orbit stores the data related to the planet's placement within the Kerbal universe, or rather, the path that it will follow through said universe.
 +
 
 +
''Template {}''
 +
Template allows you to clone a stock planet. If you choose a template, anything you declare in your config will be applied as a patch to a ''copy'' of that template's config file. Note: you are ''not'' altering the stock planet itself, rather Kopernicus clones it and applies the data you specified to that clone. Using a template is highly recommended. In the Template node, you can also do some rather interesting things, such as removing PQSMods from the template planet (we'll go over what in the world PQSMods are later), removing the ocean of the clone, or removing the atmosphere of the cloned planet.
 +
 
 +
''Atmosphere {}''
 +
Atmosphere stores all of the information regarding a planet's atmosphere. Not just the altitude limiter, but also physical and chemical properties such as the adiabatic index (used for calculating the speed of sound), the molar mass (used for calculating the density), the temperature-height profile, and many other things.
 +
 
 +
''Ocean {}''
 +
The Ocean node stores all data regarding a planet's oceans. If a planet's configuration does not contain an Ocean node, it will not have oceans.
 +
 
 +
''ScaledVersion {}''
 +
Because keeping an entire planet loaded is rather taxing, KSP cleverly unloads the planet should the camera go too far from the planet, and instead will load in a relatively low-poly representation. Through ScaledVersion we can edit this representation. Essentially, ScaledVersion is in charge of making our planet look good from afar (such as in the Map View)
 +
 
 +
''PQS {}''
 +
PQS stands for Procedural Quad Sphere, and is the kind of terrain KSP uses for its planetary surfaces. The PQS node contains all of the data regarding our planet's ''actual'' terrain. It is therefore, in essence, the counterpart to ScaledVersion. Note that non-terrestrial objects such as Jool and the Sun lack the PQS node and thus a Quad Sphere, which is why they have no solid surface.
 +
 
 +
=== Making a Gas Giant ===
 +
 
 +
Now that we have the above cleared up regarding Config Nodes, we can select the Config Nodes that we will be needing, as well as a template.
 +
 
 +
Let's use Jool.
 +
 
 +
@Kopernicus:FOR[Tutora]
 +
{
 +
    Body
 +
    {
 +
        name = Tutora
 +
        Debug //We want to add some changes here.
 +
        {
 +
            exportMesh = false //Setting this to false means that no cache file is generated.
 +
            //Since a gasplanet has no solid surface, we don't need the cache file, as there is no PQS to store there.
 +
            update = true //We do want the planet to be updated though.
 +
        }
 +
        Template
 +
        {
 +
            name = Jool
 +
            //Besides picking a template there isn't anything else to do here. We don't need to remove anything else.
 +
        }
 +
        Properties
 +
        {
 +
            description = This stores the text that will be visible in-game in the info tab.
 +
            radius = 4000000 //This CfgValue stores the radius of the planet (average distance from surface to center), 6000km = 1 Jool radii. 4000km = 2/3 Jool radii.
 +
            geeASL = 0.63    //With geeASL you can define the gravitational acceleration at the surface, expressed in g's (IE the amount of times Earth's gravity. 9.81 m*s^-2 = 1g)
 +
        }
 +
        Orbit
 +
        {
 +
            semiMajorAxis = 5000000000 //Nothing too fancy. We basically clone Jool's orbit but with a different average distance.
 +
        }
 +
        Atmosphere //Let's access the atmosphere
 +
        {
 +
            ambientColor = 0.7,0.5,0.1,1 //Ambient color provides a slight tint to any craft inside the atmosphere, with the tint intensity increasing with depth
 +
            lightColor = 0.37,0.47,0.62,1 //Light color is somewhat strange, for some reason the lower the intensity of a color, the more prominent that color is.
 +
            //Pro tip: adjust lightColor in-game with KittopiaTech.
 +
        }
 +
        ScaledVersion //Gas planets are only the scaledspace mesh
 +
        {
 +
            Material //The Material subnode is where we actually alter the appearance of the ScaledSpace mesh
 +
            {
 +
                texture = Tutorial/PluginData/Tutora_c.dds //Here we assign a new texture to the sphere.
 +
            }
 +
        }
 
     }
 
     }
}
+
}
 +
 
 +
I would like to draw your attention to the line ''texture = Tutorial/PluginData/Tutora_c.dds'', because there is a reason why the texture is placed in a folder called 'PluginData', why it is in the DirectDrawSurface format, and why the filetype extension is included in the filepath.
 +
 
 +
Saving a texture in a folder called ''PluginData'' prevents KSP from loading it. This is because KSP does not check in folders named ''PluginData'' for some odd, yet very convenient reason. Because KSP does not load the textures when they are in a folder called ''PluginData'' saving them there means that loading times are greatly reduced.
  
When you have filled this out, save it as ''YourPlanetName''.cfg. Go inside your '''Kopernicus''' folder, go into the '''Config''' folder, and you should see a config file that says '''System'''. Do not open that file under any circumstances. Inside the '''Config''' folder, make a new folder that says ''YourPlanetName''. Move ''YourPlanetName.cfg'', and your three texture files inside.<br />
+
It is then that a built-in Kopernicus feature called ''On-Demand Loading'' comes into play. O.D.L only loads textures of planets in view, and unloads textures of planets that have been out of the camera's view for a while. This saves a lot of RAM memory. However, O.D.L only works when a texture is both:
  
==== 3. Setting Up KittopiaTech ====
+
1. Saved in a folder called ''PluginData''.
(NOTE: The link included in the description does not include a '''SaveLoad''' folder.)
+
2. Assigned with the filetype extension added (IE the texture filepath ends with the filetype, for example .png, or .dds)
(This is only if you have a rocky or ocean planet.)Go inside your '''KittopiaTech''' Folder, and then into the '''SaveLoad''' folder, and make a new file in your text editor. Copy this code into it.
 
CODE:
 
Planet''YourPlanetName'' //In ''YourPlanetName'', put the name of your planet.
 
{
 
    AdditionalData  //Leave all of this false
 
    {
 
        Stock = False
 
        AddAtmoFx = False
 
        AddOceanFx = False
 
        OceanLoadTextures = False
 
        UnlitOcean = False
 
        ModScaledAtmoShader = False
 
        AddRings = False
 
        AddParticles = False
 
        DisableOrbitRenderer = False
 
    }
 
    PQS
 
    {
 
        PQSMod_HeightColorMap  //Leave this false
 
        {
 
            modEnabled = False
 
        }
 
        PQSCity  //Leave this false
 
        {
 
            modEnabled = False
 
        }
 
        PQSMod_VertexHeightMap
 
        {
 
            heightMap = GameData/Kopernicus/Config/  //Make this the location of your height map. Make sure you put GameData at the beginning, and to leave .dds on there.
 
            heightMapDeformity = 2500  //Basically determines the height of your mountains
 
            heightMapOffset = 0  //If your planet has oceans, set this to a negative number
 
            scaleDeformityByRadius = False
 
        }
 
        PQSMod_VertexColorMap
 
        {
 
            modEnabled = true
 
            vertexColorMap = GameData/Kopernicus/Config/  //Same as above, but make this the location of your color map.
 
        }
 
        PQSMod_VertexSimplexHeight  //Dont change any of this, except for the deformity
 
        {
 
            seed = 95374       
 
            deformity = 300
 
            octaves = 8       
 
            persistence = 0.5 
 
            frequency = 12
 
        }
 
        PQSMod_VertexSimplexHeightAbsolute  //Same as above
 
        {
 
            seed = 637926           
 
            deformity = 100 
 
            octaves = 3             
 
            persistence = 0.5
 
            frequency = 0.8
 
        }
 
        PQSMod_VertexSimplexHeightMap  //Leave this false
 
        {
 
            modEnabled = False
 
        }
 
        PQSMod_VertexHeightNoiseVertHeight  //Leave this false
 
        {
 
            modEnabled = False
 
        }
 
    }
 
}
 
Save this config file as ''YourPlanetName''.cfg in your SaveLoad folder. Now, put the Kopernicus and KittopiaTech folders inside GameData in your KSP directory.
 
  
=== Final Note ===
+
Lastly, there is the fact that the texture is saved as a DirectDrawSurface file. The reason for this is that DDS is the filetype used by the GPU, other types such as PNG and JPEG have to be converted first. This means that saving and loading DDS textures is faster than other filetypes. It is therefore recommended to use DDS as much as possible. Adobe Photoshop can pretty much do this out of the box, and for GIMP there is a free plugin that allows for DDS texture saving.
The only reason you need this last config file is so your planet can have a custom height. If you didnt have this, your planet would almost look like Tylo on a different scale. If you get a glitch where only one side of the planet is lit up, change the opacity of your normal map to 50%.
 
  
== Ocean Planets ==
+
=== Making a terrestrial world ===
=== Steps ===
 
1. Get your textures.<br />
 
  
2. DO THE SAME THING THAT YOU DID ABOVE!!!<br />
+
Making a terrestrial planet differs from gasplanets in one major way - the Procedural Quad Sphere.
  
3. Under the '''template''' section of your Kopernicus config, change it from Tylo to Laythe.<br />
+
So, let's do a little code revamp to change Tutora into a terrestrial world.
  
4. In the KittopiaTech config, under the '''PQS_VertexHeightMap''' section, change the '''heightMapOffset''' from 0 to a negative number, such as -1000.<br />
+
@Kopernicus:FOR[Tutora]
 +
{
 +
    Body
 +
    {
 +
        name = Tutora
 +
        Debug //Now we want both to be true.
 +
        {
 +
            exportMesh = true
 +
            update = true
 +
        }
 +
        Template
 +
        {
 +
            name = Dres
 +
            removeAllPQSMods = true //This strips the template of its PQSMods, meaning that it is essentially a clean slate for us to work with.
 +
        }
 +
        Properties
 +
        {
 +
            description = This stores the text that will be visible in-game in the info tab.
 +
            radius = 400000 //This CfgValue stores the radius of the planet (average distance from surface to center), 600km = 1 Kerbin radii. 400km = 2/3 Kerbin radii.
 +
            geeASL = 0.63    //With geeASL you can define the gravitational acceleration at the surface, expressed in g's (IE the amount of times Earth's gravity. 9.81 m*s^-2 = 1g)
 +
        }
 +
        Orbit
 +
        {
 +
            semiMajorAxis = 5000000000 //Nothing too fancy. We basically clone Dres' orbit but with a different average distance.
 +
        }
 +
        //Dres does not have an atmosphere, so let's remove the atmosphere node for now.
 +
        //Note: you can add an atmosphere to a vacuum template, that's not an issue at all.
 +
        PQS //We access the quad sphere module
 +
        {
 +
            Mods //We access the PQSMods - the mods are what shape the surface
 +
            {
 +
                VertexSimplexHeightAbsolute
 +
                {
 +
                    deformity = 250 //The amount of meters that this noise mod should affect the terrain
 +
                    frequency = 25 //The greater this number, the smaller the noise is
 +
                    octaves = 3 //The greater this number, the prettier the result, but also the more costly it is
 +
                    persistence = 0.3 //This subdivides the noise a little bit. Be careful with setting this value
 +
                    seed = 28396 //Just enter a random number here
 +
                    enabled = true //Should this mod be taken into consideration when building the terrain?
 +
                    order = 10 //The order in which this mod is applied. The lower the 'order', the sooner the mod is applied.
 +
                }
 +
                VertexSimplexNoiseColor
 +
                {
 +
                    blend = 1 //Between 0-1, the amount of control this color mod has over the terrain
 +
                    colorStart = 0.4,0.4,0.4,1 //Color A
 +
                    colorEnd = 0.8,0.6,0.2,1 //Color B
 +
                    //The below values generate a Simplex noise that linearly interpolates between colors A and B.
 +
                    frequency = 6
 +
                    octaves = 8
 +
                    persistence = 0.3
 +
                    seed = 90135
 +
                    enabled = true
 +
                    order = 500
 +
                }
 +
            }
 +
        }
 +
    }
 +
}
  
5. In your height map, paint all of the areas where you want your water to be pitch black, so the RGB amount reads 0,0,0
+
Although the planet generated with the below code may not look that aesthetically pleasing, it will in fact work, which is the point I'm trying to demonstrate here. Planets do not require maps to work, and neither do they need maps to look good, as demonstrated by [https://forum.kerbalspaceprogram.com/index.php?/topic/120111-131kopernicus-uncharted-lands-v054-26dec17/ this] planet pack.
  
=== Final Note ===
+
So for the main part, editing planets comes down to knowledge of PQSMods, or image editor skills.
You still need both config files for an ocean planet. Be careful with the '''heightMapOffset''', if you make it too low, like -5000, it will flood your planet.
 
  
== Gas Giants ==
+
=== Config Value List ===
=== Steps ===
 
  
==== 1. Get Your Textures ====
+
Below is an extensive list of values for each Config Node
This will be the same as above, except you only need a color texture.
 
  
==== 2. Make Your Planet Folder ====
+
''Legend''
Do the same thing as above where you make the folder that will hold your planet.
+
*string    A string of text
 +
*path      A filepath (usually with the filetype extension)
 +
*integer  A whole number
 +
*float    A number with decimals
 +
*bool      Either 'true' or 'false'
  
==== 3. Set up config ====
+
''Body {}''
Make a new text file and copy this into it.
+
Placement: the Body node goes inside the ''@Kopernicus {}'' node.
CODE:
+
*name - string - Controls the name of the planet.
@Kopernicus  
+
*cacheFile - path - Controls the location where Kopernicus generates a cache file for this planet. X should be a filepath ending in a name, with the .bin extension added at the end.
{
+
*flightGlobalsIndex - integer - FlightGlobalsIndex is used for the orbit of crafts in the save files. In a KSP safe file, what planet a craft is orbiting is identified by the FlightGlobalsIndex. It is recommended that you set this to a value (which has to be a unique number, a number not shared by any planet in any planet pack), or leave it out entirely, in which case Kopernicus will assign it a F.G.I depending on the order of the planet in the solar system, from the Sun outward. Leaving it out is best for compatibility with other planet packs, but this means that adding a non-indexed planet to an already-in-progress save file could make crafts shift orbits.
    Body
 
    {
 
        name =
 
        flightGlobalsIndex = //Change this to any number, just not too big.  
 
        Template
 
        {
 
            name = Jool  //Jool is the main template for a gas giant.             
 
        }
 
        Properties
 
        {
 
            radius =  //Distance in meters from the surface to the core.                                 
 
            geeASL =      //Amount of gravity your planet has. Kerbin is 1.                                
 
            mass =  //The mass is not important.                     
 
            description =  //The description of your planet.
 
            ScienceValues //The amount of science you will get around your planet.                                   
 
            {
 
                landedDataValue = 100
 
                splashedDataValue = 0
 
                flyingLowDataValue = 0
 
                flyingHighDataValue = 0
 
                inSpaceLowDataValue = 40
 
                inSpaceHighDataValue = 30
 
                recoveryValue = 5
 
            }
 
        }
 
        Orbit
 
        {
 
            referenceBody = Sun  //Body where your planet will orbit. Do NOT change to Kerbol, it is the Sun in game.
 
            inclination =  //Self-explanatory         
 
            eccentricity =  //Self-explanatory         
 
            semiMajorAxis =  //Distance from the parent body in meters.
 
            longitudeOfAscendingNode = 0 //Leave the next four as zero.
 
            argumentOfPeriapsis = 0
 
            meanAnomalyAtEpoch = 0
 
            epoch = 0
 
            color = RGB value of your orbit. Divide each number by 255, and put a fourth 1 so you can see it. Ex: 0, 0, 0, 1 is black.
 
        }
 
        ScaledVersion
 
        {
 
            Material
 
            {   
 
                texture = Kopernicus/Config/  //Make this the location of your ''YourPlanetName''_Color. Do NOT include .dds.
 
            }
 
        }
 
    }
 
}
 
Save this file as ''YourPlanetName''.cfg, and move it into your planet's folder, along with the texture. Move the Kopernicus folder into your GameData and you are done!
 
  
=== Final Note ===
+
''Properties {}''
Making a gas giant is the one of the easiest planets you can make. You only need one texture file, and you do not need a separate KittopiaTech config.
+
Placement: the Properties node goes inside the ''Node {}'' node.
 +
*description - string - The text assigned to this Config Value shows up in-game in the info tab.
 +
*radius - integer - The radius of the planet in meters.
 +
    Use one of these three to set the gravity of a planet:
 +
*geeASL - float - The surface gravity in G's.
 +
*mass - float - The mass of the planet in kilograms.
 +
*gravParameter - float - The gravitational parameter is the mass times the gravitational constant. (G = 6.6741*10^-11)
  
== Finishing Word ==
+
*rotates - bool - If true, the planet rotates. If false, it does not rotate.
With this tutorial, anyone should be able to create their own planets, to land on and collect science from. With a little more expirience, it is possible to actually make your planets into a mod.
+
*rotationPeriod - float - The rotation period of the planet in seconds
 +
*tidallyLocked - bool - If true, the planet's rotation period is set equal to the planet's orbital period. Essentially this will make an object always display the same face when viewed from its parent planet/sun, much like our moon does.
 +
*initialRotation - float - Can be used to offset the planet's rotation at t = 0 (the start of a new save file)
 +
*albedo - float - Albedo controls the amount of incoming radiation reflected by an object. [https://en.wikipedia.org/wiki/Albedo Here is an article on the albedo-effect].
 +
*timewarpAltitudeLimits - 8 floats - The altitudes at which timewarp speeds are unlocked. This should have zero as the first number, followed by seven others, separated with a space. (Not a comma)
 +
*biomeMap - path - The filepath to the biome map of the planet
 +
*displayName - string - This value controls the external name of the planet, IE the name seen in-game. Internally it does not change the planet's name.
 +
 
 +
''Biomes {}''
 +
Placement: the Biomes node goes inside the ''Properties {}'' node.
 +
Note: There should be multiple ''Biome {}'' nodes inside the ''Biome {}'' node, each corresponding to a biome on the biomeMap. Here is the syntax for one such node.
 +
 
 +
    Biome
 +
    {
 +
        name = X //String, this should be the name you want the biome to wear in-game
 +
        value = X //Float, you can use this to increase/decrease the science multipliers for this biome
 +
        color = X //Color, should be set to the color on the biome map representing this color
 +
    }
  
=== Important Note ===
+
[[Category:Tutorials| ]]
If anyone could tell me if it is possible to make other stars with Kopernicus, that would be greatly appreciated.
 

Revision as of 18:36, 16 April 2018

Creating Your Own Planets

This tutorial is designed for those with a relentless, creative spirit. Those seeking a way to vent said creativity will be delighted to learn that, with the Kopernicus plugin's existence, it is now possible to modify the planetary system in Kerbal Space Program, allowing for new planets to be added and existing planets to be modified or removed entirely.

Specifications

  • Length: 15-20 minutes
  • Difficulty: Advanced
  • For Version: 1.3.X (Planets will work in 1.4, but the map exporter won't, so we'll be using 1.3 for this tutorial)

Requirements

  • Kopernicus
  • KittopiaTech
  • A text editor. Notepad can do the job, but Notepad++ is highly recommended.
  • (No, you do not need textures or image editors of any kind. In fact, if you're going to be advising SpaceEngine, I'm glaring at you.)
  • The only objects that require the use of image editors and such are gas planets and stars. Terrestrial planets do not require textures to function.

Config Files

The first step when making planets is knowing the basics of config files. Let's start by creating one! For Notepad users, simply open up Notepad, then head to File -> Save As. Navigate to a location that you will be creating your mod at. Recommended is to create a folder for your mod somewhere (your desktop, for example) and using that folder to store all of your planet pack's data. We'll go over organizing said data later, for now, let's focus on not cluttering the hard drive and storing all mod info in a similar location.

Once you have settled on a nice saving location, write the name of your planet and remove the .txt as we will not be saving in this format. Add .cfg behind it, and select All Files in the drop-down menu following Save as type

For this tutorial, we will be making a planet called Tutora. So, in this case, we would write Tutora.cfg. The file name is actually not that important, but it's recommended to name config files properly so that you know just from the name what it contains.

Now we should have a .cfg file. Let's get to editing it!

Firstly, there are two kinds of config entries that you must memorize. The first is called a 'Config Node'. These appear as follows:

Orbit { ... }

As you can see, the name of the node is followed up by an opening bracket, which is in turn followed up by the node's contents, then lastly - and this is very, very important - the closing bracket. (Notepad++ automatically highlights opening and closing bracket pairs, which is why it is pretty much industry standard when making planets.)

The other kind of config entry is called a 'Config Value', and these appear as follows:

semiMajorAxis = 19000000

As you can see, a config value is always in the format of 'X = Y', where X is the name of the Config Value and Y is the data assigned to it. Y can be many different kinds of data, for example a line of text (a 'string', as it is called in programming languages), a whole number (also known as an integer), or a number with decimals (also known as a 'float' or a 'double', depending on the situation).

Making planets is largely the product of simply placing the correctly named nodes in the right locations, and supplying the right config values with the right data.

Module Manager Syntax

Contrary to what some might expect, we are not actually writing a piece of code for Kopernicus. Rather, Kopernicus internally has a config file, which we will be altering - and this is very important - indirectly. We will be using the 'Module Manager' plugin to patch Kopernicus' config file instead. This way, users can add and remove planet packs at will without having to go into the config files and swapping things out manually.

Although writing configs largely comes down to Nodes and Values, there are several handy commands that you can leave in your code for ModuleManager to use.

Let's go over a few.

@Orbit { ... }

The @ operator means 'edit'. In the above example, instead of declaring a node named 'Orbit', we are instead telling Module Manager to patch an already existing Orbit node. Note that this will not randomly edit an Orbit node - only one in the exact same location, in another file. (IE the parent nodes of the node marked for editing must match those of the target node in terms of name)

!Orbit {}

The ! operator differs in use. In the above example, we tell Module Manager to remove the Orbit node. We do not need to specify anything in the brackets, just add them to inform Module Manager that we are targeting a NODE, not a VALUE. Another case for the ! operator is conditioning:

@Kopernicus:NEEDS[!OPM] { .. }

Above, you can see that we edit the 'Kopernicus' node. However, we have added the 'NEEDS' condition to it. The above code, when translated to English, basically means:

Edit the config node Kopernicus with the below changes, BUT only do so if the tag named OPM is NOT present.

Note that 'not' is written in capital letters. This is because I would like to draw your attention to that word. Rather, the fact that, if we were to remove the ! operator from the above code example, we would have to remove the 'NOT' word in the translation. Ergo:

NEEDS[OPM] = only patch when the tag 'OPM' is present
NEEDS[!OPM] = only patch when the tag 'OPM' is NOT present

But what are these 'tags' that I have mentioned thrice thus far? Tags can be targeted by Module Manager conditions, and can be declared in many ways: - Folders directly inside the GameData folder of your KSP directory can be targeted as a tag. - Tags can be declared with the :FOR[X] condition, where X is the name of the tag

And that brings us to the next condition: FOR.

@Kopernicus:FOR[Bob] { ... }

FOR on it's own does not do anything, it is merely a marker for other conditions, namely BEFORE, AFTER and NEEDS. Let's call the config file containing the above node 'File A'. In that case, making config edits with conditions will have the following effects:

BEFORE[Bob] = The patch is applied before the patch declared in File A (which is marked as 'FOR[Bob]', remember!) is applied.
NEEDS[Bob] = The patch is only applied if File A (or another file declaring the tag Bob through the use of FOR) is present.
NEEDS[!Bob] = The patch is only applied if the tag 'Bob' is not declared anywhere.
AFTER[Bob] = The patch is applied after the patch declared in File A (or any other file declaring the tag Bob through the use of FOR)

And lastly, a more advanced condition, especially handy when editing a specific node of which there are multiple.

!Atmo:HAS[#name[Duna]]{} (Taken from here with lots of thanks.)

As you can see, we are removing the config node named 'Atmo', but we have the HAS condition preventing the deletion of every single node named 'Atmo'. The HAS condition limits the effect of a patch to config nodes that meet the declared condition. In the above example, each Atmo node is checked if it contains a Config Value named 'name', with an assigned value of 'Duna'.

Planetary Nodes

Before we start making planets, let's go over the config structure.

The first thing that we want to do is edit the Kopernicus Config Node. So let's open up the config we made earlier. Remember that we will be making a planet called Tutora.

@Kopernicus:FOR[Tutora] { }

The observant among you have noticed that we are declaring this config with the tag 'Tutora'. This means that we can specify a loading order for config files (should we need this later) by marking patches with AFTER, BEFORE, and NEEDS.

Every celestial body has its data stored in a node called 'Body'. There can be multiple Body nodes per config, but only one planet per Body node.

Let's add the Body node to the above start.

@Kopernicus:FOR[Tutora] {

   Body
   {
       name = Tutora
   }

}

I have also added the 'name' Config Value real quick. The 'name' Config value declares the name that the celestial body will wear, both internally and in-game (unless otherwise specified).

Inside the Body node of Tutora, we can add a variety of Config Nodes. Let's go over a few.

Debug {} Debug stores data for debugging planets, for example whether or not we want Kopernicus to generate a cache file.

Properties {} Properties stores most of our planet's physical properties (mass, radius, gravitational acceleration, rotation period, whether or not our planet is tidally locked, et cetera) as well as some miscellaneous items such as the in-game description, the science multipliers, and the timewarp altitude limiters.

Orbit {} Orbit stores the data related to the planet's placement within the Kerbal universe, or rather, the path that it will follow through said universe.

Template {} Template allows you to clone a stock planet. If you choose a template, anything you declare in your config will be applied as a patch to a copy of that template's config file. Note: you are not altering the stock planet itself, rather Kopernicus clones it and applies the data you specified to that clone. Using a template is highly recommended. In the Template node, you can also do some rather interesting things, such as removing PQSMods from the template planet (we'll go over what in the world PQSMods are later), removing the ocean of the clone, or removing the atmosphere of the cloned planet.

Atmosphere {} Atmosphere stores all of the information regarding a planet's atmosphere. Not just the altitude limiter, but also physical and chemical properties such as the adiabatic index (used for calculating the speed of sound), the molar mass (used for calculating the density), the temperature-height profile, and many other things.

Ocean {} The Ocean node stores all data regarding a planet's oceans. If a planet's configuration does not contain an Ocean node, it will not have oceans.

ScaledVersion {} Because keeping an entire planet loaded is rather taxing, KSP cleverly unloads the planet should the camera go too far from the planet, and instead will load in a relatively low-poly representation. Through ScaledVersion we can edit this representation. Essentially, ScaledVersion is in charge of making our planet look good from afar (such as in the Map View)

PQS {} PQS stands for Procedural Quad Sphere, and is the kind of terrain KSP uses for its planetary surfaces. The PQS node contains all of the data regarding our planet's actual terrain. It is therefore, in essence, the counterpart to ScaledVersion. Note that non-terrestrial objects such as Jool and the Sun lack the PQS node and thus a Quad Sphere, which is why they have no solid surface.

Making a Gas Giant

Now that we have the above cleared up regarding Config Nodes, we can select the Config Nodes that we will be needing, as well as a template.

Let's use Jool.

@Kopernicus:FOR[Tutora] {

   Body
   {
       name = Tutora
       Debug //We want to add some changes here.
       {
           exportMesh = false //Setting this to false means that no cache file is generated.
           //Since a gasplanet has no solid surface, we don't need the cache file, as there is no PQS to store there.
           update = true //We do want the planet to be updated though.
       }
       Template
       {
           name = Jool
           //Besides picking a template there isn't anything else to do here. We don't need to remove anything else.
       }
       Properties
       {
           description = This stores the text that will be visible in-game in the info tab.
           radius = 4000000 //This CfgValue stores the radius of the planet (average distance from surface to center), 6000km = 1 Jool radii. 4000km = 2/3 Jool radii.
           geeASL = 0.63    //With geeASL you can define the gravitational acceleration at the surface, expressed in g's (IE the amount of times Earth's gravity. 9.81 m*s^-2 = 1g)
       }
       Orbit
       {
           semiMajorAxis = 5000000000 //Nothing too fancy. We basically clone Jool's orbit but with a different average distance.
       }
       Atmosphere //Let's access the atmosphere
       {
           ambientColor = 0.7,0.5,0.1,1 //Ambient color provides a slight tint to any craft inside the atmosphere, with the tint intensity increasing with depth
           lightColor = 0.37,0.47,0.62,1 //Light color is somewhat strange, for some reason the lower the intensity of a color, the more prominent that color is.
           //Pro tip: adjust lightColor in-game with KittopiaTech.
       }
       ScaledVersion //Gas planets are only the scaledspace mesh
       {
           Material //The Material subnode is where we actually alter the appearance of the ScaledSpace mesh
           {
               texture = Tutorial/PluginData/Tutora_c.dds //Here we assign a new texture to the sphere.
           }
       }
   }

}

I would like to draw your attention to the line texture = Tutorial/PluginData/Tutora_c.dds, because there is a reason why the texture is placed in a folder called 'PluginData', why it is in the DirectDrawSurface format, and why the filetype extension is included in the filepath.

Saving a texture in a folder called PluginData prevents KSP from loading it. This is because KSP does not check in folders named PluginData for some odd, yet very convenient reason. Because KSP does not load the textures when they are in a folder called PluginData saving them there means that loading times are greatly reduced.

It is then that a built-in Kopernicus feature called On-Demand Loading comes into play. O.D.L only loads textures of planets in view, and unloads textures of planets that have been out of the camera's view for a while. This saves a lot of RAM memory. However, O.D.L only works when a texture is both:

1. Saved in a folder called PluginData. 2. Assigned with the filetype extension added (IE the texture filepath ends with the filetype, for example .png, or .dds)

Lastly, there is the fact that the texture is saved as a DirectDrawSurface file. The reason for this is that DDS is the filetype used by the GPU, other types such as PNG and JPEG have to be converted first. This means that saving and loading DDS textures is faster than other filetypes. It is therefore recommended to use DDS as much as possible. Adobe Photoshop can pretty much do this out of the box, and for GIMP there is a free plugin that allows for DDS texture saving.

Making a terrestrial world

Making a terrestrial planet differs from gasplanets in one major way - the Procedural Quad Sphere.

So, let's do a little code revamp to change Tutora into a terrestrial world.

@Kopernicus:FOR[Tutora] {

   Body
   {
       name = Tutora
       Debug //Now we want both to be true.
       {
           exportMesh = true
           update = true
       }
       Template
       {
           name = Dres
           removeAllPQSMods = true //This strips the template of its PQSMods, meaning that it is essentially a clean slate for us to work with.
       }
       Properties
       {
           description = This stores the text that will be visible in-game in the info tab.
           radius = 400000 //This CfgValue stores the radius of the planet (average distance from surface to center), 600km = 1 Kerbin radii. 400km = 2/3 Kerbin radii.
           geeASL = 0.63    //With geeASL you can define the gravitational acceleration at the surface, expressed in g's (IE the amount of times Earth's gravity. 9.81 m*s^-2 = 1g)
       }
       Orbit
       {
           semiMajorAxis = 5000000000 //Nothing too fancy. We basically clone Dres' orbit but with a different average distance.
       }
       //Dres does not have an atmosphere, so let's remove the atmosphere node for now.
       //Note: you can add an atmosphere to a vacuum template, that's not an issue at all.
       PQS //We access the quad sphere module
       {
           Mods //We access the PQSMods - the mods are what shape the surface
           {
               VertexSimplexHeightAbsolute
               {
                   deformity = 250 //The amount of meters that this noise mod should affect the terrain
                   frequency = 25 //The greater this number, the smaller the noise is
                   octaves = 3 //The greater this number, the prettier the result, but also the more costly it is
                   persistence = 0.3 //This subdivides the noise a little bit. Be careful with setting this value
                   seed = 28396 //Just enter a random number here
                   enabled = true //Should this mod be taken into consideration when building the terrain?
                   order = 10 //The order in which this mod is applied. The lower the 'order', the sooner the mod is applied.
               }
               VertexSimplexNoiseColor
               {
                   blend = 1 //Between 0-1, the amount of control this color mod has over the terrain
                   colorStart = 0.4,0.4,0.4,1 //Color A
                   colorEnd = 0.8,0.6,0.2,1 //Color B
                   //The below values generate a Simplex noise that linearly interpolates between colors A and B.
                   frequency = 6
                   octaves = 8
                   persistence = 0.3
                   seed = 90135
                   enabled = true
                   order = 500
               }
           }
       }
   }

}

Although the planet generated with the below code may not look that aesthetically pleasing, it will in fact work, which is the point I'm trying to demonstrate here. Planets do not require maps to work, and neither do they need maps to look good, as demonstrated by this planet pack.

So for the main part, editing planets comes down to knowledge of PQSMods, or image editor skills.

Config Value List

Below is an extensive list of values for each Config Node

Legend

  • string A string of text
  • path A filepath (usually with the filetype extension)
  • integer A whole number
  • float A number with decimals
  • bool Either 'true' or 'false'

Body {} Placement: the Body node goes inside the @Kopernicus {} node.

  • name - string - Controls the name of the planet.
  • cacheFile - path - Controls the location where Kopernicus generates a cache file for this planet. X should be a filepath ending in a name, with the .bin extension added at the end.
  • flightGlobalsIndex - integer - FlightGlobalsIndex is used for the orbit of crafts in the save files. In a KSP safe file, what planet a craft is orbiting is identified by the FlightGlobalsIndex. It is recommended that you set this to a value (which has to be a unique number, a number not shared by any planet in any planet pack), or leave it out entirely, in which case Kopernicus will assign it a F.G.I depending on the order of the planet in the solar system, from the Sun outward. Leaving it out is best for compatibility with other planet packs, but this means that adding a non-indexed planet to an already-in-progress save file could make crafts shift orbits.

Properties {} Placement: the Properties node goes inside the Node {} node.

  • description - string - The text assigned to this Config Value shows up in-game in the info tab.
  • radius - integer - The radius of the planet in meters.
   Use one of these three to set the gravity of a planet:
  • geeASL - float - The surface gravity in G's.
  • mass - float - The mass of the planet in kilograms.
  • gravParameter - float - The gravitational parameter is the mass times the gravitational constant. (G = 6.6741*10^-11)
  • rotates - bool - If true, the planet rotates. If false, it does not rotate.
  • rotationPeriod - float - The rotation period of the planet in seconds
  • tidallyLocked - bool - If true, the planet's rotation period is set equal to the planet's orbital period. Essentially this will make an object always display the same face when viewed from its parent planet/sun, much like our moon does.
  • initialRotation - float - Can be used to offset the planet's rotation at t = 0 (the start of a new save file)
  • albedo - float - Albedo controls the amount of incoming radiation reflected by an object. Here is an article on the albedo-effect.
  • timewarpAltitudeLimits - 8 floats - The altitudes at which timewarp speeds are unlocked. This should have zero as the first number, followed by seven others, separated with a space. (Not a comma)
  • biomeMap - path - The filepath to the biome map of the planet
  • displayName - string - This value controls the external name of the planet, IE the name seen in-game. Internally it does not change the planet's name.

Biomes {} Placement: the Biomes node goes inside the Properties {} node. Note: There should be multiple Biome {} nodes inside the Biome {} node, each corresponding to a biome on the biomeMap. Here is the syntax for one such node.

   Biome
   {
       name = X //String, this should be the name you want the biome to wear in-game
       value = X //Float, you can use this to increase/decrease the science multipliers for this biome
       color = X //Color, should be set to the color on the biome map representing this color
   }