Skip to main content
Hero Light

Welcome to FFXIVClientStructs

FFXIVClientStructs is a comprehensive C# library that encapsulates community efforts to reverse engineer the object layout of native classes in Final Fantasy XIV. It provides powerful tools to assist in interop with native objects and functions in the running game.
This library is designed to work seamlessly with Dalamud, the primary third-party plugin loader for FFXIV.

Quick Start

Get started with FFXIVClientStructs in minutes

Installation

Add the library to your C# project

Reverse Engineering Database

IDA/Ghidra scripts for reverse engineering

GitHub Repository

View source code and contribute

Key Features

Type-Safe Native Interop

FFXIVClientStructs uses explicit layout unmanaged structs that map 1:1 in memory with the game’s objects. All types are represented with StructLayout(LayoutKind.Explicit) for precise memory alignment.
Framework.cs
namespace FFXIVClientStructs.FFXIV.Client.System.Framework;

[GenerateInterop]
[StructLayout(LayoutKind.Explicit, Size = 0x35D8)]
public unsafe partial struct Framework {
    [StaticAddress("48 8B 1D ?? ?? ?? ?? 8B 7C 24", 3, isPointer: true)]
    public static partial Framework* Instance();

    [FieldOffset(0x16C0)] public float FrameDeltaTime;
    [FieldOffset(0x16D0)] public uint FrameCounter;
    [FieldOffset(0x2B38)] public ExcelModuleInterface* ExcelModuleInterface;
}

Source Generator-Powered Function Calls

No marshalling overhead - all native functions are called via C# function pointers with automatic null safety checks. The library uses C# Source Generators to eliminate boilerplate.
Character.cs
namespace FFXIVClientStructs.FFXIV.Client.Game.Character;

[GenerateInterop(isInherited: true)]
[StructLayout(LayoutKind.Explicit, Size = 0x2370)]
public unsafe partial struct Character {
    // Virtual function call - resolved via vtable
    [VirtualFunction(78)]
    public partial StatusManager* GetStatusManager();

    // Member function call - resolved via signature
    [MemberFunction("E8 ?? ?? ?? ?? 4C 8B E0 48 8B 4F")]
    public partial GameObjectId GetTargetId();
}

Singleton Access

Many native singletons can be accessed via static instance methods, providing easy entry points to the game’s systems.
Example Usage
using FFXIVClientStructs.FFXIV.Client.System.Framework;
using FFXIVClientStructs.FFXIV.Client.UI;

// Access the Framework singleton
var framework = Framework.Instance();
if (framework != null) {
    var deltaTime = framework->FrameDeltaTime;
    var frameCount = framework->FrameCounter;
}

// Access the UI Module
var uiModule = UIModule.Instance();
if (uiModule != null) {
    var shouldExit = uiModule->ShouldExitGame;
}

C++ STD Library Support

Wrappers for accessing data from C++ standard library collections used by the game, including std::vector, std::map, std::set, and more.

String Handling

The game uses Utf8String (similar to std::string) and C-style null-terminated UTF-8 strings. The library provides automatic string conversion overloads for convenience.
Interacting with native game code is fundamentally unsafe. The library makes no attempt to prevent undefined behavior. Use with caution and always validate pointers before dereferencing.

How It Works

FFXIVClientStructs represents native classes as fixed-offset structs. When you have a pointer or reference to one of these structs, you can:
  1. Access native memory the same way you’d access a field on any C# class or struct
  2. Call native functions as if they were regular C# methods
  3. Navigate object hierarchies through pointer fields
Source generation creates wrappers that automatically:
  • Pass the struct’s pointer to C++ member and virtual functions
  • Resolve function addresses from signatures at runtime
  • Perform null safety checks
  • Handle UTF-8 string conversions

Real-World Example

Complete Example
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Character;

// Get a character's status information
unsafe {
    Character* player = GetPlayerCharacter(); // Your method to get the player
    if (player != null) {
        // Call a virtual function to get the status manager
        var statusManager = player->GetStatusManager();
        if (statusManager != null) {
            // Call member functions to query status
            if (statusManager->HasStatus(1234)) {
                var statusIndex = statusManager->GetStatusIndex(1234);
                var remainingTime = statusManager->GetRemainingTime(statusIndex);
            }
        }
    }
}

Community & Credits

This project is maintained by the FFXIV reverse engineering and Dalamud communities, with contributions from numerous developers.

Project Maintainers

Next: Installation

Learn how to add FFXIVClientStructs to your project

Quick Start Guide

Start using the library in your code

Build docs developers (and LLMs) love