Using xlibs and AlifePlus

Guide for mod authors · Damian Sirbu · 2026-04-05

Want to build on these systems? See the architecture section for the design and integration examples, or jump straight to integration levels. Contact details at the bottom.

What They Are

xlibs is an engine abstraction layer for STALKER Anomaly. It wraps X-Ray engine APIs in safe Lua functions: squad operations, smart terrain queries, entity resolution, an event bus, MCM config, PDA messaging, logging, and profiling.

AlifePlus is a reactive behavior framework built on xlibs. Engine callbacks produce causes (a squad entered a smart terrain, an NPC died, a stash was looted). The pipeline routes causes to registered consequences (a nearby faction investigates, a revenge squad is dispatched). Throttling, protection, rate limiting, ownership, and lifecycle are handled by the framework. Mods register a predicate and a handler.

Modsdomain logic: predicate + handler
AlifePlusdispatcher, throttling, protection, cause/consequence routing, lifecycle
xlibsxbus, xsquad, xsmart, xlevel, xobject, xtime, xlog, xmcm
X-Ray Enginecallbacks, luabind, server objects, A-Life simulation

Both are published under the PolyForm Perimeter License. Addons, integrations, and modpacks are encouraged with visible credit.

License

AllowedNot Allowed
Calling xlibs/AP functions from your mod
Addons and integrations that depend on them
Modpacks (encouraged)
Reading source to learn, extend, debug
Using AI tools to learn the public API
Reproducing the implementation as a standalone replacement
Reverse engineering internals to reproduce design
Automated extraction for reproduction

Required: Visible credit -- "xlibs by Damian Sirbu" and/or "AlifePlus by Damian Sirbu".

xlibs: The Modder's Toolbox

xlibs wraps X-Ray engine APIs based on reading the engine source (X-Ray Monolith C++), the Anomaly scripting layer, modded executable extensions, and established patterns from reputable community mods. The API surface was validated through tracing and load testing the Anomaly engine using Grafana k6 and a custom benchmarking framework. Key modules:

ModuleWhat it doesExample
xbusEvent bus (pub/sub)xbus.subscribe("cause:massacre", fn, "my_handler")
xsquadFind, script, release, protect squadsxsquad.find_squads(pos, {factions=t, max_distance=500})
xsmartSmart terrain queriesxsmart.find_smart(pos, {filter=xsmart.is_base})
xcreatureEntity identity and queriesxcreature.community(id), xcreature.query():stalkers():each(fn)
xpdaPDA messages and map markersxpda.send("Title", "Message")
xmcmMCM config managementxmcm.create_config("mymod", defaults, path_builder)
xlogBuffered file loggingxlog.get_logger("MY.MOD", {outfile="mymod.log"})
xlevelLevel/map queriesxlevel.get_actor_level_id()
xobjectEntity resolution, item creationxobject.se(any_input), xobject.create_item(sec, npc_id)
xtimeGame timextime.game_sec()
xmathRNG, probability, weighted choicexmath.chance(30), xmath.sample(tbl)
xeventFunction hooking, synthetic callbacksxevent.hook("module", "func", wrapper)

Full docs: github.com/damiansirbu-stalker/xlibs

AlifePlus: Three Levels of Integration

Level 1: Listen to events (easiest, no AP internals)

Subscribe to AlifePlus cause events via xbus. This is the recommended starting point.

function on_game_start()
    xbus.subscribe("cause:massacre", function(data)
        -- data.position, data.level_id, data.total_deaths
        my_response(data)
    end, "my_mod_massacre")
end

Available events: cause:elite, cause:elitekill, cause:massacre, cause:squadkill, cause:basekill, cause:area, cause:wounded, cause:stash, cause:harvest, cause:needs.

Level 2: Register causes and consequences (intermediate)

Register your behavior with AP's pipeline. You get throttling, protection, rate limiting, and PDA for free.

-- Cause: detect something interesting
local function _predicate(trace, squad)
    if not is_interesting(squad) then return nil end
    return { cause = "cause:my_event", squad_id = squad.id, ... }
end

-- Consequence: react to it
local function _handler(event_data)
    if not xmath.chance(30) then return { code = ap_const.RESULT.CHANCE_NEXT } end
    local squad = xobject.se(event_data.squad_id)
    local base = xsmart.find_smart(squad.position, { filter = xsmart.is_base })
    xsquad.control_squad(squad, base, true)
    return { code = ap_const.RESULT.OK_STOP }
end

function on_game_start()
    for i = 1, #ap_const.RADIANT_CALLBACKS do
        ap_producer_reactive.register("cause:my_event",
            { callback = ap_const.RADIANT_CALLBACKS[i] }, _predicate)
    end
    ap_consumer.register("consequence:my_reaction",
        { event = "cause:my_event", priority = 20 }, _handler)
end

Level 3: Deep integration (coordinate first)

If you need access to AP's tracker, chase system, territory conquest, or other internal systems -- reach out via the GitHub page. These APIs are not yet stable or documented for external use. The plan is to stabilize them as proper public APIs based on what mod authors actually need.

Architecture

Problem

Most alife mods for Anomaly hook engine callbacks independently, iterate over squads on a timer, implement their own throttling, check squad validity in their own way, and set engine fields directly. Each mod operates as a silo with no awareness of other mods controlling the same squads.

Design

xlibs and AlifePlus are designed as a shared alife layer that mods register to rather than build around.

  • xlibs provides invariants: event bus (publish/subscribe), squad safety (protection checks, scripting, release), smart terrain queries, entity resolution, and a squad ownership protocol (claim/release with TTL, one owner at a time, framework-enforced lifecycle)
  • AlifePlus provides the pipeline: a radiant callback dispatcher with rate limiting, a unified protection stack, cause/consequence routing via the event bus, and lifecycle management (scripting, arrival, cooldown, cleanup)
  • Mods register domain logic: a predicate and a handler. The framework handles the rest.

What the framework provides

Mods that register with the pipeline get these facilities without implementing them:

FacilityWhat it does
Bresenham rate limiterInteger-only ratio gate based on the Bresenham line algorithm. Distributes callback budget fairly across causes with zero floating-point arithmetic and no timer dependencies.
TTL bucket collectionsTime-bounded data structures with automatic expiry. Used for cooldowns, claim lifetimes, and deferred cleanup.
Deferred queuesExpensive or unsafe operations are batched and flushed outside the callback, keeping the tick lightweight.
Protection stackUnified squad safety checks applied everywhere: the pipeline, squad search functions, and scripting calls all use the same protection layer.
Ownership protocolClaim/release with TTL. One owner at a time. Framework auto-releases expired claims.
TracingHierarchical trace context flows through the entire pipeline. Every gate decision, squad action, and result is recorded.
LoggingStructured file logging with buffered writes. Per-module log files, configurable verbosity.
Performance monitoringWall-clock and game-time profiling per cause, per consequence, per gate. Identifies bottlenecks without external tools.

Pipeline

Every squad event passes through the same sequence of gates. Each gate either passes the event forward or rejects it.

Registered callbackany engine callback registered with the dispatcher
Rate limiterper-cause budget, Bresenham ratio gatebudget exceeded: skip
Protection stackpermanent squad? active role? task target? owned by another mod?protected: skip
Cause predicatemod-registered condition (is this event interesting?)condition not met: skip
xbus publishcause event dispatched to all subscribers
Consequence gatesenabled? chance roll? data valid?gate failed: next handler
Handlerfind squads, claim ownership, script to target, send PDA

Integration examples

ModAs AP plugin
WarfareBase-capture and patrol as AP causes/consequences. Squad ownership via framework claim/release.
Semi Radiant AIPatrols as radiant causes with arrival-based release.
Guards SpawnerGuard-return as cause. Long-TTL ownership claim with auto-renew.
Night MutantsSpawn/despawn as causes with time-of-day conditions.
Bounty Squads ExtendedBounty as consequence using the chase template.
Faction RelationsPure xbus subscriber. Listens to cause events, adjusts faction goodwill.
Mugging SquadsLoot detection as reactive cause, hostile response as consequence.

Planned

  • Cause/consequence templates: reusable patterns (respond, chase, flee, patrol, guard) that mods instantiate with their own parameters instead of reimplementing squad scripting.
  • xbus expansion: typed events with schemas, priority subscribers, event namespaces.
  • Plugin SDK: documentation and a minimal example mod (~50 lines) showing how to register one cause and one consequence.
Open invitation. If you maintain an alife mod and want to integrate, reach out. The goal is to establish proper APIs based on what mod authors actually need.
Discord: damian_sirbu | ModDB: damian_sirbu | Email: dami.sirbu@gmail.com