Axiom/Docs
Axiom SDK

Write once. Run where the capabilities match.

One capability API across injected native games, managed runtimes and emulated targets. Mods compile to WebAssembly by default, so a build made today still loads after the game patches.

QUICKSTARTthree commands to a running mod
$ axiom new myhud --tier wasm --lang cpp
$ axiom build
$ axiom watch --game treyarch.bo2

Pick a tier before you pick a language.

The tier decides what the mod can be trusted with, how it is distributed, and whether it survives a game update.

TIER W · DEFAULT
WebAssembly

Sandboxed and portable. One artifact runs on every backend and architecture, hot-reloads in under a second, and cannot crash the game.

C++ · Rust · Zig · C# · Go · C
TIER N · TRUSTED
Native C ABI

No boundary and no sandbox. For renderers, physics and anything that must run inside the game's own frame budget. Signed, and prompted once.

C++ · Rust · Zig · C# · Go · C
TIER S · SCRIPT
Lua and JS

One file, no build step, instant reload. For config tweaks, event handlers and the thing you want working before dinner.

Lua · JavaScript

The surface is generated, not written.

Every binding, every tier and this reference come from one definition, so none of them can drift apart.

SURFACEaxiom.idl · one definition, every binding
capability entity.transform {
  version: 1

  fn position(e: EntityId) -> Vec3
  bulk fn positions(e: []EntityId) -> []Vec3
  event moved { entity, from, to }
}

Anything you would call in a loop has a bulk form. The linter warns when a sandboxed mod uses the scalar one inside a frame callback.

The same mod, three ways.

A HUD mod that hooks one function, reads every live entity once per frame and submits a panel. The bindings differ, the surface does not.

src/main.cpp · tier W
#include <axiom/surface.hpp>
#include <vector>

struct BetterHud final : axiom::Mod {
  void on_load(axiom::Context& ctx) override {
    ctx.hooks().install("CG_DrawHud", 100);
    ctx.config().bind("scale", &scale_);
  }

  void on_frame(axiom::Frame& f) override {
    auto ids = f.entities().alive();
    markers_.clear();
    // bulk form: one boundary crossing for the whole frame
    for (auto const& p : f.entities().positions(ids))
      markers_.push_back(f.camera().project(p));
  }

  void on_draw(axiom::ui::Surface& ui) override {
    auto panel = ui.panel("Better HUD", axiom::ui::Anchor::BottomLeft);
    panel.scale(scale_);
    panel.text("{} contacts", markers_.size());
    for (auto const& m : markers_) panel.marker(m);
    ui.submit(std::move(panel));  // retained tree, only the diff crosses
  }

  float scale_ = 1.1f;
  std::vector<axiom::ui::Point> markers_;
};

AXIOM_MOD(BetterHud);
LUAtier S · no build step
local axiom = require("axiom")

local markers = {}

axiom.hooks.install("CG_DrawHud", 100)

axiom.on_frame(function(f)
  local ids = f.entities.alive()
  markers = f.entities.positions(ids)  -- bulk
end)

axiom.on_draw(function(ui)
  ui.panel("Better HUD", { anchor = "bottom-left" })
    :text("%d contacts", #markers)
    :markers(markers)
    :submit()
end)

-- save the file and it reloads in place
CONFIG SCHEMAaxiom.toml
[config.scale]
label   = "Scale"
type    = "range"
min     = 50
max     = 150
default = 110
unit    = "%"

[config.anchor]
label   = "Anchor"
type    = "enum"
options = ["bottom-left", "bottom-centre", "top-right"]
default = "bottom-left"
BACKENDC++23 · what a target implements
class NativeBackend final : public axiom::Backend {
  public:
  Caps capabilities() const override {
    return Caps::Memory | Caps::Symbols | Caps::Hooks
         | Caps::Frame | Caps::Surface | Caps::Input;
  }

  Result<Addr> resolve(std::string_view name) override;
  Result<Hook> install(Addr at, Detour d) override;
  Result<void>  read(Addr at, std::span<std::byte>) override;
};

// the managed backend returns the same Caps minus
// Memory::Protect, and the loader does the rest

Start here.

Axiom does not attach to protected processes.

Backends refuse a process with a known kernel anticheat driver loaded, and the registry marks those titles as blocked. Single-player, private servers, dedicated servers and emulated titles are the target. Read the policy.