Class ConfigFileManager
Static orchestrator for the layered config file system. Manages global enable/disable state based on build type (debug vs production) and resolves layered overrides from user documents and app folder config files. Per-config enable/disable is handled by each ScyllaConfiguration instance.
Thread Safety: This class is NOT thread-safe. All methods must be called from Unity's main thread.
Inherited Members
Namespace: Scylla.Core.Config
Assembly: ScyllaCore.dll
Syntax
public static class ConfigFileManager
Properties
CreateEnabled
Gets or sets whether auto-creation of config files is globally enabled. When true and a configuration's CreateConfigFile is also true, missing config files will be created with default values on launch.
Declaration
public static bool CreateEnabled { get; }
Property Value
| Type | Description |
|---|---|
| bool |
IsEnabled
Gets or sets whether the config file system is globally enabled. Resolved from the core configuration's build-type switches during initialization.
Declaration
public static bool IsEnabled { get; }
Property Value
| Type | Description |
|---|---|
| bool |
Methods
ApplyOverrides(ScyllaConfiguration)
Resolves layered overrides and applies them to a configuration. Loads config files from user documents (highest priority) and app folder (lower priority), merges them, and applies the result to the configuration.
Both the global gate (IsEnabled) and the per-config gate (IsConfigFileEnabledForCurrentBuild()) must be true for overrides to be applied.
This method does not validate the resulting configuration values. Callers should invoke Validate() or ValidateAllConfigurations() after applying overrides to ensure values remain within valid ranges.
Declaration
public static int ApplyOverrides(ScyllaConfiguration configuration)
Parameters
| Type | Name | Description |
|---|---|---|
| ScyllaConfiguration | configuration | The configuration asset to apply file-based overrides to. Must not be |
Returns
| Type | Description |
|---|---|
| int | The number of individual property values successfully applied from the merged config file,
or |
Remarks
The layered resolution order is:
- User documents config (highest priority) - located via GetUserDocumentsConfigPath(string). This is the file users edit to personalise settings on their own machine without touching the shipped application folder.
- App folder config (lower priority) - located via GetAppFolderConfigPath(string). This is the file shipped alongside the application executable, used for deployment or server-side configuration that applies to all users on the machine.
When both files exist, they are merged via Merge(ConfigFile, ConfigFile) with the user documents values winning any key conflicts. Only keys present in the config files are overridden; configuration asset fields with no corresponding file key retain their ScriptableObject-assigned defaults.
CreateConfigFileIfNeeded(ScyllaConfiguration)
Creates a config file with default values for the given configuration if all conditions are met. Config file creation is intentionally independent of the override-reading gate (IsEnabled); only the creation gate (CreateEnabled) and per-config flags are checked. This allows config files to be seeded for the user even when override reading is disabled in the current build type.
Declaration
public static void CreateConfigFileIfNeeded(ScyllaConfiguration configuration)
Parameters
| Type | Name | Description |
|---|---|---|
| ScyllaConfiguration | configuration | The configuration asset to export. Must not be |
Remarks
Three gates must all be satisfied before any file I/O is attempted:
-
CreateEnabled must be
true(global creation gate, driven by CreateConfigFiles). -
IsConfigFileEnabledForCurrentBuild() must
return
true(per-config build-type gate). -
CreateConfigFile must be
true(per-config opt-in gate).
Additionally, the config file must not already exist at the user documents path (determined via GetUserDocumentsConfigPath(string)). Existing files are never overwritten, so user edits are always preserved.
The exported file captures the effective runtime values at the time of the call. To snapshot values after all file-based overrides have been resolved, call ApplyOverrides(ScyllaConfiguration) before calling this method.
CreateDefaultConfigFileIfNeeded<T>()
Creates a config file with default values for a configuration type when no config asset exists.
Creates a temporary UnityEngine.ScriptableObject instance of type T,
resets it to its canonical defaults, runs it through CreateConfigFileIfNeeded(ScyllaConfiguration),
and immediately destroys the temporary instance using DestroyImmediate(Object, bool).
Only requires CreateEnabled to be true (independent of
IsEnabled); all other gates are evaluated inside
CreateConfigFileIfNeeded(ScyllaConfiguration).
Declaration
public static void CreateDefaultConfigFileIfNeeded<T>() where T : ScyllaConfiguration
Type Parameters
| Name | Description |
|---|---|
| T | The concrete ScyllaConfiguration subtype for which to generate a default config file. Must be a non-abstract type instantiable via UnityEngine.ScriptableObject.CreateInstance<T>(). |
Remarks
Use this overload when a module or the bootstrap has no config asset assigned in the Inspector, but you still want a seed file written to the user documents path so that users have a starting point to customise.
ResetToDefaults() is called on the temporary instance before exporting it. This is necessary because UnityEngine.ScriptableObject.CreateInstance<T>() does not invoke field initializers for values derived from presets or other runtime sources (e.g. color schemes loaded from named palette assets). Without the reset step, the exported file would contain zero or null values for those fields instead of the intended design defaults.
Initialize(ScyllaCoreConfiguration)
Initializes the config file manager from the core configuration.
Resolves the global enable state based on the current build type
(debug vs production) and the global auto-creation switch, populating
IsEnabled and CreateEnabled accordingly.
If coreConfig is null, both flags are set to
false and the system remains inactive for the current session.
Declaration
public static void Initialize(ScyllaCoreConfiguration coreConfig)
Parameters
| Type | Name | Description |
|---|---|---|
| ScyllaCoreConfiguration | coreConfig | The core configuration asset whose build-type flags determine whether the config file system
is active for the current build. May be |
Remarks
This method is called by ScyllaBootstrap during framework startup before any module
configurations are applied. It must be called once per domain load. Because
Reset() is decorated with
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)],
Unity invokes it automatically on every domain reload (including entering Play Mode in the
Editor), ensuring both flags start at false until Initialize is called again
by the bootstrap. This means the system is always in a clean, disabled state when no
bootstrap has run yet in the current domain.
Reset()
Resets the config file manager to its default state by setting both
IsEnabled and CreateEnabled to false.
Called automatically by Unity on every domain reload (including entering Play Mode
in the Editor) before any other initialization code runs, preventing stale static
state from a previous session from leaking into the new one.
Also callable directly in unit tests to establish a known baseline before exercising
config file logic without a full bootstrap.
Declaration
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
public static void Reset()
Remarks
The [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
attribute causes Unity to invoke this method at the very beginning of the subsystem
registration phase - the earliest available hook in the Unity initialization sequence.
This guarantees that static state is always cleared before Initialize(ScyllaCoreConfiguration) is
called by the bootstrap, even if the previous Play Mode session ended with the system enabled.