aers / FFXIVClientStructs
Resources for reverse-engineering the FFXIV client's native classes.
View on GitHubAI Architecture Analysis
This repository is indexed by RepoMind. By analyzing aers/FFXIVClientStructs in our AI interface, you can instantly generate complete architecture diagrams, visualize control flows, and perform automated security audits across the entire codebase.
Our Agentic Context Augmented Generation (Agentic CAG) engine loads full source files into context on-demand, avoiding the fragmentation of traditional RAG systems. Ask questions about the architecture, dependencies, or specific features to see it in action.
Repository Overview (README excerpt)
Crawler viewFFXIVClientStructs ================== This library encapsulates community efforts to reverse engineer the object layout of native classes in the game Final Fantasy XIV and provide tools to assist in interop with native objects and functions in the running game. The library is written in C# as the main third party plug-in loader, Dalamud, is also written in C#. Interacting with native game code is fundamentally unsafe and the library makes no attempt to prevent the user from shooting themselves in the foot. There is no type marshalling and all types are represented as explicit layout unmanaged structs that map 1:1 in memory with the game's objects. Since the game is written in C++, pointers are everywhere and you will likely need unsafe blocks when doing much of anything. We make extensive use of C# Source Generators to reduce the boilerplate necessary to call native functions. Rather than marshalled delegates, all functions are represented by function pointers resolved by the library from signatures and wrapped in a null safety check. From the user standpoint, calling these functions is as simple as calling a native C# method. Reverse Engineering Rename Database A database and script(s) are maintained in the ida folder which can be used to import a large number of location names to IDA or Ghidra. This database is updated with every patch, although keep in mind this is volunteer work and some patches require more effort than others. There is more info in the readme in the folder itself. Credits This project would not be possible without significant work from many members of the FFXIV RE/Dalamud communities. Project Maintainers • aers • pohky • Caraxi • daemitus • wolfcomp • Haselnussbomber Contributors Too many to list. For Library Users Signature Resolution The library uses signatures to resolve locations at runtime. In order to populate locations from signatures to call functions, you need to initialize the library once at load. However, if you're writing a Dalamud plugin using the built-in copy of the library, you can just reference it in the project and Dalamud will have already initialized it for you. The following code is only necessary if you are not using Dalamud or using a local copy of the library in your plugin. Setup has three optional arguments. The first allows you to pass a pointer to a copy of the FFXIV module somewhere in memory. The primary use of this is to allow the resolver to scan a fresh copy of the binary rather than one modified by active hooks from other sources. You can access Dalamud's module copy via the service's argument if you are trying to resolve your local copy within a Dalamud plugin. the second argument takes a string for the version of which is the key for what cache index to use from the file supplied in the third argument. The third argument takes a path to a JSON file as a C# object. This will cause the resolver to use that JSON file as a signature cache, speeding up resolving on future runs. The resolver is relatively fast, but using the cache is near-instant, so using it is your choice. Library Design Native classes are represented as fixed-offset structs. If you have a pointer or reference to one of these structs, you can access native memory the same way you'd access a field on any C# class or struct. Native function calls are wrapped in methods on these structs and can be called the same way you would call a C# method. Source generation creates wrappers that automatically pass the struct's pointer to C++ member and virtual functions making them mostly-seamless. Many native singletons can be accessed via static instance methods, which should get you started accessing native objects. Caveats C# is not C++. There are some constructs that aren't possible to represent properly as well and some rough edges around the interop process. String types The game has a string class, , which is roughly analogous to and is used in most places where strings are stored. However, it also uses C-style strings, aka pointers to null terminated character (UTF-8-encoded) arrays. C# strings are UTF-16 and pointers to them cannot be passed directly to functions requiring these C string pointers. Also, the C# type is 16-bit and cannot be used to represent the arguments. All functions that take C string arguments therefore have as the argument type. The library generates overloads for these methods that take and perform the UTF-16 -> UTF-8 byte array conversion for you. Be aware this conversion is happening and consider storing your own copies of UTF-8 converted strings if you are noticing a performance hit from the string conversions. This is unlikely, but could happen. There are also generated overloads that take arguments. This is primarily to allow the use of UTF-8 string literals as function arguments. No functions will ever return a C# type in order to avoid making assumptions about the memory lifetime of pointers returned by the game. Fixed-Size Arrays C# fixed size arrays are not the same as C++ fixed size arrays. This means that we have to use another feature called Inline Arrays. This feature allows us to create structs that represents the array type with a set size. This is done through generators which means that the array is only done after the Roslyn analyser has run after file modification. These will be accessible through when used. Generic Pointers C# doesn't allow pointer types in generics. This makes it impossible to represent constructs like . The library uses a wrapper type to get around this. will implicitly convert to but you might need to do explicit conversions when working with collections of pointers. STD collections There are wrappers for accessing data from a handful of C++ std library collections used by the game such as vector and map. For Library Developers FFXIV is built with the MSVC 64-bit compiler and any mention of the way the compiler works applies to that compiler. Signatures All signatures in the…