From 0f40e37d1c11d3be2d93775a2f445d9caedb7aea Mon Sep 17 00:00:00 2001 From: Ben C Date: Sat, 23 Jul 2022 17:01:30 -0400 Subject: [PATCH 01/29] Start on docs redo --- docs/content/pages/home.md | 111 +------- docs/content/pages/tutorials/api.md | 47 ---- docs/content/pages/tutorials/details.md | 167 ------------ docs/content/pages/tutorials/dialogue.md | 164 ----------- .../pages/tutorials/getting_started.md | 255 ++++++++++++++++++ docs/content/pages/tutorials/planet_gen.md | 148 ++++++++++ .../pages/tutorials/reading_schemas.md | 78 ++++++ docs/content/pages/tutorials/star_system.md | 46 ---- docs/content/pages/tutorials/translation.md | 34 --- .../pages/tutorials/update_existing.md | 34 --- .../mod_manager_show_in_explorer.webp | Bin 0 -> 14312 bytes .../images/reading_schemas/body_schema_1.webp | Bin 0 -> 16008 bytes .../images/reading_schemas/body_schema_2.webp | Bin 0 -> 5756 bytes .../images/reading_schemas/body_schema_3.webp | Bin 0 -> 16610 bytes .../images/reading_schemas/body_schema_4.webp | Bin 0 -> 12050 bytes 15 files changed, 483 insertions(+), 601 deletions(-) delete mode 100644 docs/content/pages/tutorials/api.md delete mode 100644 docs/content/pages/tutorials/details.md delete mode 100644 docs/content/pages/tutorials/dialogue.md create mode 100644 docs/content/pages/tutorials/getting_started.md create mode 100644 docs/content/pages/tutorials/planet_gen.md create mode 100644 docs/content/pages/tutorials/reading_schemas.md delete mode 100644 docs/content/pages/tutorials/star_system.md delete mode 100644 docs/content/pages/tutorials/translation.md delete mode 100644 docs/content/pages/tutorials/update_existing.md create mode 100644 docs/content/static/images/getting_started/mod_manager_show_in_explorer.webp create mode 100644 docs/content/static/images/reading_schemas/body_schema_1.webp create mode 100644 docs/content/static/images/reading_schemas/body_schema_2.webp create mode 100644 docs/content/static/images/reading_schemas/body_schema_3.webp create mode 100644 docs/content/static/images/reading_schemas/body_schema_4.webp diff --git a/docs/content/pages/home.md b/docs/content/pages/home.md index 534cda0c..fa228b44 100644 --- a/docs/content/pages/home.md +++ b/docs/content/pages/home.md @@ -8,118 +8,11 @@ Sort_Priority: 100 # Outer Wilds New Horizons -This is the official documentation for [New Horizons](https://github.com/xen-42/outer-wilds-new-horizons), a framework for creating custom planets in the game [Outer Wilds](https://www.mobiusdigitalgames.com/outer-wilds.html) by Mobius Digital. Planets are created using simple JSON and XML files and are loaded at runtime. An [API]({{ "API"|route }}) is also provided for more advanced use-cases. +This is the official documentation for [New Horizons](https://github.com/xen-42/outer-wilds-new-horizons), a framework for creating custom planets in the game [Outer Wilds](https://www.mobiusdigitalgames.com/outer-wilds.html) by Mobius Digital. Planets are created using simple JSON and XML files and are loaded at runtime. An [API]({{ "API"|route }}) is also provided for more advanced use-cases. ## Getting Started -Before starting, go into your in-game mod settings for New Horizons and switch Debug mode on. This allows you to: - -- Use the [Prop Placer tool]({{ "detailing"|route }}#using-the-prop-placer). This convienence tool allows you to place details in game and save your work to your config files. -- Print the position of what you are looking at to the logs by pressing "P". This is useful for determining locations to place props the Prop Placer is unable to, such as signal scope points or dialogue triggers. -- Use the "Reload Configs" button in the pause menu. This will restart the current solar system and update all the planets. Much faster than quitting and relaunching the game. - -!!! alert-danger "Get VSCode" - Please get [VSCode](https://code.visualstudio.com/){ target="_blank" } or some other advanced text editor, as it will help highlight common errors. - -Planets are created using a JSON file format structure, and placed in a folder called planets (or in any subdirectory of it) in the location where New Horizons is installed (by default this folder doesn't exist, you have to create it within the xen.NewHorizons directory). You can learn how the configs work by picking apart the [Real Solar System](https://github.com/xen-42/outer-wilds-real-solar-system){ target="_blank" } mod or the [New Horizons Examples](https://github.com/xen-42/ow-new-horizons-examples){ target="_blank" } mod. - -To locate this directory, click the "⋮" symbol next to "New Horizons" in the Outer Wilds Mod Manager and then click " -show in explorer" in the pop-up. - -![Click the three dots in the mod manager]({{ "images/home/mod_manager_dots.webp"|static }}) - -![Create a new folder named "planets"]({{ "images/home/create_planets.webp"|static }}) - -Planets can also be placed in a folder called planets within a separate mod, if you plan on releasing your planets on the mod database. The [Config Template](https://github.com/xen-42/ow-new-horizons-config-template){ target="_blank" } is available if you want to release your own planet mod using configs. - -Now that you have created your planets folder, this is where you will put your planet config files. A config file will -look something like this: - -```json -{ - "name": "Wetrock", - "$schema": "https://raw.githubusercontent.com/xen-42/outer-wilds-new-horizons/main/NewHorizons/Schemas/body_schema.json", - "starSystem": "SolarSystem", - "Base": { - "groundSize": 100, - "surfaceSize": 101, - "surfaceGravity": 12, - "hasMapMarker": true - }, - "Orbit": { - "semiMajorAxis": 1300, - "inclination": 0, - "primaryBody": "TIMBER_HEARTH", - "isMoon": true, - "isTidallyLocked": true, - "longitudeOfAscendingNode": 0, - "eccentricity": 0, - "argumentOfPeriapsis": 0 - }, - "Atmosphere": { - "size": 150, - "fogTint": { - "r": 200, - "g": 255, - "b": 255, - "a": 255 - }, - "fogSize": 150, - "fogDensity": 0.2, - "hasRain": true - }, - "Props": { - "scatter": [ - { - "path": "DreamWorld_Body/Sector_DreamWorld/Sector_DreamZone_1/Props_DreamZone_1/OtherComponentsGroup/Trees_Z1/DreamHouseIsland/Tree_DW_M_Var", - "count": 12 - } - ] - } -} -``` - -The first field you should have in any config file is the `name`. This should be unique in the solar system. If it -isn't, the mod will instead try to modify the planet that already has that name. - -After `name` is `starSystem`. You can use this to place the planet in a different system accessible using a black-hole or via the ship's warp drive (accessible from the ship log computer). To ensure compatibility with other mods this name should be unique. After setting a value for this, the changes in the config will only affect that body in that star system. By default, it is "SolarSystem", which is the scene from the stock game. - -Including the "$schema" line is optional, but will allow your text editor to highlight errors and auto-suggest words in your config. I recommend using VSCode as a text editor, but anything that supports Json files will work. Something as basic as notepad will work but will not highlight any of your errors. - -The config file is then split into modules, each one with its own fields that define how that part of the planet will be generated. In the example above I've used the `Base`, `Orbit`, `Atmosphere`, and `Props` modules. A config file must have a `Base` and `Orbit` module, the rest are optional. - -Each `{` must match up with a closing `}` to denote its section. If you don't know how JSONs work then check Wikipedia. - -Modules look like this: - -```json -{ - "Star": { - "size": 3000, - "tint": { - "r": 201, - "g": 87, - "b": 55, - "a": 255 - } - } -} -``` - -In this example the `Star` module has a `size` field and a `tint` field. Since the colour is a complex object it needs -another set of `{` and `}` around it, and then it has its own fields inside it : `r`, `g`, `b`, and `a`. Don't forget to put -commas after each field. - -Most fields are either true/false, a decimal number, and integer number, or a string (word with quotation marks around -it). - -To see all the different things you can put into a config file check out the [Celestial Body schema]({{ 'Celestial Body Schema'|route}}). - -Check out the rest of the site for how to format [star system]({{ 'Star System Schema'|route}}), [dialogue]({{ 'Dialogue Schema'|route}}), [ship log]({{ 'Shiplog Schema'|route}}), and [translation]({{ 'Translation Schema'|route}}) files! - -## Publishing Your Mod - -Once your mod is complete, you can use the [planet creation template](https://github.com/xen-42/ow-new-horizons-config-template#readme){ target="_blank" } GitHub template. +For a guide on getting started an getting familiar with New Horizons, go to the [Getting Started]({{ "Getting Started"|route }}) page. ## Helpful Resources diff --git a/docs/content/pages/tutorials/api.md b/docs/content/pages/tutorials/api.md deleted file mode 100644 index 8689943c..00000000 --- a/docs/content/pages/tutorials/api.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -Title: API -Sort_Priority: 40 ---- - -## How to use the API - -First create the following interface in your mod: - -```cs -public interface INewHorizons -{ - void LoadConfigs(IModBehaviour mod); - - GameObject GetPlanet(string name); - - string GetCurrentStarSystem(); - - UnityEvent GetChangeStarSystemEvent(); - - UnityEvent GetStarSystemLoadedEvent(); - - GameObject SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, float scale, bool alignWithNormal); - - string[] GetInstalledAddons(); -} -``` - -In your main `ModBehaviour` class you can get the NewHorizons API like so: - -```cs -public class MyMod : ModBehaviour -{ - void Start() - { - INewHorizons NewHorizonsAPI = ModHelper.Interaction.GetModApi("xen.NewHorizons"); - } -} -``` - -You can then use the APIs `LoadConfigs()` method to load from a "planets" folder, or use the `GetPlanet()` method to get planets and do whatever with them. Just make sure you create planets in the `Start()` method or at least before the SolarSystem scene loads, or they will not be created. - -The `GetChangeStarSystemEvent` and `GetStarSystemLoadedEvent` events let you listen in for when the player starts changing to a new system (called when entering a black hole or using the warp drive) and when the system is fully loaded in, respectively. - -You can also use the `GetInstalledAddons` method to get a list of addons that are installed and enabled. - -You can also use `SpawnObject` to directly copy a base-game GameObject to the specified position and rotation. diff --git a/docs/content/pages/tutorials/details.md b/docs/content/pages/tutorials/details.md deleted file mode 100644 index 41f704b3..00000000 --- a/docs/content/pages/tutorials/details.md +++ /dev/null @@ -1,167 +0,0 @@ ---- -Title: Detailing -Sort_Priority: 85 ---- - -# Details/Scatterer - -For physical objects there are currently two ways of setting them up: specify an asset bundle and path to load a custom asset you created, or specify the path to the item you want to copy from the game in the scene hierarchy. Use the [Unity Explorer](https://outerwildsmods.com/mods/unityexplorer){ target="_blank" } mod to find an object you want to copy onto your new body. Some objects work better than others for this. Good luck. Some pointers: - -- Use "Object Explorer" to search -- Do not use the search functionality on Scene Explorer, it is really, really slow. Use the "Object Search" tab instead. -- Generally you can find planets by writing their name with no spaces/punctuation followed by "_Body". -- There's also [this community-maintained list of props](https://docs.google.com/spreadsheets/d/1VJaglB1kRL0VqaXhvXepIeymo93zqhWex-j7_QDm6NE/edit?usp=sharing) which you can use to find interesting props and check to see if they have collision. - -## Using the Prop Placer - -The Prop Placer is a convenience tool that lets you manually place details from inside the game. Once enabled, press "G" and your currently selected prop will be placed wherever your crosshair is pointing. - -### Enabling - -1. Pause the game. You will see an extra menu option titled "Toggle Prop Placer Menu". Click it -2. The prop placer menu should now be open. At the bottom of the menu, you will see a list of mods. Click yours. - 1. This menu scrolls. If you do not see your mod, it may be further down the list. -3. The Prop Placer is now active! Unpause the game and you can now place Nomai vases using "G" - -### How to Save - -1. In the Prop Placer Menu, you will see a greyed out button titled "Update your mod's configs". -2. Click the small button to the left of it. -3. Click "Update your mod's configs" to save! - -!!! alert-danger "IMPORTANT" - Your updated configs will save *only* to your mod's build folder, eg "AppData\Roaming\OuterWildsModManager\OWML\Mods\you.yourModName" - -!!! alert-warning "WARNING" - Dying in-game will cause you to lose all work since you last saved. Make sure to save often. - -What's that? You want to place something other than just vases? Well I can't say I agree with your choices, but here's how you would do that. - -### How to Select Props - -1. Pause the game again. The prop placer menu should still be visible. -2. At the top of the menu, you'll see a text box contianing the path for the vase. Replace this with the path for the prop you want to place. For example: `DreamWorld_Body/Sector_DreamWorld/Sector_DreamZone_1/Props_DreamZone_1/OtherComponentsGroup/Trees_Z1/DreamHouseIsland/Tree_DW_M_Var` -3. Tip: use the Unity Explorer mod to find the path for the object you want to place. You only have to do this once. -4. Unpause the game and press "G". Say hello to your new tree! -5. Pause the game again. You will now see the prop you just placed on the list of recently placed props just below the "path" text box. -6. Click on the button titled "Prefab_NOM_VaseThin". You can now place vases again. - -### Extra features - -1. Made a mistake? **Press the "-" key to undo.** Press the "+" key to redo. -2. If you have the Unity Explorer mod enabled, you can use this to tweak the position, rotation, and scale of your props. Your changes will be saved. -3. Want to save some recently placed props between game launches? On the recently placed props list, click the star next to the prop's name to favorite it. -4. Found a bug that ruined your configs? Check `AppData\Roaming\OuterWildsModManager\OWML\Mods\xen.NewHorizons\configBackups` for backup saves of your work. Folders are titled "\[date\]T\[time\]". -5. Want to add props to Ember Twin but don't feel like making a config file for it? We got you! Place that prop and the config file will be created automatically on your next save. -6. This even works for planets that were created by other mods! - -## Asset Bundles - -Here is a template project: [Outer Wilds Unity Template](https://github.com/xen-42/outer-wilds-unity-template){ target="_blank" } - -The template project contains ripped versions of all the game scripts, meaning you can put things like DirectionalForceVolumes in your Unity project to have artificial gravity volumes loaded right into the game. - -If for whatever reason you want to set up a Unity project manually instead of using the template, follow these instructions: - -1. Start up a Unity 2017 project (I use Unity 2017.4.40f1 (64-bit), so if you use something else I can't guarantee it will work). The DLC updated Outer Wilds to 2019.4.27 so that probably works, but I personally haven't tried it. -2. In the "Assets" folder in Unity, create a new folder called "Editor". In it create a file called "CreateAssetBundle.cs" with the following code in it: - -```cs -using UnityEditor; -using UnityEngine; -using System.IO; - -public class CreateAssetBundles -{ - [MenuItem("Assets/Build AssetBundles")] - static void BuildAllAssetBundles() - { - string assetBundleDirectory = "Assets/StreamingAssets"; - if (!Directory.Exists(Application.streamingAssetsPath)) - { - Directory.CreateDirectory(assetBundleDirectory); - } - BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64); - } -} -``` - -3. Create your object in the Unity scene and save it as a prefab. -4. Add all files used (models, prefabs, textures, materials, etc.) to an asset bundle by selecting them and using the dropdown in the bottom right. Here I am adding a rover model to my "rss" asset bundle for the Real Solar System add-on. -![setting asset bundle]({{ 'images/detailing/asset_bundle.webp'|static }}) - -5. In the top left click the "Assets" drop-down and select "Build AssetBundles". This should create your asset bundle in a folder in the root directory called "StreamingAssets". -6. Copy the asset bundle and asset bundle .manifest files from StreamingAssets into your mod's "planets" folder. If you did everything properly they should work in game. To double-check everything is included, open the .manifest file in a text editor to see the files included and their paths. - -## Importing a planet's surface from Unity - -Making a planet's entire surface from a Unity prefab is the exact same thing as adding one single big detail at position (0, 0, 0). - -## Examples - -To add a Mars rover to the red planet in [RSS](https://github.com/xen-42/outer-wilds-real-solar-system), its model was put in an asset bundle as explained above, and then the following was put into the `Props` module: - -```json -{ - "Props": { - "Details": [ - { - "assetBundle": "planets/assetbundle/rss", - "path": "Assets/RSS/Prefabs/Rover.prefab", - "position": { - "x": 146.5099, - "y": -10.83688, - "z": -36.02736 - }, - "alignToNormal": true - } - ] - } -} -``` - -To scatter 12 trees from the Dream World around Wetrock in [NH Examples](https://github.com/xen-42/ow-new-horizons-examples) , the following was put into the `Props` module: - -```json -{ - "Props": { - "Scatter": [ - { - "path": "DreamWorld_Body/Sector_DreamWorld/Sector_DreamZone_1/Props_DreamZone_1/OtherComponentsGroup/Trees_Z1/DreamHouseIsland/Tree_DW_M_Var", - "count": 12 - } - ] - } -} -``` - -You can swap these around too. The following would scatter 12 Mars rovers across the planet and place a single tree at a given position: - -```json -{ - "Props": { - "Details": [ - { - "path": "DreamWorld_Body/Sector_DreamWorld/Sector_DreamZone_1/Props_DreamZone_1/OtherComponentsGroup/Trees_Z1/DreamHouseIsland/Tree_DW_M_Var", - "position": { - "x": 146.5099, - "y": -10.83688, - "z": -36.02736 - }, - "alignToNormal": true - } - ], - "Scatter": [ - { - "assetBundle": "planets/assetbundle/rss", - "path": "Assets/RSS/Prefabs/Rover.prefab", - "count": 12 - } - ] - } -} -``` - -## Use the schema - -To view additional options for detailing, check [the schema]({{ "Celestial Body Schema"|route}}#Props_details) diff --git a/docs/content/pages/tutorials/dialogue.md b/docs/content/pages/tutorials/dialogue.md deleted file mode 100644 index 63a7fbb7..00000000 --- a/docs/content/pages/tutorials/dialogue.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -Title: Dialogue -Description: Guide to making dialogue in New Horizons -Sort_Priority: 50 ---- - -# Dialogue - -This page goes over how to use dialogue in New Horizons. - -# Understanding Dialogue - -## Dialogue Tree - -A dialogue tree is an entire conversation, it's made up of dialogue nodes. - -## Dialogue Node - -A node is a set of pages shown to the player followed by options the player can choose from to change the flow of the conversation. - -## Condition - -A condition is a yes/no value stored **for this loop and this loop only**. It can be used to show new dialogue options, stop someone from talking to you (looking at you Slate), and more. - -## Persistent Condition - -A persistent condition is similar to a condition, except it *persists* through loops, and is saved on the player's save file. - -## Remote Trigger - -A remote trigger is used to have an NPC talk to you from a distance; ex: Slate stopping you for the umpteenth time to tell you information you already knew. - -# Example XML - -Here's an example dialogue XML: - -```xml - - - - EXAMPLE NPC - - - Start - DEFAULT - - Start - Start Part 2 - - - - - Goto 1 - 1 - - - - Goto 2 - 2 - - - Goto End - End - - - - - - 1 - - - This is 1 - - - - - Goto 2 - 2 - - - Goto End - End - - - - - - 2 - - This is 2 - - - - - Goto 1 - 1 - - - Goto End - End - - - - - - End - - This is the end - - - - -``` - -# Using the XML - -To use the dialogue XML you have created, you simply need to reference it in the `dialogue` prop - -```json -{ - "Props": { - "dialogue": [ - { - "position": {"x": 5, "y": 10, "z": 0}, - "xmlFile": "planets/path/to/your_file.xml" - } - ] - } -} -``` - -# Dialogue Config - -To view the options for the dialogue prop, check [the schema]({{ "Celestial Body Schema"|route }}#Props_dialogue) - -# Controlling Conditions - -You can set condition in dialogue with the `` and `` tags - -```xml - - - EXAMPLE_CONDITION - EXAMPLE_P_CONDITION - - -``` - -# Dialogue Options - -There are many control structures for dialogue options to hide/reveal them if conditions are met. Take a look at [the DialogueOption schema]({{ "Dialogue Schema"|route }}#DialogueTree-DialogueNode-DialogueOptionsList-DialogueOption-DialogueTarget) for more info. - -# Controlling Flow - -In addition to ``, there are other ways to control the flow of the conversation. - -## DialogueTarget - -Defining `` in the `` tag instead of a `` will make the conversation go directly to that target after the character is done talking. - -## DialogueTargetShipLogCondition - -Used in tandum with `DialogueTarget`, makes it so you must have a [ship log fact]({{ "Ship Log"|route }}#explore-facts) to go to the next node. diff --git a/docs/content/pages/tutorials/getting_started.md b/docs/content/pages/tutorials/getting_started.md new file mode 100644 index 00000000..8f06fcb8 --- /dev/null +++ b/docs/content/pages/tutorials/getting_started.md @@ -0,0 +1,255 @@ +--- +Title: Getting Started +Sort_Priority: 100 +--- + +# Getting Started + +Congrats on taking the first step to becoming an addon developer! +This tutorial will outline how to begin learning to use new horizons. + +## Recommended Tools + +It's strongly recommended you get [VSCode](https://code.visualstudio.com/){ target="_blank" } to edit your files, as it can provide syntax and error highlighting. + +## Using The Sandbox + +Making an entirely separate addon can get a little complicated, so New Horizons provides a way to play around without the need to set up a full addon. +To get started, navigate to your mod manager and click the ⋮ symbol, then select "Show In Explorer". + +![Select "Show in explorer"]({{ "images/getting_started/mod_manager_show_in_explorer.webp"|static }}) + +Now, in explorer and create a new folder named "planets". As the name suggests, New Horizons will search the files in this folder for planets to generate. + +## Making Your First Planet + +To get started, create a new file in this folder called `wetrock.json`, we'll explain what that .json at the end means soon. +Open this file in VSCode (you can do so by right-clicking the file and clicking "Open with Code") +Once in VSCode, paste this code into the file: + +```json +{ + "name": "Wetrock", + "$schema": "https://raw.githubusercontent.com/xen-42/outer-wilds-new-horizons/main/NewHorizons/Schemas/body_schema.json", + "starSystem": "SolarSystem", + "Base": { + "groundSize": 100, + "surfaceSize": 101, + "surfaceGravity": 12, + "hasMapMarker": true + }, + "Orbit": { + "semiMajorAxis": 1300, + "primaryBody": "TIMBER_HEARTH", + "isMoon": true, + "isTidallyLocked": true + }, + "Atmosphere": { + "size": 150, + "fogTint": { + "r": 200, + "g": 255, + "b": 255, + "a": 255 + }, + "fogSize": 150, + "fogDensity": 0.2, + "hasRain": true + } +} +``` + +This language is **J**ava**S**cript **O**bject **N**otation, or JSON. +It's a common way to convey data in many programs. + +## Understanding JSON + +All JSON files start out with an `object`, or a set of key value mappings, for example is we represent a person as JSON it might look like: + +```json +{ + "name": "Jim" +} +``` + +Those braces (`{}`) denote an object, and by doing `"name": "Jim"` we're saying that the name of this object (in this case person) is Jim +`"name"` is the key, and `"Jim"` is the value. + +Objects can have multiple keys as well, as long as you separate them by commas: + +```json +{ + "name": "Jim", + "age": 23 +} +``` + +But wait! why is `Jim` in quotation marks while `23` isn't? that's because of a little something called data types. +Each value has a datatype, in this case `"Jim"` is a `string`, because it represents a *string* of characters. +Age is a `number`, it represents a numerical value. If we put 23 in quotation marks, its data type switches from a number to a string. +And if we remove the quotation marks from `"Jim"` we get a syntax error. Datatypes are a common source of errors, which is why we recommend using an editor like VSCode. + +### JSON Data Types + +Here's a list of data types you'll use when making your addons: + +#### String + +A string of characters surrounded in quotation marks + +```json +"Im a string!" +``` + +If you need to use quotation marks within your string, place a backslash (`\`) before them + +```json +"\"Im a string!\" - Mr. String Stringerton" +``` + +#### Number + +A numerical value, can be negative and have decimals, **not** surrounded in quotation marks + +```json +-25.3 +``` + +#### Boolean + +A `true` or `false` value, think of it like an on or off switch + +```json +true +``` + +#### Array + +A set of values, values can be of any data type. Items are seperated by commas + +```json +[23, 45, 56] +``` + +```json +["Bob", "Suzy", "Mark"] +``` + +And they can be empty like so: + +```json +[] +``` + +#### Object + +A set of key value pairs, where each key is a string and each value can be of any data type (even other objects!) + +```json +{ + "name": "Jim", + "age": 23, + "isMarried": false, + "clothes": { + "shirtColor": "red", + "pantsColor": "blue" + }, + "friends": ["Bob", "Wade"], + "enemies": [] +} +``` + +## Back to Wetrock + +Now that we understand JSON better, let's look at that config file again: + +```json +{ + "name": "Wetrock", + "$schema": "https://raw.githubusercontent.com/xen-42/outer-wilds-new-horizons/main/NewHorizons/Schemas/body_schema.json", + "starSystem": "SolarSystem", + "Base": { + "groundSize": 100, + "surfaceSize": 101, + "surfaceGravity": 12, + "hasMapMarker": true + }, + "Orbit": { + "semiMajorAxis": 1300, + "primaryBody": "TIMBER_HEARTH", + "isMoon": true, + "isTidallyLocked": true + }, + "Atmosphere": { + "size": 150, + "fogTint": { + "r": 200, + "g": 255, + "b": 255, + "a": 255 + }, + "fogSize": 150, + "fogDensity": 0.2, + "hasRain": true + } +} +``` + +Here we can see we have a planet object, which name is "Wetrock", and is in the "SolarSystem" (Base-game) star system. +It has an object called Base, which has a groundSize of 100, and a surfaceSize of 101, and the list continues on. + +Alright so now that we understand how the file is structures, let's look into what each value actually does: + +- `name` simply sets the name of the planet +- `$schema` we'll get to in a second +- `starSystem` specifies what star system this planet is located in, in this case we're using the base game star system, so we put "SolarSystem" + - Then it has an object called `Base` + - Base has a `groundSize` of 100, this generates a perfect sphere that is 100 units in radius as the ground of our planet + - It also has a `surfaceSize` of 101, surface size is used in many calculations, it's generally good to set it to a bit bigger than ground size. + - `surfaceGravity` describes the strength of gravity on this planet, in this case it's 12 which is the same as Timber Hearth + - `hasMapMarker` tells new horizons that we want this planet to have a marker on the map screen + - Next it has another object called `Orbit` + - `semiMajorAxis` specifies the radius of the orbit (how far away the body is from its parent) + - `primaryBody` is set to TIMBER_HEARTH, this makes our planet orbit timber hearth + - `isMoon` simply tells the game how close you have to be to the planet in map mode before its name appears + - `isTidallyLocked` makes sure that one side of our planet is always facing timber hearth (the primary body) + - Finally, we have `Atmosphere` + - Its `size` is 150, this simply sets how far away from the planet our atmosphere stretches + - Its `fogTint` is set to a color which is an object with r, g, b, and a properties (properties is another word for keys) + - `fogSize` determines how far away the fog stretches from the planet + - `fogDensity` is simply how dense the fog is + - `hasRain` makes rainfall on the planet + +### What's a Schema? + +That `$schema` property is a bit special, it instructs VSCode to use a pre-made schema to provide a better editing experience. +With the schema you get: + +- Automatic descriptions for properties when hovering over keys +- Automatic error detection for incorrect data types or values +- Autocomplete, also called IntelliSense + +## Testing The Planet + +With the new planet created (*and saved!*), launch the game through the mod manager and click resume expedition. If all went well you should be able to open your map and see wetrock orbiting Timber Hearth. + +If you run into issues please make sure: + +- You placed the JSON file in a folder called `planets` in the New Horizons mod folder +- There are no red or yellow squiggly lines in your file + +## Experiment! + +With that, try tweaking some value like groundSize and semiMajorAxis, get a feel for how editing JSON works. + +## Reloading Configs + +It can get annoying when you have to keep closing and opening the game over and over again to test changes, that's why New Horizons has a "Reload Configs" feature. +To enable it, head to your Mods menu and select New Horizons and check the box that says Debug, this will cause a "Reload Configs" option to appear in your pause menu which will reload changes from your filesystem. +You may also notice blue and yellow logs start appearing in your console, this is New Horizons providing additional info on what it's currently doing, it can be helpful when you're trying to track down an issue. + +## More Objects + +Base, Atmosphere, and Orbit aren't all the objects (or "modules") there are to use, to learn about these other objects, you'll need to learn how to use the "Schemas" section of this site, which lists every possible property you can put in your files. + +**Next Up: [Reading Schemas]({{ "Reading Schemas"|route }})** diff --git a/docs/content/pages/tutorials/planet_gen.md b/docs/content/pages/tutorials/planet_gen.md new file mode 100644 index 00000000..a7c0e3ec --- /dev/null +++ b/docs/content/pages/tutorials/planet_gen.md @@ -0,0 +1,148 @@ +--- +Title: Planet Generation +Sort_Priority: 80 +--- + +# Planet Generation + +The first thing you'll need to create on a planet is its surface, this can be done in a variety of ways + +## Surface + +Ground of the planet + +### Ground Size + +`groundSize` is the absolute simplest way to make a planet's surface, you simply specify a radius and New Horizons will make a sphere for you. + +```json +{ + "name": "My Cool Planet", + "Base": { + "groundSize": 100 + } +} +``` + +### Heightmaps + +Heightmaps are a way to generate unique terrain on your planet. First you specify a maximum and minimum height, and then specify a [heightMap]({{ "Celestial Body Schema"|route }}#HeightMap_heightMap) image. The more white a section of that image is, the closer to `maxHeight` that part of the terrain will be. Finally, you specify a `textureMap` which is an image that gets applied to the terrain. + + + +```json +{ + "name": "My Cool Planet", + "HeightMap": { + "minHeight": 5, + "maxHeight": 100, + "heightMap": "planets/assets/my_cool_heightmap.png", + "textureMap": "planets/assets/my_cool_texturemap.png" + } +} +``` + +There are also tools to help generate these images for you such as [Textures For Planets](https://www.texturesforplanets.com/){ target="_blank" }. + +## Variable Size Modules + +The following modules support variable sizing, meaning they can change scale over the course of the loop. + +- Water +- Lava +- Star +- Sand +- Funnel +- Ring + +To do this, simply specify a `curve` property on the module + +```json +{ + "name": "My Cool Planet", + "Water": { + "curve": [ + { + "time": 0, + "value": 100 + }, + { + "time": 22, + "value": 0 + } + ] + } +} +``` + +This makes the water on this planet shrink over the course of 22 minutes. + +## Quantum Planets + +In order to create a quantum planet, first create a normal planet. Then, create a second planet config with the same `name` as the first and `isQuantumState` set to `true`. +This makes the second planet a quantum state of the first, anything you specify here will only apply when the planet is in this state. + +```json +{ + "name": "MyPlanet", + "Orbit": { + "semiMajorAxis": 5000, + "primaryBody": "Sun" + } +} +``` + +```json +{ + "name": "MyPlanet", + "isQuantumState": true, + "Orbit": { + "semiMajorAxis": 1300, + "primaryBody": "TIMBER_HEARTH" + } +} +``` + +## Barycenter (Focal Point) + +To create a binary system of planets (like ash twin and ember twin), first create a config with `FocalPoint` set + +```json +{ + "name": "My Focal Point", + "Orbit": { + "semiMajorAxis": 22000, + "primaryBody": "Sun" + }, + "FocalPoint": { + "primary": "Planet A", + "secondary": "Planet B" + } +} +``` + +Now in each config set the `primaryBody` to the focal point + +```json +{ + "name": "Planet A", + "Orbit": { + "primaryBody": "My Focal Point", + "semiMajorAxis": 0, + "isTidallyLocked": true, + "isMoon": true + } +} +``` + +```json +{ + "name": "Planet B", + "Orbit": { + "primaryBody": "My Focal Point", + "semiMajorAxis": 440, + "isTidallyLocked": true, + "isMoon": true + } +} +``` diff --git a/docs/content/pages/tutorials/reading_schemas.md b/docs/content/pages/tutorials/reading_schemas.md new file mode 100644 index 00000000..13a6a1cc --- /dev/null +++ b/docs/content/pages/tutorials/reading_schemas.md @@ -0,0 +1,78 @@ +--- +Title: Reading Schemas +Sort_Priority: 90 +--- + +# Reading Schema Pages + +Reading and understanding the schema pages are key to knowing how to create planets. While these tutorials may be helpful, they won't cover everything, and new features may be added before the tutorial on them can be written. + +## Celestial Body Schema + +The [celestial body schema]({{ "Celestial Body Schema"|route }}) is the schema for making planets, there are other schemas which will be explained later but for now let's focus on this one. + +![The Celestial Body Schema Page]({{ "images/reading_schemas/body_schema_1.webp"|static }}) + +As you can see the type of this is `object`, which we talked about in the previous section. +We can also observe a blue badge that says "No Additional Properties", this signifies that you can't add keys to the object that aren't in the schema, for example: + +```json +{ + "name": "Wetrock", + "coolKey": "Look at my cool key!" +} +``` + +Will result in a warning in VSCode. Now, this will *not* prevent the planet from being loaded, however you should still avoid doing it. + +## Simple Properties + +![The name property on the celestial body schema]({{ "images/reading_schemas/body_schema_2.webp"|static }}) + +Next up let's look at `name`, this field is required, meaning you *have* to have it for a planet to load. +When we click on name we first see a breadcrumb, this is essentially a guide of where you are in the schema, right now we're in the name property of the root (topmost) object. +We can also see it's description, its type is `string`, and that it requires at least one character (so you can't just put `""`). + +Badges can also show stuff such as the default value, the minimum and maximum values, and more. + +## Object Properties + +![The Base object on the celestial body schema]({{ "images/reading_schemas/body_schema_3.webp"|static }}) + +Next let's look at an `object` withing our root `object`, let's use `Base` as the example. + +Here we can see it's similar to our root object, in that it doesn't allow additional properties. +We can also see all of its properties listed out. + +## Array Properties + +Now let's take a look over at [removeChildren]({{ "Celestial Body Schema"|route }}#removeChildren) to see how arrays work (if you're wondering how you can get the page to scroll to a specific property, simply click on the property and copy the URL in your URL bar) + +![The curve property on a star in the celestial body schema]({{ "images/reading_schemas/body_schema_4.webp"|static }}) + +Here we can see that the type is an `array`, and each item in this array must be a `string` + +## Some Vocabulary + +- GameObject: Essentially just any object in, well, the game. You can view these object in a tree-like structure with the [Unity Explorer](https://outerwildsmods.com/mods/unityexplorer) mod. Every GameObject has a path, which is sort of like a file path in that it's a list of parent GameObjects seperated by forward slashes followed by the GameObject's name. +- Component: By themselves, a GameObject doesn't actually *do* anything, components provide stuff like collision, rendering, and logistics to GameObjects +- Config: Just another name for a JSON file "planet config" simply means a json file that describes a planet +- Module: A specific section of the config (e.g. Base, Atmosphere, etc), these usually start with capital letters + +## Note About File Paths + +Whenever a description refers to the "relative path" of a file, it means relative to the mod's directory, this means you **must** include the `planets` folder in the path: + +```json +"planets/assets/images/MyCoolImage.png" +``` + +## Other Schemas + +There are other schemas available, some are for JSON, and some are for XML. + +## Moving Forward + +Now that you know how to read the schema pages, you can understand the rest of this site. A lot of the other tutorials here will often tell you to take a look at schemas to explain what certain properties do. + +**Next Up: [Planet Generation]({{ "Planet Generation"|route }})** diff --git a/docs/content/pages/tutorials/star_system.md b/docs/content/pages/tutorials/star_system.md deleted file mode 100644 index 734a9b61..00000000 --- a/docs/content/pages/tutorials/star_system.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -Title: Star System -Description: A guide to editing a custom star system in New Horizons -Sort_Priority: 90 ---- - -# Intro - -Welcome! This page outlines how to edit a custom star system. - -## Getting Started - -Star Systems are placed in a folder called systems within your mod folder. - -The name of your star system config must be the same as the unique id used in the `starSystem` field of your planet configs. Example: `xen.RealSolarSystem.json`. - -A star system config file will look something like this: - -```json -{ - "$schema": "https://raw.githubusercontent.com/xen-42/outer-wilds-new-horizons/main/NewHorizons/Schemas/star_system_schema.json", - "coords": { - "x": [ 4, 0, 3, 1 ], - "y": [ 0, 5, 4 ], - "z": [ 5, 4, 0, 3, 1 ] - }, - "vesselPosition": { - "x": 0, - "y": 0, - "z": 8000 - } -} -``` - -To see all the different things you can put into a config file check out the [Star System Schema]({{ 'Star System Schema'|route}}). - -## Vessel Coordinates - -You can warp to custom star systems via the Nomai vessel. Each coordinate has to be 2-6 points long. -These are the points for each coordinate node. When making your unique coordinate you should only use each point once. -![nomaiCoordinateIndexes]({{ "images/star_system/nomai_coordinate_indexes.webp"|static }}) - -### Hearthian Solar System Vessel Coordinates - -You can use these coordinates to warp back to the hearthian solar system. -![hearthianSolarSystemCoordinates]({{ "images/star_system/hearthian_solar_system_coordinates.webp"|static }}) \ No newline at end of file diff --git a/docs/content/pages/tutorials/translation.md b/docs/content/pages/tutorials/translation.md deleted file mode 100644 index a4702901..00000000 --- a/docs/content/pages/tutorials/translation.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -Title: Translations -Sort_Priority: 60 ---- - -## Translations - -There are 12 supported languages in Outer Wilds: english, spanish_la, german, french, italian, polish, portuguese_br, japanese, russian, chinese_simple, korean, and turkish. - -All translations must go in a folder in the root directory called "translations". - -In this folder you can put json files with the name of the language you want to translate for. Inside this file just follow the translation schema. - -Here's an example, for `russian.json`: - -```json -{ - "$schema": "https://raw.githubusercontent.com/xen-42/outer-wilds-new-horizons/main/NewHorizons/Schemas/translation_schema.json", - "DialogueDictionary" : - { - "Fred" : "Фред", - "You looking at something?" : "Ты что-то искал?", - "Aren't you guys all supposed to be dead?" : "А разве номаи не вымерли?", - "OH MY GOD A LIVING NOMAI AHHH WHAT HOW?!" : "ААААА, ЖИВАЯ НОМАИ?!" - }, - "ShipLogDictionary" : - { - "Unexpected guests" : "Незванные гости", - "Visitors" : "Гости", - "When I went to sleep by the campfire only Slate was here, who are these characters?" : "Когда я ложился спать у костра здесь был только Сланец. Кто все остальные?", - "I met a talking jellyfish. His name is Geswaldo!" : "Я встретил говорящую медузу. Его зовут Гесвальдо!" - } -} -``` diff --git a/docs/content/pages/tutorials/update_existing.md b/docs/content/pages/tutorials/update_existing.md deleted file mode 100644 index 7e67ea0a..00000000 --- a/docs/content/pages/tutorials/update_existing.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -Title: Update Planets -Sort_Priority: 80 ---- - -## Update Existing Planets - -Similar to above, make a config where "Name" is the name of the planet. The name should be able to just match their in-game english names, however if you encounter any issues with that here are the in-code names for planets that are guaranteed to work: `SUN`, `CAVE_TWIN` (Ember Twin), `TOWER_TWIN` (Ash Twin), `TIMBER_HEARTH`, `BRITTLE_HOLLOW`, `GIANTS_DEEP`, `DARK_BRAMBLE`, `COMET` (Interloper), `WHITE_HOLE`, `WHITE_HOLE_TARGET` (Whitehole station I believe), `QUANTUM_MOON`, `ORBITAL_PROBE_CANNON`, `TIMBER_MOON` (Attlerock), `VOLCANIC_MOON` (Hollow's Lantern), `DREAMWORLD`, `MapSatellite`, `RINGWORLD` (the Stranger). - -Only some of the above modules are supported (currently) for existing planets. Things you cannot modify for existing planets include: heightmaps, procedural generation, gravity, or their orbits. You also can't make them into stars or binary focal points (but why would you want to, just delete them and replace them entirely). However this still means there are many things you can do: completely change their atmospheres, give them rings, asteroid belts, comet tails, lava, water, prop details, or signals. - -You can also delete parts of an existing planet. Here's part of an example config which would delete the rising sand from Ember Twin: -```json -{ - "name": "Ember Twin", - "removeChildren": [ - "SandSphere_Rising" - ] -} -``` - -In `childrenToDestroy` you list the relative paths for the children of the planet's gameObject that you want to delete. - -## Destroy Existing Planets - -You do this (but with the appropriate name) as its own config. -```json -{ - "name" : "Ember Twin", - "destroy" : true -} -``` - -Remember that if you destroy Timber Hearth you better put a `Spawn` module on another planet. If you want to entirely replace the solar system you can destroy everything, including the sun. Also, deleting a planet destroys anything orbiting it, so if you want to replace the solar system you can just destroy the sun. If you're making a brand new star system, you don't have to worry about deleting any existing planets; they won't be there. \ No newline at end of file diff --git a/docs/content/static/images/getting_started/mod_manager_show_in_explorer.webp b/docs/content/static/images/getting_started/mod_manager_show_in_explorer.webp new file mode 100644 index 0000000000000000000000000000000000000000..a54601f7be39bf8f8329b6d702ff839040b54778 GIT binary patch literal 14312 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

X{xwQe`&`5Ce1spHneXs-ws6 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
*JZJA0+f_1) z(`Ni@$N>GdX_6?#=_vp6)`N?gtm#llTYWN0iom+^2)JOK2$|Sldnbb(vP?H@{CFKzuslQ}LzpcSB*5pq8u8i6x&R=O`Xg1;lcDps7iKFp)$#1mYvg9V^GF zAF2UZDK{2gs^luY2TYyP3P8s)z46&RMgK=7g=?1-4AKF28oqo#<-MQHKa^ z1S|=*zID|PvKx&;@%^;iE}}6*H`b=AdF<<{)Z6ne{Gv^t^sJp(aJfE+yWk+qt3bYP zFMSB4?>*0x5hZb(Qd9AkC5&)V{cwpwm^~gPyr4SjivpFdwUVX;gNx}qrGcnZhizSc zkvg@!&K6q)4F$(>yE4&{FwxzLtWHBqP3*aBwceZh>ZpdNZ|zIGk6F^HRf;mMCwG-f zY63>%)%IKN*_OO6w`pBPD=9)18gS0yb)J<)ie@G;Yf&k-*B5HYg=m`CTS&_r>I(KpV3t z_!F|F?c<8F;yJx66QxKX?Ks`~NLd?G#+i6xKS1Qzh%R4SbM1j?tXBjKnR#E8eF-To ztE59)Klpb4gK&h3NYL7@kdalj{YvR~Wl>5f%JWrKZ;3|3_jG4EWPUFd?%yRzB`yD4_@fQ1AbB$GDJVnWd~24iY3V~u=rh2 zMiYvpvxB(WouaCr%jf&ugbvD6|HBuVmfNxJ;DD@8xC%soKkeC_ht06z2#C z6~26nj973Wz%;<>nL&`&1mkJel zBY3xc28W$v_9+MVhA)pGpN8WXkyo37<`g%5dbs$?7TK13S|U&9zuBat)e0WbACt;u zP&8d(l*DI;bqTFs$II$ee^lhq{|Wnos!YH!;uuqoAxf$pF=s2!cn8dCK%%QS8jkOI zDi#-tv6e8!MOFy7^HCe)je)M&2xde=%xw_X_I2mda$kEtr}&l|fyrm#3P zacyPwnmyPA`S#C=iI>L1oT^bu28At#girz^M}s&{C+0w|)tiHX=2CxNhQUfwT)xi@ z*Zl-{#Ti`ORn>XyZG~i=M*Ulz{@p_WaF^(NN{m{=h4eVykGQ;5R`prw(*i#{Mv~-h z(aNK{f^?Aixtn`wsh%*cpq_{3g2z3>SmGkPSdwq3x5M)!4)fFt=Og>CdKsXz>f-|j zks!Txhh4Qns?}_^OyehLYqf8~dkvheXek2WcB-$G1@dX*#Kt*@7FUTM%|B{7@mR|X zq2}-*@#AIWGe<%PN^yzLZpeS>%A;sd_$8)JDhxlf5(HX;1ALLKL0gxs6chR@T&PA&;78e zUX3p7N+sbN<6vPr>xj!>%lYgVqm&=TGczo5W|ghN|3=>6UG=LM-q((P zWqAgZccwb4X;h?oV^Llh#w~<}slTRL)KTL;#PzG60{PnJV9Zu5&kYj42+=7AQky;% zV3Z{VJ$z4N8fSOkXAh{BY4$Y*n4!6Mlj_(NHNA?PPxciGr+CqrhRQS5Y9uB0F;+9= zQ#KedC2~0EsQxBdTcgx<`rS;eu2Nls)FThhyUrWZ5-J%{VoKFki_6RA4|#cZ+U*5{ zi)M_#a!%BV%%oi*mDCn*8ktPXz1os; z8!Gy#Pbb&n<+qqePHZu=ZEakASwbNCe)FR~6U7qPa-5Ar;5Cn_KcTCh$M5b&=0of{ bPE@a3d}2hxjv9RZd+86uL}-}P{-5(d1c5z1 literal 0 HcmV?d00001 diff --git a/docs/content/static/images/reading_schemas/body_schema_3.webp b/docs/content/static/images/reading_schemas/body_schema_3.webp new file mode 100644 index 0000000000000000000000000000000000000000..3ca75b144517c9ec02dd049dff972086845b9885 GIT binary patch literal 16610 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 literal 0 HcmV?d00001 From 5e0f0c8faf71da55017deaf75b03f604065ab42a Mon Sep 17 00:00:00 2001 From: Ben C Date: Sat, 23 Jul 2022 18:26:58 -0400 Subject: [PATCH 02/29] Gorbo Mode --- docs/content/pages/tutorials/getting_started.md | 4 ++-- docs/content/pages/tutorials/reading_schemas.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/content/pages/tutorials/getting_started.md b/docs/content/pages/tutorials/getting_started.md index 8f06fcb8..df2de29d 100644 --- a/docs/content/pages/tutorials/getting_started.md +++ b/docs/content/pages/tutorials/getting_started.md @@ -248,8 +248,8 @@ It can get annoying when you have to keep closing and opening the game over and To enable it, head to your Mods menu and select New Horizons and check the box that says Debug, this will cause a "Reload Configs" option to appear in your pause menu which will reload changes from your filesystem. You may also notice blue and yellow logs start appearing in your console, this is New Horizons providing additional info on what it's currently doing, it can be helpful when you're trying to track down an issue. -## More Objects +## Modules -Base, Atmosphere, and Orbit aren't all the objects (or "modules") there are to use, to learn about these other objects, you'll need to learn how to use the "Schemas" section of this site, which lists every possible property you can put in your files. +Base, Atmosphere, and Orbit are all modules, which define the different aspects of your planet represented by objects **Next Up: [Reading Schemas]({{ "Reading Schemas"|route }})** diff --git a/docs/content/pages/tutorials/reading_schemas.md b/docs/content/pages/tutorials/reading_schemas.md index 13a6a1cc..d3b851d5 100644 --- a/docs/content/pages/tutorials/reading_schemas.md +++ b/docs/content/pages/tutorials/reading_schemas.md @@ -39,7 +39,7 @@ Badges can also show stuff such as the default value, the minimum and maximum va ![The Base object on the celestial body schema]({{ "images/reading_schemas/body_schema_3.webp"|static }}) -Next let's look at an `object` withing our root `object`, let's use `Base` as the example. +Next let's look at an `object` within our root `object`, let's use `Base` as the example. Here we can see it's similar to our root object, in that it doesn't allow additional properties. We can also see all of its properties listed out. From 6863ccdf31988e013ac144003f40230aabe363ec Mon Sep 17 00:00:00 2001 From: Ben C Date: Sun, 24 Jul 2022 18:06:58 -0400 Subject: [PATCH 03/29] Add Addon Creation Guide --- .../content/pages/tutorials/creating_addon.md | 83 ++++++++++++++++++ docs/content/pages/tutorials/planet_gen.md | 27 ++---- .../pages/tutorials/reading_schemas.md | 8 +- .../static/images/home/create_planets.webp | Bin 15468 -> 0 bytes .../static/images/home/mod_manager_dots.webp | Bin 10872 -> 0 bytes .../images/planet_gen/earth_heightmap.webp | Bin 0 -> 8504 bytes .../images/reading_schemas/body_schema_5.webp | Bin 0 -> 14938 bytes 7 files changed, 96 insertions(+), 22 deletions(-) create mode 100644 docs/content/pages/tutorials/creating_addon.md delete mode 100644 docs/content/static/images/home/create_planets.webp delete mode 100644 docs/content/static/images/home/mod_manager_dots.webp create mode 100644 docs/content/static/images/planet_gen/earth_heightmap.webp create mode 100644 docs/content/static/images/reading_schemas/body_schema_5.webp diff --git a/docs/content/pages/tutorials/creating_addon.md b/docs/content/pages/tutorials/creating_addon.md new file mode 100644 index 00000000..4a21dacf --- /dev/null +++ b/docs/content/pages/tutorials/creating_addon.md @@ -0,0 +1,83 @@ +--- +Title: Creating An Addon +Sort_Priority: 85 +--- + +# Creating An Addon + +Up until now, you've been using the sandbox feature of New Horizons (simply placing your files in the `xen.NewHorizons` folder). +While this is the easiest way to get started, you won't be able to publish your work like this. In this tutorial we will: + +- Create a new GitHub repository from a template +- Use GitHub Desktop to clone this repository to our computer +- Edit the files in this repository to make our addon + +## Making a GitHub Repository + +To get started, we need a place to store our code. GitHub is one of the most popular websites to store source code, and it's also what the mod database uses to let people access our mod. +First you're going to want to [create a GitHub account](https://github.com/signup){ target="_blank" }, and then head to [this repository](https://github.com/xen-42/ow-new-horizons-config-template){ target="_blank" }. +Now, click the green "Use This Template" button. + +- Set the Name to your username followed by a dot (`.`), followed by your mod's name in PascalCase (no spaces, new words have capital letters). So for example if my username was "Test" and my mod's name was "Really Cool Addon", I would name the repo `Test.ReallyCoolAddon`. +- The description is what will appear in the mod manager under the mod's name, you can always edit it later +- You can set the visibility to what you want; But when you go to publish your mod, it will need to be public + +## Cloning the Repository + +Now that we've created our GitHub repository (or "repo"), we need to clone (or download) it onto our computer. +To do this we recommend using the [GitHub Desktop App](https://desktop.github.com/){ target="_blank" }, as it's much easier to use than having to fight with the command line. + +Once we open GitHub desktop we're going to log in, select File -> Options -> Accounts and sign in to your newly created GitHub account. +Now we're ready to clone the repo, select File -> Clone Repository. Your repository should appear in the list. +Before you click "Clone", we need to select where to store the repo, open up the mod manager and go to "Settings", then copy the value located in the "OWML path" field and paste it in the "Local path" field on GitHub desktop. +This *will* show an error, and this is going to sound extremely stupid, but just click the "Choose..." button, and press "Select Folder" and it will be fixed. + +Our repository is now cloned to our computer! + +## Editing Files + +Now that our repo is clones, we're going to need to edit the files in it. +To get started editing the files, simply click "Open in Visual Studio Code" in GitHub Desktop. + +### Files Explanation + +- .github: This folder contains special files for use on GitHub, they aren't useful right now but will be when we go to publish the mod +- planets: This folder contains a single example config file that destroys the Quantum Moon, we'll keep it for now so we can test our addon later. +- .gitattributes: This is another file that will be useful when publishing +- default-config.json: This file is used in C#-based mods to allow a custom options menu, New Horizons doesn't support a custom options menu, but we still need the file here in order for the addon to work. +- manifest.json: This is the first file we're going to edit, we need to fill it out with information about our mod + - First you're going to set `author` to your author name, this should be the same name that you used when creating the GitHub repo. + - Next, set `name` to the name you want to appear in the mod manager and website. + - Now set `uniqueName` to the name of your GitHub Repo. + - You can leave `version`, `owmlVersion`, and `dependencies` alone +- NewHorizonsConfig.dll: This is the heart of your addon, make sure to never move or rename it. +- README.md: This file is what's displayed on the mod website when you go to a specific mod's page, you can delete the current contents. + - This file is a [markdown](https://www.markdowntutorial.com/){ target="_blank" } file, if you're not comfortable writing an entire README right now, just write a small description of your mod. + +### Committing The Changes + +Now that we have our files set up, switch back to GitHub desktop, you'll notice that the files you've changed have appeared in a list on the left. +What GitHub Desktop does is keep track of changes you make to your files over time. +Then, once you're ready, you commit these changes to your repo by filling out the "Summary" field with a small description of your changes, and then pressing the blue button that says "commit to main". + +Think of committing like taking a snapshot of your project at this moment in time. If you ever mess up your project, you can always revert to another commit to get back to a working version. It is highly recommended to commit often, there is no downside to committing too much. + +### Pushing The Changes + +OK, so we've committed our new changes, but these commits still only exist on our computer, to get these changes onto GitHub we can click the "Push Origin" button the right. + +## Testing The Addon + +Now that we have our manifest filled out, go take a look at the "Mods" tab in the manager and scroll to the bottom of the "Enabled Mods" list. + +You should see your mod there with the downloads counter set as a dash and the version set to "0.0.0". + +### Checking In-Game + +Now when you click "Start Game" and load into the solar system, you should be able to notice that the quantum moon is gone entirely, this means that your addon and its configs were successfully loaded. + +## Going Forward + +Now instead of using the New Horizons mod folder, you can use your own mod's folder instead. + +**Next Up: [Planet Generation]({{ "Planet Generation"|route }})** diff --git a/docs/content/pages/tutorials/planet_gen.md b/docs/content/pages/tutorials/planet_gen.md index a7c0e3ec..b10073c6 100644 --- a/docs/content/pages/tutorials/planet_gen.md +++ b/docs/content/pages/tutorials/planet_gen.md @@ -5,30 +5,15 @@ Sort_Priority: 80 # Planet Generation -The first thing you'll need to create on a planet is its surface, this can be done in a variety of ways +This guide covers some aspects of generating your planet, a lot of stuff is already explained in [the celestial body schema]({{ "Celestial Body Schema"|route }}). -## Surface - -Ground of the planet - -### Ground Size - -`groundSize` is the absolute simplest way to make a planet's surface, you simply specify a radius and New Horizons will make a sphere for you. - -```json -{ - "name": "My Cool Planet", - "Base": { - "groundSize": 100 - } -} -``` - -### Heightmaps +## Heightmaps Heightmaps are a way to generate unique terrain on your planet. First you specify a maximum and minimum height, and then specify a [heightMap]({{ "Celestial Body Schema"|route }}#HeightMap_heightMap) image. The more white a section of that image is, the closer to `maxHeight` that part of the terrain will be. Finally, you specify a `textureMap` which is an image that gets applied to the terrain. - +Here's an example heightmap or earth from the Real Solar System addon. + +![Earth's Heightmap]({{ "images/planet_gen/earth_heightmap.webp"|static }}) ```json { @@ -103,7 +88,7 @@ This makes the second planet a quantum state of the first, anything you specify } ``` -## Barycenter (Focal Point) +## Barycenters (Focal Points) To create a binary system of planets (like ash twin and ember twin), first create a config with `FocalPoint` set diff --git a/docs/content/pages/tutorials/reading_schemas.md b/docs/content/pages/tutorials/reading_schemas.md index d3b851d5..db162888 100644 --- a/docs/content/pages/tutorials/reading_schemas.md +++ b/docs/content/pages/tutorials/reading_schemas.md @@ -52,6 +52,12 @@ Now let's take a look over at [removeChildren]({{ "Celestial Body Schema"|route Here we can see that the type is an `array`, and each item in this array must be a `string` +## Enum Properties + +Enum properties simply mean that they must be of one of the values shown, for example [Ring fluid type]({{ "Celestial Body Schema"|route }}#Ring_fluidType) has to be one of these values. + +![The enum values of fluidType]({{ "images/reading_schemas/body_schema_5.webp"|static }}) + ## Some Vocabulary - GameObject: Essentially just any object in, well, the game. You can view these object in a tree-like structure with the [Unity Explorer](https://outerwildsmods.com/mods/unityexplorer) mod. Every GameObject has a path, which is sort of like a file path in that it's a list of parent GameObjects seperated by forward slashes followed by the GameObject's name. @@ -75,4 +81,4 @@ There are other schemas available, some are for JSON, and some are for XML. Now that you know how to read the schema pages, you can understand the rest of this site. A lot of the other tutorials here will often tell you to take a look at schemas to explain what certain properties do. -**Next Up: [Planet Generation]({{ "Planet Generation"|route }})** +**Next Up: [Creating An Addon]({{ "Creating An Addon"|route }})** diff --git a/docs/content/static/images/home/create_planets.webp b/docs/content/static/images/home/create_planets.webp deleted file mode 100644 index 7629e85df803cceeb12349fbc8027df91cafe3bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15468 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 O4ThGH(qUHhfB*oEFnAvT diff --git a/docs/content/static/images/planet_gen/earth_heightmap.webp b/docs/content/static/images/planet_gen/earth_heightmap.webp new file mode 100644 index 0000000000000000000000000000000000000000..3f822c92248142441f4f17393a32a4ca65f54e41 GIT binary patch literal 8504 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 literal 0 HcmV?d00001 diff --git a/docs/content/static/images/reading_schemas/body_schema_5.webp b/docs/content/static/images/reading_schemas/body_schema_5.webp new file mode 100644 index 0000000000000000000000000000000000000000..9c88e15c0688f61be3c6400ed54ee98c6ed7d04b GIT binary patch literal 14938 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 STJ#Pot+!1A0Ex!|0RIo0jOH)^ literal 0 HcmV?d00001 From b6f03bca88cab136e9e905f531db427420d6513a Mon Sep 17 00:00:00 2001 From: Ben C Date: Sun, 24 Jul 2022 18:45:43 -0400 Subject: [PATCH 04/29] Typos in Getting Started --- .../pages/tutorials/getting_started.md | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/docs/content/pages/tutorials/getting_started.md b/docs/content/pages/tutorials/getting_started.md index df2de29d..b9f5dcb5 100644 --- a/docs/content/pages/tutorials/getting_started.md +++ b/docs/content/pages/tutorials/getting_started.md @@ -19,7 +19,7 @@ To get started, navigate to your mod manager and click the ⋮ symbol, then sele ![Select "Show in explorer"]({{ "images/getting_started/mod_manager_show_in_explorer.webp"|static }}) -Now, in explorer and create a new folder named "planets". As the name suggests, New Horizons will search the files in this folder for planets to generate. +Now, create a new folder named "planets". As the name suggests, New Horizons will search the files in this folder for planets to generate. ## Making Your First Planet @@ -64,7 +64,7 @@ It's a common way to convey data in many programs. ## Understanding JSON -All JSON files start out with an `object`, or a set of key value mappings, for example is we represent a person as JSON it might look like: +All JSON files start out with an `object`, or a set of key value mappings, for example if we represent a person as JSON it might look like: ```json { @@ -72,7 +72,7 @@ All JSON files start out with an `object`, or a set of key value mappings, for e } ``` -Those braces (`{}`) denote an object, and by doing `"name": "Jim"` we're saying that the name of this object (in this case person) is Jim +Those braces (`{}`) denote an object, and by doing `"name": "Jim"` we're saying that the name of this person is Jim `"name"` is the key, and `"Jim"` is the value. Objects can have multiple keys as well, as long as you separate them by commas: @@ -84,10 +84,10 @@ Objects can have multiple keys as well, as long as you separate them by commas: } ``` -But wait! why is `Jim` in quotation marks while `23` isn't? that's because of a little something called data types. +But wait! why is `Jim` in quotation marks while `23` isn't? that's because of something called data types. Each value has a datatype, in this case `"Jim"` is a `string`, because it represents a *string* of characters. Age is a `number`, it represents a numerical value. If we put 23 in quotation marks, its data type switches from a number to a string. -And if we remove the quotation marks from `"Jim"` we get a syntax error. Datatypes are a common source of errors, which is why we recommend using an editor like VSCode. +And if we remove the quotation marks from `"Jim"` we get a syntax error (a red underline). Datatypes are a common source of errors, which is why we recommend using an editor like VSCode. ### JSON Data Types @@ -95,7 +95,7 @@ Here's a list of data types you'll use when making your addons: #### String -A string of characters surrounded in quotation marks +A set of characters surrounded in quotation marks ```json "Im a string!" @@ -117,15 +117,19 @@ A numerical value, can be negative and have decimals, **not** surrounded in quot #### Boolean -A `true` or `false` value, think of it like an on or off switch +A `true` or `false` value, think of it like an on or off switch, also not surrounded in quotation marks ```json true ``` +```json +false +``` + #### Array -A set of values, values can be of any data type. Items are seperated by commas +A set of values, values can be of any data type. Items are seperated by commas. ```json [23, 45, 56] @@ -250,6 +254,6 @@ You may also notice blue and yellow logs start appearing in your console, this i ## Modules -Base, Atmosphere, and Orbit are all modules, which define the different aspects of your planet represented by objects +Base, Atmosphere, and Orbit are all modules, which define the different aspects of your planet, modules are represented by JSON objects **Next Up: [Reading Schemas]({{ "Reading Schemas"|route }})** From 19f4f5709467bf45a47e1d5a0917b544d96e5c0e Mon Sep 17 00:00:00 2001 From: Ben C Date: Sun, 24 Jul 2022 18:47:05 -0400 Subject: [PATCH 05/29] Typos in Home --- docs/content/pages/home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/pages/home.md b/docs/content/pages/home.md index fa228b44..6fc7c70e 100644 --- a/docs/content/pages/home.md +++ b/docs/content/pages/home.md @@ -12,7 +12,7 @@ This is the official documentation for [New Horizons](https://github.com/xen-42/ ## Getting Started -For a guide on getting started an getting familiar with New Horizons, go to the [Getting Started]({{ "Getting Started"|route }}) page. +For a guide on getting started with New Horizons, go to the [Getting Started]({{ "Getting Started"|route }}) page. ## Helpful Resources From b28576dfd63d4b1963d8d04632c54f31d37a88d7 Mon Sep 17 00:00:00 2001 From: Ben C Date: Sun, 24 Jul 2022 19:16:45 -0400 Subject: [PATCH 06/29] Typos in Getting Started --- docs/content/pages/tutorials/getting_started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/pages/tutorials/getting_started.md b/docs/content/pages/tutorials/getting_started.md index b9f5dcb5..1b2da307 100644 --- a/docs/content/pages/tutorials/getting_started.md +++ b/docs/content/pages/tutorials/getting_started.md @@ -72,7 +72,7 @@ All JSON files start out with an `object`, or a set of key value mappings, for e } ``` -Those braces (`{}`) denote an object, and by doing `"name": "Jim"` we're saying that the name of this person is Jim +Those braces (`{}`) denote an object, and by doing `"name": "Jim"` we're saying that the name of this person is Jim; `"name"` is the key, and `"Jim"` is the value. Objects can have multiple keys as well, as long as you separate them by commas: From c568787278e02125916f79fdf93c8d1f498d45d0 Mon Sep 17 00:00:00 2001 From: Ben C Date: Tue, 6 Sep 2022 11:31:32 -0400 Subject: [PATCH 07/29] Add Editor Page --- docs/content/pages/tutorials/editor.md | 65 ++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 docs/content/pages/tutorials/editor.md diff --git a/docs/content/pages/tutorials/editor.md b/docs/content/pages/tutorials/editor.md new file mode 100644 index 00000000..2366b950 --- /dev/null +++ b/docs/content/pages/tutorials/editor.md @@ -0,0 +1,65 @@ +--- +Title: Config Editor +Sort_Priority: 50 +--- + +# Config Editor + +Are you tired of manually editting JSON? Do you want richer validation than a JSON schema? Well then the config editor may be for you! + +This page outlines how to install and use the config editor. + +## Installation + +To get started, head over to the [releases page for the editor](https://github.com/Outer-Wilds-New-Horizons/nh-config-editor/releases/latest) and install the file for your OS: + +- Windows: The .msi file (not the .msi.zip and .msi.zip.sig file) +- MacOS: The .AppImage file (not the .AppImage.tar.gz or the .AppImage.tar.gx.sig file) + +Follow the installer instructions to complete setup + +## Creating a New Project + +Creating a new project is as simple as clicking the button. +Fill out the form with thr info for your mod and a new project will be made at the specified path. + +## Editing Files + +To edit a file, navigate to it in the left panel and click on it. + +### JSON files + +JSON files (planets, systems, etc) have a graphical interface for editing, **this will clear comments!** + +If you don't want comments to be cleared, use the text editor + +#### Using the Text Editor + +Already familiar with JSON and prefer text-based editing? Simply open up settings (File -> Settings) and turn on the "Always use Text Editor" option. + +### Image and Audio Files + +You can view images and play audio files with this editor. + +### XML Files + +Right now, XML support is limited. You'll get syntax highlighting but no error checking or auto-fill. + + +## Running the Game + +You can start the game from the editor by selecting Project -> Run Project this will open a new window where you can run the game + +### Log Port + +If you're using the mod manager and would like logs to appear there, you need to get the log port from the console, it's always the first entry in the logs. Keep in mind this port changes whenever you restart the manager. + +![TODO: Get Log Screenshot]() + + +## Building + +The editor also provides a system for building your mod to a zip file, which can then be uploaded to GitHub in a release. To do this, press Project -> Build (Release) + + + From 8cdc3f842ff8d3eee2540a9781db0e378cb2fbff Mon Sep 17 00:00:00 2001 From: Ben C Date: Tue, 6 Sep 2022 15:22:06 -0400 Subject: [PATCH 08/29] Fixed Typos --- docs/content/pages/tutorials/creating_addon.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/content/pages/tutorials/creating_addon.md b/docs/content/pages/tutorials/creating_addon.md index 4a21dacf..fc88919f 100644 --- a/docs/content/pages/tutorials/creating_addon.md +++ b/docs/content/pages/tutorials/creating_addon.md @@ -36,7 +36,7 @@ Our repository is now cloned to our computer! ## Editing Files -Now that our repo is clones, we're going to need to edit the files in it. +Now that our repo is cloned, we're going to need to edit the files in it. To get started editing the files, simply click "Open in Visual Studio Code" in GitHub Desktop. ### Files Explanation @@ -51,7 +51,7 @@ To get started editing the files, simply click "Open in Visual Studio Code" in G - Now set `uniqueName` to the name of your GitHub Repo. - You can leave `version`, `owmlVersion`, and `dependencies` alone - NewHorizonsConfig.dll: This is the heart of your addon, make sure to never move or rename it. -- README.md: This file is what's displayed on the mod website when you go to a specific mod's page, you can delete the current contents. +- README.md: This file is displayed on the mod website when you go to a specific mod's page, you can delete the current contents. - This file is a [markdown](https://www.markdowntutorial.com/){ target="_blank" } file, if you're not comfortable writing an entire README right now, just write a small description of your mod. ### Committing The Changes @@ -64,7 +64,7 @@ Think of committing like taking a snapshot of your project at this moment in tim ### Pushing The Changes -OK, so we've committed our new changes, but these commits still only exist on our computer, to get these changes onto GitHub we can click the "Push Origin" button the right. +OK, so we've committed our new changes, but these commits still only exist on our computer, to get these changes onto GitHub we can click the "Push Origin" button on the top right. ## Testing The Addon From c75162137f9ba1feb387f8471eabc343f73ce8ec Mon Sep 17 00:00:00 2001 From: Ben C Date: Wed, 7 Sep 2022 07:48:27 -0400 Subject: [PATCH 09/29] Add Orbit Section to Planet Gen --- docs/content/pages/{tutorials => }/editor.md | 0 docs/content/pages/tutorials/planet_gen.md | 4 ++++ 2 files changed, 4 insertions(+) rename docs/content/pages/{tutorials => }/editor.md (100%) diff --git a/docs/content/pages/tutorials/editor.md b/docs/content/pages/editor.md similarity index 100% rename from docs/content/pages/tutorials/editor.md rename to docs/content/pages/editor.md diff --git a/docs/content/pages/tutorials/planet_gen.md b/docs/content/pages/tutorials/planet_gen.md index b10073c6..978424f3 100644 --- a/docs/content/pages/tutorials/planet_gen.md +++ b/docs/content/pages/tutorials/planet_gen.md @@ -7,6 +7,10 @@ Sort_Priority: 80 This guide covers some aspects of generating your planet, a lot of stuff is already explained in [the celestial body schema]({{ "Celestial Body Schema"|route }}). +## Orbits + +First thing you should specify about your planet is its orbit. `primaryBody` will specify what planet this body will orbit. If you're in a new solar system and want this planet to be the center, set `centerOfSolarSystem` to `true` (keep in mind `centerOfSolarSystem` is in the `Base` module, not `Orbit`). Next up you'll need to specify the [orbital parameters](https://en.wikipedia.org/wiki/Orbital_elements). + ## Heightmaps Heightmaps are a way to generate unique terrain on your planet. First you specify a maximum and minimum height, and then specify a [heightMap]({{ "Celestial Body Schema"|route }}#HeightMap_heightMap) image. The more white a section of that image is, the closer to `maxHeight` that part of the terrain will be. Finally, you specify a `textureMap` which is an image that gets applied to the terrain. From 3259a7e206d1b64c5f03674f4dc8a57f8e5154f7 Mon Sep 17 00:00:00 2001 From: Ben C Date: Wed, 7 Sep 2022 08:10:57 -0400 Subject: [PATCH 10/29] Added XML Guide --- docs/content/pages/tutorials/ship_log.md | 4 +- docs/content/pages/tutorials/xml.md | 64 ++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 docs/content/pages/tutorials/xml.md diff --git a/docs/content/pages/tutorials/ship_log.md b/docs/content/pages/tutorials/ship_log.md index d1405eee..ac032ed4 100644 --- a/docs/content/pages/tutorials/ship_log.md +++ b/docs/content/pages/tutorials/ship_log.md @@ -1,13 +1,15 @@ --- Title: Ship Log Description: A guide to editing the ship log in New Horizons -Sort_Priority: 70 +Sort_Priority: 40 --- # Intro Welcome! this page outlines how to create a custom ship log. +If you haven't already, you may want to take a look at [Understanding XML]({{ "Understanding XML"|route }}) to get a better idea of how XML works. + # Understanding Ship Logs First thing's first, I'll define some terminology regarding ship logs in the game, and how ship logs are structured. diff --git a/docs/content/pages/tutorials/xml.md b/docs/content/pages/tutorials/xml.md new file mode 100644 index 00000000..62f3965e --- /dev/null +++ b/docs/content/pages/tutorials/xml.md @@ -0,0 +1,64 @@ +--- +Title: Understanding XML +Sort_Priority: 50 +--- + +# Understanding XML + +XML is the other language New Horizons uses for content. +XML files are usually passed straight to the game's code instead of going through New Horizons. + +## Syntax + +XML is comprised of tags, a tag can represent a section or attribute + +```xml + + Jim + 32 + + +``` + +Notice how each tag is closed by an identical tag with a slash at the front (i.e `` is closed by ``). + +If the tag has no content you can use the self-closing tag shorthand (i.e. `` doesn't need a closing tag because of the `/` at the end). + +This XML could be written in JSON as: + +```json +{ + "name": "Jim", + "age": 32, + "isMarried": true +} +``` + +XML is a lot more descriptive, you can actually tell that the object is supposed to be a person by the name of the tag. + +## Structure + +All XML files must have **one** top-level tag, this varies depending on what you're using it for (like how ship logs use a `` tag). + +## Schemas + +XML files can also have schemas, you specify them by adding attributes to the top-level tag: + +```xml + + +``` + +In order to get schema validation and auto-fill you'll need the [Redhat XML VSCode extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-xml). + + +## Uses + +XML is used for the following: + +- [Shiplog Entries]({{ "Ship Log"|route }}) +- [Dialogue](#) +- [Translatable Text](#) + + + From bf4fe574ea947446673d61acc643623fcf7c35b1 Mon Sep 17 00:00:00 2001 From: Ben C Date: Wed, 7 Sep 2022 09:31:54 -0400 Subject: [PATCH 11/29] Added some Pages --- docs/content/pages/tutorials/dialogue.md | 168 ++++++++++++++++++++ docs/content/pages/tutorials/translation.md | 34 ++++ docs/content/pages/tutorials/xml.md | 3 +- 3 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 docs/content/pages/tutorials/dialogue.md create mode 100644 docs/content/pages/tutorials/translation.md diff --git a/docs/content/pages/tutorials/dialogue.md b/docs/content/pages/tutorials/dialogue.md new file mode 100644 index 00000000..aa1b5a02 --- /dev/null +++ b/docs/content/pages/tutorials/dialogue.md @@ -0,0 +1,168 @@ +--- +Title: Dialogue +Description: Guide to making dialogue in New Horizons +Sort_Priority: 30 +--- + + + +# Dialogue + +This page goes over how to use dialogue in New Horizons. + +You may want to view [Understanding XML]({{ "Understanding XML"|route }}) if you haven't already. + +# Understanding Dialogue + +## Dialogue Tree + +A dialogue tree is an entire conversation, it's made up of dialogue nodes. + +## Dialogue Node + +A node is a set of pages shown to the player followed by options the player can choose from to change the flow of the conversation. + +## Condition + +A condition is a yes/no value stored **for this loop and this loop only**. It can be used to show new dialogue options, stop someone from talking to you (looking at you Slate), and more. + +## Persistent Condition + +A persistent condition is similar to a condition, except it *persists* through loops, and is saved on the player's save file. + +## Remote Trigger + +A remote trigger is used to have an NPC talk to you from a distance; ex: Slate stopping you for the umpteenth time to tell you information you already knew. + +# Example XML + +Here's an example dialogue XML: + +```xml + + + + EXAMPLE NPC + + + Start + DEFAULT + + Start + Start Part 2 + + + + + Goto 1 + 1 + + + + Goto 2 + 2 + + + Goto End + End + + + + + + 1 + + + This is 1 + + + + + Goto 2 + 2 + + + Goto End + End + + + + + + 2 + + This is 2 + + + + + Goto 1 + 1 + + + Goto End + End + + + + + + End + + This is the end + + + + +``` + +# Using the XML + +To use the dialogue XML you have created, you simply need to reference it in the `dialogue` prop + +```json +{ + "Props": { + "dialogue": [ + { + "position": {"x": 5, "y": 10, "z": 0}, + "xmlFile": "planets/path/to/your_file.xml" + } + ] + } +} +``` + +# Dialogue Config + +To view the options for the dialogue prop, check [the schema]({{ "Celestial Body Schema"|route }}#Props_dialogue) + +# Controlling Conditions + +You can set condition in dialogue with the `` and `` tags + +```xml + + + EXAMPLE_CONDITION + EXAMPLE_P_CONDITION + + +``` + +# Dialogue Options + +There are many control structures for dialogue options to hide/reveal them if conditions are met. Take a look at [the DialogueOption schema]({{ "Dialogue Schema"|route }}#DialogueTree-DialogueNode-DialogueOptionsList-DialogueOption-DialogueTarget) for more info. + +# Controlling Flow + +In addition to ``, there are other ways to control the flow of the conversation. + +## DialogueTarget + +Defining `` in the `` tag instead of a `` will make the conversation go directly to that target after the character is done talking. + +## DialogueTargetShipLogCondition + +Used in tandum with `DialogueTarget`, makes it so you must have a [ship log fact]({{ "Ship Log"|route }}#explore-facts) to go to the next node. diff --git a/docs/content/pages/tutorials/translation.md b/docs/content/pages/tutorials/translation.md new file mode 100644 index 00000000..095a9f01 --- /dev/null +++ b/docs/content/pages/tutorials/translation.md @@ -0,0 +1,34 @@ +--- +Title: Translations +Sort_Priority: 60 +--- + +# Translations + +There are 12 supported languages in Outer Wilds: english, spanish_la, german, french, italian, polish, portuguese_br, japanese, russian, chinese_simple, korean, and turkish. + +All translations must go in a folder in the root directory called "translations". + +In this folder you can put json files with the name of the language you want to translate for. Inside this file just follow the translation schema. + +Here's an example, for `russian.json`: + +```json +{ + "$schema": "https://raw.githubusercontent.com/Outer-Wilds-New-Horizons/new-horizons/main/NewHorizons/Schemas/translation_schema.json", + "DialogueDictionary" : + { + "Fred" : "Фред", + "You looking at something?" : "Ты что-то искал?", + "Aren't you guys all supposed to be dead?" : "А разве номаи не вымерли?", + "OH MY GOD A LIVING NOMAI AHHH WHAT HOW?!" : "ААААА, ЖИВАЯ НОМАИ?!" + }, + "ShipLogDictionary" : + { + "Unexpected guests" : "Незванные гости", + "Visitors" : "Гости", + "When I went to sleep by the campfire only Slate was here, who are these characters?" : "Когда я ложился спать у костра здесь был только Сланец. Кто все остальные?", + "I met a talking jellyfish. His name is Geswaldo!" : "Я встретил говорящую медузу. Его зовут Гесвальдо!" + } +} +``` diff --git a/docs/content/pages/tutorials/xml.md b/docs/content/pages/tutorials/xml.md index 62f3965e..3f182a2b 100644 --- a/docs/content/pages/tutorials/xml.md +++ b/docs/content/pages/tutorials/xml.md @@ -49,8 +49,7 @@ XML files can also have schemas, you specify them by adding attributes to the to ``` -In order to get schema validation and auto-fill you'll need the [Redhat XML VSCode extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-xml). - +In order to get schema validation and auto-fill you'll need the [Redhat XML VSCode extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-xml){ target="_blank" }. ## Uses From b9a5a8abfef0305a61c3385abf559f9850cccb15 Mon Sep 17 00:00:00 2001 From: Ben C Date: Wed, 7 Sep 2022 09:36:11 -0400 Subject: [PATCH 12/29] Fix typo in editor.md --- docs/content/pages/editor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/pages/editor.md b/docs/content/pages/editor.md index 2366b950..4f40cb27 100644 --- a/docs/content/pages/editor.md +++ b/docs/content/pages/editor.md @@ -14,7 +14,7 @@ This page outlines how to install and use the config editor. To get started, head over to the [releases page for the editor](https://github.com/Outer-Wilds-New-Horizons/nh-config-editor/releases/latest) and install the file for your OS: - Windows: The .msi file (not the .msi.zip and .msi.zip.sig file) -- MacOS: The .AppImage file (not the .AppImage.tar.gz or the .AppImage.tar.gx.sig file) +- MacOS: The .AppImage file (not the .AppImage.tar.gz or the .AppImage.tar.gz.sig file) Follow the installer instructions to complete setup From bf6745d351216dfb7ea6d3bbace9de45ba01277c Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Wed, 7 Sep 2022 17:21:42 -0700 Subject: [PATCH 13/29] groups on details --- NewHorizons/Builder/General/GroupBuilder.cs | 30 +++++++++++++++++++++ NewHorizons/Builder/Props/DetailBuilder.cs | 2 ++ 2 files changed, 32 insertions(+) create mode 100644 NewHorizons/Builder/General/GroupBuilder.cs diff --git a/NewHorizons/Builder/General/GroupBuilder.cs b/NewHorizons/Builder/General/GroupBuilder.cs new file mode 100644 index 00000000..828a7117 --- /dev/null +++ b/NewHorizons/Builder/General/GroupBuilder.cs @@ -0,0 +1,30 @@ +using UnityEngine; +using Logger = NewHorizons.Utility.Logger; + +namespace NewHorizons.Builder.General; + +public static class GroupBuilder +{ + ///

+ /// puts groups on objects. + /// run this before the gameobject is active. + /// + public static void Make(GameObject go, Sector sector) + { + Logger.LogVerbose($"putting groups on {go} (linked to {sector})"); + if (!sector) + { + Logger.LogWarning("tried to put groups on a null sector"); + return; + } + if (go.activeInHierarchy) + { + Logger.LogWarning("tried to put groups on an active gameobject"); + return; + } + + go.GetAddComponent()._sector = sector; + go.GetAddComponent()._sector = sector; + go.GetAddComponent()._sector = sector; + } +} \ No newline at end of file diff --git a/NewHorizons/Builder/Props/DetailBuilder.cs b/NewHorizons/Builder/Props/DetailBuilder.cs index ae7a63f7..2c849ecf 100644 --- a/NewHorizons/Builder/Props/DetailBuilder.cs +++ b/NewHorizons/Builder/Props/DetailBuilder.cs @@ -1,3 +1,4 @@ +using NewHorizons.Builder.General; using NewHorizons.External.Configs; using NewHorizons.External.Modules; using NewHorizons.Handlers; @@ -100,6 +101,7 @@ namespace NewHorizons.Builder.Props prop.transform.localScale = detail.scale != 0 ? Vector3.one * detail.scale : prefab.transform.localScale; + if (!detail.keepLoaded) GroupBuilder.Make(prop, sector); prop.SetActive(true); if (prop == null) return null; From 01419392f6a7b380c1b4f1913536b69e6d59a577 Mon Sep 17 00:00:00 2001 From: Ben C Date: Wed, 7 Sep 2022 20:29:25 -0400 Subject: [PATCH 14/29] More Pages --- docs/content/pages/404.md | 10 +++ docs/content/pages/tutorials/dialogue.md | 30 ++++----- docs/content/pages/tutorials/extending.md | 74 +++++++++++++++++++++ docs/content/pages/tutorials/planet_gen.md | 2 +- docs/content/pages/tutorials/star_system.md | 49 ++++++++++++++ docs/content/pages/tutorials/xml.md | 6 +- 6 files changed, 151 insertions(+), 20 deletions(-) create mode 100644 docs/content/pages/404.md create mode 100644 docs/content/pages/tutorials/extending.md create mode 100644 docs/content/pages/tutorials/star_system.md diff --git a/docs/content/pages/404.md b/docs/content/pages/404.md new file mode 100644 index 00000000..a999f185 --- /dev/null +++ b/docs/content/pages/404.md @@ -0,0 +1,10 @@ +--- +Title: Page not Found +Hide_In_Nav: True +Render_TOC: False +--- + +# Page Not Found + +The page you requested could not be found. + diff --git a/docs/content/pages/tutorials/dialogue.md b/docs/content/pages/tutorials/dialogue.md index aa1b5a02..50063480 100644 --- a/docs/content/pages/tutorials/dialogue.md +++ b/docs/content/pages/tutorials/dialogue.md @@ -4,37 +4,35 @@ Description: Guide to making dialogue in New Horizons Sort_Priority: 30 --- - - # Dialogue This page goes over how to use dialogue in New Horizons. You may want to view [Understanding XML]({{ "Understanding XML"|route }}) if you haven't already. -# Understanding Dialogue +## Understanding Dialogue -## Dialogue Tree +### Dialogue Tree A dialogue tree is an entire conversation, it's made up of dialogue nodes. -## Dialogue Node +### Dialogue Node A node is a set of pages shown to the player followed by options the player can choose from to change the flow of the conversation. -## Condition +### Condition A condition is a yes/no value stored **for this loop and this loop only**. It can be used to show new dialogue options, stop someone from talking to you (looking at you Slate), and more. -## Persistent Condition +### Persistent Condition A persistent condition is similar to a condition, except it *persists* through loops, and is saved on the player's save file. -## Remote Trigger +### Remote Trigger A remote trigger is used to have an NPC talk to you from a distance; ex: Slate stopping you for the umpteenth time to tell you information you already knew. -# Example XML +## Example XML Here's an example dialogue XML: @@ -117,7 +115,7 @@ Here's an example dialogue XML: ``` -# Using the XML +## Using the XML To use the dialogue XML you have created, you simply need to reference it in the `dialogue` prop @@ -134,11 +132,11 @@ To use the dialogue XML you have created, you simply need to reference it in the } ``` -# Dialogue Config +## Dialogue Config To view the options for the dialogue prop, check [the schema]({{ "Celestial Body Schema"|route }}#Props_dialogue) -# Controlling Conditions +## Controlling Conditions You can set condition in dialogue with the `` and `` tags @@ -151,18 +149,18 @@ You can set condition in dialogue with the `` and ` ``` -# Dialogue Options +## Dialogue Options There are many control structures for dialogue options to hide/reveal them if conditions are met. Take a look at [the DialogueOption schema]({{ "Dialogue Schema"|route }}#DialogueTree-DialogueNode-DialogueOptionsList-DialogueOption-DialogueTarget) for more info. -# Controlling Flow +## Controlling Flow In addition to ``, there are other ways to control the flow of the conversation. -## DialogueTarget +### DialogueTarget Defining `` in the `` tag instead of a `` will make the conversation go directly to that target after the character is done talking. -## DialogueTargetShipLogCondition +### DialogueTargetShipLogCondition Used in tandum with `DialogueTarget`, makes it so you must have a [ship log fact]({{ "Ship Log"|route }}#explore-facts) to go to the next node. diff --git a/docs/content/pages/tutorials/extending.md b/docs/content/pages/tutorials/extending.md new file mode 100644 index 00000000..0e9b30bc --- /dev/null +++ b/docs/content/pages/tutorials/extending.md @@ -0,0 +1,74 @@ +--- +Title: Extending Configs +Description: A guide on extending config files with the New Horizons API +Sort_Priority: 5 +--- + +# Extending Configs + +This guide will explain how to use the API to add new features to New Horizons. + +## How Extending Works + +Addon developers will add a key to the `extras` object in the root of the config + +```json +{ + "name": "Wetrock", + "extras": { + "myCoolExtensionData": { + "myCoolExtensionProperty": 2 + } + } +} +``` + +Your mod will then use the API's `QueryBody` method to obtain the `myCoolExtensionData` object. + +**It's up to the addon dev to list your mod as a dependency!** + +## Extending Planets + +You can extend all planets by hooking into the `OnBodyLoaded` event of the API: + +```csharp +var api = ModHelper.Interactions.TryGetModApi("xen.NewHorizons"); +api.GetBodyLoadedEvent().AddListener((name) => { + ModHelper.Console.WriteLine($"Body: {name} Loaded!"); +}); +``` + +In order to get your extra module, first define the module as a class: + +```csharp +public class MyCoolExtensionData { + int myCoolExtensionProperty; +} +``` + +Then, use the `QueryBody` method: + +```csharp +var api = ModHelper.Interactions.TryGetModApi("xen.NewHorizons"); +api.GetBodyLoadedEvent().AddListener((name) => { + ModHelper.Console.WriteLine($"Body: {name} Loaded!"); + var potentialData = api.QueryBody(typeof(MyCoolExtensionData), "$.extras.myCoolExtensionData", name); + // Makes sure the module is valid and not null + if (potentialData is MyCoolExtensionData data) { + ModHelper.Console.WriteLine($"myCoolExtensionProperty for {name} is {data.myCoolExtensionProperty}!"); + } +}); +``` + +## Extending Systems + +Extending systems is the exact same as extending planets, except you use the `QuerySystem` method instead. + +## Accessing Other Values + +You can also use the `QueryBody` method to get values of the config outside of your extension object + +```csharp +var primaryBody = api.QueryBody(typeof(string), "Wetrock", "$.Orbit.primaryBody"); + ModHelper.Console.WriteLine($"Primary of {bodyName} is {primaryBody ?? "NULL"}!"); +``` diff --git a/docs/content/pages/tutorials/planet_gen.md b/docs/content/pages/tutorials/planet_gen.md index 978424f3..c634b1fd 100644 --- a/docs/content/pages/tutorials/planet_gen.md +++ b/docs/content/pages/tutorials/planet_gen.md @@ -15,7 +15,7 @@ First thing you should specify about your planet is its orbit. `primaryBody` wil Heightmaps are a way to generate unique terrain on your planet. First you specify a maximum and minimum height, and then specify a [heightMap]({{ "Celestial Body Schema"|route }}#HeightMap_heightMap) image. The more white a section of that image is, the closer to `maxHeight` that part of the terrain will be. Finally, you specify a `textureMap` which is an image that gets applied to the terrain. -Here's an example heightmap or earth from the Real Solar System addon. +Here's an example heightmap of earth from the Real Solar System addon. ![Earth's Heightmap]({{ "images/planet_gen/earth_heightmap.webp"|static }}) diff --git a/docs/content/pages/tutorials/star_system.md b/docs/content/pages/tutorials/star_system.md new file mode 100644 index 00000000..aa3218de --- /dev/null +++ b/docs/content/pages/tutorials/star_system.md @@ -0,0 +1,49 @@ +--- +Title: Star Systems +Description: A guide to editing a custom star system in New Horizons +Sort_Priority: 65 +--- + +# Intro + +Welcome! This page outlines how to edit a custom star system. + +## Getting Started + +Star Systems are placed in a folder called systems within your mod folder. + +The name of your star system config must be the same as the unique id used in the `starSystem` field of your planet configs. Example: `xen.RealSolarSystem.json`. + +A star system config file will look something like this: + +```json +{ + "$schema": "https://raw.githubusercontent.com/Outer-Wilds-New-Horizons/new-horizons/main/NewHorizons/Schemas/star_system_schema.json", + "travelAudio": "assets/Travel.mp3", + "Vessel": { + "coords": { + "x": [ 4, 0, 3, 1 ], + "y": [ 0, 5, 4 ], + "z": [ 5, 4, 0, 3, 1 ] + }, + "vesselPosition": { + "x": 0, + "y": 0, + "z": 8000 + } + } +} +``` + +To see all the different things you can put into a config file check out the [Star System Schema]({{ 'Star System Schema'|route}}). + +## Vessel Coordinates + +You can warp to custom star systems via the Nomai vessel. Each coordinate has to be 2-6 points long. +These are the points for each coordinate node. When making your unique coordinate you should only use each point once. +![nomaiCoordinateIndexes]({{ "images/star_system/nomai_coordinate_indexes.webp"|static }}) + +### Hearthian Solar System Vessel Coordinates + +You can use these coordinates to warp back to the hearthian solar system. +![hearthianSolarSystemCoordinates]({{ "images/star_system/hearthian_solar_system_coordinates.webp"|static }}) \ No newline at end of file diff --git a/docs/content/pages/tutorials/xml.md b/docs/content/pages/tutorials/xml.md index 3f182a2b..6b4f2fbd 100644 --- a/docs/content/pages/tutorials/xml.md +++ b/docs/content/pages/tutorials/xml.md @@ -49,14 +49,14 @@ XML files can also have schemas, you specify them by adding attributes to the to ``` -In order to get schema validation and auto-fill you'll need the [Redhat XML VSCode extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-xml){ target="_blank" }. +In order to get schema validation and autofill you'll need the [Redhat XML VSCode extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-xml){ target="_blank" }. ## Uses XML is used for the following: -- [Shiplog Entries]({{ "Ship Log"|route }}) -- [Dialogue](#) +- [Ship log Entries]({{ "Ship Log"|route }}) +- [Dialogue]({{ "Dialogue"|route }}) - [Translatable Text](#) From 7a67a1f9807c20590fe353e6482ad8666d38bc2a Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Wed, 7 Sep 2022 17:30:22 -0700 Subject: [PATCH 15/29] improve warnings --- NewHorizons/Builder/General/GroupBuilder.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/NewHorizons/Builder/General/GroupBuilder.cs b/NewHorizons/Builder/General/GroupBuilder.cs index 828a7117..c9227ce3 100644 --- a/NewHorizons/Builder/General/GroupBuilder.cs +++ b/NewHorizons/Builder/General/GroupBuilder.cs @@ -11,15 +11,14 @@ public static class GroupBuilder /// public static void Make(GameObject go, Sector sector) { - Logger.LogVerbose($"putting groups on {go} (linked to {sector})"); if (!sector) { - Logger.LogWarning("tried to put groups on a null sector"); + Logger.LogWarning($"tried to put groups on {go.name} when sector is null"); return; } if (go.activeInHierarchy) { - Logger.LogWarning("tried to put groups on an active gameobject"); + Logger.LogWarning($"tried to put groups on an active gameobject {go.name}"); return; } From da211eff755eb15fa1561b9abbf5664e8eb6be92 Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Wed, 7 Sep 2022 17:33:38 -0700 Subject: [PATCH 16/29] scatter builder keep loaded --- NewHorizons/Builder/Props/ScatterBuilder.cs | 1 + NewHorizons/External/Modules/PropModule.cs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/NewHorizons/Builder/Props/ScatterBuilder.cs b/NewHorizons/Builder/Props/ScatterBuilder.cs index 26af9d33..3ce71605 100644 --- a/NewHorizons/Builder/Props/ScatterBuilder.cs +++ b/NewHorizons/Builder/Props/ScatterBuilder.cs @@ -96,6 +96,7 @@ namespace NewHorizons.Builder.Props { position = point.normalized * height, scale = propInfo.scale, + keepLoaded = propInfo.keepLoaded, alignToNormal = true }; var prop = DetailBuilder.Make(go, sector, prefab, detailInfo); diff --git a/NewHorizons/External/Modules/PropModule.cs b/NewHorizons/External/Modules/PropModule.cs index 932b1bc0..b02f762d 100644 --- a/NewHorizons/External/Modules/PropModule.cs +++ b/NewHorizons/External/Modules/PropModule.cs @@ -139,6 +139,11 @@ namespace NewHorizons.External.Modules /// The highest height that these objects will be placed at (only relevant if there's a heightmap) /// public float? maxHeight; + + /// + /// Should this detail stay loaded even if you're outside the sector (good for very large props) + /// + public bool keepLoaded; } [JsonObject] From e12de937cd2d58b3da7ae4bb1a35c0be1945a86a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 8 Sep 2022 00:40:31 +0000 Subject: [PATCH 17/29] Updated Schemas --- NewHorizons/Schemas/body_schema.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NewHorizons/Schemas/body_schema.json b/NewHorizons/Schemas/body_schema.json index 18185e87..9a5b05f9 100644 --- a/NewHorizons/Schemas/body_schema.json +++ b/NewHorizons/Schemas/body_schema.json @@ -1391,6 +1391,10 @@ ], "description": "The highest height that these objects will be placed at (only relevant if there's a heightmap)", "format": "float" + }, + "keepLoaded": { + "type": "boolean", + "description": "Should this detail stay loaded even if you're outside the sector (good for very large props)" } } }, From 5dcaac14f58c694b500a3e48217db97f8e09f0eb Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Wed, 7 Sep 2022 17:56:41 -0700 Subject: [PATCH 18/29] rename --- .../Builder/General/{GroupBuilder.cs => GroupsBuilder.cs} | 4 ++-- NewHorizons/Builder/Props/DetailBuilder.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename NewHorizons/Builder/General/{GroupBuilder.cs => GroupsBuilder.cs} (89%) diff --git a/NewHorizons/Builder/General/GroupBuilder.cs b/NewHorizons/Builder/General/GroupsBuilder.cs similarity index 89% rename from NewHorizons/Builder/General/GroupBuilder.cs rename to NewHorizons/Builder/General/GroupsBuilder.cs index c9227ce3..e37e7eab 100644 --- a/NewHorizons/Builder/General/GroupBuilder.cs +++ b/NewHorizons/Builder/General/GroupsBuilder.cs @@ -3,10 +3,10 @@ using Logger = NewHorizons.Utility.Logger; namespace NewHorizons.Builder.General; -public static class GroupBuilder +public static class GroupsBuilder { /// - /// puts groups on objects. + /// puts groups on an object, activated by sector. /// run this before the gameobject is active. /// public static void Make(GameObject go, Sector sector) diff --git a/NewHorizons/Builder/Props/DetailBuilder.cs b/NewHorizons/Builder/Props/DetailBuilder.cs index 2c849ecf..25e22eb2 100644 --- a/NewHorizons/Builder/Props/DetailBuilder.cs +++ b/NewHorizons/Builder/Props/DetailBuilder.cs @@ -101,7 +101,7 @@ namespace NewHorizons.Builder.Props prop.transform.localScale = detail.scale != 0 ? Vector3.one * detail.scale : prefab.transform.localScale; - if (!detail.keepLoaded) GroupBuilder.Make(prop, sector); + if (!detail.keepLoaded) GroupsBuilder.Make(prop, sector); prop.SetActive(true); if (prop == null) return null; From 44b181a3879b817543e0ac9565c04fd4939d19fb Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Wed, 7 Sep 2022 18:01:54 -0700 Subject: [PATCH 19/29] dont use file scoped namespace --- NewHorizons/Builder/General/GroupsBuilder.cs | 42 ++++++++++---------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/NewHorizons/Builder/General/GroupsBuilder.cs b/NewHorizons/Builder/General/GroupsBuilder.cs index e37e7eab..5d8ef6a4 100644 --- a/NewHorizons/Builder/General/GroupsBuilder.cs +++ b/NewHorizons/Builder/General/GroupsBuilder.cs @@ -1,29 +1,31 @@ using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.Builder.General; - -public static class GroupsBuilder +namespace NewHorizons.Builder.General { - /// - /// puts groups on an object, activated by sector. - /// run this before the gameobject is active. - /// - public static void Make(GameObject go, Sector sector) + public static class GroupsBuilder { - if (!sector) + /// + /// puts groups on an object, activated by sector. + /// run this before the gameobject is active. + /// + public static void Make(GameObject go, Sector sector) { - Logger.LogWarning($"tried to put groups on {go.name} when sector is null"); - return; - } - if (go.activeInHierarchy) - { - Logger.LogWarning($"tried to put groups on an active gameobject {go.name}"); - return; - } + if (!sector) + { + Logger.LogWarning($"tried to put groups on {go.name} when sector is null"); + return; + } + if (go.activeInHierarchy) + { + Logger.LogWarning($"tried to put groups on an active gameobject {go.name}"); + return; + } + Logger.LogVerbose($"putting groups on {go.name}"); - go.GetAddComponent()._sector = sector; - go.GetAddComponent()._sector = sector; - go.GetAddComponent()._sector = sector; + go.GetAddComponent()._sector = sector; + go.GetAddComponent()._sector = sector; + go.GetAddComponent()._sector = sector; + } } } \ No newline at end of file From 5847a751c6ae78c953b89960bba8fc1a1f8151db Mon Sep 17 00:00:00 2001 From: Ben C Date: Wed, 7 Sep 2022 21:02:13 -0400 Subject: [PATCH 20/29] Add Log Port Image --- docs/content/pages/editor.md | 2 +- docs/content/pages/tutorials/api.md | 2 +- docs/content/pages/tutorials/details.md | 2 +- docs/content/pages/tutorials/planet_gen.md | 2 +- docs/content/static/images/editor/log_port.webp | Bin 0 -> 14282 bytes 5 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 docs/content/static/images/editor/log_port.webp diff --git a/docs/content/pages/editor.md b/docs/content/pages/editor.md index 4f40cb27..100b8409 100644 --- a/docs/content/pages/editor.md +++ b/docs/content/pages/editor.md @@ -54,7 +54,7 @@ You can start the game from the editor by selecting Project -> Run Project this If you're using the mod manager and would like logs to appear there, you need to get the log port from the console, it's always the first entry in the logs. Keep in mind this port changes whenever you restart the manager. -![TODO: Get Log Screenshot]() +![Get the log port]({{ "images/editor/log_port.webp"|static }}) ## Building diff --git a/docs/content/pages/tutorials/api.md b/docs/content/pages/tutorials/api.md index 5c7a8996..2afd6ffe 100644 --- a/docs/content/pages/tutorials/api.md +++ b/docs/content/pages/tutorials/api.md @@ -1,6 +1,6 @@ --- Title: API -Sort_Priority: 40 +Sort_Priority: 20 --- ## How to use the API diff --git a/docs/content/pages/tutorials/details.md b/docs/content/pages/tutorials/details.md index c8483065..0e96a484 100644 --- a/docs/content/pages/tutorials/details.md +++ b/docs/content/pages/tutorials/details.md @@ -1,6 +1,6 @@ --- Title: Detailing -Sort_Priority: 85 +Sort_Priority: 80 --- # Details/Scatterer diff --git a/docs/content/pages/tutorials/planet_gen.md b/docs/content/pages/tutorials/planet_gen.md index c634b1fd..0dc589f0 100644 --- a/docs/content/pages/tutorials/planet_gen.md +++ b/docs/content/pages/tutorials/planet_gen.md @@ -1,6 +1,6 @@ --- Title: Planet Generation -Sort_Priority: 80 +Sort_Priority: 85 --- # Planet Generation diff --git a/docs/content/static/images/editor/log_port.webp b/docs/content/static/images/editor/log_port.webp new file mode 100644 index 0000000000000000000000000000000000000000..0382c847282d306bfa7df8b80e9ca4d2668142fc GIT binary patch literal 14282 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 z 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 Date: Wed, 7 Sep 2022 18:06:20 -0700 Subject: [PATCH 21/29] Revert "dont use file scoped namespace" This reverts commit 44b181a3879b817543e0ac9565c04fd4939d19fb. --- NewHorizons/Builder/General/GroupsBuilder.cs | 46 ++++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/NewHorizons/Builder/General/GroupsBuilder.cs b/NewHorizons/Builder/General/GroupsBuilder.cs index 5d8ef6a4..e37e7eab 100644 --- a/NewHorizons/Builder/General/GroupsBuilder.cs +++ b/NewHorizons/Builder/General/GroupsBuilder.cs @@ -1,31 +1,29 @@ using UnityEngine; using Logger = NewHorizons.Utility.Logger; -namespace NewHorizons.Builder.General -{ - public static class GroupsBuilder - { - /// - /// puts groups on an object, activated by sector. - /// run this before the gameobject is active. - /// - public static void Make(GameObject go, Sector sector) - { - if (!sector) - { - Logger.LogWarning($"tried to put groups on {go.name} when sector is null"); - return; - } - if (go.activeInHierarchy) - { - Logger.LogWarning($"tried to put groups on an active gameobject {go.name}"); - return; - } - Logger.LogVerbose($"putting groups on {go.name}"); +namespace NewHorizons.Builder.General; - go.GetAddComponent()._sector = sector; - go.GetAddComponent()._sector = sector; - go.GetAddComponent()._sector = sector; +public static class GroupsBuilder +{ + /// + /// puts groups on an object, activated by sector. + /// run this before the gameobject is active. + /// + public static void Make(GameObject go, Sector sector) + { + if (!sector) + { + Logger.LogWarning($"tried to put groups on {go.name} when sector is null"); + return; } + if (go.activeInHierarchy) + { + Logger.LogWarning($"tried to put groups on an active gameobject {go.name}"); + return; + } + + go.GetAddComponent()._sector = sector; + go.GetAddComponent()._sector = sector; + go.GetAddComponent()._sector = sector; } } \ No newline at end of file From 33e28078a6a6ae2e8b09f21e9701d266e6f62d97 Mon Sep 17 00:00:00 2001 From: Ben C Date: Thu, 8 Sep 2022 08:08:26 -0400 Subject: [PATCH 22/29] Added Publishing Page --- docs/content/pages/tutorials/publishing.md | 56 +++++++++++++++++++ .../pages/tutorials/update_existing.md | 34 +++++++++++ 2 files changed, 90 insertions(+) create mode 100644 docs/content/pages/tutorials/publishing.md create mode 100644 docs/content/pages/tutorials/update_existing.md diff --git a/docs/content/pages/tutorials/publishing.md b/docs/content/pages/tutorials/publishing.md new file mode 100644 index 00000000..8cd36c01 --- /dev/null +++ b/docs/content/pages/tutorials/publishing.md @@ -0,0 +1,56 @@ +--- +Title: Publishing Addons +Sort_Priority: 1 +--- + +# Publishing Your Addon + +This page goes over how to publish a release for your mod and submit your mod to the [outer wilds mod database](https://github.com/ow-mods/ow-mod-db) for review. + +This guide assumes you've created your addon by following [the addon creation guide]({{ "Creating An Addon"|route }}). + +## Housekeeping + +Before you release anything, you'll want to make sure: + +- Your mod has a descriptive `README.md`. (This will be shown on the website) +- Your repo has the description field (click the cog in the right column on the "Code" tab) set. (this will be shown in the manager) +- There's no `config.json` in your addon. (Not super important, but good practice) +- Your manifest has a valid name, author, and unique name. + + +## Releasing + +First things first we're going to create a release on GitHub. To do this, first make sure all your changes are committed and pushed in GitHub desktop. + +Then, edit your `manifest.json` and set the version number to `0.1.0` (or any version number that's higher than `0.0.0`). + +Finally, push your changes to GitHub, head to the "Actions" tab of your repository and you should see an action running. + +Once the action finishes head back to the "Code" tab and you should see a Version 0.1.0 (or whatever version you put) in the column on the right. + +Double check the release, it should have a zip file in the assets with your mod's unique name. + +## Submitting + +The hard part is over now, all that's left is to submit your mod to the database. + +[Head to the mod database and make a new "Add/Update Existing Mod" issue](#) + +Fill this out with your mod's info and make sure to put `xen.NewHorizons` in the parent mod field. + +Once you're done filling out the form, an admin will review your mod, make sure it works, and approve it into the database. + +Congrats! You just published your addon! + +## Updating + +If you want to update your mod, you can simply bump the version number in `manifest.json` again. + +To edit the release notes displayed in discord, enter them in the "Description" field before you commit in GitHub desktop. The most recent commit's description is used for the relase notes. + +**You don't need to create a new issue on the database to update your mod, it will be updated automatically after a few minutes** + + + + diff --git a/docs/content/pages/tutorials/update_existing.md b/docs/content/pages/tutorials/update_existing.md new file mode 100644 index 00000000..229a2f1a --- /dev/null +++ b/docs/content/pages/tutorials/update_existing.md @@ -0,0 +1,34 @@ +--- +Title: Update Planets +Sort_Priority: 85 +--- + +# Update Existing Planets + +Similar to above, make a config where "Name" is the name of the planet. The name should be able to just match their in-game english names, however if you encounter any issues with that here are the in-code names for planets that are guaranteed to work: `SUN`, `CAVE_TWIN` (Ember Twin), `TOWER_TWIN` (Ash Twin), `TIMBER_HEARTH`, `BRITTLE_HOLLOW`, `GIANTS_DEEP`, `DARK_BRAMBLE`, `COMET` (Interloper), `WHITE_HOLE`, `WHITE_HOLE_TARGET` (Whitehole station I believe), `QUANTUM_MOON`, `ORBITAL_PROBE_CANNON`, `TIMBER_MOON` (Attlerock), `VOLCANIC_MOON` (Hollow's Lantern), `DREAMWORLD`, `MapSatellite`, `RINGWORLD` (the Stranger). + +Only some of the above modules are supported (currently) for existing planets. Things you cannot modify for existing planets include: heightmaps, procedural generation, gravity, or their orbits. You also can't make them into stars or binary focal points (but why would you want to, just delete them and replace them entirely). However this still means there are many things you can do: completely change their atmospheres, give them rings, asteroid belts, comet tails, lava, water, prop details, or signals. + +You can also delete parts of an existing planet. Here's part of an example config which would delete the rising sand from Ember Twin: +```json +{ + "name": "Ember Twin", + "removeChildren": [ + "SandSphere_Rising" + ] +} +``` + +In `childrenToDestroy` you list the relative paths for the children of the planet's gameObject that you want to delete. + +## Destroy Existing Planets + +You do this (but with the appropriate name) as its own config. +```json +{ + "name" : "Ember Twin", + "destroy" : true +} +``` + +Remember that if you destroy Timber Hearth you better put a `Spawn` module on another planet. If you want to entirely replace the solar system you can destroy everything, including the sun. Also, deleting a planet destroys anything orbiting it, so if you want to replace the solar system you can just destroy the sun. If you're making a brand new star system, you don't have to worry about deleting any existing planets; they won't be there. From 694496f9539e7beb4dce04945ba9aadc32339979 Mon Sep 17 00:00:00 2001 From: Ben C Date: Thu, 8 Sep 2022 08:09:41 -0400 Subject: [PATCH 23/29] Paste Link --- docs/content/pages/tutorials/publishing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/pages/tutorials/publishing.md b/docs/content/pages/tutorials/publishing.md index 8cd36c01..9090e4de 100644 --- a/docs/content/pages/tutorials/publishing.md +++ b/docs/content/pages/tutorials/publishing.md @@ -35,7 +35,7 @@ Double check the release, it should have a zip file in the assets with your mod' The hard part is over now, all that's left is to submit your mod to the database. -[Head to the mod database and make a new "Add/Update Existing Mod" issue](#) +[Head to the mod database and make a new "Add/Update Existing Mod" issue](https://github.com/ow-mods/ow-mod-db/issues/new?assignees=&labels=add-mod&template=add-mod.yml&title=%5BYour+mod+name+here%5D) Fill this out with your mod's info and make sure to put `xen.NewHorizons` in the parent mod field. From 9b482bd2570316dd0dadfaaa01aac38daa4484d3 Mon Sep 17 00:00:00 2001 From: Ben C Date: Thu, 8 Sep 2022 17:02:16 -0400 Subject: [PATCH 24/29] Fix Typos --- docs/content/pages/editor.md | 4 ++-- docs/content/pages/tutorials/details.md | 4 ++-- docs/content/pages/tutorials/dialogue.md | 4 ++-- docs/content/pages/tutorials/extending.md | 4 ++-- docs/content/pages/tutorials/publishing.md | 8 ++++---- docs/content/pages/tutorials/update_existing.md | 2 +- docs/content/pages/tutorials/xml.md | 4 ++-- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/content/pages/editor.md b/docs/content/pages/editor.md index 100b8409..fd314789 100644 --- a/docs/content/pages/editor.md +++ b/docs/content/pages/editor.md @@ -5,7 +5,7 @@ Sort_Priority: 50 # Config Editor -Are you tired of manually editting JSON? Do you want richer validation than a JSON schema? Well then the config editor may be for you! +Are you tired of manually editing JSON? Do you want richer validation than a JSON schema? Well then the config editor may be for you! This page outlines how to install and use the config editor. @@ -43,7 +43,7 @@ You can view images and play audio files with this editor. ### XML Files -Right now, XML support is limited. You'll get syntax highlighting but no error checking or auto-fill. +Right now, XML support is limited. You'll get syntax highlighting but no error checking or autofill. ## Running the Game diff --git a/docs/content/pages/tutorials/details.md b/docs/content/pages/tutorials/details.md index 0e96a484..1c4c0cae 100644 --- a/docs/content/pages/tutorials/details.md +++ b/docs/content/pages/tutorials/details.md @@ -20,7 +20,7 @@ The Prop Placer is a convenience tool that lets you manually place details from 1. Pause the game. You will see an extra menu option titled "Toggle Prop Placer Menu". Click it 2. The prop placer menu should now be open. At the bottom of the menu, you will see a list of mods. Click yours. 1. This menu scrolls. If you do not see your mod, it may be further down the list. -3. The Prop Placer is now active! Unpause the game and you can now place Nomai vases using "G" +3. The Prop Placer is now active! Unpause the game, and you can now place Nomai vases using "G" ### How to Save @@ -39,7 +39,7 @@ What's that? You want to place something other than just vases? Well I can't say ### How to Select Props 1. Pause the game again. The prop placer menu should still be visible. -2. At the top of the menu, you'll see a text box contianing the path for the vase. Replace this with the path for the prop you want to place. For example: `DreamWorld_Body/Sector_DreamWorld/Sector_DreamZone_1/Props_DreamZone_1/OtherComponentsGroup/Trees_Z1/DreamHouseIsland/Tree_DW_M_Var` +2. At the top of the menu, you'll see a text box containing the path for the vase. Replace this with the path for the prop you want to place. For example: `DreamWorld_Body/Sector_DreamWorld/Sector_DreamZone_1/Props_DreamZone_1/OtherComponentsGroup/Trees_Z1/DreamHouseIsland/Tree_DW_M_Var` 3. Tip: use the Unity Explorer mod to find the path for the object you want to place. You only have to do this once. 4. Unpause the game and press "G". Say hello to your new tree! 5. Pause the game again. You will now see the prop you just placed on the list of recently placed props just below the "path" text box. diff --git a/docs/content/pages/tutorials/dialogue.md b/docs/content/pages/tutorials/dialogue.md index 50063480..bd44c160 100644 --- a/docs/content/pages/tutorials/dialogue.md +++ b/docs/content/pages/tutorials/dialogue.md @@ -26,7 +26,7 @@ A condition is a yes/no value stored **for this loop and this loop only**. It c ### Persistent Condition -A persistent condition is similar to a condition, except it *persists* through loops, and is saved on the player's save file. +A persistent condition is similar to a condition, except it *persists* through loops, and is saved on the players save file. ### Remote Trigger @@ -163,4 +163,4 @@ Defining `` in the `` tag instead of a ` @@ -20,7 +20,7 @@ XML is comprised of tags, a tag can represent a section or attribute ``` -Notice how each tag is closed by an identical tag with a slash at the front (i.e `` is closed by ``). +Notice how each tag is closed by an identical tag with a slash at the front (i.e. `` is closed by ``). If the tag has no content you can use the self-closing tag shorthand (i.e. `` doesn't need a closing tag because of the `/` at the end). From fafdb1c48b82fbc33f6c6a6c62e584219d783018 Mon Sep 17 00:00:00 2001 From: Noah Pilarski Date: Thu, 8 Sep 2022 21:12:27 -0400 Subject: [PATCH 25/29] Allow ship log details to be added to vanilla planets --- NewHorizons/Builder/ShipLog/MapModeBuilder.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NewHorizons/Builder/ShipLog/MapModeBuilder.cs b/NewHorizons/Builder/ShipLog/MapModeBuilder.cs index b377bf51..12e55581 100644 --- a/NewHorizons/Builder/ShipLog/MapModeBuilder.cs +++ b/NewHorizons/Builder/ShipLog/MapModeBuilder.cs @@ -219,7 +219,7 @@ namespace NewHorizons.Builder.ShipLog foreach (NewHorizonsBody body in bodies) { - if (body.Config.ShipLog?.mapMode?.manualNavigationPosition == null) continue; + if (body.Config.ShipLog?.mapMode?.manualNavigationPosition == null && body.Config.ShipLog?.mapMode?.details == null) continue; // Sometimes they got other names idk var name = body.Config.name.Replace(" ", ""); @@ -283,6 +283,7 @@ namespace NewHorizons.Builder.ShipLog { gameObject.transform.localScale = Vector3.one * body.Config.ShipLog.mapMode.scale; } + MakeDetails(body, gameObject.transform, greyScaleMaterial); } } } From 1f224b3e72800549339ce1b1e07a090290b724fc Mon Sep 17 00:00:00 2001 From: Noah Pilarski Date: Thu, 8 Sep 2022 22:48:28 -0400 Subject: [PATCH 26/29] Set shuttle landing radius --- NewHorizons/Builder/Atmosphere/VolumesBuilder.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/NewHorizons/Builder/Atmosphere/VolumesBuilder.cs b/NewHorizons/Builder/Atmosphere/VolumesBuilder.cs index cba3845d..ceb9b758 100644 --- a/NewHorizons/Builder/Atmosphere/VolumesBuilder.cs +++ b/NewHorizons/Builder/Atmosphere/VolumesBuilder.cs @@ -31,6 +31,7 @@ namespace NewHorizons.Builder.Atmosphere PlanetoidRuleset PR = rulesetGO.AddComponent(); PR._altitudeFloor = innerRadius; PR._altitudeCeiling = sphereOfInfluence; + PR._shuttleLandingRadius = sphereOfInfluence; PR._useMinimap = config.Base.showMinimap; PR._useAltimeter = config.Base.showMinimap; From f38aacf7bfe36c9acb2e450946c43e5e26793d22 Mon Sep 17 00:00:00 2001 From: Dominik Date: Fri, 9 Sep 2022 15:13:28 +0200 Subject: [PATCH 27/29] Fix JSON file lookup for Proton * Add separate lookup for JSON and JSONC files * Add warning when an empty folder is found --- NewHorizons/Main.cs | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 4c0f4403..a2178860 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -490,10 +490,22 @@ namespace NewHorizons } var folder = mod.ModHelper.Manifest.ModFolderPath; + var systemsFolder = Path.Combine(folder, "systems"); + var planetsFolder = Path.Combine(folder, "planets"); + // Load systems first so that when we load bodies later we can check for missing ones - if (Directory.Exists(folder + @"systems\")) + if (Directory.Exists(systemsFolder)) { - foreach (var file in Directory.GetFiles(folder + @"systems\", "*.json?", SearchOption.AllDirectories)) + var systemFiles = Directory.GetFiles(systemsFolder, "*.json", SearchOption.AllDirectories) + .Concat(Directory.GetFiles(systemsFolder, "*.jsonc", SearchOption.AllDirectories)) + .ToArray(); + + if(systemFiles.Length == 0) + { + Logger.LogWarning($"Found no JSON files in systems folder: {systemsFolder}"); + } + + foreach (var file in systemFiles) { var name = Path.GetFileNameWithoutExtension(file); @@ -526,9 +538,18 @@ namespace NewHorizons } } } - if (Directory.Exists(folder + "planets")) + if (Directory.Exists(planetsFolder)) { - foreach (var file in Directory.GetFiles(folder + @"planets\", "*.json?", SearchOption.AllDirectories)) + var planetFiles = Directory.GetFiles(planetsFolder, "*.json", SearchOption.AllDirectories) + .Concat(Directory.GetFiles(planetsFolder, "*.jsonc", SearchOption.AllDirectories)) + .ToArray(); + + if(planetFiles.Length == 0) + { + Logger.LogWarning($"Found no JSON files in planets folder: {planetsFolder}"); + } + + foreach (var file in planetFiles) { var relativeDirectory = file.Replace(folder, ""); var body = LoadConfig(mod, relativeDirectory); From 6bd84bef8353d8408e5f9f0bea62328aa47355f8 Mon Sep 17 00:00:00 2001 From: Dominik Date: Fri, 9 Sep 2022 15:39:07 +0200 Subject: [PATCH 28/29] Change log level to verbose --- NewHorizons/Main.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index a2178860..b86c8d65 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -502,7 +502,7 @@ namespace NewHorizons if(systemFiles.Length == 0) { - Logger.LogWarning($"Found no JSON files in systems folder: {systemsFolder}"); + Logger.LogVerbose($"Found no JSON files in systems folder: {systemsFolder}"); } foreach (var file in systemFiles) @@ -546,7 +546,7 @@ namespace NewHorizons if(planetFiles.Length == 0) { - Logger.LogWarning($"Found no JSON files in planets folder: {planetsFolder}"); + Logger.LogVerbose($"Found no JSON files in planets folder: {planetsFolder}"); } foreach (var file in planetFiles) From 5fee72e649472f09bd250262ec9e12ba5fab20f9 Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 9 Sep 2022 19:38:27 -0400 Subject: [PATCH 29/29] Patch CharacterDialogueTree to end conversation when attaching --- .../Patches/CharacterDialogueTreePatches.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 NewHorizons/Patches/CharacterDialogueTreePatches.cs diff --git a/NewHorizons/Patches/CharacterDialogueTreePatches.cs b/NewHorizons/Patches/CharacterDialogueTreePatches.cs new file mode 100644 index 00000000..6493eba1 --- /dev/null +++ b/NewHorizons/Patches/CharacterDialogueTreePatches.cs @@ -0,0 +1,21 @@ +using HarmonyLib; + +namespace NewHorizons.Patches; + +[HarmonyPatch] +internal class CharacterDialogueTreePatches +{ + [HarmonyPrefix] + [HarmonyPatch(typeof(CharacterDialogueTree), nameof(CharacterDialogueTree.Awake))] + private static void CharacterDialogueTree_Awake(CharacterDialogueTree __instance) + { + GlobalMessenger.AddListener("AttachPlayerToPoint", (_) => __instance.EndConversation()); + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(CharacterDialogueTree), nameof(CharacterDialogueTree.OnDestroy))] + private static void CharacterDialogueTree_OnDestroy(CharacterDialogueTree __instance) + { + GlobalMessenger.RemoveListener("AttachPlayerToPoint", (_) => __instance.EndConversation()); + } +}