Example: ESP with Dependencies#
A walkthrough of examples/enemy_esp_with_deps.cpp — an ESP plugin that depends on the math helpers library.
Full Source#
#include <xenon/SDK.hpp>
#include <xenon/libs/math_helpers.hpp>
using namespace xenon;
// ── Configuration ────────────────────────────────────────
static bool g_showHealthBars = true;
static bool g_showDistance = true;
static bool g_showSnaplines = false;
static bool g_visibleOnly = false;
static float g_maxDistance = 100.f;
static float g_pulseTimer = 0.f;
// ── Plugin Info (with dependency) ────────────────────────
XENON_PLUGIN_INFO_DEPS(
"VisualsWithDeps",
"Enemy ESP (with deps)",
"Xenon",
"ESP using math_helpers library",
"1.0",
0,
PluginFlags::HasOverlay | PluginFlags::HasMenu,
"math_helpers\0"
)
// ── Load / Unload ────────────────────────────────────────
extern "C" void on_load()
{
g_showHealthBars = Config::GetBool("showHealthBars", true);
g_showDistance = Config::GetBool("showDistance", true);
g_showSnaplines = Config::GetBool("showSnaplines", false);
g_visibleOnly = Config::GetBool("visibleOnly", false);
g_maxDistance = Config::GetFloat("maxDistance", 100.f);
Log("Enemy ESP (with deps) loaded!");
}
extern "C" void on_unload()
{
Config::SetBool("showHealthBars", g_showHealthBars);
Config::SetBool("showDistance", g_showDistance);
Config::SetBool("showSnaplines", g_showSnaplines);
Config::SetBool("visibleOnly", g_visibleOnly);
Config::SetFloat("maxDistance", g_maxDistance);
Config::Save();
}
// ── Frame Logic ──────────────────────────────────────────
extern "C" void on_frame(float deltaTime)
{
g_pulseTimer = g_pulseTimer + deltaTime;
if (g_pulseTimer > 2.0f)
g_pulseTimer = g_pulseTimer - 2.0f;
}
// ── Render ───────────────────────────────────────────────
extern "C" void on_render()
{
Vector2 screenCenter = ScreenCenter();
// Pulse alpha using library remap
float pulseT = g_pulseTimer;
if (pulseT > 1.0f) pulseT = 2.0f - pulseT; // triangle wave 0→1→0
int pulseAlpha = static_cast<int>(
math::Remap(pulseT, 0.0f, 1.0f, 100.0f, 255.0f));
for (Entity enemy : Players())
{
if (enemy.IsLocal()) continue;
if (!enemy.IsAlive()) continue;
if (g_visibleOnly && !enemy.IsVisible()) continue;
Vector3 rootPos = enemy.GetPosition();
Vector3 headWorld = enemy.GetBonePos(Bone::Head);
if (headWorld.x == 0.f && headWorld.y == 0.f && headWorld.z == 0.f)
headWorld = Vector3(rootPos.x, rootPos.y + 1.8f, rootPos.z);
Vector2 headScreen;
if (!WorldToScreen(headWorld, headScreen)) continue;
// Dynamic circle radius using library clamp + remap
float dist = enemy.GetDistance();
float radius = math::Clamp(
math::Remap(dist, 5.0f, 80.0f, 8.0f, 3.0f), 3.0f, 8.0f);
Color color = enemy.IsVisible()
? Color(255, 50, 50, static_cast<uint8_t>(pulseAlpha))
: Color::Orange();
Draw::CircleFilled(headScreen, radius, color);
if (g_showHealthBars)
{
float hp = enemy.GetHealthPercent();
float barWidth = math::Lerp(20.0f, 60.0f,
math::Clamp(80.0f / dist, 0.0f, 1.0f));
Draw::HealthBar(headScreen.x - barWidth * 0.5f,
headScreen.y + 10, barWidth, 4, hp);
}
if (g_showDistance)
{
char distText[32];
int d = static_cast<int>(dist);
distText[0] = '0' + (d / 100) % 10;
distText[1] = '0' + (d / 10) % 10;
distText[2] = '0' + d % 10;
distText[3] = 'm';
distText[4] = '\0';
Draw::Text(headScreen.x - 10, headScreen.y + 20,
Color::White(), distText);
}
if (g_showSnaplines)
{
float fadeAlpha = math::Lerp(200.0f, 40.0f,
math::Clamp(dist / g_maxDistance, 0.0f, 1.0f));
Draw::Line(screenCenter, headScreen,
color.WithAlpha(static_cast<uint8_t>(fadeAlpha)), 1.f);
}
}
}
// ── Menu ─────────────────────────────────────────────────
extern "C" void on_menu()
{
if (ImGui::CollapsingHeader("Enemy ESP (deps)"))
{
ImGui::Checkbox("Show Health Bars", &g_showHealthBars);
ImGui::Checkbox("Show Distance", &g_showDistance);
ImGui::Checkbox("Show Snaplines", &g_showSnaplines);
ImGui::Separator();
ImGui::Checkbox("Visible Only", &g_visibleOnly);
ImGui::SliderFloat("Max Distance", &g_maxDistance, 10.f, 200.f);
}
}
What's Different from the Basic ESP#
Dependency Declaration#
#include <xenon/libs/math_helpers.hpp>
XENON_PLUGIN_INFO_DEPS(
...,
"math_helpers\0" // dependency on math_helpers service
)
The #include gives access to xenon::math::Lerp, Clamp, Remap. The XENON_PLUGIN_INFO_DEPS macro tells the host to load the math library first.
Pulsing Effect#
float pulseT = g_pulseTimer;
if (pulseT > 1.0f) pulseT = 2.0f - pulseT; // triangle wave 0→1→0
int pulseAlpha = static_cast<int>(
math::Remap(pulseT, 0.0f, 1.0f, 100.0f, 255.0f));
Uses math::Remap to convert a 0-1 triangle wave into an alpha range of 100-255. Visible enemies pulse in brightness.
Dynamic Circle Radius#
Circles are larger for close enemies (8px) and smaller for far ones (3px), using Remap for smooth interpolation and Clamp to bound the result.
Adaptive Health Bar Width#
Health bars scale with distance — wider when close, narrower when far.
Fading Snaplines#
Snaplines fade out with distance using Lerp.
Build#
Both the library and this plugin must be built:
Both .wasm files must be loaded by Xenon. The host automatically orders them so the library loads first.
See Also#
- Math Library example — the library this depends on
- Dependencies guide — full workflow