{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "Celestial Body Schema",
  "type": "object",
  "description": "Describes a body to generate",
  "additionalProperties": false,
  "required": [
    "name"
  ],
  "properties": {
    "AsteroidBelt": {
      "description": "Generate asteroids around this body",
      "$ref": "#/definitions/AsteroidBeltModule"
    },
    "Atmosphere": {
      "description": "Describes this Body's atmosphere",
      "$ref": "#/definitions/AtmosphereModule"
    },
    "Base": {
      "description": "Base Properties of this Body",
      "$ref": "#/definitions/BaseModule"
    },
    "Bramble": {
      "description": "Add bramble nodes to this planet and/or make this planet a bramble dimension",
      "$ref": "#/definitions/BrambleModule"
    },
    "buildPriority": {
      "type": "integer",
      "description": "Set to a higher number if you wish for this body to be built sooner",
      "format": "int32",
      "default": -1
    },
    "canShowOnTitle": {
      "type": "boolean",
      "description": "Should this planet ever be shown on the title screen?"
    },
    "Cloak": {
      "description": "Add a cloaking field to this planet",
      "$ref": "#/definitions/CloakModule"
    },
    "destroy": {
      "type": "boolean",
      "description": "`true` if you want to delete this planet"
    },
    "FocalPoint": {
      "description": "Make this body into a focal point (barycenter)",
      "$ref": "#/definitions/FocalPointModule"
    },
    "Funnel": {
      "description": "Add funnel from this planet to another",
      "$ref": "#/definitions/FunnelModule"
    },
    "HeightMap": {
      "description": "Generate the surface of this planet using a heightmap",
      "$ref": "#/definitions/HeightMapModule"
    },
    "isQuantumState": {
      "type": "boolean",
      "description": "Does this config describe a quantum state of a custom planet defined in another file?"
    },
    "Lava": {
      "description": "Add lava to this planet",
      "$ref": "#/definitions/LavaModule"
    },
    "name": {
      "type": "string",
      "description": "Unique name of your planet",
      "minLength": 1
    },
    "Orbit": {
      "description": "Describes this Body's orbit (or lack there of)",
      "$ref": "#/definitions/OrbitModule"
    },
    "ProcGen": {
      "description": "Procedural Generation",
      "$ref": "#/definitions/ProcGenModule"
    },
    "Props": {
      "description": "Spawn various objects on this body",
      "$ref": "#/definitions/PropModule"
    },
    "ReferenceFrame": {
      "description": "Reference frame properties of this body",
      "$ref": "#/definitions/ReferenceFrameModule"
    },
    "removeChildren": {
      "type": "array",
      "description": "A list of paths to child GameObjects to destroy on this planet",
      "items": {
        "type": "string"
      }
    },
    "Ring": {
      "description": "Creates a ring around the planet",
      "$ref": "#/definitions/RingModule"
    },
    "Sand": {
      "description": "Add sand to this planet",
      "$ref": "#/definitions/SandModule"
    },
    "ShipLog": {
      "description": "Add ship log entries to this planet and describe how it looks in map mode",
      "$ref": "#/definitions/ShipLogModule"
    },
    "Spawn": {
      "description": "Spawn the player at this planet",
      "$ref": "#/definitions/SpawnModule"
    },
    "Star": {
      "description": "Make this body a star",
      "$ref": "#/definitions/StarModule"
    },
    "starSystem": {
      "type": "string",
      "description": "Unique star system containing your planet",
      "default": "SolarSystem"
    },
    "version": {
      "type": "string",
      "description": "Version of New Horizons this config is using (Doesn't do anything)"
    },
    "Water": {
      "description": "Add water to this planet",
      "$ref": "#/definitions/WaterModule"
    },
    "$schema": {
      "type": "string",
      "description": "The schema to validate with"
    }
  },
  "definitions": {
    "AsteroidBeltModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "amount": {
          "type": "integer",
          "description": "Amount of asteroids to create.",
          "format": "int32",
          "default": -1,
          "maximum": 200.0,
          "minimum": -1.0
        },
        "inclination": {
          "type": "number",
          "description": "Angle between the rings and the equatorial plane of the planet.",
          "format": "float"
        },
        "innerRadius": {
          "type": "number",
          "description": "Lowest distance from the planet asteroids can spawn",
          "format": "float",
          "minimum": 0.0
        },
        "longitudeOfAscendingNode": {
          "type": "number",
          "description": "Angle defining the point where the rings rise up from the planet's equatorial plane if inclination is nonzero.",
          "format": "float"
        },
        "maxSize": {
          "type": "number",
          "description": "Maximum size of the asteroids.",
          "format": "float",
          "default": 50,
          "minimum": 0.0
        },
        "minSize": {
          "type": "number",
          "description": "Minimum size of the asteroids.",
          "format": "float",
          "default": 20,
          "minimum": 0.0
        },
        "outerRadius": {
          "type": "number",
          "description": "Greatest distance from the planet asteroids can spawn",
          "format": "float",
          "minimum": 0.0
        },
        "procGen": {
          "description": "How the asteroids are generated",
          "$ref": "#/definitions/ProcGenModule"
        },
        "randomSeed": {
          "type": "integer",
          "description": "Number used to randomize asteroid positions",
          "format": "int32"
        }
      }
    },
    "ProcGenModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "color": {
          "$ref": "#/definitions/MColor"
        },
        "scale": {
          "type": "number",
          "format": "float",
          "minimum": 0.0
        }
      }
    },
    "MColor": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "r": {
          "type": "integer",
          "description": "The red component of this colour",
          "format": "int32",
          "maximum": 2147483647.0,
          "minimum": 0.0
        },
        "g": {
          "type": "integer",
          "description": "The green component of this colour",
          "format": "int32",
          "maximum": 2147483647.0,
          "minimum": 0.0
        },
        "b": {
          "type": "integer",
          "description": "The blue component of this colour",
          "format": "int32",
          "maximum": 2147483647.0,
          "minimum": 0.0
        },
        "a": {
          "type": "integer",
          "description": "The alpha (opacity) component of this colour",
          "format": "int32",
          "default": 255,
          "maximum": 255.0,
          "minimum": 0.0
        }
      }
    },
    "AtmosphereModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "atmosphereTint": {
          "description": "Colour of atmospheric shader on the planet.",
          "$ref": "#/definitions/MColor"
        },
        "atmosphereSunIntensity": {
          "type": "number",
          "description": "How intense should the sun appear in the sky.\nAlso affects general atmosphere brightness.\nDefault value of 1 matches Timber Hearth.\nIf not set, this will be determined based off the distance to the sun.",
          "format": "float",
          "minimum": 0.0
        },
        "clouds": {
          "description": "Describes the clouds in the atmosphere",
          "$ref": "#/definitions/CloudInfo"
        },
        "fogDensity": {
          "type": "number",
          "description": "How dense the fog is, if you put fog.",
          "format": "float",
          "maximum": 1.0,
          "minimum": 0.0
        },
        "fogSize": {
          "type": "number",
          "description": "Radius of fog sphere, independent of the atmosphere. This has to be set for there to be fog.",
          "format": "float",
          "minimum": 0.0
        },
        "fogTint": {
          "description": "Colour of fog on the planet, if you put fog.",
          "$ref": "#/definitions/MColor"
        },
        "hasOxygen": {
          "type": "boolean",
          "description": "Lets you survive on the planet without a suit."
        },
        "hasRain": {
          "type": "boolean",
          "description": "Does this planet have rain?"
        },
        "hasSnow": {
          "type": "boolean",
          "description": "Does this planet have snow?"
        },
        "size": {
          "type": "number",
          "description": "Scale height of the atmosphere",
          "format": "float"
        },
        "useAtmosphereShader": {
          "type": "boolean",
          "description": "Whether we use an atmospheric shader on the planet. Doesn't affect clouds, fog, rain, snow, oxygen, etc. Purely\nvisual."
        },
        "minShockSpeed": {
          "type": "number",
          "description": "Minimum speed that your ship can go in the atmosphere where flames will appear.",
          "format": "float",
          "default": 100.0
        },
        "maxShockSpeed": {
          "type": "number",
          "description": "Maximum speed that your ship can go in the atmosphere where flames will appear at their brightest.",
          "format": "float",
          "default": 300.0
        }
      }
    },
    "CloudInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "cloudsPrefab": {
          "description": "Should these clouds be based on Giant's Deep's banded clouds, or the Quantum Moon's non-banded clouds?",
          "$ref": "#/definitions/CloudPrefabType"
        },
        "capPath": {
          "type": "string",
          "description": "Relative filepath to the cloud cap texture, if the planet has clouds."
        },
        "fluidType": {
          "description": "Fluid type for sounds/effects when colliding with this cloud.",
          "default": "cloud",
          "$ref": "#/definitions/CloudFluidType"
        },
        "hasLightning": {
          "type": "boolean",
          "description": "Add lightning to this planet like on Giant's Deep."
        },
        "innerCloudRadius": {
          "type": "number",
          "description": "Radius from the center to the inner layer of the clouds.",
          "format": "float"
        },
        "lightningGradient": {
          "type": "array",
          "description": "Colour gradient of the lightning, time is in seconds.",
          "items": {
            "$ref": "#/definitions/MGradient"
          }
        },
        "outerCloudRadius": {
          "type": "number",
          "description": "Radius from the center to the outer layer of the clouds.",
          "format": "float"
        },
        "rampPath": {
          "type": "string",
          "description": "Relative filepath to the cloud ramp texture, if the planet has clouds. If you don't put anything here it will be\nauto-generated."
        },
        "texturePath": {
          "type": "string",
          "description": "Relative filepath to the cloud texture, if the planet has clouds."
        },
        "tint": {
          "description": "Colour of the inner cloud layer.",
          "$ref": "#/definitions/MColor"
        },
        "unlit": {
          "type": "boolean",
          "description": "If the top layer shouldn't have shadows. Set to true if you're making a brown dwarf for example."
        },
        "rotationSpeed": {
          "type": "number",
          "description": "How fast the clouds will rotate in degrees per second.",
          "format": "float",
          "default": 10.0
        }
      }
    },
    "CloudPrefabType": {
      "type": "string",
      "description": "",
      "x-enumNames": [
        "GiantsDeep",
        "QuantumMoon",
        "Basic"
      ],
      "enum": [
        "giantsDeep",
        "quantumMoon",
        "basic"
      ]
    },
    "CloudFluidType": {
      "type": "string",
      "description": "",
      "x-enumNames": [
        "None",
        "Water",
        "Cloud",
        "Sand",
        "Plasma"
      ],
      "enum": [
        "none",
        "water",
        "cloud",
        "sand",
        "plasma"
      ]
    },
    "MGradient": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "time": {
          "type": "number",
          "format": "float"
        },
        "tint": {
          "$ref": "#/definitions/MColor"
        }
      }
    },
    "BaseModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "ambientLight": {
          "type": "number",
          "description": "The intensity of light the dark side of the body should have. Timber Hearth has `1.4` for reference",
          "format": "float"
        },
        "centerOfSolarSystem": {
          "type": "boolean",
          "description": "Set this to true if you are replacing the sun with a different body. Only one object in a star system should ever\nhave this set to true."
        },
        "cometTailRotation": {
          "description": "If it has a comet tail, it'll be oriented according to these Euler angles.",
          "$ref": "#/definitions/MVector3"
        },
        "gravityFallOff": {
          "description": "How gravity falls off with distance. Most planets use linear but the sun and some moons use inverseSquared.",
          "default": "linear",
          "$ref": "#/definitions/GravityFallOff"
        },
        "groundSize": {
          "type": "number",
          "description": "Radius of a simple sphere used as the ground for the planet. If you want to use more complex terrain, leave this as\n0.",
          "format": "float"
        },
        "hasCometTail": {
          "type": "boolean",
          "description": "If you want the body to have a tail like the Interloper."
        },
        "hasMapMarker": {
          "type": "boolean",
          "description": "If the body should have a marker on the map screen."
        },
        "invulnerableToSun": {
          "type": "boolean",
          "description": "Can this planet survive entering a star?"
        },
        "showMinimap": {
          "type": "boolean",
          "description": "Do we show the minimap when walking around this planet?",
          "default": true
        },
        "soiOverride": {
          "type": "number",
          "description": "An override for the radius of the planet's gravitational sphere of influence. Optional",
          "format": "float"
        },
        "surfaceGravity": {
          "type": "number",
          "description": "The acceleration due to gravity felt as the surfaceSize. Timber Hearth has 12 for reference",
          "format": "float"
        },
        "surfaceSize": {
          "type": "number",
          "description": "A scale height used for a number of things. Should be the approximate radius of the body.",
          "format": "float"
        },
        "zeroGravityRadius": {
          "type": "number",
          "description": "Radius of the zero gravity volume. This will make it so no gravity from any planet will affect you. Useful for satellites.",
          "format": "float"
        }
      }
    },
    "MVector3": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "x": {
          "type": "number",
          "format": "float"
        },
        "y": {
          "type": "number",
          "format": "float"
        },
        "z": {
          "type": "number",
          "format": "float"
        }
      }
    },
    "GravityFallOff": {
      "type": "string",
      "description": "",
      "x-enumNames": [
        "Linear",
        "InverseSquared"
      ],
      "enum": [
        "linear",
        "inverseSquared"
      ]
    },
    "BrambleModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "dimension": {
          "description": "Defining this value will make this body a bramble dimension. Leave it null to not do that.",
          "$ref": "#/definitions/BrambleDimensionInfo"
        },
        "nodes": {
          "type": "array",
          "description": "Place nodes/seeds that take you to other bramble dimensions",
          "items": {
            "$ref": "#/definitions/BrambleNodeInfo"
          }
        }
      }
    },
    "BrambleDimensionInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "fogTint": {
          "description": "The color of the fog inside this dimension. Leave blank for the default yellowish color: (113, 107, 81)",
          "$ref": "#/definitions/MColor"
        },
        "linksTo": {
          "type": "string",
          "description": "The name of the *node* that the player is taken to when exiting this dimension."
        },
        "radius": {
          "type": "number",
          "description": "The internal radius (in meters) of the dimension. The default is 1705.",
          "format": "float",
          "default": 1705.0
        },
        "allowedEntrances": {
          "type": "array",
          "description": "An array of integers from 0-5. By default, all entrances are allowed. To force this dimension to warp players in from only one point (like the anglerfish nest dimension in the base game) set this value to [3], [5], or similar. Values of 0-5 only.",
          "items": {
            "type": "integer",
            "format": "int32"
          }
        }
      }
    },
    "BrambleNodeInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "position": {
          "description": "The physical position of the node",
          "$ref": "#/definitions/MVector3"
        },
        "rotation": {
          "description": "The physical rotation of the node",
          "$ref": "#/definitions/MVector3"
        },
        "scale": {
          "type": "number",
          "description": "The physical scale of the node, as a multiplier of the original size",
          "format": "float",
          "default": 1.0
        },
        "linksTo": {
          "type": "string",
          "description": "The name of the planet that hosts the dimension this node links to"
        },
        "name": {
          "type": "string",
          "description": "The name of this node. Only required if this node should serve as an exit."
        },
        "isSeed": {
          "type": "boolean",
          "description": "Set this to true to make this node a seed instead of a node the player can enter",
          "default": false
        },
        "fogTint": {
          "description": "The color of the fog inside the node. Leave blank for the default yellowish color: (131, 124, 105, 255)",
          "$ref": "#/definitions/MColor"
        },
        "lightTint": {
          "description": "The color of the shafts of light coming from the entrances to the node. Leave blank for the default yellowish color: (131, 124, 105, 255)",
          "$ref": "#/definitions/MColor"
        },
        "farFogTint": {
          "description": "The color a dimension's background fog turns when you approach this node (if it's in a dimension). If this node is not in a dimension, this does nothing. Leave blank for the default yellowish white color: (255, 245, 217, 255)",
          "$ref": "#/definitions/MColor"
        },
        "possibleExits": {
          "type": "array",
          "description": "An array of integers from 0-5. By default, all exits are allowed. To force this node to warp players out from only one hole set this value to [3], [5], or similar. Values of 0-5 only.",
          "items": {
            "type": "integer",
            "format": "int32"
          }
        }
      }
    },
    "CloakModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "radius": {
          "type": "number",
          "description": "Radius of the cloaking field around the planet. It's a bit finicky so experiment with different values. If you\ndon't want a cloak, leave this as 0.",
          "format": "float"
        },
        "audio": {
          "type": "string",
          "description": "The audio that will play when entering the cloaking field. Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list."
        }
      }
    },
    "FocalPointModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "primary": {
          "type": "string",
          "description": "Name of the primary planet in this binary system"
        },
        "secondary": {
          "type": "string",
          "description": "Name of the secondary planet in this binary system"
        }
      }
    },
    "FunnelModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "curve": {
          "type": "array",
          "description": "Scale this module over time",
          "items": {
            "$ref": "#/definitions/TimeValuePair"
          }
        },
        "target": {
          "type": "string",
          "description": "The planet the funnel will flow to"
        },
        "tint": {
          "description": "Tint of the funnel",
          "$ref": "#/definitions/MColor"
        },
        "type": {
          "description": "Type of fluid the funnel transfers",
          "default": "sand",
          "$ref": "#/definitions/FunnelType"
        }
      }
    },
    "TimeValuePair": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "time": {
          "type": "number",
          "description": "A specific point in time",
          "format": "float"
        },
        "value": {
          "type": "number",
          "description": "The value for this point in time",
          "format": "float"
        }
      }
    },
    "FunnelType": {
      "type": "string",
      "description": "",
      "x-enumNames": [
        "Sand",
        "Water",
        "Lava",
        "Star"
      ],
      "enum": [
        "sand",
        "water",
        "lava",
        "star"
      ]
    },
    "HeightMapModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "heightMap": {
          "type": "string",
          "description": "Relative filepath to the texture used for the terrain height."
        },
        "maxHeight": {
          "type": "number",
          "description": "The highest points on your planet will be at this height.",
          "format": "float",
          "minimum": 0.0
        },
        "minHeight": {
          "type": "number",
          "description": "The lowest points on your planet will be at this height.",
          "format": "float",
          "minimum": 0.0
        },
        "stretch": {
          "description": "The scale of the terrain.",
          "$ref": "#/definitions/MVector3"
        },
        "textureMap": {
          "type": "string",
          "description": "Relative filepath to the texture used for the terrain."
        },
        "resolution": {
          "type": "integer",
          "description": "Resolution of the heightmap.\nHigher values means more detail but also more memory/cpu/gpu usage.\nThis value will be 1:1 with the heightmap texture width, but only at the equator.",
          "format": "int32",
          "default": 204,
          "maximum": 2000.0,
          "minimum": 4.0
        }
      }
    },
    "LavaModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "curve": {
          "type": "array",
          "description": "Scale this module over time",
          "items": {
            "$ref": "#/definitions/TimeValuePair"
          }
        },
        "size": {
          "type": "number",
          "description": "Size of the lava sphere",
          "format": "float"
        },
        "tint": {
          "description": "Tint of the lava",
          "$ref": "#/definitions/MColor"
        }
      }
    },
    "OrbitModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "staticPosition": {
          "description": "Specify this if you want the body to remain stationary at a given location (ie not orbit its parent). Required for Bramble dimensions",
          "$ref": "#/definitions/MVector3"
        },
        "primaryBody": {
          "type": "string",
          "description": "The name of the body this one will orbit around"
        },
        "isMoon": {
          "type": "boolean",
          "description": "Is this the moon of a planet? Used for determining when its name is shown on the map."
        },
        "axialTilt": {
          "type": "number",
          "description": "The angle between the normal to the orbital plane and its axis of rotation.",
          "format": "float"
        },
        "siderealPeriod": {
          "type": "number",
          "description": "Rotation period in minutes.",
          "format": "float"
        },
        "isTidallyLocked": {
          "type": "boolean",
          "description": "Should the body always have one side facing its primary?"
        },
        "alignmentAxis": {
          "description": "If it is tidally locked, this direction will face towards the primary. Ex: Interloper uses `0, -1, 0`. Most planets\nwill want something like `-1, 0, 0`.",
          "$ref": "#/definitions/MVector3"
        },
        "showOrbitLine": {
          "type": "boolean",
          "description": "Referring to the orbit line in the map screen.",
          "default": true
        },
        "dottedOrbitLine": {
          "type": "boolean",
          "description": "Should the orbit line be dotted?"
        },
        "isStatic": {
          "type": "boolean",
          "description": "Is the body meant to stay in one place without moving? If staticPosition is not set, the initial position\nwill be determined using its orbital parameters."
        },
        "tint": {
          "description": "Colour of the orbit-line in the map view.",
          "$ref": "#/definitions/MColor"
        },
        "trackingOrbitLine": {
          "type": "boolean",
          "description": "Should we just draw a line behind its orbit instead of the entire circle/ellipse?"
        },
        "semiMajorAxis": {
          "type": "number",
          "description": "The semi-major axis of the ellipse that is the body's orbit. For a circular orbit this is the radius.",
          "format": "float",
          "default": 5000.0,
          "minimum": 0.0
        },
        "inclination": {
          "type": "number",
          "description": "The angle (in degrees) between the body's orbit and the plane of the star system",
          "format": "float"
        },
        "longitudeOfAscendingNode": {
          "type": "number",
          "description": "An angle (in degrees) defining the point where the orbit of the body rises above the orbital plane if it has\nnonzero inclination.",
          "format": "float"
        },
        "eccentricity": {
          "type": "number",
          "description": "At 0 the orbit is a circle. The closer to 1 it is, the more oval-shaped the orbit is.",
          "format": "float",
          "maximum": 1.0,
          "minimum": 0.0
        },
        "argumentOfPeriapsis": {
          "type": "number",
          "description": "An angle (in degrees) defining the location of the periapsis (the closest distance to it's primary body) if it has\nnonzero eccentricity.",
          "format": "float"
        },
        "trueAnomaly": {
          "type": "number",
          "description": "Where the planet should start off in its orbit in terms of the central angle.",
          "format": "float"
        }
      }
    },
    "PropModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "details": {
          "type": "array",
          "description": "Place props in predefined positions on the planet",
          "items": {
            "$ref": "#/definitions/DetailInfo"
          }
        },
        "dialogue": {
          "type": "array",
          "description": "Add dialogue triggers to this planet",
          "items": {
            "$ref": "#/definitions/DialogueInfo"
          }
        },
        "entryLocation": {
          "type": "array",
          "description": "Add ship log entry locations on this planet",
          "items": {
            "$ref": "#/definitions/EntryLocationInfo"
          }
        },
        "geysers": {
          "type": "array",
          "description": "Add Geysers to this planet",
          "items": {
            "$ref": "#/definitions/GeyserInfo"
          }
        },
        "nomaiText": {
          "type": "array",
          "description": "Add translatable text to this planet",
          "items": {
            "$ref": "#/definitions/NomaiTextInfo"
          }
        },
        "proxyDetails": {
          "type": "array",
          "description": "Details which will be shown from 50km away. Meant to be lower resolution.",
          "items": {
            "$ref": "#/definitions/DetailInfo"
          }
        },
        "rafts": {
          "type": "array",
          "description": "Add rafts to this planet",
          "items": {
            "$ref": "#/definitions/RaftInfo"
          }
        },
        "reveal": {
          "type": "array",
          "description": "Add triggers that reveal parts of the ship log on this planet",
          "items": {
            "$ref": "#/definitions/RevealInfo"
          }
        },
        "scatter": {
          "type": "array",
          "description": "Scatter props around this planet's surface",
          "items": {
            "$ref": "#/definitions/ScatterInfo"
          }
        },
        "slideShows": {
          "type": "array",
          "description": "Add slideshows (from the DLC) to the planet",
          "items": {
            "$ref": "#/definitions/ProjectionInfo"
          }
        },
        "quantumGroups": {
          "type": "array",
          "description": "A list of quantum groups that props can be added to. An example of a group would be a list of possible locations for a QuantumSocketedObject.",
          "items": {
            "$ref": "#/definitions/QuantumGroupInfo"
          }
        },
        "tornados": {
          "type": "array",
          "description": "Add tornadoes to this planet",
          "items": {
            "$ref": "#/definitions/TornadoInfo"
          }
        },
        "volcanoes": {
          "type": "array",
          "description": "Add volcanoes to this planet",
          "items": {
            "$ref": "#/definitions/VolcanoInfo"
          }
        },
        "singularities": {
          "type": "array",
          "description": "Add black/white-holes to this planet",
          "items": {
            "$ref": "#/definitions/SingularityModule"
          }
        },
        "audioVolumes": {
          "type": "array",
          "description": "Add audio volumes to this planet",
          "items": {
            "$ref": "#/definitions/AudioVolumeInfo"
          }
        },
        "signals": {
          "type": "array",
          "description": "Add signalscope signals to this planet",
          "items": {
            "$ref": "#/definitions/SignalInfo"
          }
        }
      }
    },
    "DetailInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "rename": {
          "type": "string",
          "description": "An optional rename of the detail"
        },
        "alignToNormal": {
          "type": "boolean",
          "description": "Do we override rotation and try to automatically align this object to stand upright on the body's surface?"
        },
        "assetBundle": {
          "type": "string",
          "description": "Relative filepath to an asset-bundle to load the prefab defined in `path` from"
        },
        "path": {
          "type": "string",
          "description": "Either the path in the scene hierarchy of the item to copy or the path to the object in the supplied asset bundle"
        },
        "position": {
          "description": "Position of this prop relative to the body's center",
          "$ref": "#/definitions/MVector3"
        },
        "removeChildren": {
          "type": "array",
          "description": "A list of children to remove from this detail",
          "items": {
            "type": "string"
          }
        },
        "removeComponents": {
          "type": "boolean",
          "description": "Do we reset all the components on this object? Useful for certain props that have dialogue components attached to\nthem."
        },
        "rotation": {
          "description": "Rotate this prop",
          "$ref": "#/definitions/MVector3"
        },
        "scale": {
          "type": "number",
          "description": "Scale the prop",
          "format": "float",
          "default": 1.0
        },
        "quantumGroupID": {
          "type": "string",
          "description": "If this value is not null, this prop will be quantum. Assign this field to the id of the quantum group it should be a part of. The group it is assigned to determines what kind of quantum object it is"
        },
        "parentPath": {
          "type": "string",
          "description": "The path (not including the root planet object) of the parent of this game object. Optional (will default to the root sector)."
        }
      }
    },
    "DialogueInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "blockAfterPersistentCondition": {
          "type": "string",
          "description": "Prevents the dialogue from being created after a specific persistent condition is set. Useful for remote dialogue\ntriggers that you want to have happen only once."
        },
        "lookAtRadius": {
          "type": "number",
          "description": "If a pathToAnimController is supplied, if you are within this distance the character will look at you. If it is set\nto 0, they will only look at you when spoken to.",
          "format": "float"
        },
        "pathToAnimController": {
          "type": "string",
          "description": "If this dialogue is meant for a character, this is the relative path from the planet to that character's\nCharacterAnimController or SolanumAnimController."
        },
        "position": {
          "description": "When you enter into dialogue, you will look here.",
          "$ref": "#/definitions/MVector3"
        },
        "radius": {
          "type": "number",
          "description": "Radius of the spherical collision volume where you get the \"talk to\" prompt when looking at. If you use a\nremoteTriggerPosition, you can set this to 0 to make the dialogue only trigger remotely.",
          "format": "float"
        },
        "remoteTriggerPosition": {
          "description": "Allows you to trigger dialogue from a distance when you walk into an area.",
          "$ref": "#/definitions/MVector3"
        },
        "range": {
          "type": "number",
          "description": "Distance from radius the prompt appears",
          "format": "float",
          "default": 2.0
        },
        "remoteTriggerRadius": {
          "type": "number",
          "description": "The radius of the remote trigger volume.",
          "format": "float"
        },
        "xmlFile": {
          "type": "string",
          "description": "Relative path to the xml file defining the dialogue."
        }
      }
    },
    "EntryLocationInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "cloaked": {
          "type": "boolean",
          "description": "Whether this location is cloaked"
        },
        "id": {
          "type": "string",
          "description": "ID of the entry this location relates to"
        },
        "position": {
          "description": "The position of this entry location",
          "$ref": "#/definitions/MVector3"
        }
      }
    },
    "GeyserInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "position": {
          "description": "Position of the geyser",
          "$ref": "#/definitions/MVector3"
        },
        "disableBubbles": {
          "type": "boolean",
          "description": "Disable the individual particle systems of the geyser"
        },
        "disableShaft": {
          "type": "boolean",
          "description": "Disable the individual particle systems of the geyser"
        },
        "disableSpout": {
          "type": "boolean",
          "description": "Disable the individual particle systems of the geyser"
        }
      }
    },
    "NomaiTextInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "arcInfo": {
          "type": "array",
          "description": "Additional information about each arc in the text",
          "items": {
            "$ref": "#/definitions/NomaiTextArcInfo"
          }
        },
        "normal": {
          "description": "The normal vector for this object. Used for writing on walls and positioning computers.",
          "$ref": "#/definitions/MVector3"
        },
        "position": {
          "description": "Position of the root of this text",
          "$ref": "#/definitions/MVector3"
        },
        "rotation": {
          "description": "The euler angle rotation of this object. Not required if setting the normal. Computers and cairns will orient\nthemselves to the surface of the planet automatically.",
          "$ref": "#/definitions/MVector3"
        },
        "seed": {
          "type": "integer",
          "description": "The random seed used to pick what the text arcs will look like.",
          "format": "int32"
        },
        "type": {
          "description": "The type of object this is.",
          "default": "wall",
          "$ref": "#/definitions/NomaiTextType"
        },
        "xmlFile": {
          "type": "string",
          "description": "The relative path to the xml file for this object."
        },
        "parentPath": {
          "type": "string",
          "description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector)."
        },
        "rename": {
          "type": "string",
          "description": "An optional rename of this object"
        }
      }
    },
    "NomaiTextArcInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "mirror": {
          "type": "boolean",
          "description": "Whether to flip the spiral from left-curling to right-curling or vice versa."
        },
        "position": {
          "description": "The local position of this object on the wall.",
          "$ref": "#/definitions/MVector2"
        },
        "type": {
          "description": "The type of text to display.",
          "default": "adult",
          "$ref": "#/definitions/NomaiTextArcType"
        },
        "variation": {
          "type": "integer",
          "description": "Which variation of the chosen type to place. If not specified, a random variation will be selected based on the seed provided in the parent module.",
          "format": "int32",
          "default": -1
        },
        "zRotation": {
          "type": "number",
          "description": "The z euler angle for this arc.",
          "format": "float",
          "maximum": 360.0,
          "minimum": 0.0
        }
      }
    },
    "MVector2": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "x": {
          "type": "number",
          "format": "float"
        },
        "y": {
          "type": "number",
          "format": "float"
        }
      }
    },
    "NomaiTextArcType": {
      "type": "string",
      "description": "",
      "x-enumNames": [
        "Adult",
        "Child",
        "Stranger"
      ],
      "enum": [
        "adult",
        "child",
        "stranger"
      ]
    },
    "NomaiTextType": {
      "type": "string",
      "description": "",
      "x-enumNames": [
        "Wall",
        "Scroll",
        "Computer",
        "Cairn",
        "Recorder",
        "PreCrashRecorder",
        "PreCrashComputer"
      ],
      "enum": [
        "wall",
        "scroll",
        "computer",
        "cairn",
        "recorder",
        "preCrashRecorder",
        "preCrashComputer"
      ]
    },
    "RaftInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "position": {
          "description": "Position of the raft",
          "$ref": "#/definitions/MVector3"
        }
      }
    },
    "RevealInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "maxAngle": {
          "type": "number",
          "description": "The max view angle (in degrees) the player can see the volume with to unlock the fact (`observe` only)",
          "format": "float"
        },
        "maxDistance": {
          "type": "number",
          "description": "The max distance the user can be away from the volume to reveal the fact (`snapshot` and `observe` only)",
          "format": "float"
        },
        "position": {
          "description": "The position to place this volume at",
          "$ref": "#/definitions/MVector3"
        },
        "radius": {
          "type": "number",
          "description": "The radius of this reveal volume",
          "format": "float"
        },
        "revealOn": {
          "description": "What needs to be done to the volume to unlock the facts",
          "default": "enter",
          "$ref": "#/definitions/RevealVolumeType"
        },
        "reveals": {
          "type": "array",
          "description": "A list of facts to reveal",
          "items": {
            "type": "string"
          }
        },
        "achievementID": {
          "type": "string",
          "description": "An achievement to unlock. Optional."
        }
      }
    },
    "RevealVolumeType": {
      "type": "string",
      "description": "",
      "x-enumNames": [
        "Enter",
        "Observe",
        "Snapshot"
      ],
      "enum": [
        "enter",
        "observe",
        "snapshot"
      ]
    },
    "ScatterInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "assetBundle": {
          "type": "string",
          "description": "Relative filepath to an asset-bundle"
        },
        "count": {
          "type": "integer",
          "description": "Number of props to scatter",
          "format": "int32"
        },
        "offset": {
          "description": "Offset this prop once it is placed",
          "$ref": "#/definitions/MVector3"
        },
        "path": {
          "type": "string",
          "description": "Either the path in the scene hierarchy of the item to copy or the path to the object in the supplied asset bundle"
        },
        "rotation": {
          "description": "Rotate this prop once it is placed",
          "$ref": "#/definitions/MVector3"
        },
        "scale": {
          "type": "number",
          "description": "Scale this prop once it is placed",
          "format": "float"
        },
        "seed": {
          "type": "integer",
          "description": "The number used as entropy for scattering the props",
          "format": "int32"
        },
        "minHeight": {
          "type": [
            "null",
            "number"
          ],
          "description": "The lowest height that these object will be placed at (only relevant if there's a heightmap)",
          "format": "float"
        },
        "maxHeight": {
          "type": [
            "null",
            "number"
          ],
          "description": "The highest height that these objects will be placed at (only relevant if there's a heightmap)",
          "format": "float"
        }
      }
    },
    "ProjectionInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "position": {
          "description": "The position of this slideshow.",
          "$ref": "#/definitions/MVector3"
        },
        "reveals": {
          "type": "array",
          "description": "The ship log entries revealed after finishing this slide reel.",
          "items": {
            "type": "string"
          }
        },
        "rotation": {
          "description": "The rotation of this slideshow.",
          "$ref": "#/definitions/MVector3"
        },
        "slides": {
          "type": "array",
          "description": "The list of slides for this object.",
          "items": {
            "$ref": "#/definitions/SlideInfo"
          }
        },
        "type": {
          "description": "The type of object this is.",
          "default": "slideReel",
          "$ref": "#/definitions/SlideShowType"
        },
        "parentPath": {
          "type": "string",
          "description": "The relative path from the planet to the parent of this slideshow. Optional (will default to the root sector)."
        }
      }
    },
    "SlideInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "ambientLightColor": {
          "description": "Ambient light colour when viewing this slide.",
          "$ref": "#/definitions/MColor"
        },
        "ambientLightIntensity": {
          "type": "number",
          "description": "Ambient light intensity when viewing this slide.",
          "format": "float"
        },
        "ambientLightRange": {
          "type": "number",
          "description": "Ambient light range when viewing this slide.",
          "format": "float"
        },
        "backdropAudio": {
          "type": "string",
          "description": "The name of the AudioClip that will continuously play while watching these slides"
        },
        "backdropFadeTime": {
          "type": "number",
          "description": "The time to fade into the backdrop audio",
          "format": "float"
        },
        "beatAudio": {
          "type": "string",
          "description": "The name of the AudioClip for a one-shot sound when opening the slide."
        },
        "beatDelay": {
          "type": "number",
          "description": "The time delay until the one-shot audio",
          "format": "float"
        },
        "blackFrameDuration": {
          "type": "number",
          "description": "Before viewing this slide, there will be a black frame for this many seconds.",
          "format": "float"
        },
        "imagePath": {
          "type": "string",
          "description": "The path to the image file for this slide."
        },
        "playTimeDuration": {
          "type": "number",
          "description": "Play-time duration for auto-projector slides.",
          "format": "float"
        },
        "reveal": {
          "type": "string",
          "description": "Ship log entry revealed when viewing this slide"
        },
        "spotIntensityMod": {
          "type": "number",
          "description": "Spotlight intensity modifier when viewing this slide.",
          "format": "float"
        }
      }
    },
    "SlideShowType": {
      "type": "string",
      "description": "",
      "x-enumNames": [
        "SlideReel",
        "AutoProjector",
        "VisionTorchTarget",
        "StandingVisionTorch"
      ],
      "enum": [
        "slideReel",
        "autoProjector",
        "visionTorchTarget",
        "standingVisionTorch"
      ]
    },
    "QuantumGroupInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "type": {
          "description": "What type of group this is: does it define a list of states a single quantum object could take or a list of sockets one or more quantum objects could share?",
          "$ref": "#/definitions/QuantumGroupType"
        },
        "id": {
          "type": "string",
          "description": "A unique string used by props (that are marked as quantum) use to refer back to this group"
        },
        "sockets": {
          "type": "array",
          "description": "Only required if type is `sockets`. This lists all the possible locations for any props assigned to this group.",
          "items": {
            "$ref": "#/definitions/QuantumSocketInfo"
          }
        },
        "hasEmptyState": {
          "type": "boolean",
          "description": "Optional. Only used if type is `states`. If this is true, then the first prop made part of this group will be used to construct a visibility box for an empty game object, which will be considered one of the states."
        },
        "sequential": {
          "type": "boolean",
          "description": "Optional. Only used if type is `states`. If this is true, then the states will be presented in order, rather than in a random order"
        },
        "loop": {
          "type": "boolean",
          "description": "Optional. Only used if type is `states` and `sequential` is true. If this is false, then after the last state has appeared, the object will no longer change state",
          "default": true
        }
      }
    },
    "QuantumGroupType": {
      "type": "string",
      "description": "",
      "x-enumNames": [
        "Sockets",
        "States",
        "FailedValidation"
      ],
      "enum": [
        "sockets",
        "states",
        "FailedValidation"
      ]
    },
    "QuantumSocketInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "position": {
          "description": "The location of this socket",
          "$ref": "#/definitions/MVector3"
        },
        "rotation": {
          "description": "The rotation the quantum object will take if it's occupying this socket",
          "$ref": "#/definitions/MVector3"
        },
        "probability": {
          "type": "number",
          "description": "The probability any props that are part of this group will occupy this socket",
          "format": "float",
          "default": 1.0
        }
      }
    },
    "TornadoInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "elevation": {
          "type": "number",
          "description": "Alternative to setting the position. Will choose a random place at this elevation.",
          "format": "float"
        },
        "height": {
          "type": "number",
          "description": "The height of this tornado.",
          "format": "float",
          "default": 30.0
        },
        "position": {
          "description": "Position of the tornado",
          "$ref": "#/definitions/MVector3"
        },
        "tint": {
          "description": "The colour of the tornado.",
          "$ref": "#/definitions/MColor"
        },
        "type": {
          "description": "What type of cyclone should this be? Upwards and downwards are both tornados and will push in that direction.",
          "default": "downwards",
          "$ref": "#/definitions/TornadoType"
        },
        "wanderDegreesX": {
          "type": "number",
          "description": "Angular distance from the starting position that it will wander, in terms of the angle around the x-axis.",
          "format": "float",
          "default": 45.0
        },
        "wanderDegreesZ": {
          "type": "number",
          "description": "Angular distance from the starting position that it will wander, in terms of the angle around the z-axis.",
          "format": "float",
          "default": 45.0
        },
        "wanderRate": {
          "type": "number",
          "description": "The rate at which the tornado will wander around the planet. Set to 0 for it to be stationary. Should be around\n0.1.",
          "format": "float"
        },
        "audioDistance": {
          "type": "number",
          "description": "The maximum distance at which you'll hear the sounds of the cyclone. If not set it will scale relative to the size of the cyclone.",
          "format": "float"
        }
      }
    },
    "TornadoType": {
      "type": "string",
      "description": "",
      "x-enumNames": [
        "Downwards",
        "Upwards",
        "Hurricane"
      ],
      "enum": [
        "downwards",
        "upwards",
        "hurricane"
      ]
    },
    "VolcanoInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "lavaTint": {
          "description": "The colour of the meteor's lava.",
          "$ref": "#/definitions/MColor"
        },
        "maxInterval": {
          "type": "number",
          "description": "Maximum time between meteor launches.",
          "format": "float",
          "default": 20.0
        },
        "maxLaunchSpeed": {
          "type": "number",
          "description": "Maximum random speed at which meteors are launched.",
          "format": "float",
          "default": 150.0
        },
        "minInterval": {
          "type": "number",
          "description": "Minimum time between meteor launches.",
          "format": "float",
          "default": 5.0
        },
        "minLaunchSpeed": {
          "type": "number",
          "description": "Minimum random speed at which meteors are launched.",
          "format": "float",
          "default": 50.0
        },
        "position": {
          "description": "Position of this volcano.",
          "$ref": "#/definitions/MVector3"
        },
        "scale": {
          "type": "number",
          "description": "Scale of the meteors.",
          "format": "float"
        },
        "stoneTint": {
          "description": "The colour of the meteor's stone.",
          "$ref": "#/definitions/MColor"
        }
      }
    },
    "SingularityModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "curve": {
          "type": "array",
          "description": "Scale this module over time",
          "items": {
            "$ref": "#/definitions/TimeValuePair"
          }
        },
        "makeZeroGVolume": {
          "type": "boolean",
          "description": "Only for White Holes. Should this white hole repel the player from it.",
          "default": true
        },
        "pairedSingularity": {
          "type": "string",
          "description": "The uniqueID of the white hole or black hole that is paired to this one. If you don't set a value, entering will kill\nthe player"
        },
        "uniqueID": {
          "type": "string",
          "description": "The uniqueID of this white hole or black hole. If not set it will default to the name of the planet"
        },
        "position": {
          "description": "Position of the singularity",
          "$ref": "#/definitions/MVector3"
        },
        "size": {
          "type": "number",
          "description": "Radius of the singularity. Note that this isn't the same as the event horizon, but includes the entire volume that\nhas warped effects in it.",
          "format": "float",
          "minimum": 0.0
        },
        "targetStarSystem": {
          "type": "string",
          "description": "If you want a black hole to load a new star system scene, put its name here."
        },
        "type": {
          "description": "Type of singularity (white hole or black hole)",
          "$ref": "#/definitions/SingularityType"
        }
      }
    },
    "SingularityType": {
      "type": "string",
      "description": "",
      "x-enumNames": [
        "BlackHole",
        "WhiteHole"
      ],
      "enum": [
        "blackHole",
        "whiteHole"
      ]
    },
    "AudioVolumeInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "position": {
          "description": "The location of this audio volume. Optional (will default to 0,0,0).",
          "$ref": "#/definitions/MVector3"
        },
        "radius": {
          "type": "number",
          "description": "The radius of this audio volume",
          "format": "float"
        },
        "audio": {
          "type": "string",
          "description": "The audio to use. Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list."
        },
        "track": {
          "description": "The audio track of this audio volume",
          "default": "environment",
          "$ref": "#/definitions/AudioMixerTrackName"
        }
      }
    },
    "AudioMixerTrackName": {
      "type": "string",
      "description": "",
      "x-enumNames": [
        "Undefined",
        "Menu",
        "Music",
        "Environment",
        "Environment_Unfiltered",
        "EndTimes_SFX",
        "Signal",
        "Death",
        "Player",
        "Player_External",
        "Ship",
        "Map",
        "EndTimes_Music",
        "MuffleWhileRafting",
        "MuffleIndoors",
        "SlideReelMusic"
      ],
      "enum": [
        "undefined",
        "menu",
        "music",
        "environment",
        "environmentUnfiltered",
        "endTimesSfx",
        "signal",
        "death",
        "player",
        "playerExternal",
        "ship",
        "map",
        "endTimesMusic",
        "muffleWhileRafting",
        "muffleIndoors",
        "slideReelMusic"
      ]
    },
    "SignalInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "audio": {
          "type": "string",
          "description": "The audio to use. Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list."
        },
        "detectionRadius": {
          "type": "number",
          "description": "How close the player must get to the signal to detect it. This is when you get the \"Unknown Signal Detected\"\nnotification.",
          "format": "float",
          "minimum": 0.0
        },
        "frequency": {
          "type": "string",
          "description": "The frequency ID of the signal. The built-in game values are `Default`, `Traveler`, `Quantum`, `EscapePod`,\n`Statue`, `WarpCore`, `HideAndSeek`, and `Radio`. You can also put a custom value."
        },
        "identificationRadius": {
          "type": "number",
          "description": "How close the player must get to the signal to identify it. This is when you learn its name.",
          "format": "float",
          "default": 10.0,
          "minimum": 0.0
        },
        "insideCloak": {
          "type": "boolean",
          "description": "Only set to `true` if you are putting this signal inside a cloaking field."
        },
        "name": {
          "type": "string",
          "description": "The unique ID of the signal."
        },
        "onlyAudibleToScope": {
          "type": "boolean",
          "description": "`false` if the player can hear the signal without equipping the signal-scope.",
          "default": true
        },
        "position": {
          "description": "Position of the signal's source",
          "$ref": "#/definitions/MVector3"
        },
        "reveals": {
          "type": "string",
          "description": "A ship log fact to reveal when the signal is identified.",
          "default": ""
        },
        "sourceRadius": {
          "type": "number",
          "description": "Radius of the sphere giving off the signal.",
          "format": "float",
          "default": 1.0
        },
        "parentPath": {
          "type": "string",
          "description": "The relative path from the planet to the parent of this signal. Optional (will default to the root sector)."
        }
      }
    },
    "ReferenceFrameModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "enabled": {
          "type": "boolean",
          "description": "Allows the object to be targeted.",
          "default": true
        },
        "hideInMap": {
          "type": "boolean",
          "description": "Stop the object from being targeted on the map."
        },
        "bracketRadius": {
          "type": "number",
          "description": "Radius of the brackets that show up when you target this. Defaults to the sphere of influence.",
          "format": "float",
          "default": -1
        },
        "targetWhenClose": {
          "type": "boolean",
          "description": "If it should be targetable even when super close."
        },
        "maxTargetDistance": {
          "type": "number",
          "description": "The maximum distance that the reference frame can be targeted from. Defaults to 100km and cannot be greater than that.",
          "format": "float"
        },
        "targetColliderRadius": {
          "type": "number",
          "description": "The radius of the sphere around the planet which you can click on to target it. Defaults to twice the sphere of influence.",
          "format": "float"
        },
        "localPosition": {
          "description": "Position of the reference frame relative to the object.",
          "$ref": "#/definitions/MVector3"
        }
      }
    },
    "RingModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "curve": {
          "type": "array",
          "description": "Scale this module over time",
          "items": {
            "$ref": "#/definitions/TimeValuePair"
          }
        },
        "fluidType": {
          "description": "Fluid type for sounds/effects when colliding with this ring.",
          "$ref": "#/definitions/CloudFluidType"
        },
        "inclination": {
          "type": "number",
          "description": "Angle between the rings and the equatorial plane of the planet.",
          "format": "float"
        },
        "innerRadius": {
          "type": "number",
          "description": "Inner radius of the disk",
          "format": "float",
          "minimum": 0.0
        },
        "longitudeOfAscendingNode": {
          "type": "number",
          "description": "Angle defining the point where the rings rise up from the planet's equatorial plane if inclination is nonzero.",
          "format": "float"
        },
        "outerRadius": {
          "type": "number",
          "description": "Outer radius of the disk",
          "format": "float",
          "minimum": 0.0
        },
        "rotationSpeed": {
          "type": "number",
          "description": "Allows the rings to rotate.",
          "format": "float"
        },
        "texture": {
          "type": "string",
          "description": "Relative filepath to the texture used for the rings."
        },
        "unlit": {
          "type": "boolean",
          "description": "Should this ring be unlit?"
        }
      }
    },
    "SandModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "curve": {
          "type": "array",
          "description": "Scale this module over time",
          "items": {
            "$ref": "#/definitions/TimeValuePair"
          }
        },
        "size": {
          "type": "number",
          "description": "Size of the sand",
          "format": "float"
        },
        "tint": {
          "description": "Tint of the sand",
          "$ref": "#/definitions/MColor"
        }
      }
    },
    "ShipLogModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "mapMode": {
          "description": "Describe what this planet looks and like in map mode",
          "$ref": "#/definitions/MapModeInfo"
        },
        "spriteFolder": {
          "type": "string",
          "description": "A path to the folder where entry sprites are stored."
        },
        "xmlFile": {
          "type": "string",
          "description": "The relative path to the xml file to load ship log entries from."
        }
      }
    },
    "MapModeInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "details": {
          "type": "array",
          "description": "Place non-selectable objects in map mode (like sand funnels).",
          "items": {
            "$ref": "#/definitions/ShipLogDetailInfo"
          }
        },
        "invisibleWhenHidden": {
          "type": "boolean",
          "description": "Hide the planet completely if unexplored instead of showing an outline."
        },
        "manualNavigationPosition": {
          "description": "Specify where this planet is in terms of navigation.",
          "$ref": "#/definitions/MVector2"
        },
        "manualPosition": {
          "description": "Manually place this planet at the specified position.",
          "$ref": "#/definitions/MVector2"
        },
        "offset": {
          "type": "number",
          "description": "Extra distance to apply to this object in map mode.",
          "format": "float"
        },
        "outlineSprite": {
          "type": "string",
          "description": "The path to the sprite to show when the planet is unexplored in map mode."
        },
        "remove": {
          "type": "boolean",
          "description": "Completely remove this planet (and it's children) from map mode."
        },
        "revealedSprite": {
          "type": "string",
          "description": "The path to the sprite to show when the planet is revealed in map mode."
        },
        "scale": {
          "type": "number",
          "description": "Scale to apply to the planet in map mode.",
          "format": "float",
          "default": 1.0
        }
      }
    },
    "ShipLogDetailInfo": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "invisibleWhenHidden": {
          "type": "boolean",
          "description": "Whether to completely hide this detail when the parent AstroBody is unexplored."
        },
        "outlineSprite": {
          "type": "string",
          "description": "The sprite to show when the parent AstroBody is rumored/unexplored."
        },
        "position": {
          "description": "The position (relative to the parent) to place the detail.",
          "$ref": "#/definitions/MVector2"
        },
        "revealedSprite": {
          "type": "string",
          "description": "The sprite to show when the parent AstroBody is revealed."
        },
        "rotation": {
          "type": "number",
          "description": "The angle in degrees to rotate the detail.",
          "format": "float"
        },
        "scale": {
          "description": "The amount to scale the x and y-axis of the detail by.",
          "$ref": "#/definitions/MVector2"
        }
      }
    },
    "SpawnModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "playerSpawnPoint": {
          "description": "If you want the player to spawn on the new body, set a value for this. Press `P` in game with Debug mode on to have\nthe game log the position you're looking at to find a good value for this.",
          "$ref": "#/definitions/MVector3"
        },
        "playerSpawnRotation": {
          "description": "Euler angles by which the player will be oriented.",
          "$ref": "#/definitions/MVector3"
        },
        "shipSpawnPoint": {
          "description": "Required for the system to be accessible by warp drive.",
          "$ref": "#/definitions/MVector3"
        },
        "shipSpawnRotation": {
          "description": "Euler angles by which the ship will be oriented.",
          "$ref": "#/definitions/MVector3"
        },
        "startWithSuit": {
          "type": "boolean",
          "description": "If you spawn on a planet with no oxygen, you probably want to set this to true ;;)"
        }
      }
    },
    "StarModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "curve": {
          "type": "array",
          "description": "Scale this module over time",
          "items": {
            "$ref": "#/definitions/TimeValuePair"
          }
        },
        "endTint": {
          "description": "Colour of the star at the end of its life.",
          "$ref": "#/definitions/MColor"
        },
        "goSupernova": {
          "type": "boolean",
          "description": "Should this star explode after 22 minutes?",
          "default": true
        },
        "hasStarController": {
          "type": "boolean",
          "description": "Should we add a star controller to this body? If you want clouds to work on a binary brown dwarf system, set this to false.",
          "default": true
        },
        "hasAtmosphere": {
          "type": "boolean",
          "description": "The default sun has its own atmosphere that is different from regular planets. If you want that, set this to\n`true`.",
          "default": true
        },
        "lightTint": {
          "description": "Colour of the light given off. Defaults to yellowish.",
          "$ref": "#/definitions/MColor"
        },
        "size": {
          "type": "number",
          "description": "Radius of the star.",
          "format": "float",
          "default": 2000.0,
          "minimum": 0.0
        },
        "solarLuminosity": {
          "type": "number",
          "description": "Relative strength of the light compared to the sun.",
          "format": "float",
          "default": 1.0,
          "minimum": 0.0
        },
        "supernovaTint": {
          "description": "The tint of the supernova this star creates when it dies.",
          "$ref": "#/definitions/MColor"
        },
        "tint": {
          "description": "Colour of the star.",
          "$ref": "#/definitions/MColor"
        },
        "starRampTexture": {
          "type": "string",
          "description": "Path to the texture to put as the star ramp. Optional."
        },
        "starCollapseRampTexture": {
          "type": "string",
          "description": "Path to the texture to put as the star ramp while it is collapsing. Optional."
        },
        "lightRadius": {
          "type": "number",
          "description": "How far the light from the star can reach.",
          "format": "float",
          "default": 50000.0,
          "minimum": 0.0
        }
      }
    },
    "WaterModule": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "curve": {
          "type": "array",
          "description": "Scale this module over time",
          "items": {
            "$ref": "#/definitions/TimeValuePair"
          }
        },
        "size": {
          "type": "number",
          "description": "Size of the water sphere",
          "format": "float"
        },
        "tint": {
          "description": "Tint of the water",
          "$ref": "#/definitions/MColor"
        }
      }
    }
  },
  "$docs": {
    "title": "Celestial Body Schema",
    "description": "Schema for a celestial body in New Horizons"
  }
}