Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core redirects guide for end users #297

Merged
merged 15 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ Contact us for more details if you'd like to set this up. The general steps are
- If you want the deployed copy to automatically update when you push changes to your repo, you should set up an Actions file similar to [this one](.github/workflows/SubModPush.yml.example) and contact us on the Discord to get a token to [add to your secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) so the Actions file can function.
- PR the `Dev` branch with your changes to the playbook files.

Sub-mod documentation sites are currently still subject to the Lychee link checker run by our CI,
so if you have broken links in your docs, the build will fail and your site will not be updated.
You can check the [Actions](https://github.com/satisfactorymodding/Documentation/actions) for this repo to see if/why they failed. Mod docs updates are started by the SatisfactoryModdingBot github user under the action name `mod-docs-update`.

## Adding new version branches

We typically create new version branches once a new major or minor version of SML has released.
Expand Down
2 changes: 1 addition & 1 deletion antora-playbook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ content:
sources:
## Used for prod
- url: https://github.com/satisfactorymodding/Documentation.git
branches: master, v3.5.1, v3.4.1, v3.3.2, v3.1.1, v2.2.1, v2.1.1, v2.0.0, v1.0.2
branches: master, v3.6.1, v3.5.1, v3.4.1, v3.3.2, v3.1.1, v2.2.1, v2.1.1, v2.0.0, v1.0.2
edit_url: '{web_url}/blob/{refname}/{path}'

## Used for dev
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
** xref:ForUsers/ConfiguringMods.adoc[Configuring Mods]
** xref:ForUsers/Tags.adoc[Tags and Tag Search]
** xref:ForUsers/DedicatedServerSetup.adoc[Installing Mods on Dedicated Servers]
** xref:ForUsers/CoreRedirectMigration.adoc[Migrating Modded Content with Core Redirects]

* xref:Development/index.adoc[Development]

Expand Down
37 changes: 28 additions & 9 deletions modules/ROOT/pages/Development/ModLoader/AccessTransformers.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ UE-CSS 4.25.3 build 42 adds a new feature: the ability to make accessors for fie
This ability, called the **Access Transformer** system, is beneficial because it allows you to essentially make header accessor edits without the cost of having to deal with merge conflicts when bringing in updated SML and game headers later down the line. It also makes it easier to collaborate with other developers, because normal header edits are made in files outside of the plugin directory, meaning they would not be included in plugin (mod) source code repositories. Access transformers are defined in a file within the plugin directory, so they can easily be included in repositories.

As of UE-CSS 4.26.2 build 30, BlueprintCallable is also supported.
Additionally, access transformers that are not written correctly,
or refer to fields that are no longer present,
will result in an error message at compile time:
`Unused <transformer type> for class <ClassName>, <extra details>. Requested by <ModReference>`.
If you see this error message, it means you probably made a typo in your access transformer, or you are not using that access transformer type correctly.

[NOTE]
====
Expand Down Expand Up @@ -37,6 +32,23 @@ BlueprintCallable=(Class="/Script/FactoryGame.FGSomeClass", Function="SomeFuncti
You can have multiple (or none) of each of the access transformer types in one file,
but they should all be under the same `[AccessTransformers]` section header.

== Target Class

All access transformers require a target class (or struct) to be specified in the Class field.
This is the class being modified by the transformer.
It should be specified in the format `"/Script/CppModuleName.ClassName"`.

Remove any Unreal type prefixes (like `U`, `F`, or `A`) from the class name when specifying it in the Class field.
For example, the `FFootstepEffectSurface` struct should use `FootstepEffectSurface` in the class name field.

== Troubleshooting

Access transformers that are not written correctly,
or refer to fields that are no longer present,
will result in an error message at compile time and in the Output Log:
`Unused <transformer type> for class <ClassName>, <extra details>. Requested by <ModReference>`.
If you see this error message, it means you probably made a typo in your access transformer, or you are not using that access transformer type correctly.

== Definitions

=== Friend
Expand All @@ -47,7 +59,8 @@ Adds `friend class UMyClass;` into the class you specify, allowing `UMyClass` to

Creates the public methods `FORCEINLINE PropertyType GetSomeProperty() { return mSomeProperty; }` and `FORCEINLINE void SetSomeProperty(PropertyType SomeProperty) { mSomeProperty = SomeProperty; }`.

This is beneficial when you are trying to access a field and you are not in a class to use Friend for. Below is an example from PowerSuit for the FEquipmentStats struct.
This is beneficial when you are trying to access a field and you are not in a class to use Friend for.
Below is a usage example from PowerSuit for the FEquipmentStats struct.

// cspell:ignore Getm
[source,cpp]
Expand All @@ -60,11 +73,15 @@ SuitCostToUse = Parent->EquipmentParent.GetmCostToUse();

=== BlueprintReadWrite

Adds `BlueprintReadWrite` to the specified UPROPERTY, allowing you to access that property from blueprints (it cannot be added to a non-UPROPERTY field). It also bypasses the private BPRW conflict check (which is compile time only, it does not affect the editor, or the game), so that no changes to the game headers are required.
Adds `BlueprintReadWrite` to the specified UPROPERTY, allowing you to access that property from blueprints.
It cannot be added to a non-`UPROPERTY` field.
It also bypasses the private BPRW conflict check (which is compile time only, it does not affect the editor, or the game),
so that no changes to the game headers are required.

=== BlueprintCallable

Adds `BlueprintCallable` to the specified UFUNCTION, allowing you to call that function from blueprints (it cannot be added to a non-UFUNCTION function).
Adds `BlueprintCallable` to the specified UFUNCTION, allowing you to call that function from blueprints.
It cannot be added to a non-`UFUNCTION` function.

== Loading

Expand Down Expand Up @@ -92,7 +109,9 @@ so the generator will mistakenly decide not to build the transformers in that fi

[WARNING]
====
Access Transformers can't modify engine classes, since the UHT will not generate `.generated.h` files for the engine classes when using a prebuilt engine. It has not been tested if they would work on a source built engine.
Access Transformers can't modify engine classes,
since the UHT will not generate `.generated.h` files for the engine classes when using a prebuilt engine.
It has not been tested if they would work on a source built engine.
====

[WARNING]
Expand Down
28 changes: 26 additions & 2 deletions modules/ROOT/pages/Development/TestingResources.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ This page lists some helpful resources and information regarding testing your mo

SML Logging is a valuable troubleshooting and testing tool, especially for blueprint mods.

You can find more information on how to use and configure it on the
xref:Development/ModLoader/Logging.adoc[Logging page].
You can find more information on how to use and configure it,
as well as how to launch a live log viewer when you launch the game,
on the xref:Development/ModLoader/Logging.adoc[Logging page].

If you select text in the log terminal window,
it will freeze the game until you press 'enter' to deselect it.
Expand All @@ -28,6 +29,29 @@ will affect every instance of Command Prompt on your system.
See the link:#_launch_script_enhancements[Launch Script Enhancements] section below
for another method of controlling where the window will appear.

== Unreal Console

The Unreal Console is a useful tool for debugging your mods.
It extends the original log terminal mentioned in the previous section with some new features:

- Options to filter (include/exclude) displayed log messages
- Clearing the displayed log
- Creating numbered "checkpoint" log markers
- Running console commands from outside the game window (especially useful for dedicated servers)
- See the game's current status regardless of log position
- Selecting displayed log messages no longer freezes the game, which you may consider a benefit or a drawback.

In order to use the new console, add the following to your game's command-line launch arguments:

`-Log -NewConsole`

If you don't know how to configure launch arguments,
refer to xref:faq.adoc#_how_do_i_start_the_game_with_launch_arguments[this guide].

Now, when you launch the game, you should now see the Unreal Console appear as a separate window.

image:TestingResources/Unreal-Console.png[image]

[id="LaunchScript"]
== Quick Launch Script

Expand Down
211 changes: 211 additions & 0 deletions modules/ROOT/pages/ForUsers/CoreRedirectMigration.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
= Migrating Modded Content with Core Redirects

Unreal Engine's **Core Redirects** feature can be used to force
the game to replace modded content with alternative content, under certain conditions.

The following use cases are particularly relevant for users of mods:

* Uninstalling a mod, but replacing its buildings with the closest base-game equivalent
* Migrating from one mod to another mod that offers similar buildings

Core Redirects are the system that modders can use to ensure saved content is not lost when they move it internally inside their mods.
Mod developers can read more about this on the xref:Development/UnrealEngine/CoreRedirect.adoc[mod-developer-focused page about Core Redirects].

== Restrictions

Using core redirects may not work for your use case. Carefully consider the following:

* Core Redirects can only be used to replace _every_ instance of content with another. You can't replace just the constructors in one building, the operation applies to your entire save file
* For the redirect to take effect, the old content must become undefined or unloaded
** You can cause this manually by uninstalling the mod that contains the old content
** It's not possible to replace _part_ of a mod's buildings, you must replace everything from that mod, or accept that you will lose the content that was not migrated
* You must find out the Asset Path of the new and old content
** This requires some non-trivial work on your end
** Finding asset paths will be covered in another section
* The new content must be similar enough in internal structure to the old content
** As a user, it's not always clear if this is possible, even if it seems like it "should" be. You will have to try it and see.
** Keep in mind that **if this process doesn't work, there is not really anything you can change to make it work**. The restrictions on what can be replaced with what stem from what the content is and how it was implemented in the mod.
** For example, you can sometimes replace a modded belt with another modded belt, or a modded power pole with a vanilla power pole, but replacing a constructor with a foundation won't work

[id="BackUpSaves"]
== Step 1: Back Up Your Saves!

Before you start messing with core redirects, back up your saves.
If you make a mistake, you could lose content or even corrupt your save file.
Both of these risks are entirely avoided by simply making a backup of your save files first.

[id="FindAssetPathOld"]
== Step 2: Find the Asset Path of the Content to Replace

In order to write a core redirect,
you must obtain the Unreal Asset Paths for the content you want to replace
and what you want to replace it with.

An asset path is a string that represents where the content is stored in the mod's packaged files.
Although it may look similar to a traditional file path, you can't simply browse to it in your file explorer.
Read the sections below to learn how to find asset paths.

They generally look like this:
`/Game/FactoryGame/Buildable/Building/Foundation/Build_Foundation_8x1_01.Build_Foundation_8x1_01_C`

Finding the asset paths is the most difficult part of the process, so don't be discouraged if it takes a while to figure out.

=== You Can Load Into the Save File

If you can still load into a save that contains the old content,
finding the asset path is relatively straightforward.
Two different approaches are described below.

[id="ContentInspectorMethod_InSaveFile"]
==== Content Inspector Method

The https://ficsit.app/mod/ContentInspector[Content Inspector] mod
allows you to browse a mod's content in-game in a file-explorer-like interface.
Read its mod page for examples and usage instructions.

Look at a building and use the `/inspect this` chat command to attempt to open Content Inspector on what your character is looking at.

Content Inspector displays the path to the class default object (not quite what we want, but close) in the `JS_LibOuter` field near the top of the text box.

image:ForUsers/CoreRedirectMigration/ContentInspector.png[Content Inspector showing the asset path of a building]

For example, the 8m x 1m Foundation displays this in ContentInspector:

`/Game/FactoryGame/Buildable/Building/Foundation/Build_Foundation_8x1_01.Default__Build_Foundation_8x1_01_C`

...which you can edit to get the asset path of:

`/Game/FactoryGame/Buildable/Building/Foundation/Build_Foundation_8x1_01.Build_Foundation_8x1_01_C`

[id="TFITMethod_InSaveFile"]
==== TFIT Method

Debugging features in the https://ficsit.app/mod/TFIT[TFIT] mod can display asset paths for you.

For buildings, enable the "Overlay: Debug Mode" and "Overlay: Logging" mod config options
and the asset path will be printed in your xref:faq.adoc#Files_Logs[log files].

image:ForUsers/CoreRedirectMigration/TFIT.png[TFIT showing the asset path of a building in the log files]

Remember to turn these options off after you're done because they produce a lot of log spam.

Other debugging features in the mod can reveal item and recipe paths.
See the bottom of the mod page for more details.

=== You Can't Load Into the Save File

If you can't load into the save file, finding the asset path is more difficult, and your options are limited.

[id="ContentInspectorMethod_FromMenu"]
==== Content Inspector Method (from the main menu)

If you still have the mod offering the content installed, Content Inspector can also be used to browse mod assets from the main menu.
See the link:#ContentInspectorMethod_InSaveFile[directions above] for more information about this tool.

==== Use External Software

If you have a copy of the mod, but can't launch the game for some reason,
you can use the external software xref:Development/ExtractGameFiles.adoc#FModel[FModel]
to browse the mod's package files with the game closed and find the asset path that way.

You may also be able to use save editors that display class information about your save file.

[id="FindAssetPathNew"]
== Step 3: Find the Asset Path of the New Content to Replace With

Do Step 2 again, but this time you're looking for the asset path of the 'new' content.

[id="CreateCoreRedirectIni"]
== Step 4: Create the Core Redirect File

. Close the game, if you currently have it open
. Create a new text file `Engine.ini` in the following location: `[GameInstallFolder]\FactoryGame\Mods\SML\Config`
* Note that any mod's config folder will work, SML's is just a convenient place to put it
. Ensure that the file extension is `.ini` and not `.ini.txt`
. Edit the file to add the following content as a template:

```ini
[CoreRedirects]
+ClassRedirects=(OldName="YOUR_OLD_PATH_HERE",NewName="YOUR_NEW_PATH_HERE")
```

Now, put the asset path for the content you want to replace in place of `YOUR_OLD_PATH_HERE`
and the new content's asset path in place of `YOUR_NEW_PATH_HERE`.

Compare against the link:#Examples[examples below] to ensure you've formatted it correctly.

If you want to replace more than one type of content at once,
you can add more `+ClassRedirects` lines and repeat steps 2 and 3 to find paths to use.

[id="VerifySuccess"]
== Step 5: Making Sure it Worked

Once your `Engine.ini` file is set up and saved:

. Uninstall the mod providing the old content, if you still have it installed
. Launch the game
. Load your save file. SML will warn you about a mod missing before you load - this is to be expected.

Go around your save and look around to see if the core redirect succeeded.
Core redirects are all-or-nothing, so if you see one place where it didn't work,
you don't need to check anywhere else in the save, just quit out and check your core redirect file syntax.

If it didn't work,
make sure your asset paths end in `_C`, don't contain `Default__`,
and are correctly encased in quotes and parentheses like in the examples below.

Your xref:faq.adoc#Files_Logs[log files] will contain messages near the `========= [] Load error summary =========` heading
about any classes that couldn't be found on load.
You may want to set up redirects for these classes as well.

Keep in mind that you generally don't need to redirect recipes, schematics,
and any content that doesn't seem to be a building/item/etc
either because there is no good equivalent to redirect to (recipes/schematics)
or because the game will construct it on its own (redirecting an already-unlocked schematic will unlock its recipes).

Note that classes you have core redirected will not appear in this list
because they "have" been found - by pointing to the new content instead.

[id="CleanUp"]
== Step 6: Clean Up

Hooray! You've successfully migrated your content.

Once you save your game and exit, the redirect will have permanently replaced the old content with the new content in that save file.

As such, you don't need the redirectors any more, so go back to `[GameInstallFolder]\FactoryGame\Mods\SML\Config` and remove the `Engine.ini` file you created.

[id="Examples"]
== Examples

Here are some examples of known-to-work core redirects.

[id="Example_BeltReplace"]
=== Replacing Modded Belt with Vanilla Belt

Replaces all Conveyor Belts and Lifts from the https://ficsit.app/mod/BeltMk6[Conveyor Belt Mk6*] mod with Mk5 versions from the base game.

```ini
[CoreRedirects]
+ClassRedirects=(OldName="/BeltMk6/Buildable/ConveyorLiftMk6/Build_ConveyorLiftMk6.Build_ConveyorLiftMk6_C",NewName="/Game/FactoryGame/Buildable/Factory/ConveyorLiftMk5/Build_ConveyorLiftMk5.Build_ConveyorLiftMk5_C")
+ClassRedirects=(OldName="/BeltMk6/Buildable/ConveyorBeltMk6/Build_ConveyorBeltMk6.Build_ConveyorBeltMk6_C",NewName="/Game/FactoryGame/Buildable/Factory/ConveyorBeltMk5/Build_ConveyorBeltMk5.Build_ConveyorBeltMk5_C")
```

=== Replacing Flex Power Lines with Vanilla Power Lines

Replace all Flex Power Lines from the https://ficsit.app/mod/FlexSplines[Flex Splines] mod with the base game's Power Lines.
Note that they may render incorrectly due to the different placement restrictions.

```ini
[CoreRedirects]
+ClassRedirects=(OldName="/FlexSplines/PowerLine/Build_FlexPowerline.Build_FlexPowerline_C",NewName="/Game/FactoryGame/Buildable/Factory/PowerLine/Build_PowerLine.Build_PowerLine_C")
```

=== Migrating Mk++ to Industrial Evolution

// cspell:ignore Acxd

https://ficsit.app/guide/Mg9t1BzVdaGhz[This guide by Acxd]
walks you through migrating buildings from the
https://ficsit.app/mod/MK22k20[Mk++] mod to similar ones from the
https://ficsit.app/mod/MkPlus[Industrial Evolution] mod.
9 changes: 8 additions & 1 deletion modules/ROOT/pages/ForUsers/DedicatedServerSetup.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ Contact us on the https://discord.ficsit.app[Discord Server] if something is con
== Installing Mods

Once you have set up the mod manager of choice you can start installing mods on the server.
Read the below warning, then check out the set of directions specific to the mod manager you chose.
Read the below warnings, then check out the set of directions specific to the mod manager you chose.

[id="CheckModDedicatedServerSupport"]
=== Checking if a Mod Supports Dedicated Servers
Expand Down Expand Up @@ -275,6 +275,13 @@ and send file to your server members so they can configure their own installs ac
If you encounter any one-side-only mods
you will have to switch to using separate profiles for the server and client until the Modpacks feature is released.

[id="ShutDownServer"]
=== Shut Down the Server

Before you start installing mods, make sure the server is not currently running.
A running server will keep mod files locked in use, preventing updating or uninstalling them.
You'll have to reboot the server anyways for mod changes to take effect, so you might as well turn it off before you start.

[id="InstallingMods_SMM"]
=== Using Satisfactory Mod Manager

Expand Down
Loading