Skip to content

Server, ticks and system information

Section notes in abi.h

the core slots, present since ABI v1

§I NBT binary, KvDb (thread-safe), system & server info

Appended: tick statistics

Slots

get_current_tick

C
uint64_t (*get_current_tick)(void);

Current server tick (the tickID from Level::getCurrentTick()). Returns 0 when the level is not ready. Server thread only.

  • Call: api->get_current_tick()
  • Return type: uint64_t
  • Section of abi.h: the core slots, present since ABI v1
  • Position in the table: slot 9, counting from 0
  • Callers in each binding:

get_tick_delta_time

C
double (*get_tick_delta_time)(void);

Wall-clock period of the last frame in seconds (mTickDeltaTime; 0.05 at 20 TPS). It includes the sleep the server inserts to hold 20 Hz, so it is not the time spent computing a tick and its reciprocal is not a tick rate: it is one noisy sample of the frame rate. For TPS and MSPT use get_tps and get_mspt. Returns -1.0 if unavailable. Server thread only.

get_player_count

C
int32_t (*get_player_count)(void);

Number of currently connected players (Level::getActivePlayerCount()). Server thread only.

  • Call: api->get_player_count()
  • Return type: int32_t
  • Section of abi.h: the core slots, present since ABI v1
  • Position in the table: slot 11, counting from 0
  • Callers in each binding:

get_sim_paused

C
bool (*get_sim_paused)(void);

Whether the simulation is currently paused (Level::getSimPaused()). Server thread only.

  • Call: api->get_sim_paused()
  • Return type: bool
  • Section of abi.h: the core slots, present since ABI v1
  • Position in the table: slot 12, counting from 0
  • Callers in each binding:

sys_info_str

C
bool (*sys_info_str)(int32_t prop, void* ctx, PierStrSink sink);

Group note

System info: THREAD-SAFE (plain OS calls).

sys_get_env

C
bool (*sys_get_env)(PierStr name, void* ctx, PierStrSink sink);

Group note

System info: THREAD-SAFE (plain OS calls).

  • Call: api->sys_get_env(name, ctx, sink)
  • Parameters:
    • name : PierStr
    • ctx : void*
    • sink : PierStrSink
  • Return type: bool
  • Section of abi.h: §I NBT binary, KvDb (thread-safe), system & server info
  • Position in the table: slot 69, counting from 0
  • Callers in each binding:

sys_set_env

C
bool (*sys_set_env)(PierStr name, PierStr value);

Group note

System info: THREAD-SAFE (plain OS calls).

  • Call: api->sys_set_env(name, value)
  • Parameters:
    • name : PierStr
    • value : PierStr
  • Return type: bool
  • Section of abi.h: §I NBT binary, KvDb (thread-safe), system & server info
  • Position in the table: slot 70, counting from 0
  • Callers in each binding:

sys_is_wine

C
bool (*sys_is_wine)(void);

Group note

System info: THREAD-SAFE (plain OS calls).

  • Call: api->sys_is_wine()
  • Return type: bool
  • Section of abi.h: §I NBT binary, KvDb (thread-safe), system & server info
  • Position in the table: slot 71, counting from 0
  • Callers in each binding:

server_info_str

C
bool (*server_info_str)(int32_t prop, void* ctx, PierStrSink sink);

Group note

Server / world-level settings.

tick_freeze

C
bool (*tick_freeze)(bool on);

Group note

Tick control (additive, gated by struct_size). Backed by a bridge-owned detour on Level::tick, installed lazily on the first control call and left in place (idle cost: one predictable branch per frame — a control call can arrive from a command handler that is executing INSIDE the tick, where unpatching would not be safe). Server thread only. While frozen, mobs/blocks/redstone/time stop; players can still move and chat (movement is client-authoritative, network runs outside the level tick).

  • Call: api->tick_freeze(on)
  • Parameters:
    • on : bool
  • Return type: bool
  • Section of abi.h: §I NBT binary, KvDb (thread-safe), system & server info
  • Position in the table: slot 80, counting from 0
  • Callers in each binding:

tick_step

C
bool (*tick_step)(uint32_t n);

Group note

Tick control (additive, gated by struct_size). Backed by a bridge-owned detour on Level::tick, installed lazily on the first control call and left in place (idle cost: one predictable branch per frame — a control call can arrive from a command handler that is executing INSIDE the tick, where unpatching would not be safe). Server thread only. While frozen, mobs/blocks/redstone/time stop; players can still move and chat (movement is client-authoritative, network runs outside the level tick).

Only while frozen: queue exactly n extra frames. False if not frozen or n == 0.

  • Call: api->tick_step(n)
  • Parameters:
    • n : uint32_t
  • Return type: bool
  • Section of abi.h: §I NBT binary, KvDb (thread-safe), system & server info
  • Position in the table: slot 81, counting from 0
  • Callers in each binding:

tick_warp

C
bool (*tick_warp)(double factor);

Group note

Tick control (additive, gated by struct_size). Backed by a bridge-owned detour on Level::tick, installed lazily on the first control call and left in place (idle cost: one predictable branch per frame — a control call can arrive from a command handler that is executing INSIDE the tick, where unpatching would not be safe). Server thread only. While frozen, mobs/blocks/redstone/time stop; players can still move and chat (movement is client-authoritative, network runs outside the level tick).

0 < factor <= 100. Fractional = slow motion (accumulator), 1.0 restores normal.

  • Call: api->tick_warp(factor)
  • Parameters:
    • factor : double
  • Return type: bool
  • Section of abi.h: §I NBT binary, KvDb (thread-safe), system & server info
  • Position in the table: slot 82, counting from 0
  • Callers in each binding:

profile_begin

C
bool (*profile_begin)(uint32_t ticks);

Group note

Per-subsystem MSPT profiler (additive, gated by struct_size). Backed by five timing detours (Level/Dimension tick, redstone, chunk block ticks, block entities), installed lazily on the first profile_begin and left in place. One sampling window at a time. Server thread only.

Arm a window of ticks level ticks (1..12000). False if 0, too big, or already sampling.

  • Call: api->profile_begin(ticks)
  • Parameters:
    • ticks : uint32_t
  • Return type: bool
  • Section of abi.h: §I NBT binary, KvDb (thread-safe), system & server info
  • Position in the table: slot 83, counting from 0
  • Callers in each binding:

profile_take

C
bool (*profile_take)(void* ctx, PierStrSink sink);

Group note

Per-subsystem MSPT profiler (additive, gated by struct_size). Backed by five timing detours (Level/Dimension tick, redstone, chunk block ticks, block entities), installed lazily on the first profile_begin and left in place. One sampling window at a time. Server thread only.

Poll for the finished report. False while sampling / nothing armed; true exactly once per window, sinking one SNBT report: {ticks:N, buckets:{level_tick:{us,calls}, dimension_tick:{…}, redstone:{…}, chunk_blocks:{…}, block_entities:{…}}}. Bucket times are INCLUSIVE (nested subsystems), report side by side, don't sum.

chunk_blocks is the drain of a chunk's pending block-tick queues, both the scheduled and the random one, summed over every chunk. Work a chunk does around that drain is outside the bucket, so the number is a floor on block ticking and not the whole of it. calls counts queue drains, of which a ticking chunk contributes two, not one.

  • Call: api->profile_take(ctx, sink)
  • Parameters:
    • ctx : void*
    • sink : PierStrSink
  • Return type: bool
  • Section of abi.h: §I NBT binary, KvDb (thread-safe), system & server info
  • Position in the table: slot 84, counting from 0
  • Callers in each binding:

get_tps

C
double (*get_tps)(int32_t window_seconds);

Ticks per second over the last window_seconds (1..60, clipped) of wall clock: the number of Level::tick calls that really ran divided by elapsed time. Stays correct under the tick warp (reads above 20), the tick freeze (reads 0) and lag (reads below 20). Returns -1.0 before the first frame has been sampled. Server thread only.

  • Call: api->get_tps(window_seconds)
  • Parameters:
    • window_seconds : int32_t
  • Return type: double
  • Section of abi.h: Appended: tick statistics
  • Position in the table: slot 186, counting from 0
  • Callers in each binding:

get_mspt

C
double (*get_mspt)(int32_t window_seconds);

Milliseconds spent inside Level::tick per tick, averaged over the last window_seconds (1..60, clipped). This is the time the server computes, excluding the idle sleep between frames; a healthy server reads a few milliseconds and only approaches 50 when saturated. Returns -1.0 when no tick ran in the window. Server thread only.

  • Call: api->get_mspt(window_seconds)
  • Parameters:
    • window_seconds : int32_t
  • Return type: double
  • Section of abi.h: Appended: tick statistics
  • Position in the table: slot 187, counting from 0
  • Callers in each binding:

PierSysInfoProp

Name Value Description
PIER_SYS_OS_NAME 0 sys_utils::getSystemName
PIER_SYS_OS_VERSION 1 sys_utils::getSystemVersion → string
PIER_SYS_LOCALE 2 sys_utils::getSystemLocaleCode
PIER_SYS_LOCAL_TIME 3 sys_utils::getLocalTime → SNBT

PierServerInfoProp

server_info_str keys.

Name Value Description
PIER_SRV_BDS_VERSION 0 Common::getGameVersionString
PIER_SRV_PROTOCOL_VERSION 1 LevelData::mNetworkVersion: the protocol the level was last written by. Says how old the save is, not what the server speaks.
PIER_SRV_LEVEL_PROTOCOL_VERSION 2 "major.minor.patch" of the running build, from CurrentGameSemVersion. Lets a mod carry its own version→protocol table instead of waiting for a Pier release.
PIER_SRV_GAME_SEM_VERSION 3