Skip to content

Central Economy Script API ​

Summary: The Central Economy (CE) is DayZ's server-side spawning engine — it reads types.xml, globals.xml, events.xml, and the other mission XML files and keeps the world stocked with loot, vehicles, infected, and animals. This chapter covers the script side of the CE: the CEApi interface, ECE spawn flags, CEItemProfile, per-entity lifetime control, and the hooks the engine fires when the CE creates an entity.


Table of Contents ​


The CE at a Glance ​

The Central Economy is an engine system that runs entirely on the server. On a continuous loop it:

  1. Reads types.xml to learn every item's nominal (target count) and min (respawn threshold).
  2. Matches items to spawn locations through usage flags (Military, Town, ...) and value flags (Tier1-Tier4).
  3. Counts existing instances, and spawns replacements when a count drops below min.
  4. Deletes items whose lifetime expires untouched.
  5. Runs dynamic events (events.xml) for vehicles, helicopter crashes, and infected on their own schedule.

The CE is configured through XML files in the mission folder (types.xml, globals.xml, events.xml, cfgspawnabletypes.xml, cfgrandompresets.xml, cfgeconomycore.xml, cfglimitsdefinition.xml, cfgeventspawns.xml). Script code does not drive the spawn loop — but it can query the CE, adjust lifetimes, spawn through it, and react when it creates entities. That script surface is what this chapter documents.


Where the XML Reference Lives ​

The full field-by-field XML reference is in the server administration part of this wiki:


The Hive and CE Availability ​

The CE only exists when the mission initializes a Hive — the persistence backend that owns the economy. The vanilla mission init.c does this in main():

c
void main()
{
    // Initialize the economy
    Hive ce = CreateHive();
    if (ce)
    {
        ce.InitOffline();
    }

    // ... weather, date, mission setup ...
}

The Hive class (defined in 3_game/hive/hive.c) exposes:

c
class Hive
{
    proto native void InitOnline(string ceSetup, string host = "");
    proto native void InitOffline();
    proto native void InitSandbox();

    proto native bool IsIdleMode();

    proto native void SetShardID(string shard);
    proto native void SetEnviroment(string env);

    proto native void CharacterSave(Man player);
    proto native void CharacterKill(Man player);
    proto native void CharacterExit(Man player);
}

proto native Hive CreateHive();
proto native void DestroyHive();
proto native Hive GetHive();

Key consequences for mod code:

  • Server only. A client connected to a server has no Hive and no CE. Only the server (or an offline/single-player mission that called CreateHive()) has one.
  • Null-check everything. GetCEApi() returns null when no CE is running — for example in the main menu or on a client.

Getting the CE API ​

GetCEApi() (defined in 3_game/ce/centraleconomy.c) returns the CEApi interface:

c
CEApi ce = GetCEApi();
if (!ce)
{
    return; // no CE on this machine (client, or no Hive)
}

The vanilla game itself uses this exact pattern — for example DayZGame reads a global economy variable only after checking the API exists:

c
if (GetCEApi())
{
    bool wetUpdate = (GetCEApi().GetCEGlobalInt("WorldWetTempUpdate") == 1);
}

The CEApi methods fall into a few groups, covered in the sections below: lifetime manipulation, globals access, avoidance queries, and developer/diagnostic tooling.


ECE Spawn Flags ​

When you spawn entities from script with GetGame().CreateObjectEx(), the ECE flags control both placement behavior and how the entity relates to the CE. They are plain int constants defined in 3_game/ce/centraleconomy.c:

c
proto native Object CreateObjectEx(string type, vector pos, int iFlags, int iRotation = RF_DEFAULT);

Placement and Setup Flags ​

FlagValueMeaning
ECE_NONE0No flags
ECE_SETUP2Process full entity setup (when creating a NEW entity)
ECE_TRACE4Trace under the entity when placing it
ECE_CENTER8Use the model shape's center for placement
ECE_UPDATEPATHGRAPH32Update the navmesh where the object is placed
ECE_ROTATIONFLAGS512Enable rotation flags for placement
ECE_CREATEPHYSICS1024Create the collision envelope and physics data
ECE_INITAI2048Initialize AI (infected, animals)
ECE_AIRBORNE4096Create a flying unit in the air
ECE_NOSURFACEALIGN262144Do not align the object to the surface
ECE_KEEPHEIGHT524288Keep the given height (no trace / surface placement)
ECE_LOCAL1073741824Create the object locally (not networked)

CE-Interaction Flags ​

FlagValueCE Behavior
ECE_EQUIP_ATTACHMENTS8192Equip the configured attachments from cfgspawnabletypes.xml
ECE_EQUIP_CARGO16384Fill the configured cargo from cfgspawnabletypes.xml
ECE_EQUIP24576Both of the above (ECE_EQUIP_ATTACHMENTS + ECE_EQUIP_CARGO)
ECE_EQUIP_CONTAINER2097152Populate a dynamic-event/group container during spawn
ECE_NOLIFETIME4194304Do not set a CE lifetime — the entity never despawns from idle cleanup
ECE_NOPERSISTENCY_WORLD8388608Do not save this object in world persistence
ECE_NOPERSISTENCY_CHAR16777216Do not save this object in character persistence
ECE_DYNAMIC_PERSISTENCY33554432Spawns without persistency; becomes persistent once a player takes it

Predefined Combinations ​

Use these instead of hand-building masks when they fit:

CombinationValueComposition
ECE_PLACE_ON_SURFACE1060ECE_CREATEPHYSICS | ECE_UPDATEPATHGRAPH | ECE_TRACE
ECE_IN_INVENTORY787456ECE_CREATEPHYSICS | ECE_KEEPHEIGHT | ECE_NOSURFACEALIGN
ECE_OBJECT_SWAP787488ECE_CREATEPHYSICS | ECE_UPDATEPATHGRAPH | ECE_KEEPHEIGHT | ECE_NOSURFACEALIGN
ECE_FULL25126ECE_SETUP | ECE_TRACE | ECE_ROTATIONFLAGS | ECE_UPDATEPATHGRAPH | ECE_EQUIP

Examples ​

Spawn an item that persists forever (no CE lifetime):

c
vector pos = "7500 0 7500";
pos[1] = GetGame().SurfaceY(pos[0], pos[2]);
int flags = ECE_PLACE_ON_SURFACE | ECE_NOLIFETIME;
Object obj = GetGame().CreateObjectEx("Barrel_Green", pos, flags);

Spawn a weapon with its CE-configured attachments and cargo:

c
vector pos = "7500 0 7500";
pos[1] = GetGame().SurfaceY(pos[0], pos[2]);
int flags = ECE_PLACE_ON_SURFACE | ECE_EQUIP;
Object obj = GetGame().CreateObjectEx("AKM", pos, flags);
// The AKM rolls its attachment slots per cfgspawnabletypes.xml

Spawn event loot that becomes persistent only when picked up:

c
vector pos = "7500 0 7500";
pos[1] = GetGame().SurfaceY(pos[0], pos[2]);
int flags = ECE_PLACE_ON_SURFACE | ECE_DYNAMIC_PERSISTENCY;
Object obj = GetGame().CreateObjectEx("FirstAidKit", pos, flags);

See Entity System for the general entity creation and deletion API.


Rotation Flags (RF) ​

The fourth parameter of CreateObjectEx() takes RF rotation flags (also from centraleconomy.c), which control how the object may be oriented when placed:

FlagValueMeaning
RF_NONE0No rotation flags
RF_FRONT / RF_TOP / RF_LEFT / RF_RIGHT / RF_BACK / RF_BOTTOM1 / 2 / 4 / 8 / 16 / 32Allow placement on that side
RF_ALL63All six sides
RF_IGNORE64Ignore placement RF flags — spawn as the model was created
RF_RANDOMROT64Allow random rotation around the axis when placing
RF_ORIGINAL128Use the default placement set up on the object in config
RF_DEFAULT512Use the default placement set up on the object in config
c
vector pos = "7500 0 7500";
pos[1] = GetGame().SurfaceY(pos[0], pos[2]);
Object obj = GetGame().CreateObjectEx("Mag_AKM_30Rnd", pos, ECE_PLACE_ON_SURFACE, RF_RANDOMROT);

Reading an Item's Economy Profile ​

Every entity the CE tracks has a CEItemProfile — the parsed types.xml entry for its type. On the server you get it from EntityAI.GetEconomyProfile() (returns null when the type has no economy entry):

c
class CEItemProfile
{
    proto native int   GetNominal();      // target count on the map
    proto native int   GetMin();          // minimum count before respawn
    proto native float GetQuantityMin();  // min quantity (0.0 - 1.0)
    proto native float GetQuantityMax();  // max quantity (0.0 - 1.0)
    proto native float GetQuantity();     // random quantity in that range (0.0 - 1.0)
    proto native float GetLifetime();     // default lifetime in seconds
    proto native float GetRestock();      // restock cooldown in seconds
    proto native int   GetCost();         // priority during respawn/cleanup
    proto native int   GetUsageFlags();   // usage flag bitmask
    proto native int   GetValueFlags();   // value (tier) flag bitmask
}

Example — log the economy settings of the item a player is holding:

c
void PrintHeldItemEconomy(PlayerBase player)
{
    EntityAI held = player.GetHumanInventory().GetEntityInHands();
    if (!held)
    {
        return;
    }

    CEItemProfile profile = held.GetEconomyProfile();
    if (!profile)
    {
        Print(held.GetType() + " has no types.xml entry");
        return;
    }

    Print(held.GetType() + " nominal=" + profile.GetNominal() + " min=" + profile.GetMin());
    Print("lifetime=" + profile.GetLifetime() + " restock=" + profile.GetRestock());
}

Note the quantity getters return a 0.0-1.0 fraction, while the quantmin/quantmax fields in types.xml are written as percentages (-1 to 100).


Controlling Lifetime from Script ​

Per-Entity Lifetime ​

EntityAI exposes direct control over the CE cleanup timer of a single entity (server side):

c
// From 3_game/entities/entityai.c
proto native void  SetLifetime(float fLifeTime); // override REMAINING lifetime (seconds)
proto native float GetLifetime();                // remaining lifetime (seconds)
proto native void  IncreaseLifetime();           // reset lifetime to its default
proto native void  SetLifetimeMax(float fLifeTime); // override max lifetime for this instance
proto native float GetLifetimeMax();             // max lifetime (default comes from types.xml)

IncreaseLifetimeUp() is a script helper that resets the lifetime of an entity and every parent up its inventory hierarchy — this is what "touching" an item effectively does:

c
void KeepAlive(EntityAI item)
{
    item.IncreaseLifetimeUp();
}

Area Lifetime via CEApi ​

CEApi can adjust lifetimes in bulk. Results are clamped between 3 seconds and 10 years:

c
CEApi ce = GetCEApi();
if (!ce)
{
    return;
}

vector center = "7500 0 7500";

// Extend everything within 100 m by one hour
ce.RadiusLifetimeIncrease(center, 100, 3600);

// Shorten everything within 100 m by 10 minutes
ce.RadiusLifetimeDecrease(center, 100, 600);

// Reset everything within 100 m to its types.xml default
ce.RadiusLifetimeReset(center, 100);

// Subtract 60 seconds from the lifetime of EVERY item in the world
ce.TimeShift(60);

OverrideLifeTime(float seconds) sets a debug lifetime applied to any dynamic event spawned afterwards; pass 0 to turn it off again.


Reading globals.xml from Script ​

CEApi exposes typed getters for the <var> entries in globals.xml. The type attribute in the XML decides which getter matches: type="0" is int, type="1" is float, type="2" is string.

c
CEApi ce = GetCEApi();
if (!ce)
{
    return;
}

int zombieMax = ce.GetCEGlobalInt("ZombieMaxCount");     // returns int.MIN if not found
float dmgMax = ce.GetCEGlobalFloat("LootDamageMax");     // returns float.MIN if not found
string custom = ce.GetCEGlobalString("MyCustomVar");     // returns "" if not found

This also works for custom variables: a server can add its own <var> entries to globals.xml and mod code can read them at runtime — a lightweight way to make server-side script behavior configurable per mission without shipping a config file. The full parameter reference for the vanilla variables is in Loot Economy Deep Dive.


Avoidance Queries ​

The CE uses optimized internal checks to avoid spawning dynamic events on top of players and vehicles. The same checks are exposed to script — useful for custom spawners that should behave like the CE:

c
CEApi ce = GetCEApi();
if (!ce)
{
    return;
}

vector pos = "4500 0 10200";

// true = area is clear of players within 500 m; false = a player is inside
bool clearOfPlayers = ce.AvoidPlayer(pos, 500);

// true = area is clear of vehicles; optional third parameter narrows it
// to one dynamic event name (empty string = all vehicles)
bool clearOfVehicles = ce.AvoidVehicle(pos, 500, "VehicleCivilianSedan");

// Exact player count within a radius
int players = ce.CountPlayersWithinRange(pos, 1000);

if (clearOfPlayers && clearOfVehicles)
{
    // safe to place a custom event here
}

Note the polarity: AvoidPlayer()/AvoidVehicle() return true when the area is clear (the avoidance succeeded) and false when something is inside the radius.


The EEOnCECreate Hook ​

When the CE (or the debug spawner) creates a new entity, the engine calls EEOnCECreate() on it. This fires only for fresh CE spawns — not for entities loaded back from persistence and not for script-created objects. Vanilla uses it, for example, to randomize the food stage of spawned fruit and to set up helicopter crash sites.

Example — a custom supply cache that starts with a random amount of starter loot when the CE spawns it. The class goes in 4_World:

c
class LNT_SupplyCache : Barrel_ColorBase
{
    override void EEOnCECreate()
    {
        super.EEOnCECreate();

        // Runs on the server, only when the CE spawned this instance fresh
        int rolls = Math.RandomIntInclusive(1, 3);
        for (int i = 0; i < rolls; i++)
        {
            GetInventory().CreateInInventory("Rag");
        }
    }
}

Registration in config.cpp (the cache reuses the vanilla barrel model by inheriting from Barrel_ColorBase):

cpp
class CfgPatches
{
    class Lantern_Core_Scripts
    {
        units[] = {"LNT_SupplyCache"};
        weapons[] = {};
        requiredVersion = 0.1;
        requiredAddons[] = {"DZ_Data", "DZ_Gear_Camping"};
    };
};

class CfgVehicles
{
    class Barrel_ColorBase;
    class LNT_SupplyCache : Barrel_ColorBase
    {
        scope = 2;
        displayName = "Supply Cache";
    };
};

For the crate to actually spawn, it also needs a types.xml entry on the server — see Loot Economy Deep Dive.


Developer and Diagnostic Tools ​

Most of the remaining CEApi surface is developer/diagnostic tooling. These methods are marked DEVELOPER/DIAG ONLY in the engine headers — they are meant for the diagnostic executable and offline testing, not for live gameplay logic:

Force-Spawning Through the CE ​

MethodPurpose
SpawnDE(string name, vector pos, float angle = -1)Force-spawn a dynamic event ("StaticHeliCrash", vehicle events, ...); bypasses limits and avoidance
SpawnDEEx(string name, vector pos, float angle, int flags)Same, with custom ECE flags
SpawnLoot(string type, vector pos, float angle, int count = 1, float range = 1)Spawn one or more loot items in a circle
SpawnEntity(string type, vector pos, float range, int count)Like SpawnLoot, works better for animals/infected/vehicles
SpawnSingleEntity(string type, vector pos)Spawn one entity and get the Object back
SpawnGroup(string groupName, vector pos, float angle = -1)Force-spawn a building prototype group with its loot
SpawnAnalyze(string type)Emulate spawning of a type and dump images/logs to storage/lmap; "*" produces a CSV for all types
c
CEApi ce = GetCEApi();
if (ce)
{
    ce.SpawnDE("StaticHeliCrash", "4500 0 10200");
}

Economy Logging and Maps ​

MethodPurpose
EconomyLog(string category)Dump a CSV to storage/log/ — categories in EconomyLogCategories (e.g. Economy, RespawnQueue, InfectedZone)
EconomyMap(string what)Render spawn locations to a .tga in storage/lmap/ — a class name, or EconomyMapStrings helpers like ALL_LOOT or EconomyMapStrings.Category("food")
EconomyOutput(string what, float range)Write diagnostics to the server log — strings in EconomyOutputStrings (STATUS, SUSPICIOUS, EMPTY, CLOSE, ...)

Loot-Point Exports ​

Used when building or fixing map loot data:

MethodOutput
ExportSpawnData()Regenerates storage/spawnpoints.bin
ExportProxyData(vector center = vector.Zero, float radius = 0)storage/export/mapgrouppos.xml (zero vector/radius = whole map)
ExportClusterData()storage/export/mapgroupcluster.xml
ExportProxyProto()storage/export/mapgroupproto.xml
MarkCloseProxy(float radius, bool allSelections)Invalidate loot points closer than radius
RemoveCloseProxy()Delete the invalidated points
ListCloseProxy(float radius)Log loot points closer than radius without touching them

Summary ​

APIWherePurpose
CreateHive() / GetHive()3_game/hive/hive.cInitialize/access the persistence backend that owns the CE
GetCEApi()3_game/ce/centraleconomy.cAccess the CEApi; returns null without a Hive (e.g. on clients)
ECE flags3_game/ce/centraleconomy.cControl placement, persistence, and CE equipment when spawning via CreateObjectEx()
RF flags3_game/ce/centraleconomy.cPlacement rotation control for CreateObjectEx()
EntityAI.GetEconomyProfile()3_game/entities/entityai.cRead the parsed types.xml entry (CEItemProfile) of an entity
SetLifetime() / IncreaseLifetimeUp()EntityAIPer-entity CE cleanup timer control
RadiusLifetime*() / TimeShift()CEApiBulk lifetime manipulation
GetCEGlobalInt/Float/String()CEApiRead globals.xml variables (including custom ones) from script
AvoidPlayer() / AvoidVehicle()CEApiCE-style spawn avoidance checks for custom spawners
EEOnCECreate()EntityAIPer-entity hook fired when the CE creates the entity fresh

Released under CC BY-SA 4.0 | Code examples under MIT License