# TEngine Modules Initialization Order: Step-by-Step Startup Sequence

> Understand TEngine modules initialization order. Discover the step-by-step startup sequence from RootModule.Awake to ProcedureLaunch for efficient game setup.

- Repository: [ALEX/tengine](https://github.com/alex-rachel/tengine)
- Tags: internals
- Published: 2026-02-24

---

**TEngine initializes its Unity modules through a deterministic chain starting with `RootModule.Awake`, followed by `GameEntry` forcing core service creation, then `ProcedureSetting` launching the FSM-based procedure system, and finally the entrance procedure (`ProcedureLaunch`) initializing localization, audio, and hot-update UI before transitioning to the main game flow.**

The `alex-rachel/tengine` repository implements a strict, predictable initialization order that ensures foundational services exist before higher-level game logic executes. This article breaks down the exact sequence using source references from the TEngine runtime and GameScripts layers.

## The Complete TEngine Startup Sequence

### 1. RootModule.Awake – Framework Foundation

The bootstrap begins in [`RootModule.cs`](https://github.com/alex-rachel/tengine/blob/main/RootModule.cs) at line 16. The `Awake()` method establishes the framework's core infrastructure before any game-specific code runs.

In [`UnityProject/Assets/TEngine/Runtime/Module/RootModule.cs`](https://github.com/alex-rachel/tengine/blob/main/UnityProject/Assets/TEngine/Runtime/Module/RootModule.cs), the initialization covers:

- **Text**, **Log**, and **JSON** helper setup
- Screen DPI and target frame-rate configuration
- Low-memory warning handlers
- Per-frame `GameTime` system activation

This MonoBehaviour lives in the initial scene and executes first, providing the bare-minimum services required by all subsequent modules.

### 2. GameEntry.Awake – Core Service Instantiation

Immediately following the framework bootstrap, [`GameEntry.cs`](https://github.com/alex-rachel/tengine/blob/main/GameEntry.cs) (line 7) forces the eager instantiation of critical services. This prevents null-reference exceptions during the procedure system startup.

```csharp
// UnityProject/Assets/GameScripts/GameEntry.cs
private void Awake()
{
    ModuleSystem.GetModule<IUpdateDriver>();
    ModuleSystem.GetModule<IResourceModule>();
    ModuleSystem.GetModule<IDebuggerModule>();
    ModuleSystem.GetModule<IFsmModule>();
}

```

By calling `ModuleSystem.GetModule<T>()` for **IUpdateDriver**, **IResourceModule**, **IDebuggerModule**, and **IFsmModule**, `GameEntry` ensures these core services exist in memory before the procedure system attempts to register or transition between states.

### 3. ProcedureSetting.StartProcedure – Procedure System Activation

The third phase shifts control to the **Procedure Module** via [`ProcedureSetting.cs`](https://github.com/alex-rachel/tengine/blob/main/ProcedureSetting.cs) (lines 55-102). This asset-driven system loads the procedure list defined in `ProcedureSetting.asset` and initializes the finite state machine.

The `StartProcedure()` method performs four critical actions:

1. Reads the `ProcedureSetting` asset to discover all available procedures
2. Creates instances of every procedure object listed in the asset
3. Identifies the **entrance procedure** (typically `ProcedureLaunch`)
4. Registers the **ProcedureModule** with `IFsmModule` and starts the entrance state

This step transitions the engine from static initialization to dynamic, state-driven execution.

### 4. ProcedureLaunch.OnEnter – Entrance Procedure Execution

With the FSM active, control passes to [`ProcedureLaunch.cs`](https://github.com/alex-rachel/tengine/blob/main/ProcedureLaunch.cs) (lines 23-35), the first concrete procedure state. Its `OnEnter()` method initializes player-facing systems:

```csharp
// UnityProject/Assets/GameScripts/Procedure/ProcedureLaunch.cs
protected override void OnEnter(IFsm<IProcedureManager> procedureOwner)
{
    base.OnEnter(procedureOwner);
    LauncherMgr.Initialize();
    InitLanguageSettings();
    InitSoundSettings();
}

```

**LauncherMgr** sets up the hot-update UI, while the helper methods configure localization and audio:

- `InitLanguageSettings()` (lines 45-80): Loads the current language configuration via `ILocalizationModule`
- `InitSoundSettings()` (lines 83-92): Retrieves `IAudioModule` and applies saved volume/mute preferences

These calls trigger lazy instantiation of their respective modules through `ModuleSystem.GetModule<T>()`, ensuring `IAudioModule` and `ILocalizationModule` exist before the main menu appears.

### 5. Subsequent Procedures – Game Flow Continuation

After one frame, `ProcedureLaunch.OnUpdate()` (lines 37-43) checks a completion flag and transitions to `ProcedureSplash`. The sequence continues according to the flow defined in `ProcedureSetting.asset`:

**ProcedureSplash** → **ProcedureInitPackage** → **ProcedureInitResources** → **ProcedurePreload** → **ProcedureLoadAssembly** → **ProcedureStartGame**

Each procedure pulls required modules on demand. For example, [`ProcedureBase.cs`](https://github.com/alex-rachel/tengine/blob/main/ProcedureBase.cs) maintains a cached reference to `IResourceModule`, ensuring the resource system is available for all derived procedures handling asset loading.

## Module Lazy Instantiation Pattern

While the startup sequence is rigid, individual modules follow a **lazy instantiation** pattern. When `ProcedureLaunch` calls `GetModule<IAudioModule>()`, the `ModuleSystem` creates the module instance if it does not already exist.

This design means:
- **IResourceModule** instantiates during `GameEntry.Awake` (eager)
- **IAudioModule** instantiates during `ProcedureLaunch.InitSoundSettings` (lazy)
- **IObjectPoolModule** may instantiate later during `ProcedurePreload` (on-demand)

The deterministic startup order guarantees that foundational services (UpdateDriver, FSM, Resource) exist before any procedure can request optional modules.

## Key Source Files and Locations

- **[`RootModule.cs`](https://github.com/alex-rachel/tengine/blob/main/RootModule.cs)** ([`UnityProject/Assets/TEngine/Runtime/Module/RootModule.cs`](https://github.com/alex-rachel/tengine/blob/main/UnityProject/Assets/TEngine/Runtime/Module/RootModule.cs)): Core bootstrap MonoBehaviour handling frame-rate, memory warnings, and `GameTime`
- **[`GameEntry.cs`](https://github.com/alex-rachel/tengine/blob/main/GameEntry.cs)** ([`UnityProject/Assets/GameScripts/GameEntry.cs`](https://github.com/alex-rachel/tengine/blob/main/UnityProject/Assets/GameScripts/GameEntry.cs)): Forces eager creation of `IUpdateDriver`, `IResourceModule`, `IDebuggerModule`, and `IFsmModule`
- **[`ProcedureSetting.cs`](https://github.com/alex-rachel/tengine/blob/main/ProcedureSetting.cs)** ([`UnityProject/Assets/TEngine/Runtime/Module/ProcedureModule/ProcedureSetting.cs`](https://github.com/alex-rachel/tengine/blob/main/UnityProject/Assets/TEngine/Runtime/Module/ProcedureModule/ProcedureSetting.cs)): Loads procedure list, registers `IProcedureModule`, and starts the entrance procedure
- **[`ProcedureLaunch.cs`](https://github.com/alex-rachel/tengine/blob/main/ProcedureLaunch.cs)** ([`UnityProject/Assets/GameScripts/Procedure/ProcedureLaunch.cs`](https://github.com/alex-rachel/tengine/blob/main/UnityProject/Assets/GameScripts/Procedure/ProcedureLaunch.cs)): Entrance procedure implementing language, audio, and UI initialization
- **[`ProcedureBase.cs`](https://github.com/alex-rachel/tengine/blob/main/ProcedureBase.cs)** ([`UnityProject/Assets/GameScripts/Procedure/ProcedureBase.cs`](https://github.com/alex-rachel/tengine/blob/main/UnityProject/Assets/GameScripts/Procedure/ProcedureBase.cs)): Base class holding `IResourceModule` reference for all procedures

## Summary

- **RootModule.Awake** establishes the framework foundation (logging, time, screen settings)
- **GameEntry.Awake** eagerly instantiates core services (UpdateDriver, Resource, Debugger, FSM)
- **ProcedureSetting.StartProcedure** activates the procedure system and launches the entrance state
- **ProcedureLaunch.OnEnter** initializes localization, audio, and hot-update UI through lazy module retrieval
- The procedure chain continues through Splash, InitPackage, InitResources, Preload, LoadAssembly, and StartGame
- Modules instantiate on first use via `ModuleSystem.GetModule<T>()`, ensuring dependencies exist before access

## Frequently Asked Questions

### What triggers the first procedure in TEngine?

The `ProcedureSetting.StartProcedure()` method triggers the first procedure. After `GameEntry` ensures core services exist, `ProcedureSetting` reads the `ProcedureSetting.asset` file to identify the **entrance procedure** (by default `ProcedureLaunch`), registers the `ProcedureModule` with the `IFsmModule`, and calls `StartProcedure()` to enter the initial state.

### How does TEngine handle module dependencies during startup?

TEngine uses a hybrid eager/lazy approach. Critical modules like `IResourceModule` and `IFsmModule` are eagerly created in `GameEntry.Awake` to prevent race conditions. Optional modules like `IAudioModule` or `ILocalizationModule` are lazily instantiated via `ModuleSystem.GetModule<T>()` when a procedure first requests them, ensuring the dependency exists exactly when needed.

### Where is the entrance procedure defined in TEngine?

The entrance procedure is defined in the **`ProcedureSetting.asset`** file located at `UnityProject/Assets/TEngine/Settings/ProcedureSetting.asset`. The [`ProcedureSetting.cs`](https://github.com/alex-rachel/tengine/blob/main/ProcedureSetting.cs) script parses this asset to find the procedure marked as the entrance (typically `ProcedureLaunch`) and passes it to the `IFsmModule` to begin execution.

### Can the initialization order be customized?

You can customize the procedure flow by editing `ProcedureSetting.asset` to reorder or replace procedures in the chain (e.g., inserting a custom `ProcedureCheckUpdate` between `ProcedureSplash` and `ProcedureInitPackage`). However, the core engine initialization sequence—**RootModule** → **GameEntry** → **ProcedureSetting**—is hardcoded in [`RootModule.cs`](https://github.com/alex-rachel/tengine/blob/main/RootModule.cs) and [`GameEntry.cs`](https://github.com/alex-rachel/tengine/blob/main/GameEntry.cs) to ensure framework stability.