This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.
Community mod for Star Trek Fleet Command (STFC) — a desktop game that runs via Unity/IL2CPP. The mod hooks into the game's IL2CPP runtime to add QoL features (UI scaling, zoom controls, hotkeys, chat improvements, cargo viewers, data sync, etc.). Supports Windows (DLL proxy injection) and macOS (dylib injection).
This project uses XMake (not CMake). All build configuration is in xmake.lua files. Language standard is C++23 with multi-threaded static runtime (/MT).
# Configure and build (command line)
xmake # Build default target
xmake f -p macosx -a arm64 -m debug --target_minver=13.5 # Configure for macOS ARM debug
xmake f -p windows -m release # Configure for Windows release
# Generate Visual Studio solution
xmake project -k vsxmake -m "debug,release"
# Clean
xmake clean -a
# macOS dev script (build, run, debug, crashlogs)
scripts/mac-build-test-debug.sh [build|run|debug|crashlogs] [-m debug|release|releasedbg]debug— developmentrelease— productionreleasedbg— release with debug info, enables_MODDBGdefine
Delete the build/ folder to reset. Also delete .vs/ for a full Visual Studio reset.
- Keep changes scoped. Do not stage unrelated dirty files or generated artifacts unless the user explicitly asks.
- Before finishing C++ or patch work, run
git diff --checkand the narrowest relevant xmake build. - For macOS core mod changes, use
xmake f -p macosx -a arm64 -m debug --target_minver=13.5 -y && xmake -y mods. - Review the final diff for risky hooks, platform guards, config default mismatches, and missing example config updates.
- If a subtree such as
macos-launcher/needs specialized guidance, prefer a nestedAGENTS.mdnear that code instead of overloading this root file.
| Target | Type | Platform | Description |
|---|---|---|---|
mods |
static lib | all | Core mod logic — patches, config, IL2CPP bindings |
stfc-community-mod (win-proxy-dll) |
shared DLL | Windows | Proxy DLL (version.dll) that loads into the game process |
stfc-community-mod (macos-dylib) |
shared dylib | macOS | Injected dylib equivalent |
stfc-community-mod-loader |
binary | macOS | Loader that injects the dylib into the game |
macOSLauncher |
Xcode app | macOS | Swift GUI launcher app |
mods/src/— Core mod code (the main codebase)config.h/.cc— SingletonConfigclass, loads TOML settings, controls which patches are enabledpatches/patches.cc— Entry point: hooksil2cpp_init, then conditionally installs each patchpatches/parts/— Individual patch implementations (zoom, hotkeys, chat, UI scale, sync, etc.)patches/key.h,mapkey.h,modifierkey.h— Keyboard input mapping systemprime/— Header-only IL2CPP type definitions mirroring the game's C# classesprime/proto/— Protobuf definitions for game data syncil2cpp/— IL2CPP helper functions for resolving methods, classes, and icalls at runtime
win-proxy-dll/src/— Windows DLL proxy entry pointmacos-dylib/src/— macOS dylib entry pointmacos-loader/src/— macOS loader (finds game, injects dylib)macos-launcher/— Swift macOS GUI appthird_party/libil2cpp/— IL2CPP SDK headersxmake-packages/— Custom xmake package definitions (e.g.,spud)
Hooking pattern — All game function hooks use spud (function detour library) via SPUD_STATIC_DETOUR. Each hook function takes auto original as the first parameter to call through to the original:
void SomeFunction_Hook(auto original, SomeClass* _this, ...) {
// custom logic
original(_this, ...);
}macOS does not tolerate repeated hooks of the same function. If multiple features need to intercept the same game method, consolidate the behavior behind one detour or add platform guards instead of installing overlapping hooks.
Do not over-focus on hidden IL2CPP MethodInfo* parameters during drift repair; match the game-visible signature from dump.cs unless there is concrete runtime evidence that the hidden parameter is the issue.
Before adding a detour to a small IL2CPP wrapper or thunk, verify its native method extent against SPUD's architecture-specific overwrite size on every supported architecture for the exact client build. A successful platform build does not validate hook fit; prefer a substantive downstream method when exact per-architecture extent is unavailable.
IL2CPP class resolution — Game classes are resolved at runtime using helpers:
static auto class_helper = il2cpp_get_class_helper("Assembly.Name", "Namespace", "ClassName");
static auto method = class_helper.GetMethodInfo("MethodName");Adding a new patch — Create a .cc file in mods/src/patches/parts/, write an InstallXxxHooks() function, declare it in patches.cc, add a bool installXxx to Config, and register in the patches[] array in patches.cc. Patch toggles are only read from TOML in _MODDBG builds, so update both the _MODDBG config parsing path and the non-_MODDBG release defaults in config.cc.
Config — User settings are in TOML files. The Config singleton (Config::Get()) is loaded once during il2cpp_init_hook. Add new settings to config.h, add defaults in defaultconfig.h, and load them in config.cc. For user-facing settings, update every localized example (example_community_patch_settings_en.toml, example_community_patch_settings_de.toml, example_community_patch_settings_fr.toml, and example_community_patch_settings_nl.toml) unless the setting is intentionally internal. The unsuffixed example_community_patch_settings.toml is only a pointer to these localized examples.
spud— Function hooking/detour libraryeastl— EA's STL replacementspdlog— Loggingtoml++— TOML config parsingnlohmann_json— JSON handlingcpr/libcurl— HTTP requests (for data sync)protobuf— Protocol buffers (game data)simdutf— UTF encodinglibil2cpp— Local package pointing tothird_party/libil2cpp
- Uses
.clang-format— 2-space indent, 120 column limit, Linux brace style, aligned assignments/declarations - Version is defined in
mods/src/version.h(VERSION_MAJOR/MINOR/REVISION/PATCH) - Prefer narrow platform guards such as
#if _WIN32,#if !_WIN32, and#if __APPLE__; do not assume every non-Windows path is macOS. - Logging via
spdlog::info(),spdlog::debug(), etc.
main— stable releasesdev— active development (PR target)