diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 53cc0f3d3..b30c67dac 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -19,7 +19,16 @@ "hide": true, "presentation": { "group": "hot-rebuild-server" - } + }, + "problemMatcher": [ + { + "base": "$tsc-watch", + "background": { + "beginsPattern": "Listening on", + "endsPattern": "TODO_WHAT_END_PATTERN_TO_USE_SEEMS_FINE_WITH_THIS?" + } + } + ] }, { "type": "shell", @@ -31,8 +40,8 @@ } }, { - "label": "Open in browser", "type": "shell", + "label": "Open in browser", "windows": { "command": "Start-Process http://127.0.0.1:8000/" }, diff --git a/README.md b/README.md index 199be6539..eb8abd369 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ follow the below directions. #### Installing -1. Install [Node.js](https://nodejs.org/en/download/) (the CI uses 16 but newer should be fine) +1. Install [Node.js](https://nodejs.org/en/download/) (Check `/.github/workflows/push.yml` to find the exact version, but anything >=20 will probably be fine) and [pnpm Package Manager](https://pnpm.io/) through your preferred method. 2. Clone the repository diff --git a/antora-playbook.yml b/antora-playbook.yml index 9b11061fe..308abd80b 100644 --- a/antora-playbook.yml +++ b/antora-playbook.yml @@ -12,7 +12,7 @@ content: sources: ## Used for prod - url: https://github.com/satisfactorymodding/Documentation.git - branches: master, v3.9.1, v3.8.0, v3.7.0, 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 + branches: master, v3.10.0, v3.9.1, v3.8.0, v3.7.0, 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 diff --git a/lychee.toml b/lychee.toml index 66cc4598d..d5d340a54 100644 --- a/lychee.toml +++ b/lychee.toml @@ -36,10 +36,15 @@ exclude = [ # 403s despite being valid page, we should try to get this working somehow, since these links can change without warning "https://docs.unrealengine.com/", "https://dev.epicgames.com/", + "^https://www.unrealengine.com/en-US/blog/.*", # Times out despite being valid "https://www.adobe.com/learn/substance-3d-designer/web/the-pbr-guide-part-1", # Pages often time out and Shouldn't™ ever get deleted anyways "https://web.archive.org/web/", + # Cloudflare checks this, unlikely to be deleted + "^https://superuser.com/.*", + # Temporarily allow link to 3.10 docs that won't exist till PR is merged. Clean this up as soon as 3.10 is stable. + "https://docs.ficsit.app/satisfactory-modding/v3.10.0/index.html" ] # Exclude these filesystem paths from getting checked. diff --git a/modules/ROOT/images/Cpp/EditorCreateClass.jpg b/modules/ROOT/images/Cpp/EditorCreateClass.jpg deleted file mode 100644 index 23732d25d..000000000 Binary files a/modules/ROOT/images/Cpp/EditorCreateClass.jpg and /dev/null differ diff --git a/modules/ROOT/images/Cpp/EditorCreateClass.png b/modules/ROOT/images/Cpp/EditorCreateClass.png new file mode 100644 index 000000000..a52cdc37b Binary files /dev/null and b/modules/ROOT/images/Cpp/EditorCreateClass.png differ diff --git a/modules/ROOT/images/Development/ModLoader/ActorMixins/AddLogic.png b/modules/ROOT/images/Development/ModLoader/ActorMixins/AddLogic.png new file mode 100644 index 000000000..05800fbff Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/ActorMixins/AddLogic.png differ diff --git a/modules/ROOT/images/Development/ModLoader/ActorMixins/ChooseActor.png b/modules/ROOT/images/Development/ModLoader/ActorMixins/ChooseActor.png new file mode 100644 index 000000000..4f8e8adf0 Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/ActorMixins/ChooseActor.png differ diff --git a/modules/ROOT/images/Development/ModLoader/ActorMixins/Components.png b/modules/ROOT/images/Development/ModLoader/ActorMixins/Components.png new file mode 100644 index 000000000..655e0e673 Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/ActorMixins/Components.png differ diff --git a/modules/ROOT/images/Development/ModLoader/ActorMixins/CreateMixinAsset.png b/modules/ROOT/images/Development/ModLoader/ActorMixins/CreateMixinAsset.png new file mode 100644 index 000000000..73fdbd87e Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/ActorMixins/CreateMixinAsset.png differ diff --git a/modules/ROOT/images/Development/ModLoader/ActorMixins/EnableTick.png b/modules/ROOT/images/Development/ModLoader/ActorMixins/EnableTick.png new file mode 100644 index 000000000..dfa2e651c Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/ActorMixins/EnableTick.png differ diff --git a/modules/ROOT/images/Development/ModLoader/ActorMixins/Functions.png b/modules/ROOT/images/Development/ModLoader/ActorMixins/Functions.png new file mode 100644 index 000000000..d0da49bbe Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/ActorMixins/Functions.png differ diff --git a/modules/ROOT/images/Development/ModLoader/ActorMixins/RegisterMixin.png b/modules/ROOT/images/Development/ModLoader/ActorMixins/RegisterMixin.png new file mode 100644 index 000000000..87e92d492 Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/ActorMixins/RegisterMixin.png differ diff --git a/modules/ROOT/images/Development/ModLoader/BlueprintHooks/CreateBlueprintHook.png b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/CreateBlueprintHook.png new file mode 100644 index 000000000..0dd3142ac Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/CreateBlueprintHook.png differ diff --git a/modules/ROOT/images/Development/ModLoader/BlueprintHooks/CreateHook.png b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/CreateHook.png new file mode 100644 index 000000000..72bc077a8 Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/CreateHook.png differ diff --git a/modules/ROOT/images/Development/ModLoader/BlueprintHooks/FillDropdowns.png b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/FillDropdowns.png new file mode 100644 index 000000000..dc79b8662 Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/FillDropdowns.png differ diff --git a/modules/ROOT/images/Development/ModLoader/BlueprintHooks/LatentActionWorkaround.png b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/LatentActionWorkaround.png new file mode 100644 index 000000000..dea68822e Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/LatentActionWorkaround.png differ diff --git a/modules/ROOT/images/Development/ModLoader/BlueprintHooks/NewFunction.png b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/NewFunction.png new file mode 100644 index 000000000..d070b6dd6 Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/NewFunction.png differ diff --git a/modules/ROOT/images/Development/ModLoader/BlueprintHooks/RegisterHook.png b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/RegisterHook.png new file mode 100644 index 000000000..a8c0ae235 Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/RegisterHook.png differ diff --git a/modules/ROOT/images/Development/ModLoader/BlueprintHooks/TargetSpecifierConnected.png b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/TargetSpecifierConnected.png new file mode 100644 index 000000000..8ec68ef7d Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/TargetSpecifierConnected.png differ diff --git a/modules/ROOT/images/Development/ModLoader/BlueprintHooks/TargetSpecifierTooltip.png b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/TargetSpecifierTooltip.png new file mode 100644 index 000000000..0a57c2445 Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/TargetSpecifierTooltip.png differ diff --git a/modules/ROOT/images/Development/ModLoader/BlueprintHooks/ViewHookGraph.png b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/ViewHookGraph.png new file mode 100644 index 000000000..8c462d0ac Binary files /dev/null and b/modules/ROOT/images/Development/ModLoader/BlueprintHooks/ViewHookGraph.png differ diff --git a/modules/ROOT/images/Development/UpdatingGuides/DeadBindOnBpFuncNode.png b/modules/ROOT/images/Development/UpdatingGuides/DeadBindOnBpFuncNode.png new file mode 100644 index 000000000..c848d195d Binary files /dev/null and b/modules/ROOT/images/Development/UpdatingGuides/DeadBindOnBpFuncNode.png differ diff --git a/modules/ROOT/images/Development/UpdatingGuides/NewHookFromOldBindOnBpFuncNode.png b/modules/ROOT/images/Development/UpdatingGuides/NewHookFromOldBindOnBpFuncNode.png new file mode 100644 index 000000000..3b084a63a Binary files /dev/null and b/modules/ROOT/images/Development/UpdatingGuides/NewHookFromOldBindOnBpFuncNode.png differ diff --git a/modules/ROOT/images/Development/UpdatingGuides/OldScsHook.png b/modules/ROOT/images/Development/UpdatingGuides/OldScsHook.png new file mode 100644 index 000000000..e0511b85a Binary files /dev/null and b/modules/ROOT/images/Development/UpdatingGuides/OldScsHook.png differ diff --git a/modules/ROOT/images/Development/UpdatingGuides/PickMixinTargetClass.png b/modules/ROOT/images/Development/UpdatingGuides/PickMixinTargetClass.png new file mode 100644 index 000000000..fe2e128b2 Binary files /dev/null and b/modules/ROOT/images/Development/UpdatingGuides/PickMixinTargetClass.png differ diff --git a/modules/ROOT/images/Satisfactory/FactoryLegs/LegExampleComponent.png b/modules/ROOT/images/Satisfactory/FactoryLegs/LegExampleComponent.png new file mode 100644 index 000000000..ff0e53dfe Binary files /dev/null and b/modules/ROOT/images/Satisfactory/FactoryLegs/LegExampleComponent.png differ diff --git a/modules/ROOT/images/Satisfactory/FactoryLegs/LegExampleViewport.png b/modules/ROOT/images/Satisfactory/FactoryLegs/LegExampleViewport.png new file mode 100644 index 000000000..11f4cce03 Binary files /dev/null and b/modules/ROOT/images/Satisfactory/FactoryLegs/LegExampleViewport.png differ diff --git a/modules/ROOT/nav.adoc b/modules/ROOT/nav.adoc index 184804366..7baaab6aa 100644 --- a/modules/ROOT/nav.adoc +++ b/modules/ROOT/nav.adoc @@ -13,7 +13,9 @@ * xref:Development/index.adoc[Development] - ** xref:Development/UpdatingFromSml39.adoc[Updating from SML 3.9.0] + ** xref:Development/UpdatingFromSml310.adoc[Updating from SML 3.10.0] + *** xref:Development/Migration/ScsMigrationGuide.adoc[SCS Hook Migration Guide] + *** xref:Development/Migration/BpHookMigrationGuide.adoc[Blueprint Hook Migration Guide] ** xref:Development/UpdatingToNewVersions.adoc[_Updating your Mod_] ** xref:Development/BeginnersGuide/index.adoc[Getting Started] *** Installing Dependencies @@ -37,15 +39,17 @@ *** xref:Development/BeginnersGuide/overwriting.adoc[Class Default Objects (CDOs) and Overwriting Content] *** xref:Development/BeginnersGuide/ReleaseMod.adoc[Releasing Your Mod] *** xref:Development/BeginnersGuide/ImportingAnotherMod.adoc[Importing Other Mods to your Project] +// TODO *** xref:Development/ExampleModDirectory.adoc[ExampleMod Feature List] // Also uncomment in StaterProjectStructure.adoc ** Git and Modding *** xref:Development/BeginnersGuide/LearnGit.adoc[Learning Git] *** xref:Development/BeginnersGuide/CreateGitRepo.adoc[Creating a Mod Git Repo] ** xref:Development/Cpp/index.adoc[C++ Modding] *** xref:Development/Cpp/setup.adoc[Setup] *** xref:Development/Cpp/debugging.adoc[Debugging] - *** xref:Development/Cpp/hooking.adoc[Hooking] + *** xref:Development/Cpp/hooking.adoc[Native Hooking] // TODO *** xref:Development/Cpp/GettingBpData.adoc[Working with Assets and Blueprint-Defined Data from {cpp}] *** xref:Development/Cpp/thirdparty.adoc[Third Party Libraries] +// TODO *** xref:Development/Cpp/Cookbook.adoc[Cookbook] ** xref:Development/Modeling/index.adoc[3D Modeling] *** xref:Development/Modeling/setup.adoc[Workflow Setup] *** xref:Development/Modeling/MainMaterials.adoc[Main Materials] @@ -80,6 +84,7 @@ **** xref:Development/Satisfactory/EnhancedInputSystem.adoc[Enhanced Input System] **** xref:Development/Satisfactory/FactoryTick.adoc[Factory Tick] **** xref:Development/Satisfactory/FactoryConnectors.adoc[Factory-Connectors] + **** xref:Development/Satisfactory/FactoryLegs.adoc[Factory Legs] **** xref:Development/Satisfactory/AbstractInstance.adoc[Abstract Instances] **** xref:Development/Satisfactory/ConditionalPropertyReplication.adoc[Conditional Property Replication] **** xref:Development/Satisfactory/Savegame.adoc[SaveGame] @@ -94,7 +99,8 @@ *** xref:Development/ModLoader/AccessTransformers.adoc[Access Transformers] *** xref:Development/ModLoader/Subsystems.adoc[Mod Subsystems] *** xref:Development/ModLoader/Configuration.adoc[Configuration] - *** xref:Development/ModLoader/SimpleConstructionScript.adoc[Simple Construction Script (SCS) Hooks] + *** xref:Development/ModLoader/BlueprintHooks.adoc[Blueprint Hooking System] + *** xref:Development/ModLoader/ActorMixins.adoc[Actor Mixins] *** xref:Development/ModLoader/WidgetBlueprintHooks.adoc[Widget Blueprint Hooks] *** xref:Development/ModLoader/BlueprintInterface.adoc[Blueprint Interface] *** xref:Development/ModLoader/SessionSettings.adoc[Session Settings] @@ -105,12 +111,15 @@ *** xref:Development/ModLoader/ExtendedAttributeProvider.adoc[Extended Attribute Provider] *** xref:SMLConfiguration.adoc[SML Configuration] *** Legacy - **** xref:Development/UpdatingFromSml38.adoc[Updating from SML 3.8.0] - **** xref:Development/UpdatingFromSml37.adoc[Updating from SML 3.7.0] - **** xref:Development/UpdatingFromSml36.adoc[Updating from SML 3.6.1] - **** xref:Development/UpdatingFromSml35.adoc[Updating from SML 3.5.1] - **** xref:Development/UpdatingFromSml34.adoc[Updating from SML 3.4.1] - **** xref:Development/UpdatingFromSml2.adoc[Updating from SML 2.2.1] + **** Migration Guides + ***** xref:Development/UpdatingFromSml39.adoc[Updating from SML 3.9.0] + ***** xref:Development/UpdatingFromSml38.adoc[Updating from SML 3.8.0] + ***** xref:Development/UpdatingFromSml37.adoc[Updating from SML 3.7.0] + ***** xref:Development/UpdatingFromSml36.adoc[Updating from SML 3.6.1] + ***** xref:Development/UpdatingFromSml35.adoc[Updating from SML 3.5.1] + ***** xref:Development/UpdatingFromSml34.adoc[Updating from SML 3.4.1] + ***** xref:Development/UpdatingFromSml2.adoc[Updating from SML 2.2.1] + **** xref:Development/ModLoader/SimpleConstructionScript.adoc[Simple Construction Script (SCS) Hooks] ** Editor Tools *** xref:Development/EditorTools/SMLEditor/SMLEditor.adoc[SML Editor Utilities] **** xref:Development/EditorTools/SMLEditor/ResearchTreeEditor.adoc[Research Tree Editor] diff --git a/modules/ROOT/pages/CommunityResources/AssetToolkit.adoc b/modules/ROOT/pages/CommunityResources/AssetToolkit.adoc index 5d7558fc2..255b677d6 100644 --- a/modules/ROOT/pages/CommunityResources/AssetToolkit.adoc +++ b/modules/ROOT/pages/CommunityResources/AssetToolkit.adoc @@ -421,12 +421,17 @@ trying to use the UI usually won't fix them! Ask for help on the discord. There are currently numerous crashing issues when using the UI of the Asset Toolkit plugins as opposed to the command line interface. -Unless you have a specific reason for using the UI, -you should probably use the command line directions above to dump and generate assets instead. +Unless you have a very specific reason for using the UI, +use the command line directions above to dump and generate assets instead. ==== -[id="UI_Dump"] -==== Dumping ++++
+++ +Deprecated UI Instructions ++++
+++ + +// [id="UI_Dump"] +// ==== Dumping +*Dumping* In order to extract the assets to be imported to the editor, launch your copy of Satisfactory and open the in-game developer console, @@ -442,14 +447,16 @@ or use the `...` button to select a specific path. Next, select the asset paths you would like to dump, usually `Game/FactoryGame/`, and optionally restrict what is exported with the Asset Type Filter dropdown. -Once you're ready, press "Begin Asset Dumping". +Once you're ready, press `Begin Asset Dumping`. This will take some time; go pet a lizard doggo while you wait. -[id="UI_Generate"] -==== Generating +// [id="UI_Generate"] +// ==== Generating + +*Generating* -To open the in-editor interface, navigate to Window -> Developer Tools -> Asset Generator. +To open the in-editor interface, navigate to Tools -> Miscellaneous -> Asset Generator. Check all the asset types and asset paths, and uncheck "Public Project", otherwise you will generate placeholder assets again. -image:CommunityResources/AssetToolkit/OpenAssetGeneratorUI.png[image] ++++
+++ diff --git a/modules/ROOT/pages/Development/BeginnersGuide/SimpleMod/gameworldmodule.adoc b/modules/ROOT/pages/Development/BeginnersGuide/SimpleMod/gameworldmodule.adoc index b6bf63389..6e7e797c1 100644 --- a/modules/ROOT/pages/Development/BeginnersGuide/SimpleMod/gameworldmodule.adoc +++ b/modules/ROOT/pages/Development/BeginnersGuide/SimpleMod/gameworldmodule.adoc @@ -382,7 +382,7 @@ This error could appear when launching the game. You probably don't have Satisfactory Mod Loader installed in your copy of the game, and Unreal Engine is telling you it must be installed for your own mod to function. You can package a copy of SML yourself using Alpakit following the steps -xref:Development/BeginnersGuide/project_setup.adoc#_optional_packaging_sml[on the previous page]. +xref:Development/BeginnersGuide/project_setup.adoc#InstallSML[on the previous page]. === Corrupt data found, please verify your installation diff --git a/modules/ROOT/pages/Development/BeginnersGuide/StarterProject/ObtainStarterProject.adoc b/modules/ROOT/pages/Development/BeginnersGuide/StarterProject/ObtainStarterProject.adoc index 77eafa8d0..8f7c69f89 100644 --- a/modules/ROOT/pages/Development/BeginnersGuide/StarterProject/ObtainStarterProject.adoc +++ b/modules/ROOT/pages/Development/BeginnersGuide/StarterProject/ObtainStarterProject.adoc @@ -1,7 +1,10 @@ = Starter Project -The SML development team provides an Unreal project -that comes pre-installed with Satisfactory Mod Loader, +The Starter Project is distributed by the Satisfactory Modding team +as a GitHub repository named "Satisfactory Mod Loader". +Despite the name, the repository is actually an Unreal Engine project +that includes the source code of the Satisfactory Mod Loader (as a plugin), +the game's {cpp} headers, placeholder assets for base game content, and some useful developer plugins. diff --git a/modules/ROOT/pages/Development/BeginnersGuide/StarterProject/StarterProjectViaClone.adoc b/modules/ROOT/pages/Development/BeginnersGuide/StarterProject/StarterProjectViaClone.adoc index 06058e211..f6c38568e 100644 --- a/modules/ROOT/pages/Development/BeginnersGuide/StarterProject/StarterProjectViaClone.adoc +++ b/modules/ROOT/pages/Development/BeginnersGuide/StarterProject/StarterProjectViaClone.adoc @@ -14,11 +14,27 @@ check out our xref:Development/BeginnersGuide/LearnGit.adoc[mini tutorial] that == What Branch to Clone +==== +If you are looking to develop mods for Update 1.0, +follow the link:https://docs.ficsit.app/satisfactory-modding/v3.10.0/index.html[SML v3.10.0] documentation instead. +However, we strongly suggest developing mods for Update 1.1 instead as it will be released to the stable branch on June 10th. +==== + // When updating the below, remember to update StaterProjectViaClone.adoc, StarterProjectViaZip.adoc, and dependencies.adoc (engine) ==== -This is the *SML v3.10.0* version of the docs. +This is the *latest stable* version of the docs. +// This is the *development* version of the docs. + +// Stable (Release) and Experimental are currently both the same version - 1.0 Release. + +Clone the **`master` branch** to develop a mod for the stable version of SML. +// You should clone the **`dev` branch** because SML 3.8.? is not released yet. + +// You should clone either the **`dev` branch** or the **`master` branch**. +// Of those two, you probably want whichever branch was pushed to most recently, which you can see +// https://github.com/satisfactorymodding/SatisfactoryModLoader/branches[on the GitHub repository]. -To develop for 3.10.0, clone the `v3.10.0` tag. +If you're uncertain about which branch to clone, **ask us on the Discord**. ==== https://github.com/satisfactorymodding/SatisfactoryModLoader/[Here] diff --git a/modules/ROOT/pages/Development/BeginnersGuide/StarterProject/StarterProjectViaZip.adoc b/modules/ROOT/pages/Development/BeginnersGuide/StarterProject/StarterProjectViaZip.adoc index 3a4a9a6a5..dfc03f55d 100644 --- a/modules/ROOT/pages/Development/BeginnersGuide/StarterProject/StarterProjectViaZip.adoc +++ b/modules/ROOT/pages/Development/BeginnersGuide/StarterProject/StarterProjectViaZip.adoc @@ -8,12 +8,28 @@ or you will have to repeat some of the setup process again. == What Version to Download +==== +If you are looking to develop mods for Update 1.0, +follow the link:https://docs.ficsit.app/satisfactory-modding/v3.10.0/index.html[SML v3.10.0] documentation instead. +However, we strongly suggest developing mods for Update 1.1 instead as it will be released to the stable branch on June 10th. +==== + // When updating the below, remember to update StaterProjectViaClone.adoc, StarterProjectViaZip.adoc, and dependencies.adoc (engine) ==== -This is the *SML v3.10.0* version of the docs. +This is the *latest stable* version of the docs. +// This is the *development* version of the docs. + +Download a zip of the **`master` branch** to develop a mod for the stable version of SML +by clicking https://github.com/satisfactorymodding/SatisfactoryModLoader/archive/refs/heads/master.zip[here]. + +// Download a zip of the **`dev` branch** (because SML 3.8.? is not released yet) +// by clicking https://github.com/satisfactorymodding/SatisfactoryModLoader/archive/refs/heads/dev.zip[here]. + +// You should download a zip either of the **`dev` branch** or the **`master` branch**. +// Of those two, you probably want whichever branch was pushed to most recently, which you can see +// https://github.com/satisfactorymodding/SatisfactoryModLoader/branches[on the GitHub repository]. -To develop for 3.10.0, use this zip: -https://github.com/satisfactorymodding/SatisfactoryModLoader/archive/refs/tags/v3.10.0.zip +If you're uncertain about which branch to download, **ask us on the Discord**. ==== == Unzipping the Files diff --git a/modules/ROOT/pages/Development/BeginnersGuide/StarterProjectStructure.adoc b/modules/ROOT/pages/Development/BeginnersGuide/StarterProjectStructure.adoc index ef233285a..1226aca92 100644 --- a/modules/ROOT/pages/Development/BeginnersGuide/StarterProjectStructure.adoc +++ b/modules/ROOT/pages/Development/BeginnersGuide/StarterProjectStructure.adoc @@ -127,6 +127,8 @@ image:BeginnersGuide/simpleMod/ShowPluginContentInViewer.png[Show Plugin Content * xref:Development/EditorTools/SMLEditor/SMLEditor.adoc[SMLEditor] ** Editor-only mod that provides helpful utilities to mod creators, such as a mod configuration screen preview and a Research Tree Editor. +// TODO link to xref:Development/ExampleModDirectory.adoc[ExampleMod Feature List] once done + You should not need to edit any of the provided mod files under normal circumstances. == Plugins Folder diff --git a/modules/ROOT/pages/Development/BeginnersGuide/dependencies.adoc b/modules/ROOT/pages/Development/BeginnersGuide/dependencies.adoc index 02b852963..8ff3fd8bf 100644 --- a/modules/ROOT/pages/Development/BeginnersGuide/dependencies.adoc +++ b/modules/ROOT/pages/Development/BeginnersGuide/dependencies.adoc @@ -178,12 +178,22 @@ The below box will contain a link to the specific release that you should downlo It's imperative that you download the correct engine for the version of the game you're modding or you will have to repeat a large amount of the setup process again. +==== +If you are looking to develop mods for Update 1.0, +follow the link:https://docs.ficsit.app/satisfactory-modding/v3.10.0/index.html[SML v3.10.0] documentation instead. +However, we strongly suggest developing mods for Update 1.1 instead as it will be released to the stable branch on June 10th. +==== + // When updating the below, remember to update StaterProjectViaClone.adoc, StarterProjectViaZip.adoc, and dependencies.adoc (engine) ==== -This is the *SML v3.10.0* version of the docs. +This is the *latest stable* version of the docs. +// This is the *development* version of the docs. + +// Stable (Release) and Experimental are currently both the same version - 1.0 Release. -To develop for 3.10.0, use this engine version: -https://github.com/satisfactorymodding/UnrealEngine/releases/tag/5.3.2-css-66 +You should download from the *latest engine release*, +which an be found at the top of this page: +https://github.com/satisfactorymodding/UnrealEngine/releases ==== Download the following files from the release linked above: @@ -268,8 +278,8 @@ In the launcher's left sidebar, select the topmost `Wwise` section (note: not the "Wwise Audio Lab" section). Under the "INSTALL A NEW VERSION" heading, click the `Latest` drop-down and change it to `All`. -Select `2022.1` from the "Major" dropdown. -Select version `2022.1.10.8393` from the "Version" dropdown. +Select `2023.1` from the "Major" dropdown. +Select version `2023.1.3.8471` from the "Version" dropdown. Click `Install`. [WARNING] @@ -280,7 +290,7 @@ but they are likely to have other incompatible changes that will break the setup **Try to download the exact Wwise version mentioned above**. If you don't see it, -try any other version starting with `2022.1.10`, preferring newer versions, +try any other version starting with `2023.1.3`, preferring newer versions, or asking for help on the Discord. ==== @@ -307,20 +317,23 @@ If anything is selected by default, do not uncheck them. They are required for V Click `Next` (you may need to scroll down to see the button). You don't need to add any plugins, so press `Select None` in the top right then `Install` in the bottom left to begin the installation process. -Accept the terms and conditions prompts that appear along the way. +Accept any User Account Control or Terms and Conditions prompts that appear along the way. == Satisfactory Mod Manager xref:index.adoc#_satisfactory_mod_manager_aka_smm[Satisfactory Mod Manager] is a powerful tool that automatically install the correct versions of mod dependencies for you. -Basically all end users will be using this tool to install your mods. +All end users will be using this tool, +or its command-line colleague +xref:ForUsers/DedicatedServerSetup.adoc#GetModManager_CLI[ficsit-cli], +to play with your mods. -As a developer, you can use it to install the https://ficsit.app/mod/SML[Satisfactory Mod Loader (SML)] mod -and install other mods to test with. +Although you don't need to install it to develop mods, +you can use it to download other mods to test with, +such as xref:ForUsers/Tags.adoc[helpful mods tagged with `#developer-utility`], +and to view your mod web page within the mod manager to check its appearance and formatting. -Alternatively, once your modding environment is set up, -you can use Alpakit to automatically build and install SML. -This process will be explained on the next page. +To install Satisfactory Mod Manager, follow the directions xref:ForUsers/SatisfactoryModManager.adoc[here]. == Next Steps diff --git a/modules/ROOT/pages/Development/BeginnersGuide/project_setup.adoc b/modules/ROOT/pages/Development/BeginnersGuide/project_setup.adoc index a3a52db58..769839afe 100644 --- a/modules/ROOT/pages/Development/BeginnersGuide/project_setup.adoc +++ b/modules/ROOT/pages/Development/BeginnersGuide/project_setup.adoc @@ -50,11 +50,11 @@ and ensure the "Unreal Engine project path" matches the path to your project. Click on the `Integrate Wwise in Project...` button. Change the "Integration Version" drop-down from `Latest` to `All` otherwise Wwise will not show the version you care about. -Then use the "Major" and "Version" dropdowns to select the same version you installed earlier (likely `2022.1.10.8393`). +Then use the "Major" and "Version" dropdowns to select the same version you installed earlier (likely `2023.1.3.8471`). The version number may have additional numbers on the end of it e.g. -`2022.1.10.8393.2898` but as long as it starts with `2022.1.10.8393` it should work. +`2023.1.3.8471.2970` but as long as it starts with `2023.1.3.8471` it should work. -If version `2022.1.10.8393` does not appear even after you have selected `All`, +If version `2023.1.3.8471` does not appear even after you have selected `All`, edit the `.uproject` file in a text editor to be sure that `EngineAssociation` is set to `5.3.2-CSS`. @@ -492,13 +492,17 @@ and delete the folder named with the xref:Development/BeginnersGuide/SimpleMod/gameworldmodule.adoc#ModReference[Mod Reference] of the mod you wish to uninstall. -== (Optional) Packaging SML +[id="InstallSML"] +== Packaging SML -Note that if you have not yet installed the Satisfactory Mod Loader (SML) in your game client, +If you have not yet installed the Satisfactory Mod Loader (SML) in your game client from playing with mods before, you can use Alpakit to build SML for you and put it in the right folder. Simply press the `Alpakit!` button next to `Satisfactory Mod Loader (SML)` in the list. -In the future, using a locally build copy of SML could cause problems +Alternatively, you can use +xref:ForUsers/SatisfactoryModManager.adoc#_installing_mods[the Mod Manager to install SML from a published version]. + +As a note for the future, using a locally built copy of SML could cause problems if your copy of the Starter Project is older than the latest SML release, in which case you should xref:Development/UpdatingToNewVersions.adoc[update your Starter Project] diff --git a/modules/ROOT/pages/Development/Cpp/Cookbook.adoc b/modules/ROOT/pages/Development/Cpp/Cookbook.adoc new file mode 100644 index 000000000..3e53ff61c --- /dev/null +++ b/modules/ROOT/pages/Development/Cpp/Cookbook.adoc @@ -0,0 +1,95 @@ += Cookbook + +[NOTE] +==== +You have found a hidden docs page! + +This page is still a work in progress. + +If you have any feedback, please let us know in the Discord. +==== + +Collection of assorted code snippets and useful approaches. + +== TActorIterator + +Faster than GetAllActorsOfClass and GetTypedBuildable + +```cpp +for (TActorIterator It(GetWorld()); It; ++It) +{ + YourBuildableClass* Buildable = *It; + .... +} +``` + +https://discord.com/channels/555424930502541343/862002356626128907/1365513493456883713 + +== SetTimerForNextTick + +```cpp +FName Tag; +if (ResourceRouletteCompatibilityManager::IsCompatibilityClass(SpawnedActor, Tag)) +{ + World->GetTimerManager().SetTimerForNextTick([World, SpawnedActor, Tag]() + { + ResourceRouletteCompatibilityManager::TagActorAndMesh(SpawnedActor, Tag); + }); +} +``` + +https://discord.com/channels/555424930502541343/862002356626128907/1365406523227902043 + +== Custom Attachment Points + +https://discord.com/channels/555424930502541343/601030071221878784/1358241612546834607 + +```cpp + const TSubclassOf Type = point.Type; + const TSubclassOf SnappedType = targetPoint.Type; + UFGAttachmentPointType* LocalObject = Type.GetDefaultObject(); + const UFGAttachmentPointType* RemoteObject = SnappedType.GetDefaultObject(); + for (auto SnapType : LocalObject->mAllowedAttachmentPointSnapTypes) { + if(RemoteObject->IsA(SnapType)) { + return true; + } + } + return false; +``` + +== Collision Filtering + +https://www.unrealengine.com/en-US/blog/collision-filtering + +== Timers + +https://dev.epicgames.com/documentation/en-us/unreal-engine/gameplay-timers-in-unreal-engine + +https://dev.epicgames.com/documentation/en-us/unreal-engine/using-timers-in-unreal-engine + +== Scripted Actions + +https://dev.epicgames.com/documentation/en-us/unreal-engine/scripted-actions-in-unreal-engine?application_version=5.3 + +== Check if Main Menu + +Keep in mind that 99.99% of the time your logic should not require you to do this, +use something like a game world mod module instead. + +```cpp +if (AFGGameMode* GameMode = World->GetAuthGameMode()) { + return GameMode->IsMainMenuGameMode(); +} +return false; +``` + +== Lightweight Buildable Ref Struct Data Access + +https://discord.com/channels/555424930502541343/862002356626128907/1377079724484067469 + +```cpp +const FRuntimeBuildableInstanceData* RuntimeData = Ref.ResolveBuildableInstanceData(); +const FBuildableBeamLightweightData* beamData = RuntimeData->TypeSpecificData.GetValuePtr(); +float length = beamData->BeamLength; +return length; +``` diff --git a/modules/ROOT/pages/Development/Cpp/hooking.adoc b/modules/ROOT/pages/Development/Cpp/hooking.adoc index ed202990c..9a48f038a 100644 --- a/modules/ROOT/pages/Development/Cpp/hooking.adoc +++ b/modules/ROOT/pages/Development/Cpp/hooking.adoc @@ -1,9 +1,13 @@ -= Hooking += Native Hooking -Hooking is a {cpp} exclusive feature of SML that allows you to attach a custom function body to an existing function. +Native Hooking is a {cpp} exclusive feature of SML that allows you to attach a custom function body to an existing {cpp} function. -All C/{cpp} functioning hooking stuff can be found in `#include "Patching/NativeHookManager.h"`. -All Blueprint function hook stuff can be found in `#include "Patching/BlueprintHookManager.h"`. +All C/{cpp} functioning hooking stuff can be found in SML's `Patching/NativeHookManager.h`. + +[NOTE] +==== +Hooking of Blueprint-implemented functions is covered on the xref:Development/ModLoader/BlueprintHooks.adoc[Blueprint Hooking System] page. +==== == Background Information @@ -268,146 +272,15 @@ Macros will return a delegate that can be used with the `UNSUBSCRIBE_METHOD` or `UNSUBSCRIBE_UOBJECT_METHOD` macro respectively in order to unsubscribe from the function. - [id="BpFunctionHooks"] == Blueprint Function Hooks -Blueprint function hooking works by changing the instructions of a Blueprint UFunction so that your hook gets called at a specific point in the execution of that function. - -Like native hooks, you can hook before and after the function execution. Unlike native hooks, you can also hook at any top-level statement in the function if you know its original instruction index (which itself requires decompiling the function - look at `DEBUG_BLUEPRINT_HOOKING` in SML's BlueprintHookManager.cpp for one way to get a JSON dump of the instructions). - -[WARNING] -==== -Some blueprints (like UI blueprints) do not exist in the dedicated server build. If your mod attempts to hook such a blueprint in a dedicated server, it will crash the server. You can use the global function `IsRunningDedicatedServer()` to skip hooking in this case. -==== - -[WARNING] -==== -Once you have hooked a blueprint function, there is currently no way to unhook it without fully exiting Satisfactory. For this reason, it is recommended that you create/have a root UGameInstanceModule that installs all blueprint function hooks on game startup, usually when DispatchLifecycleEvent is first called. -==== - -The hook function signature is `void(FBlueprintHookHelper&)`. - -This FBlueprintHookHelper structure provides ways to: - -- Access the Context object (Blueprint instance on which the function is executing). -- Read/write variables of the Context, local variables of the hooked blueprint function (which include its Input variables), and Output variables of the function. -- Skip from the hooked point to the end of the function's execution (though all hooks at that location will be executed prior to this jump). - -To attach a blueprint hook, you need a reference to the Blueprint _class_ containing the function you want to hook. There are {cpp}-only ways to do this using LoadClass, but they require hardcoding resource paths, which is not recommended. Instead, you should add these types as member variables to your UGameInstanceModule and then assign them using the picker in the Unreal Editor. - -Here's an example of getting a reference to the `BPW_MapMenu` class for hooking (this widget is the left-hand-side menu in the map screen of Satisfactory that lists all the map markers): - -First, determine the native parent class of the widget. A quick way to see this is to find the blueprint you wish to hook in the Content Browser of the Unreal Editor and hover over it to find the Native Parent Class line: - -image:Development/Cpp/hooking/BPW_MapMenuHover.png[Hovering over BPW_MapMenu] - -Next, define a `TSoftClassPtr` property on a {cpp}-backed Root Game Instance Module. -Use the Native Parent Class of the blueprint class you wish to hook as the generic type. -Make it an EditAnywhere UPROPERTY so it will be available in the Unreal Editor. -Optionally, assign a `Category` name to help organize the property if you plan to hook multiple things. - - -[source,cpp] ----- - UPROPERTY(EditAnywhere, Category = "UI Widget Types") - TSoftClassPtr BPW_MapMenuClass; ----- - -Next, close the editor and rebuild the project for Development Editor, -since you just changed the class and field structure of your mod. -After the build finishes, reopen the editor. - -If your mod doesn't have a blueprint Root Instance Module yet, -create one by adding a new blueprint to your mod that uses your {cpp} Root Instance Module class as its base class. -If your mod already has an existing blueprint-implemented Root Instance Module, reparent it to your {cpp} class, -or use a submodule instead (remember, there can only be one root module of each type). - -Regardless, open your Root Instance Module blueprint in Unreal Editor. -Find the appropriate row in the module blueprint's Details section under the Category you used, click the dropdown, and find/select the type: - -image:Development/Cpp/hooking/BPW_MapMenuTypeSelected.png[BPW_MapMenu selected] - -The class is now availabe to your module for hooking. - -[WARNING] -==== -It is possible that a class might not be fully loaded by the game before your mod needs it. -Call `LoadSynchronous` on each TSoftClassPtr in your mod's initialization to ensure it is loaded. -==== - -Now that we have a reference to the blueprint class, we can hook its functions. -If you don't already know the name of the blueprint function you wish to hook, these can be found by opening the blueprint in the Unreal Editor, going to the Graph view, and then viewing the FUNCTIONS accordion under the My Blueprint tab: - -image:Development/Cpp/hooking/BPW_MapMenuFunctions.png[BPW_MapMenu functions] - -Now you can create the actual hook in {cpp}. Make sure you have the proper includes: - -[source,cpp] ----- -#include "Patching/BlueprintHookManager.h" -#include "Patching/BlueprintHookHelper.h" ----- - -Get a reference to the UBlueprintHookManager like so: - -[source,cpp] ----- -UBlueprintHookManager* hookManager = GEngine->GetEngineSubsystem(); ----- - -[WARNING] -==== -If you attempt to get the UBlueprintHookManager extremely early in startup, the game will crash. -It will be available by the time DispatchLifecycleEvent is called on your UGameInstanceModule. -Remember that DispatchLifecycleEvent is called three times with three different phase values as the game initializes -- be sure to only create the hooks in one of these phases (ELifecyclePhase::CONSTRUCTION should be fine). -==== - -Hooks can be created by calling `HookBlueprintFunction` on the hook manager: - -[source,cpp] ----- -hookManager->HookBlueprintFunction( - BPW_MapMenuClass->FindFunctionByName(TEXT("AddActorRepresentationToMenu")), // Will crash if you typo the function name - [](FBlueprintHookHelper& helper) { - // Hook code here - }, - EPredefinedHookOffset::Start ); - // EPredefinedHookOffset::Start hooks just before the function executes. - // For a hook just before the function returns, use EPredefinedHookOffset::Return ----- - -[WARNING] -==== -You can create hooks at nearly-arbitrary points in the function by passing the integer offset of the statement where you'd like to hook instead of an EPredefinedHookOffset. Only do this if you know exactly what you're doing and why! -==== - -FBlueprintHookHelper has all the functionality you should need if you wish to modify the state of the blueprint or function execution. To get and/or set the values of variables, use one of: - -[source,cpp] ----- -// For reading/writing variables on the blueprint that is being hooked (in the example above, this means member variables of BPW_MapMenu) -TSharedRef contextHelper = helper.GetContextVariableHelper(); - -// For reading/writing Input variables of the function, as well as any local variables the function is using for execution (but you have to know their names by decompiling the function) -TSharedRef localHelper = helper.GetLocalVariableHelper(); - -// For reading/writing Output variables of the function -TSharedRef outHelper = helper.GetOutVariableHelper(); ----- - -Check the header comments on each `Get*VariableHelper` method to learn which helper to use in what situation. -Here is a quick example: - -[source,cpp] ----- -TSharedRef localHelper = helper.GetLocalVariableHelper(); -ERepresentationType* representationType = localHelper->GetEnumVariablePtr(TEXT("representationType")); -int* intValuePtr = localHelper->GetVariablePtr(TEXT("someIntValue")); -*intValuePtr = 42; // You can write values to variables simply by using the returned pointers ----- +Hooking Blueprint-implemented functions from {cpp} is no longer supported as of SML 3.11.0 +for the reasons described xref:Development/UpdatingFromSml310.adoc#BlueprintHookingOverhaul_CppBpHookingRemoval[here]. +Use the xref:Development/ModLoader/BlueprintHooks.adoc[Blueprint Hooking System] instead. +If you'd like to implement the code your hooks run in {cpp}, +write the code in a blueprint function library or similar and call the functions from the hook blueprint. == Protected/Private Function Hooking diff --git a/modules/ROOT/pages/Development/Cpp/index.adoc b/modules/ROOT/pages/Development/Cpp/index.adoc index 89e81b9a4..d42df9672 100644 --- a/modules/ROOT/pages/Development/Cpp/index.adoc +++ b/modules/ROOT/pages/Development/Cpp/index.adoc @@ -24,7 +24,7 @@ Reading the article is also highly recommended. == Requirements -Well, since this is a very advanced topic, we recommend you to learn {cpp} +Since this is a very advanced topic, we recommend you to learn {cpp} and {cpp} for Unreal Engine first. We have compiled a list of some helpful learning resources xref:Development/index.adoc#_resources[here], but you will probably want to search out some more on your own. diff --git a/modules/ROOT/pages/Development/Cpp/setup.adoc b/modules/ROOT/pages/Development/Cpp/setup.adoc index 8acf26803..8ae7b1cab 100644 --- a/modules/ROOT/pages/Development/Cpp/setup.adoc +++ b/modules/ROOT/pages/Development/Cpp/setup.adoc @@ -1,11 +1,6 @@ = C++ Setup -[WARNING] -==== -This page is in the process of being updated. -==== - -In order to get started with C++ modding, you should first begin by performing the setup the project for a Blueprint-based modding project, as shown in the xref:Development/BeginnersGuide/project_setup.adoc[Getting Started guide]. +In order to get started with C++ modding, you should first follow the xref:Development/BeginnersGuide/project_setup.adoc[Getting Started guide]. This guide assumes that you have already installed all required dependencies and followed the setup process described there. == Background Information @@ -49,16 +44,42 @@ Example uses cases include: - Adding external .lib files - Calculating information (such as build ID) from the state of the file system -== Using the Alpakit Template +== Creating a {cpp} Mod Skeleton + +There are multiple approaches you can use to create a {cpp} mod. +They are presented below in order of ease of use. + +Regardless of the option you chose, +consider reading the link:#CreateCppMod_Manual[Creating the Mod-Module From Scratch] section +to get a better understanding of the purpose of the files involved in a {cpp} mod. -The Alpakit Create Mod wizard contains a template -that creates most of the files mentioned in the below sections automatically. +[id="CreateCppMod_AlpakitTemplate"] +=== Option 1: Using the Alpakit Template + +The Alpakit Create Mod wizard can automatically create a blank {cpp} mod for you. You can learn more about the wizard on the -xref:Development/BeginnersGuide/SimpleMod/gameworldmodule.adoc[Plugin Setup and Game World Module] page. +xref:Development/BeginnersGuide/SimpleMod/gameworldmodule.adoc#_unreal_plugin_creation[Plugin Setup and Game World Module] page. +Select the "{cpp} and Blueprint" template. + +After using the wizard, advance to the link:#AddClass[Adding New Classes] section of this page. + +[id="CreateCppMod_AlpakitConvert"] +=== Option 2: Alpakit "Convert to C++ & Blueprint Mod" on Existing Blueprint Mod + +If you already have an existing blueprint mod that you'd like to add {cpp} to, +open the Alpakit Edit Mod dialog for the mod from the Alpakit Dev window and click the "Convert to C++ & Blueprint Mod" button. +This will apply the Alpakit {cpp} template's files to your existing mod. + +After using the button, close the editor, +xref:Development/BeginnersGuide/project_setup.adoc#_generate_visual_studio_files[regenerate Visual Studio project files], +and build for the Development Editor target so your mod's new {cpp} module is recognized by the editor. + +Next, advance to the link:#AddClass[Adding New Classes] section of this page. -== Creating the Mod-Module From Scratch +[id="CreateCppMod_Manual"] +=== Option 3: Creating the Mod-Module From Scratch -To begin adding {cpp} code to your mod you'll have to create a Module build configuration file. +Before you can add {cpp} code to your mod you'll have to create a Module build configuration file. Navigate to your mod's folder, `Mods/YourModReference/`, where your 'YourModReference.uplugin' file is located. Create a new folder named `Source` and within it a subfolder named `YourModReference`. @@ -125,7 +146,7 @@ void FYourModReferenceModule::StartupModule() { IMPLEMENT_GAME_MODULE(FYourModReferenceModule, YourModReference); ---- -== Adding the Module to the UPlugin +=== Adding the Module to the UPlugin Next we need to tell the Unreal Editor to use our editor module. For this open up the `YourModReference.uplugin` file in your plugin root. @@ -143,40 +164,58 @@ Like this: ---- (the name used was `YourModReference`, make sure you use your own mod reference instead) -== Finishing Up +=== Finishing Up Now that you have added your module folder, configuration, source, and added it to the targets, you will need to regenerate your Visual Studio project files. Directions on how to do this can be found xref:Development/BeginnersGuide/project_setup.adoc#_generate_visual_studio_files[here]. After this process completes, you should be able to start working on the {cpp} code for your mod. -[WARNING] -==== -Make always sure you code in a custom created module! -Don't write your code in the FactoryGame or SML modules by accident. -==== - -== Adding a Class +[id="AddClass"] +== Adding New Classes When you want to add a new class, there are two generally safe ways to go about it. Note that **you should not create new files from Visual Studio directly** - it is not knowledgeable about the project structure -and will create files in a temporary directory where they won't be detected by UBT. +and will create files in a temporary directory where they won't be detected by the UBT. + +[id="AddClass_Editor"] +=== Using the Unreal Editor Add Class Wizard + +Open your project in the Unreal Editor and use the `Tools` > `New {cpp} Class...` menu option. +Then select your desired base class (`None` or `Object` if you're not sure yet), +hit next, and name your class. +Next to the "Name" field, select your mod's {cpp} module from the dropdown +to ensure the files are created in the correct location. +Leave the "Class Type" as `Public` to streamline compatibility with other mods. +Consider editing the "Path" to utilize subfolders to further organize your files. -1. Navigate to the folder in which you want to add your class in Windows Explorer -and create the `.cpp`-File and the `.h`-File manually. -You can now open them in Visual Studio or a text editor of your choice. -Fill them with a template code or just directly the class you need. +.Filled class creation pop-up with mod {cpp} module 'PowerSuit' selected as an example +image::Cpp/EditorCreateClass.png[Screenshot of unreal editor class creation pop-up] -2. Open the Unreal editor and open the "tree view" of the content browser. -Then navigate to the `C++-Classes` root folder and open the folder named with your mod reference. -Within that folder, right-click into empty space and select `New {cpp}-Class`. -Then select your desired base class, hit next, and name your class. -Change the other settings as your desire and finish with `create class`. +Finally, select `Create Class` to generate the files and trigger Unreal Engine's live coding rebuild functionality. + +Once your mod has at least one {cpp} class its classes folder will appear in Content Browser windows +assuming you have "Show {cpp} Classes" enabled in your Content Browser settings (cog button menu). +Right clicking on empty space in one of these folders also allows opening this wizard, +although it unfortunately does not pre-fill the selected module. [WARNING] ==== -Make sure you select your custom {cpp}-module when using the Unreal editor method of creating a new class file. In this screenshot, the mod reference is 'LightItUp'. - -image:Cpp/EditorCreateClass.jpg[image] +Make sure you always select your mod's Module when creating a class. +If you write your code in one of the FactoryGame or SML modules by accident, +it won't be compiled with your mod and it won't work at runtime. ==== + +[id="AddClass_ManualFiles"] +=== Manually Creating Files + +Alternatively, you can manually create the files backing your class. +This is not recommended as it's very easy to make mistakes with folders, boilerplate code, and includes while doing so. + +Navigate to your mod's {cpp} module folder in Windows Explorer +and create the `.h` and `.cpp` files in the Public and Private folders respectively. +Then run the +xref:Development/BeginnersGuide/project_setup.adoc#_generate_visual_studio_files[Generate Visual Studio project files] +utility to refresh Visual Studio's project structure. +You can now open them in Visual Studio, or a text editor of your choice. diff --git a/modules/ROOT/pages/Development/ExampleModDirectory.adoc b/modules/ROOT/pages/Development/ExampleModDirectory.adoc new file mode 100644 index 000000000..e6b56d142 --- /dev/null +++ b/modules/ROOT/pages/Development/ExampleModDirectory.adoc @@ -0,0 +1,41 @@ += ExampleMod Feature List + +[NOTE] +==== +You have found a hidden docs page! + +This page is still a work in progress. + +If you have any feedback, please let us know in the Discord. +==== + +This page exists to signpost the features demonstrated in the Starter Project's ExampleMod. +It lists every change the mod implements, where to find it in the mod's code, and links to relevant documentation for that feature. + +** Menu World Module - Adds a power slug to the main menu. +** Game World Module - Registers recipes and items +*** Adds a milestone that unlocks items and recipes +** Sub Game World Module: Class Default Object edit example +*** Adds recipe to existing milestone + +* Custom resource + +* Custom Game Levels/Maps +** Drop Pods, Somersloop/Mercer Sphere shrines +** Gas rocks +** Explodable rocks +** Foliage +** Water +** Ore Nodes, Oil Nodes, Fracking Nodes +** Deposits/Clusters + +* Mod Configuration +* Mod Session Settings + +* Chat commands +* Persistent string value stored per-player + +* Custom recipe-based production building +* Decorative building +* Item counter building with custom blueprint logic +** Custom building UI diff --git a/modules/ROOT/pages/Development/Migration/BpHookMigrationGuide.adoc b/modules/ROOT/pages/Development/Migration/BpHookMigrationGuide.adoc new file mode 100644 index 000000000..60abdc405 --- /dev/null +++ b/modules/ROOT/pages/Development/Migration/BpHookMigrationGuide.adoc @@ -0,0 +1,79 @@ += Migrating to Blueprint Hook Assets + +Migrating a pre-SML3.11 blueprint hook to the new Hook Asset system is relatively straightforward +because you already have all the information you need in the old "Bind on BPFunction" node or your old {cpp} hook macro. + +image::Development/UpdatingGuides/DeadBindOnBpFuncNode.png[Old Bind on BPFunction Node] + +This gives you the information required to make a Blueprint Hook using the new system: + +- Class +- Binding (you will transfer the logic from this event to a function in your new hook asset) +- Function Name to hook +- Hook Offset Start + +Note that one Hook Asset can contain multiple hooks on any number of classes. + +== Create Hook Asset + +Now follow the instructions in the xref:Development/ModLoader/BlueprintHooks.adoc[Blueprint Hooks] page to create a new hook asset. +Read the entire page to get an overview of the new system and how to create hooks using it. + +[IMPORTANT] +==== +xref:Development/ModLoader/BlueprintHooks.adoc[Read the Blueprint Hooks page ➡] +==== + +== Register the Hook Asset + +Don't forget to register your new Hook as described in the xref:Development/ModLoader/BlueprintHooks.adoc[Blueprint Hooks] page. + +== Create Hook Function + +Next, make a function to hold your hook's logic. +You can either reuse the default-created New Function (give it a better name!) or make a fresh one. + +Since Bind on BPFunction nodes only supported the `Target` parameter, +the only parameter your function needs is +an input named `Target` as an object reference to the class you are hooking. +If you were using the {cpp} blueprint hook macro, +see the xref:Development/ModLoader/BlueprintHooks.adoc[Blueprint Hooks] page +to set up other paramters as required. + +Next, move the logic from the event on the Binding of the old node to the function you just created. +Note that the previous system had hooks as Events and the new system has them as Functions, +preventing the use of latent nodes like Delay. +The xref:Development/ModLoader/BlueprintHooks.adoc[Blueprint Hooks] guide suggests workarounds for this. + +[NOTE] +==== +Are you working with hooks that apply to a specific actor class? +You may want to use an xref:Development/ModLoader/ActorMixins.adoc[Actor Mixin] instead, +which allows using events as your hook function, among other features. +==== + +== Create Hook Graph + +Next, switch to the Hook Graph view as described in the xref:Development/ModLoader/BlueprintHooks.adoc[Blueprint Hooks] page to create the nodes that specify how your hook will be applied. + +Right click on empty space to create a new "Hooks" node. +All "Bind on BPFunction" nodes from the old system correspond to the "Call Hook Before Statement" node in the new system. +If you were using the {cpp} blueprint hook macro, +check the xref:Development/ModLoader/BlueprintHooks.adoc[Blueprint Hooks] page to determine the equivalent node in the new system. + +Next, specify the Class and Function being hooked under the "Target Class and Function" heading. + +Under the "Hook Reference" heading, select the function you created earlier with your hook logic. + +image::Development/UpdatingGuides/NewHookFromOldBindOnBpFuncNode.png[New Hook from old Bind on BPFunction] + +Finally, connect a target specifier to the "Target Statement" pin of the hook node. + +Check your old "Bind on BPFunction" node's setting for the "Hook Offset Start" checkbox. +If it's checked, use a "Function Entry Statement" specifier, +and if it's unchecked, use a "Function Exit Statement" specifier. + +== Review your Hook Logic + +The new hooking system has greatly expanded capabilities. +You may be able to simplify the logic of your previous hooks by leveraging the new supported parameter types, hook statements, and hook types. diff --git a/modules/ROOT/pages/Development/Migration/ScsMigrationGuide.adoc b/modules/ROOT/pages/Development/Migration/ScsMigrationGuide.adoc new file mode 100644 index 000000000..14dc6cb9f --- /dev/null +++ b/modules/ROOT/pages/Development/Migration/ScsMigrationGuide.adoc @@ -0,0 +1,33 @@ += Migrating SCS Hooks to Mixins + +[IMPORTANT] +==== +Before following this guide you should read the xref:Development/ModLoader/ActorMixins.adoc[Actor Mixins] page +to get an overview of the new system and how to create Mixins using it. +==== + +Migrating from a SCS Hook to a Mixin is easy because you already have all the information you need in your Mod Game Instance Module. + +image::Development/UpdatingGuides/OldScsHook.png[Existing SCS Hook] + +New SCS Hooks cannot be made, but old ones will remain so you can use them when migrating to Mixins. + +From this old information we get: + +- Actor being attached to +- Parent Component +- Component with your logic + +Now follow the instruction from the xref:Development/ModLoader/ActorMixins.adoc[Actor Mixins] page to create a new Mixin. +When prompted for the Mixin Target use the one from the "Actor Class" in your old SCS Hook: + +image::Development/UpdatingGuides/PickMixinTargetClass.png[Pick Mixin Target] + +From here you can add any logic you had in your old SCS Component into your new Mixin. +Make sure to set any of the settings from your SCS hooks' actor component template(s) on the new component(s) you add to the Mixin, +assuming your editor displays the template, as a now-irrelevant bug prevented the option from being presented in most circumstances. + +[WARNING] +==== +Don't forget to register your new Mixin as described in the xref:Development/ModLoader/ActorMixins.adoc[Actor Mixins] page. +==== diff --git a/modules/ROOT/pages/Development/ModLoader/ActorMixins.adoc b/modules/ROOT/pages/Development/ModLoader/ActorMixins.adoc new file mode 100644 index 000000000..1114b1d33 --- /dev/null +++ b/modules/ROOT/pages/Development/ModLoader/ActorMixins.adoc @@ -0,0 +1,95 @@ += Actor Mixins + +Actor Mixins are an extension of the xref:Development/ModLoader/BlueprintHooks.adoc[Blueprint Hook System] +designed to allow adding extra functionality to Unreal Actors. +After selecting an actor class to base the Mixin off of, +you are presented with a blueprint that looks as if it was the actor itself. +From there you can add actor components or set up Blueprint Hooks to call functions you define. + +== Creating an Actor Mixin + +Creating a Mixin is similar to creating a Blueprint Hook. + +Within the Editor, create a new Blueprint of the type "Blueprint Mixin" + +image::Development/ModLoader/ActorMixins/CreateMixinAsset.png[] + +When creating it you will be given a prompt to choose which Actor to add the Mixin to. + +image::Development/ModLoader/ActorMixins/ChooseActor.png[] + +The suggested asset naming format is `Mixin_ActorOrPurpose_ModReference`. + +== Adding Components + +Upon opening the Mixin you will be presented with an empty graph. +The components of the actor you are hooking will also be shown and use the Viewport tab to visualize them. + +You can add additional components attached to anything in the actor's hierarchy. +They will appear with green text to distinguish them from the original actor's components. + +image::Development/ModLoader/ActorMixins/Components.png[] + +== Adding Logic + +By default, Mixins allow you to implement additional code for the Begin Play, Construction Script, End Play, and Tick functions on the actor. +Note that even though the editor labels these as overrides, they do not cancel the original function on the actor (TODO verify) +and are instead created as event notes. + +image::Development/ModLoader/ActorMixins/Functions.png[] + +image::Development/ModLoader/ActorMixins/AddLogic.png[] + +[NOTE] +==== +If you intend to use "Tick" make sure to check "Enable Mixin Tick" in the mixin class defaults. + +image::Development/ModLoader/ActorMixins/EnableTick.png[] +==== + +== Adding Hooks + +Since Mixins are an extension of a Blueprint Hook asset, +meaning you can open the Hook Graph window to define hooks. +These hooks always target the actor class you selected when creating the Mixin. + +image::Development/ModLoader/BlueprintHooks/ViewHookGraph.png[] + +[id="Register"] +== Registering the Mixin + +Actor Mixins must be registered in a +xref:Development/ModLoader/ModModules.adoc[Game Instance Module] to be applied in-game. +Create a Mod Game Instance Module if you don't already have one and add your new Mixin to the "Blueprint Hooks" array. + +image::Development/ModLoader/ActorMixins/RegisterMixin.png[Register Mixin to Game Instance Module] + +== Limitations and Workarounds + +=== Blueprint Actors Only + +The Blueprint Hooks system only works on blueprint-implemented content. +As the Actor Mixin system is an extension of the blueprint hooks system, +it only works on blueprint-implemented actors. +This rarely causes problems as most actors in Satisfactory are blueprint actors backed by {cpp} actor classes. + +Notable actors that are not blueprint implemented include: + +- The dropped items that spawn as loot around Drop Pods + +The closest workaround for {cpp} actors would be hooking begin play, +although that is no longer using the Mixin system. + +=== Level Actors and Saved Data + +Actors that are spawned and streamed with the level required special handling interally to work with the actor mixin system. +As a consequence of this, SaveGame properties on components added via Mixins to level actors will not be loaded. + +To work around this, save this data on something else saved instead, such as a Mod Subsystem. +Data could be associated with each component via a map of soft object references to data structs. +Using a soft reference is important here as the object could potentially be unloaded, leading to null keys in the map. + +== Examples + +Check out ExampleMod and the xref:Development/OpenSourceExamples.adoc[Open Source Examples] page +for examples of existing hook blueprints. diff --git a/modules/ROOT/pages/Development/ModLoader/BlueprintHooks.adoc b/modules/ROOT/pages/Development/ModLoader/BlueprintHooks.adoc new file mode 100644 index 000000000..a54093267 --- /dev/null +++ b/modules/ROOT/pages/Development/ModLoader/BlueprintHooks.adoc @@ -0,0 +1,186 @@ += Blueprint Hooking System + +SML3.11 introduces a new Blueprint Hooking system that allows modifying the behavior of existing Blueprint functions via custom code. +Your code can be run before or after the original function and can modify the function's inputs, return values, or cancel its execution. +It can also replace individual statements or expression within the function logic. + +Blueprint Hooks are created as blueprint assets and have full knowledge of blueprint asset structures and function signatures. + +[NOTE] +==== +Hooking of {cpp}-implemented functions is covered on the xref:Development/Cpp/hooking.adoc[Native Hooking] page. +==== + +A single Blueprint Hook asset can contain multiple hooks on any number of classes, +enabling you to organize your hooks as you see fit. + +== Creating a Hook Blueprint + +Within the Unreal Editor, create a new Blueprint of the type "Blueprint Hook" + +image::Development/ModLoader/BlueprintHooks/CreateBlueprintHook.png[Create Blueprint Hook Asset] + +The suggested asset naming format is `Hook_Purpose_ModReference`. + +== The Hook Graph + +Blueprint Hooks offer a new graph type called the "Hook Graph". +The Hook Graph is a specialized graph that allows you to +define hooks via Target Specifier and Hook nodes. + +Click the button in the editor's top bar to open it as a dockable window. +If the button is greyed out, it means you already have the window open. + +image::Development/ModLoader/BlueprintHooks/ViewHookGraph.png[] + +== Creating Hook Graph Nodes + +As with normal blueprint graphs, right clicking on empty space opens a prompt to create new nodes. +Each node has an on-hover tooltip that explains what it does. + +=== Comments + +Comments are invaluable for explaining the purpose of a hook and grouping multiple hooks together. + +Comments can be created via the "New Comment" node, the "C" hotkey does not work. +All hook graph nodes also support Unreal's comment bubble in the top left corner. + +=== Hooks + +Hook nodes are used to specify what class' function you are hooking, when the hook is executed, and what custom function to call. + +The following hook types are available: + +* Insertion Hook - Will resolve to the statement if targeting an expression +** Before +** Replace +** After +* Redirect Hook - Must return the same type + +.Hover over an entry to display an explanatory tooltip +image::Development/ModLoader/BlueprintHooks/CreateHook.png[Create Hook] + +Fill out the drop-downs to specify what class's function you are hooking. + +image::Development/ModLoader/BlueprintHooks/FillDropdowns.png[Fill dropdowns] + +=== Target Specifiers + +Target Specifier nodes connect to the "Target Statement" pin on hook nodes. +They are used to specify which statements or expressions to match in the hooked function. +Some specifiers require another specifier chained as input. + +The following target specifiers are available: + +* Constant (can choose type and value) +* Experssion Operand (takes another specifier as input) +* Function Call +* Function Entry Statement +* Function Exit Statement +* Outer Expression (takes another specifier as input) +* Property Assignment +* Property Read +* Return Value Experssion +* Target Selector (first/single/all/stuff) (takes another specifier as input) + +.Hover over an entry to display an explanatory tooltip +image::Development/ModLoader/BlueprintHooks/TargetSpecifierTooltip.png[Target Specifier with tooltip] + +=== Connecting Hooks to Target Specifiers + +All Hooks require a Target Specifier to be connected to them to tell them what part of the target function to hook. + +image::Development/ModLoader/BlueprintHooks/TargetSpecifierConnected.png[Target Specifier] + +== Hook Functions + +The code executed by a hook is defined in functions within the Hook Blueprint. +The "Hook Implementation" option on hook nodes determines what function is invoked a hook node. + +=== Hook Function Parameters + +Hook functions parameters are populated by the hooking system based on + +The first parameter should be the type of Blueprint you are hooking. +Subsequent parameters can be any variable that is available in the hooked function's context that the hook might want to read/write. If set to be By Ref, the type must exactly match, but otherwise a wider type can be used. + +Parameters will be mapped using their name to: + +* `Target` - special hooking argument that resolves to the object instance the hooked function was running +* Global Variables - on the object instance +* Local Variables - function inputs, function locals, and function temps (which you can check for in a BP code dump, either via the link:#ViewingBlueprintFunctionImplementations[`-DumpBlueprintPatchingResults` launch argument] which generates pseudocode, or in xref:Development/ExtractGameFiles.adoc#FModel[FModel] which generates a json very similar to the asset dump) +* `TargetReturnValue` - special hooking argument that resolves to the hooked function's ReturnValue +* `HookTarget` - special hooking argument for insertion hooks. Resolves to the expression the hook was pointing to, if it wasn't pointing to a statement +* `AssignmentTarget` - special hooking argument for insertion hooks on assignment statements. Resolves to the variable on the left side of an assignment statement. +* `OriginalValue` - special hooking argument that resolves to the original value when using redirect hooks (replacing an expression inside a statement, rather than an insert hook which goes before/replace/after a statement). Required when using a redirect hook. + +image::Development/ModLoader/BlueprintHooks/NewFunction.png[New Function] + +[id="Register"] +== Registering the Hook + +Hook assets must be registered in a +xref:Development/ModLoader/ModModules.adoc[Game Instance Module] to be applied in-game. +Create a Mod Game Instance Module if you don't already have one and add your new hook to the "Blueprint Hooks" array. + +image::Development/ModLoader/BlueprintHooks/RegisterHook.png[Register Hook in Game Instance Module] + +== Limitations and Workarounds + +=== Event Graph Nodes + +Because Blueprint Hook implementations are functions, some nodes you may be used to from Event Graphs are not available, +such as Latent Action nodes like Delay. + +To work around this, implement your logic in an Event Graph somewhere else, +such as a Mod Subsystem or your Mod Game World Module, +then call that event from the Hook Function. + +image::Development/ModLoader/BlueprintHooks/LatentActionWorkaround.png[Game World Module workaround] + +=== Unregistering Blueprint Hooks + +Once you have hooked a blueprint function, there is currently no way to unhook it without fully exiting Satisfactory. +This is why blueprint hooks are registered in a Game Instance Module. + +You can work around this by having your hook code check a flag in a mod subsystem or your game instance module to determine if the hook should execute. + +=== Hooking and Dedicated Servers + +Some blueprints (like UI blueprints) do not exist in the dedicated server build. +If your mod attempts to hook such a blueprint in a dedicated server, it will log an error message. +You can use the global function `IsRunningDedicatedServer()` to skip hooking to avoid this error. + +[id="ViewingBlueprintFunctionImplementations"] +== Viewing Blueprint Function Implementations + +Understanding what base-game blueprint functions do can be troublesome as we don't have their source code +and the starter project only contains xref:Development/BeginnersGuide/StarterProjectStructure.adoc#PlaceholderSystem[placeholders of blueprint assets]. + +To assist with this process, SML implements the `-DumpBlueprintPatchingResults` command line argument. +When the game is launched with this argument, +SML will dump the bytecode of all blueprint hooked functions to the log in a relatively human-readable format. + +Note that it is also possible to use xref:Development/ExtractGameFiles.adoc#FModel[FModel] to dump an asset as JSON +and view the blueprint bytecode in a less-readable format. + +== Examples + +Check out ExampleMod, SML, and the xref:Development/OpenSourceExamples.adoc[Open Source Examples] page +for examples of existing hook blueprints. + +== Blueprint Hooking from {cpp} + +It is not currently possible to hook blueprint functions from {cpp} code using SML's systems. + +Previous versions of SML allowed hooking blueprint functions from {cpp} code, +but because the {cpp} side is unaware of the structure of assets defined on the blueprint side, +these hooks were always in a messy and brittle state of requiring lots of reflection and hardcoded assumptions to work. +The only way to mitigate this brittleness was to have the hook call a blueprint-implemented function. +The modern system removes the middleman by having blueprint hooks defined and implemented on the asset side, +giving them full knowledge of asset structure. + +If you'd like to implement the code your hooks run in {cpp}, +write the code in a blueprint function library or similar and call the functions from the hook blueprint. + +// TODO mircea discussion about custom thunks? diff --git a/modules/ROOT/pages/Development/ModLoader/SimpleConstructionScript.adoc b/modules/ROOT/pages/Development/ModLoader/SimpleConstructionScript.adoc index c6de0c2e7..4276738df 100644 --- a/modules/ROOT/pages/Development/ModLoader/SimpleConstructionScript.adoc +++ b/modules/ROOT/pages/Development/ModLoader/SimpleConstructionScript.adoc @@ -1,5 +1,11 @@ = Simple Construction Script (SCS) Hooks +[IMPORTANT] +==== +As of SML 3.11, this system has been deprecated in favor of the +xref:Development/ModLoader/ActorMixins.adoc[Actor Mixins] system. +==== + Introduced in SML3.5, Blueprint Simple Construction Script hooks allow adding modded https://docs.unrealengine.com/5.1/en-US/components-in-unreal-engine/[Components] to any blueprint-based actor. diff --git a/modules/ROOT/pages/Development/OpenSourceExamples.adoc b/modules/ROOT/pages/Development/OpenSourceExamples.adoc index 72eec21c4..90f000565 100644 --- a/modules/ROOT/pages/Development/OpenSourceExamples.adoc +++ b/modules/ROOT/pages/Development/OpenSourceExamples.adoc @@ -23,6 +23,12 @@ Are you aware of an open-source mod to list here? Add it via the "Edit This Page" button in the top right corner and open a Pull Request to bring in your changes. ==== +[NOTE] +==== +This page was created before the new Actor Mixin and Blueprint Hook systems. +Entries may still refer to the old SCS Hook system until they are updated +==== + == MAM Enhancer Modifies the base game MAM, HUB, and AWESOME Shop UI to provide additional information to the player and improve the user experience. @@ -299,5 +305,5 @@ _Notable Satisfactory Features Used:_ _Notable Mod Loader Features Used:_ -* Simple Construction Script (SCS) Hooks +* Actor Mixins ** Used to spawn an additional actor component on sign placement holograms (the upwards facing arrow) diff --git a/modules/ROOT/pages/Development/Satisfactory/EnhancedInputSystem.adoc b/modules/ROOT/pages/Development/Satisfactory/EnhancedInputSystem.adoc index f278a55cf..84a176215 100644 --- a/modules/ROOT/pages/Development/Satisfactory/EnhancedInputSystem.adoc +++ b/modules/ROOT/pages/Development/Satisfactory/EnhancedInputSystem.adoc @@ -254,3 +254,13 @@ https://docs.unrealengine.com/5.1/en-US/enhanced-input-in-unreal-engine/#debugco is not available in shipping builds. However, the command `showdebug INPUT` is available and displays a reduced set of information, such as which mapping contexts are currently bound. + +== Controllers + +// TODO 1.1 controller support info + +Satisfactory 1.1 has added support for controllers and restructured many UIs with controller support in mind. +No community members have experimented with controller support features and reported their findings yet. + +Do you have additional information about controller support tips and approaches? +Add it via the "Edit This Page" button in the top right corner and open a Pull Request to bring in your changes. diff --git a/modules/ROOT/pages/Development/Satisfactory/FactoryLegs.adoc b/modules/ROOT/pages/Development/Satisfactory/FactoryLegs.adoc new file mode 100644 index 000000000..0ab8dd269 --- /dev/null +++ b/modules/ROOT/pages/Development/Satisfactory/FactoryLegs.adoc @@ -0,0 +1,19 @@ += Factory Legs + +Satisfactory machinery often includes "legs" to appear sturdily supported even when placed on uneven ground. + +To set up legs on modded buildings, your building need two things: + +* Named leg sockets defined on your building's mesh + ** The https://dev.epicgames.com/documentation/en-us/unreal-engine/using-sockets-with-static-meshes-in-unreal-engine?application_version=5.3[Unreal documentation] + covers how to add sockets to your mesh in the editor. + ** Socket names must follow the format `foot_xx` where `xx` is a zero-left-padded number starting at `01`. + According to CSS, this numbering format is hardcoded internally. +* FGFactoryLegs actor component on the building actor + ** Use the "mLegSocketNames" property to specify the names of the leg sockets used on your mesh. + +Note that if your building has a FGFactoryLegs component and its mesh NOT have leg sockets, the building hologram will always report that it's on uneven ground and prevent placement. + +image::Satisfactory/FactoryLegs/LegExampleViewport.png[Screenshot of editor viewport visualizing socket names] + +image::Satisfactory/FactoryLegs/LegExampleComponent.png[Screenshot of editor displaying FGFactoryLegs component settings] diff --git a/modules/ROOT/pages/Development/Satisfactory/ModsWithoutSML.adoc b/modules/ROOT/pages/Development/Satisfactory/ModsWithoutSML.adoc index f2fcfc841..32ddc929c 100644 --- a/modules/ROOT/pages/Development/Satisfactory/ModsWithoutSML.adoc +++ b/modules/ROOT/pages/Development/Satisfactory/ModsWithoutSML.adoc @@ -40,7 +40,17 @@ Here's a list of special considerations you'll have to make if you decide to go Every mod is different, so this will never be a comprehensive list. Please let us know what you find out so we can update this page. +- You still need to use the Starter Project to have a working Unreal Engine project to build your mod with. - Your mod breaking on game updates. {cpp} code, especially hooks, are very prone to breaking on game updates as offsets change. - Entry point for your code. {cpp} mods can use `StartupModule`, blueprint mods will need something else to help them load. - Alpakit GameVersion dependency field explained on the xref:Development/BeginnersGuide/ReleaseMod.adoc#_special_fields[Releasing Your Mod page]. - Not conflicting with any systems that SML uses, because there is a very high chance that end users will already have SML installed. + +== Examples + +Examples of mods that do not use SML: + +- https://github.com/NotNite/Statisfactory/[Statisfactory] - + Provides additional xref:Development/Satisfactory/DedicatedServerAPIDocs.adoc[Dedicated Server API endpoints] +- https://github.com/Archengius/BetterVehiclePaths/[BetterVehiclePaths] - + Alternative vehicle path definition system diff --git a/modules/ROOT/pages/Development/TestingResources.adoc b/modules/ROOT/pages/Development/TestingResources.adoc index b3df02ce3..7d8cad763 100644 --- a/modules/ROOT/pages/Development/TestingResources.adoc +++ b/modules/ROOT/pages/Development/TestingResources.adoc @@ -473,6 +473,18 @@ Switches found in AFGGameSession: .... +++ +++ +== Launch Argument: ExecCmds + +SML 3.9.0 reimplements the Unreal Engine `ExecCmds` launch argument (normally excluded from shipping builds), +allowing automatically executing xref:SMLChatCommands.adoc#ConsoleCommands[Unreal Console Commands] +after the game loads. + +You can read more about it in the +https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-engine-command-line-arguments-reference[Unreal documentation] + +The link:#LaunchScript[Quick Launch Script] +uses this argument to implement the `-clientAutoJoin` flag. + [id="TestingDedicatedServers"] == Dedicated Servers diff --git a/modules/ROOT/pages/Development/UpdatingFromSml310.adoc b/modules/ROOT/pages/Development/UpdatingFromSml310.adoc new file mode 100644 index 000000000..552cf11c6 --- /dev/null +++ b/modules/ROOT/pages/Development/UpdatingFromSml310.adoc @@ -0,0 +1,227 @@ += Upgrading from SML 3.10.x to 3.11.x + +SML3.11 brings support for Satisfactory 1.1, +revamps the blueprint hooking system, +and fixes some bugs. +Mods compiled for SML3.10 are unlikely to work with SML3.11 due to changes to the base game headers and the blueprint hooking system. + +Please _read this entire page before you begin updating your mod_. +It will save you time later to have an idea going in of what to expect while updating. +After you have finished reading this page, +follow the directions on the +xref:Development/UpdatingToNewVersions.adoc[Updating your Mod] +guide to install the updated engine, starter project, and update your mod. + +== New Features + +This section talks about the new features that SML 3.11 brings to the table. + +=== Blueprint Hooks as Assets + +The Blueprint Hooking system has been completely rewritten to offer additional capabilities, +eliminate the need for brittle hardcoded references, +and improve the developer experience. + +New capabilities include: + +- Ability to hook before/after/replacing statements +- Intuitive hook graph editor interface +- No {cpp} code required to create a hook +- Hooks implemented in the blueprint code can now alter function parameters and return values +- No more hardcoded string references to function and class names +- Editor-time checking of hook parameters and function signatures + +To learn more about the new system, +see the xref:Development/ModLoader/BlueprintHooks.adoc[Blueprint Hooks] page. +To learn what you need to do to migrate your existing hooks to the new system, see the +link:#BlueprintHookingOverhaul[Blueprint Hooking Overhaul] heading. + +=== Actor Mixins + +Actor Mixins are a special kind of Blueprint Hook that replace the SCS hooks system. +They make adding custom components to actors much easier and more intuitive to work with in the editor. + +See the xref:Development/ModLoader/ActorMixins.adoc[Actor Mixins] page for more information. + +=== Launch Argument: DumpBlueprintPatchingResults + +When the game is launched with the `-DumpBlueprintPatchingResults` argument, +SML will dump the bytecode of all blueprint hooked functions to the log in a relatively human-readable format. + +Read more about it on the xref:Development/ModLoader/BlueprintHooks.adoc#ViewingBlueprintFunctionImplementations[Blueprint Hooks] page. + +=== Example Mod Improvements + +ExampleMod has been enhanced with additional examples: + +* Persistent storage of per-player data in multiplayer +** See `ExampleMod_PerPlayerDataMixin` and `ExampleModPlayerDataComponent` +* Custom recipe-based production building +** Requires no custom logic to function +** Has 1 solid and 1 fluid input port, 3 solid output ports +** See `Build_ExampleRecipeBasedBuilding` + +=== Alpakit Mod Sorting + +The Alpakit Dev and Alpakit Release windows now allow you to sort the displayed mods by Friendly Name or Mod Reference. +Mods were previously always sorted by Mod Reference. + +=== Alpakit Add {cpp} Module + +The Alpakit Edit Mod dialog now allows adding a {cpp} module to an existing blueprint mod. +To add the module, click the "Convert to C++ & Blueprint Mod" button in the bottom left of the dialog. +Note that you must regenerate Visual Studio project files and build for Development Editor before it can be used in the Unreal Editor. + +=== Alpakit Versioned Cooked Content + +Alpakit now uses Unreal's versioned cooked content feature, +increasing the robustness of pak mods, potentially allowing them to survive engine updates without needing to be repackaged. +We do not have a good way to test this behavior, so it may be tweaked further in the future. + +== Notable Fixes + +- link:https://github.com/satisfactorymodding/SatisfactoryModLoader/pull/357[Fix crash when switching between string session settings] +- Fix AChatCommandInstance not calling Super in GetLifetimeReplicatedProps + +== Not Done Yet + +The following features are not quite ready to use yet. + +=== Advanced Game Settings values not saved + +The xref:Development/ModLoader/SessionSettings.adoc[Session Settings] page +explains how you can create your own Advanced Game Settings. +However, their values are not currently saved with the save file. +Session Settings still function correctly - their values are saved. + +=== Content Bundle Cooking + +The optimal way to add modded content to the game world (like ore nodes, deposits, etc.) +is to use the Content Bundle system, +but Unreal currently refuses to cook content bundles unless the world is also cooked. +This is a https://github.com/satisfactorymodding/SatisfactoryModLoader/issues/155[known bug] +and will be fixed in a future SML release. + +The next best way is to use sublevel spawning. +ExampleMod uses sublevel spawning to spawn its example resource nodes - check the game world submodule. +Here is an example from Kyrium of how to do that in {cpp}: + +* https://github.com/Satisfactory-KMods/KBFL/blob/d21381de3621d25f063ecfbf24b5d35533da4357/Source/KBFL/Private/Subsystems/ResourceNodes/KBFLSubLevelSpawning.cpp#L41[KBFLSubLevelSpawning] +* https://github.com/Satisfactory-KMods/KBFL/blob/d21381de3621d25f063ecfbf24b5d35533da4357/Source/KBFL/Private/Subsystems/KBFLResourceNodeSubsystem.cpp#L67[KBFLResourceNodeSubsystem] + +== Required Changes + +In addition to any specific-to-your-mod issues you may encounter, +the changes described below _must_ be made in order for your mod to be updated. + +=== Dependency Updates + +The following project dependencies have updated. +Install the updated versions as you follow the xref:Development/UpdatingToNewVersions.adoc[Updating your Mod] guide. + +==== Engine Update + +Satisfactory 1.1 is still on Unreal Engine 5.3.2, +but Coffee Stain and Fishlabs have made some engine and engine plugin modifications +in their work towards console support. +Download and set up our custom release while following the +xref:Development/UpdatingToNewVersions.adoc[Updating your Mod guide]. + +[IMPORTANT] +==== +Since both the previous and updated engine version are `5.3.2-CSS`, in order to have both editors installed, +you will need to edit the old engine's Register.bat to specify a different engine version (ex. `5.3.2-CSS-1.0`) +otherwise the 2 engine versions will share the same entry. + +Opening projects under the old engine version will also require editing the .uproject file to specify the different engine version. +==== + +==== Wwise Update + +CSS has also updated to a newer version of Wwise. +The xref:Development/BeginnersGuide/dependencies.adoc#_wwise[Dependencies page Wwise instructions] +lists the new Wwise version and guides you through integrating it into your project as you follow the +xref:Development/UpdatingToNewVersions.adoc[Updating your Mod guide]. + +=== Generate Wwise Sound Banks + +If you see the "GeneratedSoundBanks folder does not seem to be set. Would you like to open the settings window to set it?" message, use the Wwise editor to +xref:Development/BeginnersGuide/project_setup.adoc#Wwise_GenerateBanks[manually generate sound banks once], +You should not need to do this again unless you create a new Wwise project or use Wwise systems in your mod. + +== Additional Changes + +You might not be affected by these changes, +but we'd like to draw extra attention to them. + +=== CppStandard20 + +If one of your mods uses {cpp} and you haven't already added `CppStandard = CppStandardVersion.Cpp20;` to its `Build.cs` file, +this update will likely require you to do so. +See the Alpakit template in `Mods\Alpakit\Templates\CPPAndBlueprintBlank` for an example. + +=== FChatMessageStruct Changes + +The base-game FChatMessageStruct has changed in the following ways: + +- Now uses FText field `MessageText` instead of FString field `Message`. +- Now uses field `MessageSenderColor` instead of `CachedColor`. + +[id="BlueprintHookingOverhaul"] +== Blueprint Hooking Overhaul + +[id="BlueprintHookingOverhaul_CppBpHookingRemoval"] +=== {cpp} Blueprint Function Hooking Removal + +The previous FBlueprintHookManager system (`FBlueprintHookManager::HookBlueprintFunction`) has been replaced with the new Blueprint Hook system. +The old system cannot coexist with the new system, so you must migrate as part of this update. + +Because the {cpp} side is unaware of the structure of assets defined on the blueprint side, +{cpp}-implemented blueprint hooks were always in a messy and brittle state +of requiring lots of reflection and hardcoded assumptions to work. +The only way to mitigate this brittleness was to have the hook call a blueprint-implemented function. + +The new system removes the middleman by having blueprint hooks defined and implemented on the asset side, +giving them full knowledge of asset structure. +It can also do matching instead of just specifying an instruction index, and can insert the hook before/after/replacing the existing statement. + +See xref:Development/Migration/BpHookMigrationGuide.adoc[Blueprint Hook Migration Guide] + +=== Bind on BPFunction Node Removal + +The Bind on BPFunction node offered by the old hooking system has been removed. + +The old system was exceedingly limited in that you could never get function parameters or influence return values +- you only had access to the object instance calling the function. +The new system allows you to get the function parameters and modify the function behavior like was already possible with hooks implemented in {cpp} in the old system. + +Instead of a Bind on BPFunction node, move the event and hook definition to a Blueprint Hook asset. +This process is covered in the xref:Development/Migration/BpHookMigrationGuide.adoc[Blueprint Hook Migration Guide]. + +=== Widget Blueprint Hooks: Inline Widget Template Removal + +This feature was removed due to bugs in the editor causing the template configuration system to not appear under many circumstances. +You may have not even known it existed as a result. + +Instead of the inline template, make one-off widgets that contain the widget you wanted to customize, using that extra 'layer of widget' to set the template options. + +=== Simple Construction Script Hook Removal + +Simple Construction Script Hooks have been removed in favor of the new Actor Mixins system. + +The data used to set up existing SCS hooks is still visible in the editor, +but the SCS hooks themselves are not functional, +and the creation of new SCS hooks is disabled. + +For more info, see the xref:Development/Migration/ScsMigrationGuide.adoc[SCS Hook Migration Guide]. + +[IMPORTANT] +==== +Some devs have reported issues with Actor Mixins applying on level streamed actors. +Please report any issues you encounter with Actor Mixins on the Discord. +==== + +== Complete Changelog + +The full list containing every changed file and asset can be viewed using GitHub's Compare Changes feature: +https://github.com/satisfactorymodding/SatisfactoryModLoader/compare/v3.11.0...v3.10.0 diff --git a/modules/ROOT/pages/Development/UpdatingToNewVersions.adoc b/modules/ROOT/pages/Development/UpdatingToNewVersions.adoc index d7ba607f3..bf073c2f5 100644 --- a/modules/ROOT/pages/Development/UpdatingToNewVersions.adoc +++ b/modules/ROOT/pages/Development/UpdatingToNewVersions.adoc @@ -35,14 +35,14 @@ There are a few measures you can take in order to decrease the chances of your m - Avoid header edits if at all possible. Instead, use xref:Development/ModLoader/AccessTransformers.adoc[Access Transformers]. - Use already-established systems to implement behavior. - For example, use the SML Keybinds system instead of writing your own keybind handling logic. + For example, use SML's content registration systems instead of writing your own logic. Then, if it breaks, there are more people on board to fix it, rather than just you. - Consider implementing some functionality in Blueprints, since they are generally less likely to break when header updates occur. This comes at a nonzero performance cost, but that discussion is out of the scope of this docs page. Consider the case of https://ficsit.app/mod/UtilityMod[Pak Utility Mod], - which has required extremely few updates in the scale of things, + which has required extremely few updates in the scale of how long it has been around, partly because it uses no {cpp} code. == How to Tell Something Broke diff --git a/modules/ROOT/pages/Development/index.adoc b/modules/ROOT/pages/Development/index.adoc index 1fe72ff0b..2f416ec61 100644 --- a/modules/ROOT/pages/Development/index.adoc +++ b/modules/ROOT/pages/Development/index.adoc @@ -9,17 +9,22 @@ If you're just looking to play Satisfactory with mods, check out how to install == Resources -Below is a list of some good resources about making mods for Satisfactory, Unreal Engine, C++ and 3D Modeling. Please contact us if you know of other resources that should be added to this list. +Below is a list of some good resources about making mods for Satisfactory, Unreal Engine, {cpp} and 3D Modeling. Please contact us if you know of other resources that should be added to this list. - https://www.youtube.com/channel/UCOVfF7PfLbRdVEm0hONTrNQ[Mathew Wadstein] + A good YouTube Channel showing a more in-depth look at features of Unreal Engine (BP only). - https://www.youtube.com/c/AlexForsythe[Alex Forsythe] + -A YouTube Channel that covers Unreal concepts (both BP and C++) in detail, including replication. +A YouTube Channel that covers Unreal concepts (both BP and {cpp}) in detail, including replication. - https://www.youtube.com/channel/UCz-eYJAUgSE-mqzKtit7m9g[Virtus Learning Hub] + -A "general" tutorial series channel for UE game development (also covers some C++) +A "general" tutorial series channel for UE game development (also covers some {cpp}) - http://academy.unrealengine.com/[Unreal Engine Academy] + A neat learning platform made by Epic Games for learning Unreal Engine. + +=== {cpp}-specific + +- link:https://dev.epicgames.com/documentation/en-us/unreal-engine/programming-with-cplusplus-in-unreal-engine?application_version=5.3[Unreal Engine Documentation: Programming with {cpp}] +- link:https://dev.epicgames.com/documentation/en-us/unreal-engine/epic-cplusplus-coding-standard-for-unreal-engine?application_version=5.3[Unreal Engine Documentation: Coding Standard] diff --git a/modules/ROOT/pages/ForUsers/DedicatedServerSetup.adoc b/modules/ROOT/pages/ForUsers/DedicatedServerSetup.adoc index c6544b68e..e4c5e7e76 100644 --- a/modules/ROOT/pages/ForUsers/DedicatedServerSetup.adoc +++ b/modules/ROOT/pages/ForUsers/DedicatedServerSetup.adoc @@ -35,11 +35,51 @@ You will have to follow your server host's own documentation about mod setup. If your server host provides (s)ftp access to server files the Mod Manager and ficsit-cli _should_ be able to interact with them normally. + +[id="SupportedHosts"] +==== Potentially Supported Hosts + +Users have reported success using the following server hosts in the past. +We are not endorsed by them, offer no guarantees that their services will work for you, +and strongly encourage you to do your own research. +Be sure to check their documentation to see if they have any special setup instructions. + +==== + +The below list is shuffled each time the page is loaded to avoid bias towards any one host. + +// Ugly inline HTML to make randomized list +// Spacing sucks to keep asciidoc happy +// https://docs.asciidoctor.org/asciidoc/latest/pass/pass-block/ +// https://stackoverflow.com/a/46545530 +// cspell:disable +[pass] +
    + + +// cspell:enable +==== + [id="UnsupportedHosting"] ==== Unsupported Hosts -We do not currently maintain a list of server hosts that support modded servers. - ==== The following 3rd party hosting services are known to **_NOT_ support mods**, regardless of what their websites and marketing pages claim: diff --git a/modules/ROOT/pages/ForUsers/SatisfactoryModManager.adoc b/modules/ROOT/pages/ForUsers/SatisfactoryModManager.adoc index 3e462645e..d8d33bc42 100644 --- a/modules/ROOT/pages/ForUsers/SatisfactoryModManager.adoc +++ b/modules/ROOT/pages/ForUsers/SatisfactoryModManager.adoc @@ -208,7 +208,7 @@ xref:faq.adoc#_where_are_my_game_files_located[game's install directory] manuall [id="InstallSpecificModVersion"] == Installing a Specific Version of a Mod -By default, the Mod Manager will install the latest version of a mod that it thinks is compatible with your game version. +By default, the Mod Manager will automatically install the latest version of a mod that it thinks is compatible with your game version. However, it will avoid versions that end in a prerelease tag (ex. `1.0.0-PrereleaseTagHere`). If you want to install a specific version of a mod, such as a prerelease version, diff --git a/modules/ROOT/pages/faq.adoc b/modules/ROOT/pages/faq.adoc index 376c4031e..49b0e47c6 100644 --- a/modules/ROOT/pages/faq.adoc +++ b/modules/ROOT/pages/faq.adoc @@ -1,4 +1,4 @@ -= Frequently Asked Questions += Frequently Asked Questions (FAQ) You can find answers to frequently asked questions on the modding discord (and about modding in general) here. @@ -70,6 +70,19 @@ Moving or reinstalling will not affect your save files. It varies depending on the mod, but in general, yes, this is totally fine. The mod should say on its mod page on ficsit.app if it can't be added to an in-progress game. +[id="FindMissingMods"] +== Can I find out what mods I was using in a save file if I lost the mod manager profile? + +Yes, SML keeps a record of what mods a save file was using, and their versions, within the save header. + +The easiest way to see this is to install the link:https://ficsit.app/mod/SML[Satisfactory Mod Loader] mod and try to load the save file again. +A pop-up will appear with a list of the mods that were used in the save file. +If the pop-up is too long, the rest of the list will be in the link:#Files_Logs[game's log file]. + +Alternatively, you can open your save file in a text editor, as the save header modded data is not currently compressed. +Line 3 will contain a JSON object of the format `{"Version":1,"Mods":[{"Reference":"ModReferenceHere","Name":"Mod User Facing Display Name Here","Version":"SemVerHere"},]}`. +Keep in mind that large save files can crash some text editors. + [id="MultiplayerSupport"] == Do mods work with multiplayer? diff --git a/modules/ROOT/pages/index.adoc b/modules/ROOT/pages/index.adoc index 421ee964c..6c5b16f59 100644 --- a/modules/ROOT/pages/index.adoc +++ b/modules/ROOT/pages/index.adoc @@ -8,7 +8,7 @@ Here you can find lots of information regarding modding https://www.satisfactorygame.com/[Satisfactory], the factory-building sim by https://www.coffeestainstudios.com/games/[Coffee Stain Studios] (CSS). Modding for Satisfactory is more established than you might think given how long the game has been out. -There are already https://ficsit.app/[over 600 mods] released +There are already https://ficsit.app/[over 1100 mods] released and we maintain in-depth documentation on how you can create your own. In this page, we will provide some surface level information for both mod users and developers. @@ -80,7 +80,7 @@ You can find the archives https://forums.ficsit.app/[here]. == Contributing You can find information on how to contribute to the docs -https://github.com/satisfactorymodding/Documentation#contributing[in the github repo's readme]. +https://github.com/satisfactorymodding/Documentation#contributing[in the GitHub repo's readme]. == Modding Technologies @@ -93,7 +93,7 @@ to load into systems provided by the game, and to interact with each other. It also provides many helper features to assist in mod development. Due to how CSS has configured Satisfactory, it is possible to make mods that do not require SML to function, -however this is rarely done in practice. +however xref:Development/Satisfactory/ModsWithoutSML.adoc[this is rarely done in practice]. === Alpakit