{
  "$schema": "https://json-schema.org/draft-07/schema",
  "$docs": {
    "title": "Celestial Body Schema",
    "description": "Schema for a celestial body in New Horizons"
  },
  "$defs": {
    "vector3": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "x": {
          "type": "number",
          "default": 0
        },
        "y": {
          "type": "number",
          "default": 0
        },
        "z": {
          "type": "number",
          "default": 0
        }
      }
    },
    "vector2": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "x": {
          "type": "number",
          "default": 0
        },
        "y": {
          "type": "number",
          "default": 0
        }
      }
    },
    "wholeVector2": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "x": {
          "type": "integer",
          "default": 0
        },
        "y": {
          "type": "integer",
          "default": 0
        }
      }
    },
    "colorPart": {
      "type": "integer",
      "default": 0,
      "minimum": 0
    },
    "color": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "R": {
          "$ref": "#/$defs/colorPart"
        },
        "G": {
          "$ref": "#/$defs/colorPart"
        },
        "B": {
          "$ref": "#/$defs/colorPart"
        },
        "A": {
          "$ref": "#/$defs/colorPart",
          "default": 255
        }
      }
    },
    "angle": {
      "type": "number",
      "default": 0,
      "minimum": 0,
      "maximum": 360
    },
    "curve": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "time": {
            "type": "integer",
            "default": 0
          },
          "value": {
            "type": "number",
            "default": 0
          }
        }
      }
    },
    "procGen": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "scale": {
          "type": "number",
          "minimum": 0,
          "description": "Average surface size"
        },
        "colour": {
          "$ref": "#/$defs/color",
          "description": "Colour of the terrain."
        }
      }
    }
  },
  "title": "Body",
  "description": "A planet or body to generate",
  "type": "object",
  "required": [
    "name"
  ],
  "additionalProperties": false,
  "properties": {
    "$schema": {
      "type": "string",
      "description": "The schema used to validate your config."
    },
    "name": {
      "type": "string",
      "description": "Unique name of your planet"
    },
    "starSystem": {
      "type": "string",
      "description": "Unique star system containing your planet",
      "default": "SolarSystem"
    },
    "destroy": {
      "type": "boolean",
      "description": "`true` if you want to delete this planet",
      "default": false
    },
    "childrenToDestroy": {
      "type": "array",
      "description": "A list of paths to child GameObjects to destroy on this planet",
      "items": {
        "type": "string"
      },
      "default": []
    },
    "canShowOnTitle": {
      "type": "boolean",
      "description": "Should this planet ever be shown on the title screen",
      "default": "true"
    },
    "isQuantumState": {
      "type": "boolean",
      "description": "Does this config describe a quantum state of a custom planet defined in another file?",
      "default": "false"
    },
    "Base": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "hasMapMarker": {
          "type": "boolean",
          "default": false,
          "description": "If the body should have a marker on the map screen."
        },
        "hasAmbientLight": {
          "type": "boolean",
          "default": false,
          "description": "If the dark side of the body should have some slight amount of light"
        },
        "surfaceGravity": {
          "type": "number",
          "default": 12,
          "description": "The acceleration due to gravity felt as the surfaceSize. Timber Hearth has 12 for reference"
        },
        "gravityFallOff": {
          "type": "string",
          "enum": [
            "linear",
            "inverseSquared"
          ],
          "default": "linear",
          "description": "How gravity falls off with distance. Most planets use linear but the sun and some moons use inverseSquared."
        },
        "surfaceSize": {
          "type": "number",
          "default": 100,
          "description": "A scale height used for a number of things. Should be the approximate radius of the body."
        },
        "sphereOfInfluence": {
          "type": "number",
          "default": 0,
          "description": "An override for the radius of the planet's gravitational sphere of influence. Optional"
        },
        "groundSize": {
          "type": "number",
          "default": 0,
          "description": "Radius of a simple sphere used as the ground for the planet. If you want to use more complex terrain, leave this as 0."
        },
        "hasCometTail": {
          "type": "boolean",
          "default": false,
          "description": "If you want the body to have a tail like the Interloper."
        },
        "cometTailRotation": {
          "$ref": "#/$defs/vector3",
          "description": "If it has a comet tail, it'll be oriented according to these Euler angles."
        },
        "hasReferenceFrame": {
          "type": "boolean",
          "default": true,
          "description": "Allows the object to be targeted on the map."
        },
        "centerOfSolarSystem": {
          "type": "boolean",
          "default": false,
          "description": "Set this to true if you are replacing the sun with a different body. Only one object in a star system should ever have this set to true."
        },
        "isSatellite": {
          "type": "boolean",
          "default": false,
          "description": "Is this body an artificial satellite of a planet/moon/star?"
        },
        "cloakRadius": {
          "type": "number",
          "default": 0,
          "description": "Radius of the cloaking field around the planet. It's a bit finicky so experiment with different values. If you don't want a cloak, leave this as 0."
        },
        "invulnerableToSun": {
          "type": "boolean",
          "default": false,
          "description": "Can this planet survive entering a star?"
        }
      }
    },
    "Atmosphere": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "size": {
          "type": "number",
          "default": 0,
          "description": "Scale height of the atmosphere"
        },
        "cloudTint": {
          "$ref": "#/$defs/color",
          "description": "Colour of the cloud layer. Only relevant if \"cloud\" has a value"
        },
        "cloud": {
          "type": "string",
          "description": "Relative filepath to the cloud texture, if the planet has clouds."
        },
        "cloudCap": {
          "type": "string",
          "description": "Relative filepath to the cloud cap texture, if the planet has clouds."
        },
        "cloudRamp": {
          "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 auto-generated."
        },
        "cloudFluidType": {
          "type": "string",
          "default": "CLOUD",
          "description": "Fluid type for sounds/effects when colliding with this cloud.",
          "enum": [
            "NONE",
            "WATER",
            "CLOUD",
            "SAND",
            "PLASMA"
          ]
        },
        "useBasicCloudShader": {
          "type": "boolean",
          "default": false,
          "description": "Set to `false` in order to use Giant's deep shader. Set to `true` to just apply the cloud texture as is."
        },
        "shadowsOnClouds": {
          "type": "boolean",
          "default": true,
          "description": "If the top layer should have shadows. Set to false if you're making a brown dwarf."
        },
        "fogTint": {
          "$ref": "#/$defs/color",
          "description": "Colour of fog on the planet, if you put fog."
        },
        "fogDensity": {
          "type": "number",
          "minimum": 0,
          "maximum": 1,
          "description": "How dense the fog is, if you put fog."
        },
        "fogSize": {
          "type": "number",
          "description": "Radius of fog sphere, independent of the atmosphere. This has to be set for there to be fog.",
          "minimum": 0
        },
        "hasRain": {
          "type": "boolean",
          "default": false
        },
        "hasSnow": {
          "type": "boolean",
          "default": false
        },
        "hasOxygen": {
          "type": "boolean",
          "default": false,
          "description": "Lets you survive on the planet without a suit."
        },
        "hasAtmosphere": {
          "type": "boolean",
          "default": false,
          "description": "Whether we use an atmospheric shader on the planet. Doesn't affect clouds, fog, rain, snow, oxygen, etc. Purely visual."
        },
        "atmosphereTint": {
          "$ref": "#/$defs/color",
          "description": "Colour of atmospheric shader on the planet."
        }
      }
    },
    "Orbit": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "semiMajorAxis": {
          "type": "integer",
          "default": 5000,
          "minimum": 0,
          "description": "The semi-major axis of the ellipse that is the body's orbit. For a circular orbit this is the radius."
        },
        "inclination": {
          "$ref": "#/$defs/angle",
          "description": "The angle (in degrees) between the body's orbit and the plane of the star system"
        },
        "primaryBody": {
          "type": "string",
          "default": "Sun",
          "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."
        },
        "longitudeOfAscendingNode": {
          "$ref": "#/$defs/angle",
          "description": "An angle (in degrees) defining the point where the orbit of the body rises above the orbital plane if it has nonzero inclination."
        },
        "eccentricity": {
          "type": "number",
          "default": 0,
          "minimum": 0,
          "maximum": 0.99999,
          "description": "At 0 the orbit is a circle. The closer to 1 it is, the more oval-shaped the orbit is."
        },
        "argumentOfPeriapsis": {
          "$ref": "#/$defs/angle",
          "description": "An angle (in degrees) defining the location of the periapsis (the closest distance to it's primary body) if it has nonzero eccentricity."
        },
        "trueAnomaly": {
          "$ref": "#/$defs/angle",
          "description": "Where the planet should start off in its orbit in terms of the central angle."
        },
        "axialTilt": {
          "$ref": "#/$defs/angle",
          "description": "The angle between the normal to the orbital plane and its axis of rotation."
        },
        "siderealPeriod": {
          "type": "number",
          "default": 0,
          "description": "Rotation period in minutes."
        },
        "isTidallyLocked": {
          "type": "boolean",
          "default": false,
          "description": "Should the body always have one side facing its primary?"
        },
        "alignmentAxis": {
          "$ref": "#/$defs/vector3",
          "description": "If it is tidally locked, this direction will face towards the primary. Ex: Interloper uses `0, -1, 0`. Most planets will want something like `-1, 0, 0`."
        },
        "showOrbitLine": {
          "type": "boolean",
          "default": false,
          "description": "Referring to the orbit line in the map screen."
        },
        "dottedOrbitLine": {
          "type": "boolean",
          "default": false
        },
        "isStatic": {
          "type": "boolean",
          "default": false,
          "description": "Is the body meant to stay in one place without moving?"
        },
        "tint": {
          "$ref": "#/$defs/color",
          "description": "Colour of the orbit-line in the map view."
        },
        "trackingOrbitLine": {
          "type": "boolean",
          "default": false,
          "description": "Should we just draw a line behind its orbit instead of the entire circle/ellipse?"
        }
      }
    },
    "Ring": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "innerRadius": {
          "type": "number",
          "default": 0,
          "minimum": 0,
          "description": "Inner radius of the disk "
        },
        "outerRadius": {
          "type": "number",
          "default": 0,
          "minimum": 0
        },
        "inclination": {
          "type": "number",
          "default": 0,
          "description": "Angle between the rings and the equatorial plane of the planet."
        },
        "longitudeOfAscendingNode": {
          "$ref": "#/$defs/angle",
          "description": "Angle defining the point where the rings rise up from the planet's equatorial plane if inclination is nonzero."
        },
        "texture": {
          "type": "string",
          "description": "Relative filepath to the texture used for the rings."
        },
        "rotationSpeed": {
          "type": "number",
          "default": 0,
          "description": "Allows the rings to rotate."
        },
        "fluidType": {
          "type": "string",
          "default": "NONE",
          "description": "Fluid type for sounds/effects when colliding with this ring.",
          "enum": [
            "NONE",
            "WATER",
            "CLOUD",
            "SAND",
            "PLASMA"
          ]
        },
        "curve": {
          "$ref": "#/$defs/curve",
          "description": "Allows the rings to grow/shrink with time."
        }
      }
    },
    "HeightMap": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "heightMap": {
          "type": "string",
          "description": "Relative filepath to the texture used for the terrain height"
        },
        "textureMap": {
          "type": "string",
          "description": "Relative filepath to the texture used for the terrain."
        },
        "minHeight": {
          "type": "number",
          "minimum": 0,
          "description": "The lowest points on your planet will be at this height."
        },
        "maxHeight": {
          "type": "number",
          "minimum": 0,
          "description": "The highest points on your planet will be at this height."
        },
        "stretch": {
          "$ref": "#/$defs/vector3",
          "description": "The scale of the terrain."
        }
      }
    },
    "ProcGen": {
      "$ref": "#/$defs/procGen"
    },
    "AsteroidBelt": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "innerRadius": {
          "type": "number",
          "default": 0,
          "minimum": 0
        },
        "outerRadius": {
          "type": "number",
          "default": 0,
          "minimum": 0
        },
        "minSize": {
          "type": "number",
          "default": 20,
          "minimum": 0,
          "description": "Minimum size of the asteroids."
        },
        "maxSize": {
          "type": "number",
          "default": 50,
          "minimum": 0,
          "description": "Maximum size of the asteroids."
        },
        "amount": {
          "type": "integer",
          "minimum": 0,
          "maximum": 200,
          "description": "Amount of asteroids to create."
        },
        "inclination": {
          "$ref": "#/$defs/angle",
          "description": "Angle between the rings and the equatorial plane of the planet."
        },
        "longitudeOfAscendingNode": {
          "$ref": "#/$defs/angle",
          "description": "Angle defining the point where the rings rise up from the planet's equatorial plane if inclination is nonzero."
        },
        "randomSeed": {
          "type": "integer",
          "default": 0,
          "description": "Number used to randomize asteroid positions"
        },
        "procGen": {
          "$ref": "#/$defs/procGen"
        }
      }
    },
    "Star": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "size": {
          "type": "number",
          "default": 2000,
          "minimum": 0,
          "description": "Radius of the star."
        },
        "tint": {
          "$ref": "#/$defs/color",
          "description": "Colour of the star."
        },
        "solarFlareTint": {
          "$ref": "#/$defs/color",
          "description": "Colour of the solar flares. The shader is a bit weird so the value you put won't exactly reflect what you see. Try experimenting with different colours to see what works."
        },
        "lightTint": {
          "$ref": "#/$defs/color",
          "description": "Colour of the light given off."
        },
        "solarLuminosity": {
          "type": "number",
          "minimum": 0,
          "description": "Relative strength of the light compared to the sun",
          "default": 1
        },
        "hasAtmosphere": {
          "type": "boolean",
          "default": true,
          "description": "The default sun has its own atmosphere that is different from regular planets. If you want that, set this to true."
        },
        "curve": {
          "$ref": "#/$defs/curve",
          "description": "Allows the star to shrink/grow over time."
        }
      }
    },
    "FocalPoint": {
      "type": "object",
      "additionalProperties": false,
      "description": "Use this to create the focal point that two objects can orbit in a binary system",
      "properties": {
        "primary": {
          "type": "string",
          "description": "The larger of the two bodies in the binary pair."
        },
        "secondary": {
          "type": "string",
          "description": "The smaller of the two bodies in the binary pair."
        }
      }
    },
    "Props": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "scatter": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "count": {
                "type": "integer"
              },
              "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"
              },
              "assetBundle": {
                "type": "string",
                "description": "Relative filepath to an asset-bundle"
              },
              "offset": {
                "$ref": "#/$defs/vector3"
              },
              "rotation": {
                "$ref": "#/$defs/vector3",
                "description": "Euler angle degrees"
              },
              "scale": {
                "type": "number",
                "default": 1,
                "description": "How many props to scatter around the planet."
              }
            }
          }
        },
        "details": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "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"
              },
              "assetBundle": {
                "type": "string",
                "description": "Relative filepath to an asset-bundle"
              },
              "position": {
                "$ref": "#/$defs/vector3"
              },
              "rotation": {
                "$ref": "#/$defs/vector3",
                "description": "Euler angle degrees"
              },
              "scale": {
                "type": "number",
                "default": 1
              },
              "alignToNormal": {
                "type": "boolean",
                "description": "Do we override rotation and try to automatically align this object to stand upright on the body's surface?",
                "default": false
              },
              "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 them.",
                "default": false
              }
            }
          }
        },
        "dialogue": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "position": {
                "$ref": "#/$defs/vector3",
                "description": "When you enter into dialogue, you will look here."
              },
              "radius": {
                "type": "number",
                "default": 0,
                "description": "Radius of the spherical collision volume where you get the \"talk to\" prompt when looking at. If you use a remoteTriggerPosition, you can set this to 0 to make the dialogue only trigger remotely."
              },
              "xmlFile": {
                "type": "string",
                "description": "Relative path to the xml file defining the dialogue."
              },
              "remoteTriggerPosition": {
                "$ref": "#/$defs/vector3",
                "description": "Allows you to trigger dialogue from a distance when you walk into an area."
              },
              "remoteTriggerRadius": {
                "type": "number",
                "description": "The radius of the remote trigger volume."
              },
              "blockAfterPersistentCondition": {
                "type": "string",
                "description": "Prevents the dialogue from being created after a specific persistent condition is set. Useful for remote dialogue triggers that you want to have happen only once."
              },
              "pathToAnimController": {
                "type": "string",
                "description": "If this dialogue is meant for a character, this is the relative path from the planet to that character's CharacterAnimController or SolanumAnimController."
              },
              "lookAtRadius": {
                "type": "number",
                "default": 0,
                "description": "If a pathToAnimController is supplied, if you are within this distance the character will look at you. If it is set to 0, they will only look at you when spoken to."
              }
            }
          }
        },
        "reveal": {
          "type": "array",
          "description": "A set of volumes that reveal ship log fact",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "revealOn": {
                "type": "string",
                "enum": [
                  "enter",
                  "observe",
                  "snapshot"
                ],
                "description": "'enter', 'observe', or 'snapshot' what needs to be done to the volume to unlock the facts"
              },
              "reveals": {
                "type": "array",
                "description": "A list of facts to reveal",
                "items": {
                  "type": "string"
                }
              },
              "position": {
                "$ref": "#/$defs/vector3",
                "description": "The position to place the volume at"
              },
              "radius": {
                "type": "number",
                "description": "The radius of the volume",
                "default": 1.0
              },
              "maxDistance": {
                "type": "number",
                "description": "The max distance the user can be away from the volume to reveal the fact (snapshot and observe only)"
              },
              "maxAngle": {
                "$ref": "#/$defs/angle",
                "description": "The max view angle (in degrees) the player can see the volume with to unlock the fact",
                "default": 180.0
              }
            }
          }
        },
        "entryLocation": {
          "type": "array",
          "description": "A set of locations for ship log entries",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "id": {
                "type": "string",
                "description": "The ID of the entry this location is for"
              },
              "cloaked": {
                "type": "boolean",
                "description": "Whether this entry location is in a cloaking field",
                "default": false
              },
              "position": {
                "$ref": "#/$defs/vector3",
                "description": "The position of this entry location"
              }
            }
          }
        },
        "geysers": {
          "type": "array",
          "description": "A set of geysers",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "position": {
                "$ref": "#/$defs/vector3",
                "description": "The position of this geyser"
              }
            }
          }
        },
        "volcanoes": {
          "type": "array",
          "description": "A set of meteor-spewing volcanoes",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "position": {
                "$ref": "#/$defs/vector3",
                "description": "The position of this volcano."
              },
              "stoneTint": {
                "$ref": "#/$defs/color",
                "description": "The colour of the meteor's stone."
              },
              "lavaTint": {
                "$ref": "#/$defs/color",
                "description": "The colour of the meteor's lava."
              },
              "minLaunchSpeed": {
                "type": "number",
                "description": "Minimum random speed at which meteors are launched.",
                "default": 50
              },
              "maxLaunchSpeed": {
                "type": "number",
                "description": "Maximum random speed at which meteors are launched.",
                "default": 150
              },
              "minInterval": {
                "type": "number",
                "description": "Minimum time between meteor launches.",
                "default": 5
              },
              "maxInterval": {
                "type": "number",
                "description": "Maximum time between meteor launches.",
                "default": 20
              }
            }
          }
        },
        "slideShows": {
          "type": "array",
          "description": "For creating custom auto projectors or slide reels from the DLC",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "position": {
                "$ref": "#/$defs/vector3",
                "description": "The position of this object."
              },
              "rotation": {
                "$ref": "#/$defs/vector3",
                "description": "The euler angle rotation of this object."
              },
              "reveals": {
                "type": "array",
                "description": "The ship log entries revealed after finishing this slide reel.",
                "items": {
                  "type": "string"
                }
              },
              "slides": {
                "type": "array",
                "description": "The list of slides for this object.",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "imagePath": {
                      "type": "string",
                      "description": "The path to the image file for this slide."
                    },
                    "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"
                    },
                    "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"
                    },
                    "ambientLightIntensity": {
                      "type": "number",
                      "description": "Ambient light intensity when viewing this slide."
                    },
                    "ambientLightRange": {
                      "type": "number",
                      "description": "Ambient light range when viewing this slide."
                    },
                    "ambientLightColor": {
                      "$ref": "#/$defs/color",
                      "description": "Ambient light colour when viewing this slide."
                    },
                    "spotIntensityMod": {
                      "type": "number",
                      "description": "Spotlight intensity modifier when viewing this slide."
                    },
                    "playTimeDuration": {
                      "type": "number",
                      "description": "Play-time duration for auto-projector slides."
                    },
                    "blackFrameDuration": {
                      "type": "number",
                      "description": "Before viewing this slide, there will be a black frame for this many seconds."
                    },
                    "reveal": {
                      "type": "string",
                      "description": "Ship log entry revealed when viewing this slide."
                    }
                  }
                }
              },
              "type": {
                "type": "string",
                "description": "The type of object this is. Must be either SlideReel or AutoProjector",
                "enum": [
                  "slideReel",
                  "autoProjector"
                ],
                "default": "slideReel"
              }
            }
          }
        },
        "nomaiText": {
          "type": "array",
          "description": "For creating different objects containing translatable text.",
          "items": {
            "type": "object",
            "additionalProperties": "false",
            "properties": {
              "position": {
                "$ref": "#/$defs/vector3",
                "description": "The position of this object."
              },
              "normal": {
                "$ref": "#/$defs/vector3",
                "description": "The normal vector for this object. Used for writing on walls and positioning computers."
              },
              "rotation": {
                "$ref": "#/$defs/vector3",
                "description": "The euler angle rotation of this object. Not required if setting the normal. Computers and cairns will orient themselves to the surface of the planet automatically."
              },
              "type": {
                "type": "string",
                "description": "The type of object this is. Must be wall, scroll, computer, cairn, or recorder",
                "enum": [
                  "wall",
                  "scroll",
                  "computer",
                  "cairn",
                  "recorder"
                ],
                "default": "wall"
              },
              "xmlFile": {
                "type": "string",
                "description": "The relative path to the xml file for this object."
              },
              "seed": {
                "type": "integer",
                "description": "The random seed used to pick what the text arcs will look like."
              },
              "arcInfo": {
                "type": "array",
                "description": "Additional information about each arc in the text",
                "items": {
                  "type": "object",
                  "additionalProperties": "false",
                  "properties": {
                    "position": {
                      "$ref": "#/$defs/vector2",
                      "description": "The local position of this object on the wall."
                    },
                    "zRotation": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 360,
                      "description": "The z euler angle for this arc.",
                      "default": 0
                    },
                    "type": {
                      "type": "string",
                      "description": "The type of text to display. Must be one of adult, child, or stranger.",
                      "enum": [
                        "adult",
                        "child",
                        "stranger"
                      ],
                      "default": "adult"
                    }
                  }
                }
              }
            }
          }
        },
        "tornados": {
          "type": "array",
          "description": "Like those on Giant's Deep",
          "items": {
            "type": "object",
            "additionalProperties": "false",
            "properties": {
              "position": {
                "$ref": "#/$defs/vector3",
                "description": "The position of this tornado."
              },
              "elevation": {
                "type": "number",
                "description": "Alternative to setting the position. Will choose a random place at this elevation."
              },
              "height": {
                "type": "number",
                "description": "The height of this tornado.",
                "default": 30
              },
              "tint": {
                "$ref": "#/$defs/color",
                "description": "The colour of the tornado."
              },
              "downwards": {
                "type": "boolean",
                "description": "Should it pull things downwards? Will push them upwards by default."
              },
              "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 0.1.",
                "default": 0
              },
              "wanderDegreesX": {
                "type": "number",
                "description": "Angular distance from the starting position that it will wander, in terms of the angle around the x-axis.",
                "default": 45
              },
              "wanderDegreesZ": {
                "type": "number",
                "description": "Angular distance from the starting position that it will wander, in terms of the angle around the z-axis.",
                "default": 45
              }
            }
          }
        },
        "rafts": {
          "type": "array",
          "description": "Like those in the DLC",
          "items": {
            "type": "object",
            "additionalProperties": "false",
            "properties": {
              "position": {
                "$ref": "#/$defs/vector3",
                "description": "The position of this raft."
              }
            }
          }
        }
      }
    },
    "Spawn": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "playerSpawnPoint": {
          "$ref": "#/$defs/vector3",
          "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 the game log the position you're looking at to find a good value for this."
        },
        "shipSpawnPoint": {
          "$ref": "#/$defs/vector3"
        },
        "startWithSuit": {
          "type": "boolean",
          "default": false,
          "description": "If you spawn on a planet with no oxygen, you probably want to set this to true ;)"
        }
      }
    },
    "Signal": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "signals": {
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "position": {
                "$ref": "#/$defs/vector3"
              },
              "frequency": {
                "type": "string",
                "description": "The frequency ID of the signal. The built-in game values are \"Default\", \"Traveler\", \"Quantum\", \"EscapePod\", \"Statue\", \"WarpCore\", \"HideAndSeek\", and \"Radio\". You can also put a custom value."
              },
              "name": {
                "type": "string",
                "description": "The unique ID of the signal."
              },
              "audioClip": {
                "type": "string",
                "description": "Name of an existing AudioClip in the game that will player over the signal."
              },
              "audioFilePath": {
                "type": "string",
                "description": "Relative filepath to the .wav file to use as the audio. Mutually exclusive with audioClip"
              },
              "reveals": {
                "type": "string",
                "description": "A ship log fact to reveal when the signal is identified"
              },
              "sourceRadius": {
                "type": "number",
                "default": 1,
                "description": "Radius of the sphere giving off the signal"
              },
              "detectionRadius": {
                "type": "number",
                "minimum": 0,
                "description": "How close the player must get to the signal to detect it. This is when you get the \"Unknown Signal Detected\" notification."
              },
              "identificationRadius": {
                "type": "number",
                "minimum": 0,
                "description": "How close the player must get to the signal to identify it. This is when you learn its name."
              },
              "onlyAudibleToScope": {
                "type": "boolean",
                "default": true,
                "description": "False if the player can hear the signal without equipping the signal-scope."
              },
              "insideCloak": {
                "type": "boolean",
                "default": false,
                "description": "Only set to true if you are putting this signal inside a cloaking field."
              }
            }
          }
        }
      }
    },
    "Singularity": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "size": {
          "type": "number",
          "default": 0,
          "minimum": 0,
          "description": "Radius of the singularity. Note that this isn't the same as the event horizon, but includes the entire volume that has warped effects in it."
        },
        "pairedSingularity": {
          "type": "string",
          "description": "The name of the white hole or black hole that is paired to this one. If you don't set a value, entering will kill the player"
        },
        "targetStarSystem": {
          "type": "string",
          "description": "If you want a black hole to load a new star system scene, put its name here. Optional."
        },
        "type": {
          "type": "string",
          "enum": [
            "BlackHole",
            "WhiteHole"
          ]
        },
        "position": {
          "$ref": "#/$defs/vector3"
        },
        "makeZeroGVolume": {
          "type": "boolean",
          "default": true,
          "description": "Only for White Holes. Should this white hole repel the player from it."
        }
      }
    },
    "Water": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "size": {
          "type": "number",
          "default": 0
        },
        "tint": {
          "$ref": "#/$defs/color"
        },
        "curve": {
          "$ref": "#/$defs/curve"
        }
      }
    },
    "Lava": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "size": {
          "type": "number",
          "default": 0
        },
        "tint": {
          "$ref": "#/$defs/color"
        },
        "curve": {
          "$ref": "#/$defs/curve"
        }
      }
    },
    "Sand": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "size": {
          "type": "number",
          "default": 0
        },
        "tint": {
          "$ref": "#/$defs/color"
        },
        "curve": {
          "$ref": "#/$defs/curve"
        }
      }
    },
    "Funnel": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "target": {
          "type": "string",
          "description": "The body that the funnel is pouring onto"
        },
        "type": {
          "type": "string",
          "enum": [
            "Sand",
            "Water",
            "Lava",
            "Star"
          ],
          "default": "Sand"
        },
        "tint": {
          "$ref": "#/$defs/color"
        },
        "curve": {
          "$ref": "#/$defs/curve"
        }
      }
    },
    "ShipLog": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "xmlFile": {
          "type": "string",
          "description": "The relative path to the xml file to load ship log entries from."
        },
        "spriteFolder": {
          "type": "string",
          "description": "A path to the folder where entry sprites are stored."
        },
        "initialReveal": {
          "type": "array",
          "description": "A list of fact IDs to reveal when the game starts.",
          "items": {
            "type": "string"
          }
        },
        "entryPositions": {
          "type": "array",
          "description": "A set of positions to use instead of automatic layout in rumor mode.",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "id": {
                "type": "string",
                "description": "The name of the entry to apply the position to."
              },
              "position": {
                "$ref": "#/$defs/vector2"
              }
            }
          }
        },
        "MapMode": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "revealedSprite": {
              "type": "string",
              "description": "The path to the sprite to show when the planet is revealed in map mode."
            },
            "outlineSprite": {
              "type": "string",
              "description": "The path to the sprite to show when the planet is unexplored in map mode."
            },
            "manualPosition": {
              "$ref": "#/$defs/vector2",
              "description": "Manually place this planet at the specified position."
            },
            "manualNavigationPosition": {
              "$ref": "#/$defs/wholeVector2",
              "description": "Specify where this planet is in terms of navigation."
            },
            "scale": {
              "type": "number",
              "description": "Scale to apply to the planet in map mode.",
              "default": 1
            },
            "invisibleWhenHidden": {
              "type": "boolean",
              "description": "Hide the planet completely if unexplored instead of showing an outline.",
              "default": false
            },
            "offset": {
              "type": "number",
              "description": "Extra distance to apply to this object in map mode.",
              "default": 0
            },
            "remove": {
              "type": "boolean",
              "description": "Completely remove this planet (and it's children) from map mode.",
              "default": false
            },
            "details": {
              "type": "array",
              "description": "Place non-selectable object in map mode (like sand funnels).",
              "items": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "revealedSprite": {
                    "type": "string",
                    "description": "The sprite to show when the parent AstroBody is revealed."
                  },
                  "outlineSprite": {
                    "type": "string",
                    "description": "The sprite to show when the parent AstroBody is rumored/unexplored."
                  },
                  "rotation": {
                    "$refs": "#/$defs/angle",
                    "description": "The angle in degrees to rotate the detail."
                  },
                  "invisibleWhenHidden": {
                    "type": "boolean",
                    "description": "Whether to completely hide this detail when the parent AstroBody is unexplored.",
                    "default": false
                  },
                  "position": {
                    "$ref": "#/$defs/vector2",
                    "description": "The position (relative to the parent) to place the detail."
                  },
                  "scale": {
                    "$ref": "#/$defs/vector2",
                    "description": "The amount to scale the x and y-axis of the detail by."
                  }
                }
              }
            }
          }
        },
        "Curiosities": {
          "type": "array",
          "description": "A set of colors to apply to curiosities.",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "id": {
                "type": "string",
                "description": "The ID of the curiosity to apply the color to."
              },
              "color": {
                "$ref": "#/$defs/color",
                "description": "The color to apply to entries with this curiosity."
              },
              "highlightColor": {
                "$ref": "#/$defs/color",
                "description": "The color to apply to highlighted entries with this curiosity."
              }
            }
          }
        }
      }
    }
  }
}
