Skip to content

Commit

Permalink
More doc work
Browse files Browse the repository at this point in the history
  • Loading branch information
Noggog committed May 2, 2024
1 parent 9c5d728 commit db3e8a6
Show file tree
Hide file tree
Showing 12 changed files with 412 additions and 7 deletions.
14 changes: 14 additions & 0 deletions docs/External-Program.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# External Program Patcher
This type latches on and executes any executable program (exe). It will pass along the Synthesis [command line arguments](CLI-Specification.md) to inform the program of what it should be patching, and where to put its results.

![](https://i.imgur.com/HpOAsQ4.png)

## Goals and Reasons to Choose
This patcher type is meant for non-Mutagen based patcher programs that want to participate in a Synthesis patch pipeline. As long as the program can take in the [command line arguments](CLI-Specification.md), and produce a patch file in the desired location, it can be a patcher within Synthesis.


!!! tip "Not for Mutagen-Based Patchers"
This is not typically used with Mutagen-based patchers, as [Git Repository](Git-Repository.md) or [Local Solution](Local-Solution.md) are better options.

## Required Input
The only required input is a path to the executable file to run.
6 changes: 6 additions & 0 deletions docs/FAQ-and-Troubleshooting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# FAQ and Troubleshooting

## Check out the Discussions tab
Rather than writing wiki articles about common questions and problems, the [Discussions](https://github.com/Mutagen-Modding/Synthesis/discussions) area is the place to look and ask!

It is a Stack Overflow style question and answer area that hopefully will serve the job better than static wiki pages.
38 changes: 38 additions & 0 deletions docs/Git-Repository.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Git Repository Patcher
This type latches on to a patcher accessible via a Git Repository address (usually hosted on Github.com). ****It will clone the code and build the exe to run locally on your machine****. It only supports Mutagen-based projects.

![](https://i.imgur.com/DdgARsi.png)

!!! success "Recommended"
This is the recommended patcher type for typical users

## Reasons to Choose
Because it builds code on your machine, it has a few upsides:

- Can automatically update to the latest version of a patcher's code
- Can artificially update a patcher to the latest version of Mutagen/Synthesis to grab bugfixes and optimizations
- Does not require a patcher author to explicitly create and publish an exe to be runnable

## Installation
### Manual Input

The `Input` pane allows you to create a Git Patcher by explicitly providing the repository details

- Address of the git repository
- Project within the repository to use (a repository could have multiple patchers, for example)

### Patcher Browser
Alternatively, you can make use of the "Browse" feature, which lists a whole load of patchers that were automatically located on Github.

![](https://i.imgur.com/S0JsBgV.png)

To get to the Patcher browser, click and add a new Git Repository Patcher at the top left, and then go to the Browse tab.

## Versioning
Git Repository Patchers have the unique capability of being able to control what code you want to use for a patcher.

This is an important topic, and so has received its own section in the Overview documentation

[:octicons-arrow-right-24: Versioning](Versioning.md)

![](https://i.imgur.com/DpcHKDN.png)
42 changes: 42 additions & 0 deletions docs/Local-Solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Local Solution Patcher
This style uses a local C# project which is compiled and run as a patcher.

![](https://i.imgur.com/FUGCqsN.png)

## Goals and Reasons to Choose

- Preferred route any time you want to run raw code from a folder that you downloaded/created yourself
- Can create new patcher Solutions/Projects or latch on to existing projects
- Generated solutions come with a lot of initial settings configured for you, such as Nullability errors.
- Code can be developed in an IDE on the side, but run from within Synthesis as part of a larger patcher pipeline.
- Meta information tooling is offered to customize the patcher's information such as descriptions/nicknames/visibility in the patcher browser

!!! tip "Preferred for Developers, When Needed"
While this is the preferred patcher choice for developers, note that running during normal development should be done from your IDE, and not through the Synthesis UI

[:octicons-arrow-right-24: Running a Patcher](Running-And-Debugging.md)

## Required Input
The basic input required is:

- Path to a solution
- A dropdown of related projects will populate, of which one should be chosen.

## New Patcher Wizard
Synthesis is able to construct new patcher projects for you that contain a lot of starting frameworks and default settings.

![](https://i.imgur.com/06H1CRa.png)

It is able to construct whole Solutions from scratch, or add a new project to an existing solution, or latch onto existing projects.

## Patcher Settings
A patcher has a Synthesis specific meta file where you can specify patcher description, among other things. The Solution Patcher has built in GUI controls for modifying/creating this file:

![](https://i.imgur.com/mTJevUM.png)

Settings you can modify:

- Patcher display name
- One line description
- Multi-line extended description
- Whether to show in the [patcher browser](https://github.com/Mutagen-Modding/Synthesis/wiki/Git-Repository#patcher-browser) by default
5 changes: 5 additions & 0 deletions docs/Starting-Into-Profile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Synthesis can be started with command line parameters to have it open to a specific profile:

`-p ProfileName`

Using this, you can have different Mo2 profiles drive Synthesis to open with a specific associated profile
15 changes: 15 additions & 0 deletions docs/Updating-UI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Updating the Synthesis UI
There are a few [Versioning](Versioning.md) concepts within the Synthesis ecosystem, but the UI itself should generally be kept up to date with the newest version.

## Update .Net SDK
If the [Installation Instructions](Installation.md) have updated, you might need to install the newest .Net SDK

## Updating the UI
- Go to [Releases](https://github.com/Mutagen-Modding/Synthesis/releases) and download the latest stable version.
- Optionally back up your settings. This includes:
- `[UI Exe Location]/PipelineSettings.json`
- `[UI Exe Location]/GuiSettings.json`
- `[UI Exe Location]/Data/`
- Unzip the release zip
- Overwrite the old Synthesis files
- Can also opt to keep the new version in a new area, but you will want to copy over the settings mentioned above
36 changes: 32 additions & 4 deletions docs/Versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ This picture shows a UI that is `0.21.2`
!!! tip "Use the newest UI"
The UI should usually always be the newest stable version available. Only in rare circumstances might you want to downgrade it if some bug was encountered, and a hotfix hadn't been released yet.

## Patcher Versioning
This section outlines the various ways a specific patcher's versioning can controlled.
## Git Patcher Versioning
This section outlines the various ways a specific Git Patcher's versioning can controlled. As this is the most commonly used patcher, it is an important topic.

### Libraries to Use
`Mutagen` and `Synthesis` are also code libraries that patchers use to develop their logic. Depending on which version a patcher uses when running, it might get certain fixes/improvements/features.
Expand All @@ -33,26 +33,54 @@ This option is only available on individual patchers, and helps keeps all of you
This is the recommended choice for individual patchers [Read More](#recommended-setup)

#### Manual
This setting allows you to control the versioning to be used explicitly by typing in the desired version by hand. It will also show a blue arrow when there's a newer version than the one you typed, which you can click manually to upgrade, if you so choose.
Sets the patcher to use a specific version, while allowing the user to easily update to latest when desired.

Pros:

- Follows latest easily, while giving you a heads up and control over timing

Cons:

- Depending on the versions you input and the age of the patcher, it may not compile

![](https://i.imgur.com/u1xRQwE.gif)

!!! success "Recommended"
Manual is the best balance between control and convenience, and is the recommended default choice [Read More](#recommended-setup)

#### Match
Use whatever versions were listed explicitly by the patcher.

Each patcher is coded at a certain point in time. The developer will typically work with the newest versions when develop their patcher. As time progresses this listed version will become "old" as newer versions of `Mutagen` or `Synthesis` get released.

By setting a patcher to `Match`, you are telling a patcher to use the same versions it was originally coded with. This will be the most compatible, but might miss out on some necessary bugfixes.

Pros:

- More stable, as these were the versions used when the patcher was developed

Cons:

- Won't have any fixes or optimizations that came later on


!!! info "Compatibility Fallback Choice"
Only set patchers to Match if they are having problems running

#### Latest
This will upgrade the patcher to use the latest version of Mutagen/Synthesis libraries automatically. It's usually recommended to avoid using this, in favor of `Manual`, which lets you click the upgrade buttons yourself so you know when things are being upgraded.

Pros:

- Get the latest features/fixes/optimizations right as they come out

Cons:

- The resulting patch might change at any time if a patcher updates and changes its logic.
- Depending on the age of the patcher, it may not compile

!!! warning "Unexpected Updates"
Latest can result in stealth breaks as you will get no indicator that something has updated
If you want a consistent patch every time you run, you don't want to use this option

#### Recommended Setup
The recommended setup for patcher versioning is:
Expand Down
56 changes: 56 additions & 0 deletions docs/devs/Coding-a-Patcher.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Coding a Patcher
## Starting Setup
If you used a Local [Solution Patcher](Local-Solution.md) to [Create a Patcher](Create-a-Patcher.md), then you will have a project that has a minimal basic setup:

```csharp
public static async Task<int> Main(string[] args)
{
return await SynthesisPipeline.Instance
.AddPatch<ISkyrimMod, ISkyrimModGetter>(RunPatch)
.SetTypicalOpen(GameRelease.SkyrimSE, "YourPatcher.esp")
.Run(args);
}

public static void RunPatch(IPatcherState<ISkyrimMod, ISkyrimModGetter> state)
{
//Your code here!
}
```

## Run Patch Method
The `RunPatch` method is where the code for your patcher should be located. It will be run when Synthesis is running a pipeline, as well as when your program is started standalone. The method has access to the Synthesis State object, which has much of the information needed to run a patcher.

Whatever changes you want to be made should be applied to the `state.PatchMod` object.

## Synthesis State Object
The state object given to your `RunPatch` contains several important objects:

- PatchMod: The export patch mod object that all changes should be applied to
- [LoadOrder](https://github.com/Mutagen-Modding/Mutagen/wiki/Load-Orders-and-Winning-Overrides): Object containing all the readonly mod objects on the load order
- [LinkCache](https://github.com/Mutagen-Modding/Mutagen/wiki/LinkCache%3A-Record-Lookup): Link Cache created from the load order
- ExtraSettingsDataPath: Path where any custom [Internal Data](https://github.com/Mutagen-Modding/Synthesis/wiki/Internal-Data) will be located

## Typical Simple Code
Typical code for a Synthesis patcher consists of locating Winning Overrides for a record type, and adding them to the output patch mod with some changes. Here is a simplistic example:

```csharp
// Loop over all the winning NPCs in the load order
foreach (var npcGetter in state.LoadOrder.PriorityOrder.Npc().WinningOverrides())
{
// See if it is a Goblin
if (!npcGetter.EditorID?.Contains("Goblin", StringComparison.OrdinalIgnoreCase) ?? true) continue;

// Add it to the patch
var npc = state.PatchMod.Npcs.GetOrAddAsOverride(npcGetter);

// Shrink
npc.Height /= 2;
}
```

The above code will shrink any Goblin-named NPCs

Two good resources for learning further details:

- A large catalogue of [existing patchers](https://github.com/Mutagen-Modding/Synthesis/network/dependents?package_id=UGFja2FnZS0xMzg1MjY1MjYz) to look at for examples
- In-depth Mutagen documentation found on the [Mutagen wiki](https://github.com/Mutagen-Modding/Mutagen/wiki).
70 changes: 70 additions & 0 deletions docs/devs/Configuring-a-Patcher-at-Startup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Configuring a Patcher at Startup
The main method of a patcher is dedicated to calling `SynthesisPipeline`, which is a builder that lets you customize how and what your patcher is going to run.

```cs
// A typical main method
public static async Task<int> Main(string[] args)
{
return await SynthesisPipeline.Instance
.AddPatch<ISkyrimMod, ISkyrimModGetter>(RunPatch)
.SetTypicalOpen(GameRelease.SkyrimSE, "YourPatcher.esp")
.Run(args);
}
```

The main method as created by the template system can be left as-is for a basic setup, but it can be customized to your needs from there.

## AddPatch
Adds a Game Category to be handled by your patcher, and lets you decide what function should be called when your patcher is being run for that game. One `AddPatch` is generally required, as it's the entry point into your patcher for the game you want to target.

### PatcherPreferences
This is an optional argument to an `AddPatch` call, which will customize some settings related to that Patch operation.

- IncludeDisabledMods: Whether to include mods that are disabled on the LoadOrder object _(default false)_
- AddImplicitMasters: Whether to enable masters that are listed as disabled, but required by an active mod
- NoPatch: If toggled on, your patcher will skip the export step. Useful if your patcher is just modifying other unrelated files only.
- Cancel: (Advanced) If your app wants to be able to cancel an in-progress patching run, for some reason, a cancellation token can be given here.
- Inclusion/ExclusionMods: (Untested) Allows whitelisting or blacklisting mods from the load order

## Standalone Open Configuration
Determines what your patcher will do if it's run standalone, either via running the exe directly from the desktop, or more likely when running it from your IDE for testing.

!!! info "Renamed"
Will eventually be renamed to `SetStandaloneOpen`

### Target Mod File
By default, the `SetTypicalOpen` is set to:

- Output into the typical data folder
- With a given mod name
- For a given Game Release

```cs
.SetTypicalOpen(GameRelease.SkyrimSE, "YourPatcher.esp")
```

### Arbitrary Code
You can also pass `SetTypicalOpen` any C# Action, which will give you the ability to run any code you want during standalone runs:

```cs
...
.SetTypicalOpen(() =>
{
// Whatever code you want
})
```

## Run
Capstone call to the SynthesisPipeline builder which takes in the arguments given to your app when it started and runs the patcher given the rules you've specified. The program will do nothing if this is missing.

## SetAutogeneratedSettings
Associates a settings file with a settings object. This allows you to get [easy autogenerated settings](https://github.com/Mutagen-Modding/Synthesis/wiki/User-Input#automatic-settings-ui-system) provided by Synthesis.

The main method just passes the arguments given your program to the Synthesis systems, which handles all the various commands that could be passed in. Generally, the main method can be left as-is.

## AddRunnabilityCheck
Provides a callback to check if your patcher sees itself as having all the necessary things it needs to run, and block execution until those requirements are satisfied.
[Read More](https://github.com/Mutagen-Modding/Synthesis/wiki/Required-Mods-and-Runnability-Checks)

## SetOpenForSettings
This is a more advanced option, which allows your patcher to be opened as a settings editor. It requires you to modify your patcher project a lot, so that it is simultaneously a patcher executable as well as a UI application. If that is set up, then this call provides the entry point to know when to open your application as a UI for settings input.
69 changes: 69 additions & 0 deletions docs/devs/Create-a-Patcher.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
## Install an IDE
**Be sure to install an [IDE](https://visualstudio.microsoft.com/vs/community/) for C# development!** You will also need the [DotNet SDK](https://dotnet.microsoft.com/download), but this should come with the IDE.

## Solution Patcher
Synthesis provides bootstrapping functionality to get new Mutagen patchers off the ground fairly easily.

These systems can be found by creating a new [Local Solution patcher](Local-Solution.md), which is the preferred patcher type for developers.

![](https://i.imgur.com/06H1CRa.png)

There is a few options available when creating a new Solution Patcher:

- New Solution and Project (for brand new setups)
- New Project (for adding another patcher to an existing repository)
- Existing (latch on to an existing setup)

When creating a new patcher, Synthesis will construct and set up several default settings/files:

- Creates a solution
- Creates a project, with both Synthesis and Mutagen imported
- Creates a default main method, which is hooked into the standard Synthesis pipeline.
- Enables [nullability compiler features](https://github.com/Mutagen-Modding/Mutagen/wiki/Classes%2C-Interfaces%2C-and-Record-Presence#nullability-to-indicate-record-presence), which are very important when utilizing Mutagen
- Default gitignore
- Hides/upgrades some specific error types

!!! tip "Prefer IDE"
The solution patcher should not be used to execute your program during normal development. Run through your IDE instead while you're writing code to get debugging features.

[:octicons-arrow-right-24: Running a Patcher](Running-And-Debugging.md)

## Locating the Code
The Local Solution Patcher can open your preferred IDE, or you can navigate and open the solution yourself.

NOTE: While the Synthesis UI helps make a new solution, once it's made, it is recommended to just open it with your IDE, and not use the Synthesis UI during active development. Only use the Synthesis UI if you're interested in testing your patcher alongside other patchers (not usually interesting).

A patcher project should have a `Program.cs` file with the initial Synthesis bootstrapping code already in place.

```csharp
public static async Task<int> Main(string[] args)
{
return await SynthesisPipeline.Instance
.AddPatch<ISkyrimMod, ISkyrimModGetter>(RunPatch)
.SetTypicalOpen(GameRelease.SkyrimSE, "YourPatcher.esp")
.Run(args);
}

public static void RunPatch(IPatcherState<ISkyrimMod, ISkyrimModGetter> state)
{
//Your code here!
}
```

The main function calls Synthesis bootstrapping code that listens for commands from the Synthesis pipeline and calls your RunPatch code when appropriate.

## Customization
Patchers that are listed on the store use a meta json file to specify some customization. The Local Solution Patcher can modify this file for you in the GUI itself.

![](https://i.imgur.com/iA9DR89.png)

- Display Name
- One line description
- Long description
- Whether to show in the store by default

## More Topics

[:octicons-arrow-right-24: Coding a Patcher](Coding-a-Patcher.md)

[:octicons-arrow-right-24: Running a Patcher](Running-And-Debugging.md)
Loading

0 comments on commit db3e8a6

Please sign in to comment.