Skip to content

Dependencies#

The dependency system lets plugins share code through library plugins. A library exports functions that other plugins can call at runtime.

Overview#

There are three roles:

  1. Library plugin — a WASM module that exports utility functions (e.g., math_helpers_lib.cpp)
  2. Import header — a .hpp that declares the library's functions with WASM import attributes (e.g., math_helpers.hpp)
  3. Dependent plugin — a normal plugin that includes the import header and calls the library functions (e.g., enemy_esp_with_deps.cpp)

Step 1: Write the Library Plugin#

A library plugin exports extern "C" functions and uses XENON_LIBRARY_INFO instead of XENON_PLUGIN_INFO:

// math_helpers_lib.cpp
#include <xenon/SDK.hpp>

XENON_LIBRARY_INFO(
    "math_helpers_lib",   // internal name
    "Author",             // author
    "Shared math utils",  // description
    "1.0",                // version
    "math_helpers"        // service name
)

extern "C" float lerp(float a, float b, float t)
{
    return a + (b - a) * t;
}

extern "C" float clamp_f(float value, float min_val, float max_val)
{
    if (value < min_val) return min_val;
    if (value > max_val) return max_val;
    return value;
}

extern "C" float remap(float value, float from_min, float from_max,
                        float to_min, float to_max)
{
    float t = (value - from_min) / (from_max - from_min);
    return to_min + (to_max - to_min) * t;
}

Build with the --library flag:

build.bat --library examples\math_helpers_lib.cpp

This uses --export-all so every extern "C" function becomes a WASM export.

Step 2: Write the Import Header#

The import header goes in include/xenon/libs/ and declares each library function with WASM import attributes:

// include/xenon/libs/math_helpers.hpp
#pragma once

extern "C"
{
    __attribute__((import_module("lib_math_helpers"), import_name("lerp")))
    float lib_math_helpers_lerp(float a, float b, float t);

    __attribute__((import_module("lib_math_helpers"), import_name("clamp_f")))
    float lib_math_helpers_clamp_f(float value, float min_val, float max_val);

    __attribute__((import_module("lib_math_helpers"), import_name("remap")))
    float lib_math_helpers_remap(float value, float from_min, float from_max,
                                  float to_min, float to_max);
}

// Convenient C++ wrappers
namespace xenon::math
{
    inline float Lerp(float a, float b, float t)
    {
        return lib_math_helpers_lerp(a, b, t);
    }

    inline float Clamp(float value, float min_val, float max_val)
    {
        return lib_math_helpers_clamp_f(value, min_val, max_val);
    }

    inline float Remap(float value, float from_min, float from_max,
                        float to_min, float to_max)
    {
        return lib_math_helpers_remap(value, from_min, from_max, to_min, to_max);
    }
}

Key details:

  • import_module is "lib_" + the service name: "lib_math_helpers"
  • import_name matches the exported function name: "lerp", "clamp_f", etc.
  • The raw import functions have prefixed names (lib_math_helpers_lerp) to avoid collisions
  • The xenon::math namespace wrappers provide a clean C++ API

Step 3: Write the Dependent Plugin#

Include the import header and declare the dependency:

// enemy_esp_with_deps.cpp
#include <xenon/SDK.hpp>
#include <xenon/libs/math_helpers.hpp>

using namespace xenon;

XENON_PLUGIN_INFO_DEPS(
    "my_plugin",
    "My Plugin",
    "Author",
    "Uses math helpers",
    "1.0",
    0,
    PluginFlags::HasOverlay | PluginFlags::HasMenu,
    "math_helpers\0"    // dependency list
)

Now you can call library functions through the wrappers:

float result = math::Lerp(0.0f, 100.0f, 0.5f);         // 50.0
float clamped = math::Clamp(value, 0.0f, 1.0f);
float remapped = math::Remap(dist, 5.f, 80.f, 8.f, 3.f);

Build normally (no --library flag):

build.bat examples\enemy_esp_with_deps.cpp

What Happens at Runtime#

  1. The host downloads both WASM files and inspects their imports
  2. math_helpers_lib.wasm has only core imports — it's identified as a library
  3. enemy_esp_with_deps.wasm has lib_math_helpers imports — it needs the library
  4. The host topologically sorts plugins so libraries load first
  5. The library loads and the bridge registers its exports (lerp, clamp_f, remap) as native functions under the lib_math_helpers module
  6. The dependent plugin loads and its lib_math_helpers.* imports resolve against the bridge
  7. Calls from the dependent plugin forward through the bridge to the library's WASM instance

Multiple Dependencies#

List multiple service names separated by null bytes:

XENON_PLUGIN_INFO_DEPS(
    "my_plugin", "My Plugin", "Author", "Complex plugin", "1.0",
    0, PluginFlags::HasOverlay | PluginFlags::HasMenu,
    "math_helpers\0ui_widgets\0"    // two dependencies
)

Summary#

File Role Build Command Macro
math_helpers_lib.cpp Library plugin build.bat --library XENON_LIBRARY_INFO
libs/math_helpers.hpp Import header N/A (header only) N/A
enemy_esp_with_deps.cpp Dependent plugin build.bat XENON_PLUGIN_INFO_DEPS

See Also#