Architecture Overview
Dalamud’s architecture consists of multiple components working together to provide a stable plugin development environment:Components
Dalamud is composed of several distinct components, each serving a specific purpose:Dalamud.Injector.Boot (C++)
Dalamud.Injector.Boot (C++)
The first component in the boot chain. Written in C++, this component:
- Loads the .NET Core runtime via
hostfxr - Initializes the CoreCLR hosting environment
- Kicks off
Dalamud.Injectorin managed code - Handles low-level process initialization
Dalamud.Injector (C#)
Dalamud.Injector (C#)
A managed C# component that performs DLL injection:
- Injects
Dalamud.Bootinto the target FFXIV process - Manages the injection timing and methodology
- Handles error cases during injection
- Coordinates with XIVLauncher for process management
Dalamud.Boot (C++)
Dalamud.Boot (C++)
A native DLL loaded into the game process that:
- Loads the .NET Core runtime into the active process
- Bootstraps the managed Dalamud core
- Rewrites the target process entrypoint when necessary
- Sets up exception handling and crash reporting
- Initializes MinHook for function hooking
Dalamud Core (C#)
Dalamud Core (C#)
The main managed framework providing:
- Core API and game bindings
- Plugin loading and management infrastructure
- Service container and dependency injection
- Event system and game state tracking
- UI framework integration (ImGui)
Dalamud.CorePlugin (C#)
Dalamud.CorePlugin (C#)
A special testbed plugin that:
- Has access to Dalamud internals
- Used to prototype new framework features
- Tests plugin API changes before public release
- Validates core functionality
Boot Pipeline
The Dalamud boot process follows a carefully orchestrated pipeline to ensure safe initialization:XIVLauncher Starts
XIVLauncher manages the game launch and determines when to inject Dalamud based on user configuration.
Dalamud.Injector.Boot Initializes
The boot component loads the .NET Core runtime and starts the managed injector:
Dalamud.Injector Performs Injection
The injector injects
Dalamud.Boot.dll into the FFXIV process using platform-appropriate injection techniques.Dalamud.Boot Loads Runtime
Inside the game process,
Dalamud.Boot loads .NET Core and calls into EntryPoint.Initialize():EntryPoint Initializes
The managed entry point sets up logging, configuration, and creates the main Dalamud instance:
Services Initialize
The Service Manager initializes all framework services in dependency order. See Dependency Injection for details.
Game Thread Resumes
Once blocking services are ready, Dalamud signals the game’s main thread to continue:
Plugins Load
The Plugin Manager loads plugins based on their
LoadRequiredState and LoadSync settings. See Plugin Lifecycle for details.Thread Model
Dalamud operates across multiple threads to ensure safe interaction with the game:Main Game Thread
The game’s primary rendering and logic thread. Plugins should avoid blocking this thread to prevent frame drops.
Framework Thread
Dalamud’s framework update thread, synchronized with the game’s update tick. Most plugin logic runs here.
Service Initialization Threads
Background threads used during startup to initialize services without blocking the game.
Plugin Loader Threads
Separate threads for loading plugins asynchronously, preventing startup delays.
Always use
Framework.RunOnFrameworkThread() or Framework.RunOnTick() when you need to execute code that interacts with game state from another thread.Memory Architecture
Dalamud uses several techniques to safely interact with game memory:Signature Scanning
Dalamud locates game functions and data structures using byte pattern signatures:Function Hooking
Dalamud uses Reloaded.Hooks for type-safe function hooking:ClientStructs Integration
Dalamud integrates FFXIVClientStructs for type-safe access to game structures:Isolation and Safety
Dalamud provides several layers of isolation to ensure stability:Assembly Load Contexts
Each plugin loads in its own
AssemblyLoadContext, preventing assembly conflicts:Version Management
Dalamud uses API levels to handle breaking changes:As of Dalamud 9.x and later, the API level always matches the major version number. Only plugins built for the current API level will load.
Next Steps
Plugin Lifecycle
Learn how plugins are loaded, initialized, and unloaded
Dependency Injection
Understand Dalamud’s IoC container and service system
Service Locator
Learn how to access Dalamud services in your plugin
Building Dalamud
Compile Dalamud from source