Runtime module loading system for modular architecture.
The Modules system provides automatic initialization of framework components and game systems through a reflection-based module loading mechanism. It enables a plugin-style architecture where modules can be automatically discovered and initialized at runtime.
Abstract base class for all modules:
[Preserve] // Prevent code stripping
public class MyGameModule : RuntimeModule
{
public override void Initialize(ModuleConfig config)
{
// Module initialization logic
Debug.Log("MyGameModule initialized");
// Initialize systems, register services, etc.
InitializeGameSystems();
}
private void InitializeGameSystems()
{
// Setup game-specific systems
}
}Static class that handles automatic module discovery and initialization:
public static class ModuleLoader
{
// Control module loading
public static bool Enable { get; set; } = true;
// Automatically called before scene load
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
public static void InitializeModules();
}Configuration system for modules:
[ConfigPath("Chris.Modules")]
public class ModuleConfig : Config<ModuleConfig>
{
// Module-specific configuration data
// Automatically saved after module initialization
}The ModuleLoader automatically discovers and initializes modules through reflection:
- Assembly Scanning - Scans all assemblies that reference the Chris framework
- Type Discovery - Finds all classes inheriting from
RuntimeModule - Instantiation - Creates instances of discovered module types
- Initialization - Calls
Initialize()with sharedModuleConfig - Configuration Save - Persists any configuration changes
Modules are automatically initialized at RuntimeInitializeLoadType.BeforeSceneLoad:
// This happens automatically - no manual setup required
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
public static void InitializeModules()
{
// Framework handles this automatically
}You can disable automatic loading if needed:
// Disable before BeforeSceneLoad phase
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
public static void DisableModuleLoading()
{
ModuleLoader.Enable = false;
}
// Then manually initialize later
public void ManuallyInitializeModules()
{
ModuleLoader.InitializeModules();
}Handles configuration system initialization:
[Preserve]
public class ConfigsModule : RuntimeModule
{
public override void Initialize(ModuleConfig config)
{
// Extracts streaming configs to persistent storage
// Sets up config directories and serializers
}
}[Preserve]
public class AudioModule : RuntimeModule
{
public override void Initialize(ModuleConfig config)
{
// Initialize audio systems
SetupAudioMixer();
RegisterAudioEvents();
LoadAudioSettings();
}
private void SetupAudioMixer()
{
// Audio system setup
}
private void RegisterAudioEvents()
{
// Event system integration
}
private void LoadAudioSettings()
{
// Configuration loading
}
}The module loader intelligently filters assemblies:
- Includes: Assemblies that reference Chris framework
- Excludes: Editor assemblies (in builds)
- Includes: Chris framework assembly itself
// This filtering happens automatically
var validAssemblies = AppDomain.CurrentDomain.GetAssemblies()
.Where(assembly =>
{
// Skip editor assemblies in builds
if (assembly.GetName().Name.Contains(".Editor"))
return false;
// Include assemblies referencing Chris
return assembly.GetReferencedAssemblies()
.Any(name => name.Name == nameof(Chris))
|| assembly.GetName().Name == nameof(Chris);
});