Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,11 @@
*** 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]
*** Mod Configurations
**** xref:Development/ModLoader/ModConfigs/ConfigTypes.adoc[Config Types (Which one should you use?)]
**** xref:Development/ModLoader/ModConfigs/SessionSettings.adoc[Session Settings]
**** xref:Development/ModLoader/ModConfigs/ModConfig.adoc[Mod Config]
**** xref:Development/ModLoader/ModConfigs/GameUserSettings.adoc[Game UserSettings]
*** xref:Development/ModLoader/ChatCommands.adoc[Chat Commands]
*** xref:Development/ModLoader/Registry.adoc[Registry]
*** xref:Development/ModLoader/GameMapRegistry.adoc[Game Map Registry]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
= Mod Configuration Options

== Session Settings vs. Mod Config vs. Game User Settings

There are various ways for mod developers to add configuration options for their mods, and it can be confusing to know which one
to use. Listed below are the main types of configuration options, and the pros and cons of each type. In general, Session Settings
are best for options that affect gameplay and may vary between different saves, Mod Configs are best for options that are more visual
or client-specific, and Game User Settings are best for options that should be configurable on dedicated servers and designed for
per server or per client rather than per save.

xref:Development/ModLoader/ModConfigs/SessionSettings.adoc[Session Settings]:

.Pros:
** Good for things that do not pertain to a particular player, or you want to be a choice per save file, such as
*** What recipes from a mod are enabled
*** How fast a machine operates
*** Options for a custom level
** Per-save configuration
** Automatically replicated in multiplayer
** Can be made to sync between server and clients by mod developer if desired

.Cons:
** Not per-installation, settings have to be re-configured for every new session.
** Must be registered in the mod's GameInstanceModule to be registered.
** Not visible in Dedicated Servers, as the User Interface is not loaded there.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is absolutely a bug and a missing feature, not really a "con"


xref:Development/ModLoader/ModConfigs/Configuration.adoc[Mod Configurations]:

.Pros:
** Per-installation configuration
*** Carries over between saves
** Can be made to sync between server and clients by mod developer if desired
** Different users may want different settings on the same server, such as visual options or UI options that do not affect gameplay

.Cons:
** Not replicated in multiplayer by default
** Server settings must be configured through the Mod Config file

xref:Development/ModLoader/ModConfigs/UserSettings.adoc[Game User Settings], known as FGUserSetting:

.Pros:
** Per-installation configuration
*** Carries over between saves
** Can use the icon functionality offered by FGUserSettingCategory
** Allows Dedicated Server and clients to have different settings for the same mod
** Automatically replicated in multiplayer if `Is Session Setting Wide` is checked

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is not the case. User Settings are never replicated unless you manually write the code for your specific setting to replicate (like base game does for some of its settings)

** Contains an user interface for dedicated servers to configure settings that affect the server

.Cons:
** Not per-save, changes affect all save files using the same installation
** Mod must be a GameFeature to use Game User Settings, and settings must be registered in the mod's FGGameFeatureData to be registered.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth adding that they are added to the "Options" menu and not "Mod Options" or any other SML-related menu, so you need to be careful to group your settings reasonably well to avoid overwhelming the user.

Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
= User Settings

Game User Settings are a feature that is used by the base game's Creative Mode and Game Mode Settings

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are confusing two separate systems here.

The first system is User Settings (entry points in C++ are FGUserSetting, IFGOptionInterface and IFGOptionInterfaceImpl, as well FGOptionsLibrary)
User settings are just a framework that allows data-driven setting creation and management, as well as automatic UI support out of box. The only thing you need to do to implement your "options-like" UI is to implement IFGOptionInterface (or more commonly, IFGOptionInterfaceImpl)

The second system is Game User Settings. Game User Settings are User Settings implementation that uses the ini file in saved data directory to persist the setting values, shows them in Options menu (and in Server Options), and is global to the install of the game/server.

Creative Mode (aka Advanced Game Settings) are another implementation that stores the data on a per save game basis and does some additional handling to marshal it and pass it from session creation to the game logic on the loaded game map.

Game Modes are another implementation similar to Creative Mode, but with its own gameplay differences.

What your User Setting does and how it behaves heavily depends on what Manager class it actually belongs you (such as UFGGameUserSettings, UFGAdvancedGameSettings, or another implementation for game modes), because all of these behaviors are manager-specific.

that allows mods to store configuration information on a _per-game-install_ basis.
Game User Setting values are xref:Development/Satisfactory/Multiplayer.adoc[automatically replicated in multiplayer]
and can be edited by any connected player.

Game User Settings are currently stored in the Engine's GameUserSettings.ini file,
making them available exceedingly early in the loading process.
This may change in the future depending on what mod developers decide is more useful.

== Defining New Game User Settings

Game User Settings are defined by Data Assets.
To create a Game User Setting in Blueprint, in a content browser right click and select
`Create Advanced Asset` > `Miscellaneous` > `Data Asset` and search for `FGUserSetting`.

=== Selecting a Str Id

Game User Settings are handled by `UFGGameUserSettings`, the class the game uses to define the configuration options in the settings menu.

The "Str Id" field is a unique identifier for the Game User Setting
and is used for retrieving the value of the Game User Setting later.
See the table below for some examples of Str Ids and things to keep in mind when selecting one.

.Example User Setting Str Ids
|===
|✔️ Good Example |❌ Bad Practice

|✔️ `YourModReference.EnableFizzBuzz`

Prefix the id with your Mod Reference to ensure it is unique across mods.

| ❌ `EnableFizzBuzz`

Another mod could implement a User Setting by this name,
leading to a conflict.

|✔️ `YourModReference.WhizzbangStrengthMult`

Since User Settings are referenced by their string id,
giving them a verbose, unique name makes it easy to find all usages of the setting in code
via a find operation.

| ❌ `YourModReference.Multiplier`

Multiplier for what? It's easy to forget what this setting controls,
and if you ever decide to add other "multipliers" in the future,
they could easily be mentally confused with this one.

|✔️ `YourModReference.PowerCostMultFloat`

Since you must use a type-specific method to read/write a User Setting,
consider including the setting's type as part of its id as a reminder of what type it is.
Unfortunately using the wrong getter method is currently a silent error due to how the FG Options system is implemented,
making this problem particularly annoying to track down.

|
// intentionally blank

|✔️ `YourModRef.MinerMk1.PowerCostMultFloat`

Consider indicating which building/feature a setting applies to
if you offer multiple settings with similar names or functionality.

|
// intentionally blank


|===

[id="Categories"]
=== Display

The following fields control how User Settings appear to end users:

- Display Name: User-facing name of the option. Users can search for this text within the setting's category.
- Tool Tip: User-facing description of what the option does.
Appears at the bottom of the setting scroll list when the user hovers over the option.
Text will wrap as needed to fit the user's screen, but manual new lines are not supported.
- Widgets to Create: Defines where the setting appears. Elaborated on below.

[id="CategoryAsset"]
==== Category Assets

User Settings appear in categories defined by FGUserSettingCategory assets.
You must create a minimum of 2 Category assets for your mod's User Settings,
one for the overarching Category used by your mod, and a second for a Sub Category within your category.
Category assets can be reused for multiple options within the same mod.

The following defaults are suggested:

[NOTE]
====
User Setting categories can use the icon functionality offered by FGUserSettingCategory.
====

[id="CategoryAsset_Main"]
===== (Main) Category

Suggested asset name: `USC_YourModReference`

- mDisplayName: The Friendly Name of your mod, for example, `Example Mod`. The user can search all Categories for what you write here.
- mMenuPriority: Leave this at `0`, you can't infer what other mods the end user will have installed to pick a "good" value.
If you create multiple main categories, you can use this field to ensure they display next to each other.
In this case, pick a random large number to use as a base and then a small offset to group them together, for example, `864392` and `864392.1`.

Mods typically define a single main category for their User Settings.
If you end up creating multiple, make sure it's still clear which mod is offering the category.

[id="CategoryAsset_Sub"]
===== Sub Category:

Suggested asset name: `USSubC_YourModReference_SubCategoryName`

- mDisplayName: Header text for this sub category. This field's text isn't currently searchable.
- mMenuPriority: Because you control all sub categories within your mod's category, this field is useful for ordering them.

[id="WidgetsToCreate"]
==== "Widgets to Create" entry

User Settings inherit functionality from FGUserSettings that enable the same option to be displayed in multiple places,
so making one appear involves creating at least one entry in the Widgets to Create field.
Make sure to define these fields:

- Category Class: Self explanatory.
- Sub Category Class: Self explanatory.
- Menu Priority: Controls options' ordering within the sub category.

==== Level Whitelist

When values are present in this array, the User Setting is restricted to only appear when playing in one of the specified game levels.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a vanilla functionality, I do not recall vanilla FGUserSetting assets having these feature. Are you sure you are not confusing them with SML Session Settings (which are a subclass of FGUserSettings)?

Combined with the fact that users can configure User Settings when setting up a new game save,
they are especially useful as options for custom maps.

=== Behavior

Not all properties inherited from UFGGameUserSettings are relevant to User Settings.
You will have to experiment to see which ones have an effect.
Please update this documentation page via "Edit This Page" in the top right with your findings.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, behavior depends on a manager you are using, as I mentioned in the comment above.


Checking the "Use CVar" field is only required
if you wish to allow modifying the value of the User Setting via the game console.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that Use CVar is only supported for Game User Settings (not for game modes, AGS or anything else). Additionally, as a rule of thumb, you want to have all Game User Settings that are relevant for Dedicated Servers have a CVar (this is the convention that vanilla follows)


SML automatically forces the following property values on User Settings.
If you change any of these properties they will be automatically reset to these values
next time the asset is loaded.

* ShowInBuilds: `Public Builds` to ensure that User Settings are visible to the user
* ManagerAvailability: `USM MAX`, which is an invalid value, ensuring that the setting never displays in base-game options menus.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is deprecated, no need to explain this or even mention it

* IsSettingSessionWide: `true` to ensure that multiplayer clients are able to modify User Settings and have their changes stored with the save file.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this only controls a little visual UI icon next to the setting, it has zero impact on the actual behavior of the setting.


In order to have a User Setting only editable at save creation, use the "Don't show in game" Visibility Disqualifier.

=== Registration

A User Setting must be registered to be usable by the player.

To register a User Setting, list it in the relevant array of your mod's
xref:Development/Satisfactory/GameFeatureDataAsset.adoc[Game Feature Data Asset].

Registering a User Setting makes it available to be configured in Satisfactory's Settings menu
which is available at both world creation and in the pause menu.

== Reading and Writing User Settings

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all good info, but specifically for Game User Settings, not for User Settings overall


Check ExampleMod for some example User Settings and how to read their values.
There is an example in the ExampleMod Level Blueprint and in the Game World Module.

=== From Blueprints

To get a reference to the User Settings, use the "Get Option Interface" node.

You can read the value of a User Setting via the "Get <typename> Option Value" method of the User Settings Manager.
You can also subscribe to changes via "Subscribe to Dynamic Option Update".

If you want to programmatically modify the value of a User Setting,
use the "Set <typename> Option Value".

=== From {cpp}

The UFGGameUserSettings is a UGameUserSettings UObject and as such can be accessed via the standard Unreal method of getting user settings. This does not require the game world context as shown below.

An example of reading a User Setting value from {cpp}:

```cpp
UFGGameUserSettings* UserSettings = UFGGameUserSettings::GetFGGameUserSettings();

// Boolean setting
const FVariant ConfigVariant = UserSettings->GetOptionValue(TEXT("ExampleMod.ExampleUserSetting"));
bool ConfigValue = ConfigVariant.GetValue<bool>();
--or--
bool ConfigValue = UserSettings->GetBoolOptionValue(TEXT("ExampleMod.ExampleUserSetting"));

// Integer setting
const FVariant ConfigVariant = UserSettings->GetOptionValue(TEXT("ExampleMod.ExampleUserSetting"));
int32 ConfigValue = ConfigVariant.GetValue<int32>();
--or--
int32 ConfigValue = UserSettings->GetIntOptionValue(TEXT("ExampleMod.ExampleUserSetting"));

// FString setting
const FVariant ConfigVariant = UserSettings->GetOptionValue(TEXT("ExampleMod.ExampleUserSetting"));
FString ConfigValue = ConfigVariant.GetValue<FString>();
--or--
FString ConfigValue = UserSettings->GetStringOptionValue(TEXT("ExampleMod.ExampleUserSetting"));

// Float setting
const FVariant ConfigVariant = UserSettings->GetOptionValue(TEXT("ExampleMod.ExampleUserSetting"));
float ConfigValue = ConfigVariant.GetValue<float>();
--or--
float ConfigValue = UserSettings->GetFloatOptionValue(TEXT("ExampleMod.ExampleUserSetting"));

// Linear Color setting
const FVariant ConfigVariant = UserSettings->GetOptionValue(TEXT("ExampleMod.ExampleUserSetting"));
FLinearColor ConfigValue = ConfigVariant.GetValue<FLinearColor>();
--or--
FLinearColor ConfigValue = UserSettings->GetLinearColorOptionValue(TEXT("ExampleMod.ExampleUserSetting"));
```

=== Testing

Make sure to check in-game to ensure that your User Settings appear and display as you expect.
They are referred to in-game as Settings. This is the same as the game settings for Display, World, Gameplay, etc.

Check out ExampleMod for some example types and setups using User Settings.

== Advanced Game Settings

In order to create an Creative Mode setting (internally called an Advanced Game Setting) instead of a User Setting:

. Create a data asset of type `FGUserSetting`.
. Set the Manager Type Availability is set to `FGAdvancedGameSettings` in the asset properties.
. Ensure your mod's xref:Development/Satisfactory/GameFeatureDataAsset.adoc[Game Feature Data Asset]
is configured to scan for FGUserSetting assets at the path required to find your data asset.
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,6 @@ It's possible to make a session setting specific to only a certain level,
making them particularly useful for providing config options for custom levels
since they can be edited before the save is created.

== Session Settings vs. Mod Config

Session settings are always per-game-save, while mod config is stored per-game-installation.
For example, in a dedicated server, the server has its own mod config and each client has their own mod config.
Making the server aware of client's chosen configs (or vice versa) is only required if
some behavior on both sides requires it, for example movement speeds or content registration.
Replicating config values must be implemented by the mod developer.
Session Setting values are automatically xref:Development/Satisfactory/Multiplayer.adoc[replicated in multiplayer].

xref:Development/ModLoader/Configuration.adoc[Mod Configurations] are better for user interface or visual stuff
since it gets saved with the user's installation, carries over between saves, and different users may want different settings on the same server.

Session Settings are good for things that do not pertain to a particular player,
or you want to be a choice per save file, such as
what recipes from a mod are enabled,
how fast a machine operates,
or options for a custom level.

== Defining New Session Settings

Session Settings are defined by Data Assets.
Expand Down Expand Up @@ -199,7 +181,7 @@ use the "Get Session Settings Manager" node.
You can read the value of a session setting via the "Get <typename> Option Value" method of the Session Settings Manager.
You can also subscribe to changes via "Subscribe to Dynamic Option Update".

If you want to programatically modify the value of a session setting,
If you want to programmatically modify the value of a session setting,
use the "Set <typename> Option Value".

=== From {cpp}
Expand Down
Loading