-
-
Notifications
You must be signed in to change notification settings - Fork 3
API Reference
Generated from sdk/abi.json, which is checked against the host's own
capability table by tests/mod_abi_test.cpp. If a language binding
disagrees with this page, the binding is wrong.
Strings are (ptr, len) pairs of UTF-8 bytes in your linear memory.
They are not null-terminated, and the host never keeps a pointer
into your memory after a call returns.
-
Core (
gearbox:core): log, env, abort, fuel_budget -
GameState.Read (
gearbox:gamestate.read): turn_number, country_count, country_at, country_name, country_treasury, country_province_count, province_population, province_owner -
UI (
gearbox:ui): panel_register, draw_rect, draw_text, button -
Assets (
gearbox:assets): size, read -
Audio (
gearbox:audio): play, stop, set_volume, is_playing -
Net (
gearbox:net): send, recv, peer_count, self_peer, is_host -
WasiStub (
wasi_snapshot_preview1): fd_write, proc_exit, random_get, clock_time_get, environ_sizes_get, environ_get, args_sizes_get, args_get, fd_close, fd_fdstat_get, fd_prestat_get, fd_prestat_dir_name, fd_read, fd_seek, path_open, clock_res_get, sched_yield, fd_advise, fd_allocate, fd_datasync, fd_sync, fd_fdstat_set_flags, fd_filestat_get, fd_tell, fd_renumber, fd_filestat_set_size, fd_filestat_set_times, fd_pread, fd_pwrite, fd_readdir, path_create_directory, path_remove_directory, path_unlink_file, path_filestat_get, path_symlink, path_readlink, path_rename, path_link, path_filestat_set_times, poll_oneoff, sock_accept, sock_recv, sock_send, sock_shutdown -
Storage (
gearbox:storage): get, set, remove -
Map (
gearbox:map): width, height, province_count, province_at, province_name, province_center_x, province_center_y, province_is_land, province_neighbor_count, province_neighbor_at -
Diplomacy (
gearbox:diplomacy): at_war, allied, non_aggression, guaranteed, propose_war -
GameState.Write (
gearbox:gamestate.write): set_country_treasury, add_country_treasury, set_province_owner, set_province_population -
Neural (
gearbox:neural): feature_count, features, reward_count, reward_mean
Import module gearbox:core. Always granted; cannot be revoked.
(import "gearbox:core" "log" (func (param i32 i32 i32)))| Parameter | Type | |
|---|---|---|
level |
i32 |
|
msg |
i32 |
pointer into your memory |
msg_len |
i32 |
byte length |
Returns: nothing
Write a line to the game log and the mod menu's log view. Messages longer than 2048 bytes are truncated. An out-of-bounds (ptr,len) is refused and logged as an error against your mod rather than read.
(import "gearbox:core" "env" (func (param i32)))| Parameter | Type | |
|---|---|---|
out |
i32 |
pointer into your memory |
Returns: nothing
Fill a gearbox_env_t. Write your own sizeof into out->size FIRST; the host writes at most that many bytes, so an older mod stays safe against a newer host. If size is 0 or larger than the host's struct, the host uses its own size.
(import "gearbox:core" "abort" (func (param i32 i32)))| Parameter | Type | |
|---|---|---|
msg |
i32 |
pointer into your memory |
msg_len |
i32 |
byte length |
Returns: nothing — does not return, traps your mod.
Unrecoverable error. Traps out of the current call, disables the mod, and shows the message to the user. Prefer returning an error from a hook where you can.
(import "gearbox:core" "fuel_budget" (func (result i64)))Returns: i64
The instruction budget for the current hook, or 0xFFFFFFFFFFFFFFFF when unmetered. This is the LIMIT, not a live countdown: it does not decrease as you run. Use it to size your work up front and count your own iterations.
Import module gearbox:gamestate.read. Requires the GameState.Read capability in your manifest.
(import "gearbox:gamestate.read" "turn_number" (func (result i32)))Returns: i32
The current turn. 0 when no world is loaded.
(import "gearbox:gamestate.read" "country_count" (func (result i32)))Returns: i32
How many countries exist. 0 when no world is loaded. Rebel factions are not included.
(import "gearbox:gamestate.read" "country_at" (func (param i32) (result i32)))| Parameter | Type | |
|---|---|---|
index |
i32 |
Returns: i32
The country at index in [0, country_count). Returns GEARBOX_INVALID (0xFFFFFFFF) if out of range. Ordering is stable within a turn but not across turns.
(import "gearbox:gamestate.read" "country_name" (func (param i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
country |
i32 |
opaque country handle |
buf |
i32 |
pointer into your memory |
cap |
i32 |
byte length |
Returns: i32
Two-call sizing. Writes at most cap bytes of UTF-8 and returns the FULL length. Call with cap 0 to size, then again to fill. A return greater than cap means truncation, not failure. Returns 0 for an unknown country.
(import "gearbox:gamestate.read" "country_treasury" (func (param i32) (result f64)))| Parameter | Type | |
|---|---|---|
country |
i32 |
opaque country handle |
Returns: f64
Treasury balance. 0 for an unknown country.
(import "gearbox:gamestate.read" "country_province_count" (func (param i32) (result i32)))| Parameter | Type | |
|---|---|---|
country |
i32 |
opaque country handle |
Returns: i32
How many provinces the country owns. 0 for an unknown country.
(import "gearbox:gamestate.read" "province_population" (func (param i32) (result i64)))| Parameter | Type | |
|---|---|---|
province |
i32 |
opaque province handle |
Returns: i64
Population of a province. 0 for an unknown province.
(import "gearbox:gamestate.read" "province_owner" (func (param i32) (result i32)))| Parameter | Type | |
|---|---|---|
province |
i32 |
opaque province handle |
Returns: i32
Owning country, or GEARBOX_INVALID if unowned or unknown.
Import module gearbox:ui. Requires the UI capability in your manifest.
(import "gearbox:ui" "panel_register" (func (param i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
title |
i32 |
pointer into your memory |
title_len |
i32 |
byte length |
min_w |
i32 |
|
min_h |
i32 |
Returns: i32
Register a panel and return its handle. Returns 0 (invalid) when headless, when UI was revoked, or when you already hold 8 panels. Titles are truncated to 64 bytes. Call this from mod_load, not from your draw hook.
(import "gearbox:ui" "draw_rect" (func (param i32 i32 i32 i32 i32 i32)))| Parameter | Type | |
|---|---|---|
panel |
i32 |
opaque panel handle |
x |
i32 |
|
y |
i32 |
|
w |
i32 |
|
h |
i32 |
|
rgba |
i32 |
0xRRGGBBAA |
Returns: nothing
Filled rectangle in panel-relative coordinates. Colour is 0xRRGGBBAA. Coordinates outside the panel are clipped by the host; they cannot escape it.
(import "gearbox:ui" "draw_text" (func (param i32 i32 i32 i32 i32 i32)))| Parameter | Type | |
|---|---|---|
panel |
i32 |
opaque panel handle |
x |
i32 |
|
y |
i32 |
|
rgba |
i32 |
0xRRGGBBAA |
text |
i32 |
pointer into your memory |
text_len |
i32 |
byte length |
Returns: nothing
UTF-8 text in panel-relative coordinates. Truncated to 512 bytes per call.
(import "gearbox:ui" "button" (func (param i32 i32 i32 i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
panel |
i32 |
opaque panel handle |
x |
i32 |
|
y |
i32 |
|
w |
i32 |
|
h |
i32 |
|
label |
i32 |
pointer into your memory |
label_len |
i32 |
byte length |
Returns: i32
Immediate-mode button: draws it and returns 1 on the frame it is clicked. One click activates one button -- the host consumes it, so overlapping rects do not all fire. Label truncated to 64 bytes.
Import module gearbox:assets. Requires the Assets capability in your manifest.
(import "gearbox:assets" "size" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
name |
i32 |
pointer into your memory |
name_len |
i32 |
byte length |
Returns: i32
Byte size of one of your own data/ files, or 0 if there is no such asset. Names are relative to data/ and use '/' separators: data/flags/fr.png is "flags/fr.png".
(import "gearbox:assets" "read" (func (param i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
name |
i32 |
pointer into your memory |
name_len |
i32 |
byte length |
buf |
i32 |
pointer into your memory |
cap |
i32 |
byte length |
Returns: i32
Two-call sizing, like country_name. Writes at most cap bytes and returns the asset's full size. The name is looked up in your package's entry list, never resolved as a filesystem path.
Import module gearbox:audio. Requires the Audio capability in your manifest.
(import "gearbox:audio" "play" (func (param i32 i32 f32) (result i32)))| Parameter | Type | |
|---|---|---|
path |
i32 |
pointer into your memory |
path_len |
i32 |
byte length |
volume |
f32 |
Returns: i32
Play a sound from your own mod's assets. path is relative to your mod root; a path outside it is refused rather than resolved. Volume is 0..1 and is multiplied by the player's own effects setting, so a mod cannot be louder than they allowed. Returns a handle, or 0 if it could not be played.
(import "gearbox:audio" "stop" (func (param i32)))| Parameter | Type | |
|---|---|---|
handle |
i32 |
Returns: nothing
Stop a sound this mod started. A handle belonging to another mod, or one that already finished, does nothing.
(import "gearbox:audio" "set_volume" (func (param i32 f32)))| Parameter | Type | |
|---|---|---|
handle |
i32 |
|
volume |
f32 |
Returns: nothing
Change the volume of a playing sound, 0..1, again scaled by the player's setting.
(import "gearbox:audio" "is_playing" (func (param i32) (result i32)))| Parameter | Type | |
|---|---|---|
handle |
i32 |
Returns: i32
Whether that handle is still making sound.
Import module gearbox:net. Requires the Net capability in your manifest.
(import "gearbox:net" "send" (func (param i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
peer |
i32 |
|
data |
i32 |
pointer into your memory |
data_len |
i32 |
byte length |
Returns: i32
Send a message to the same mod running on another peer. peer is a peer id -- the value recv reported in from_peer -- and -1 broadcasts to every other peer, the host included. There is no fixed id for the host: a host that plays holds an ordinary seat, and a dedicated one holds none. The host stamps your mod id on the message, so you cannot send as another mod, and it never carries game traffic: orders, deltas and chat do not travel here. Messages larger than 8192 bytes are refused. Returns 0 if this is not a network game, or the message was too large.
(import "gearbox:net" "recv" (func (param i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
out |
i32 |
pointer into your memory |
out_len |
i32 |
byte length |
from_peer |
i32 |
pointer into your memory |
Returns: i32
Take the next message addressed to this mod, writing it into out and the sender's peer id into from_peer. Returns the number of bytes written, or 0 when the queue is empty. A message longer than out_len is truncated rather than dropped, so a small buffer loses data instead of stalling the queue.
(import "gearbox:net" "peer_count" (func (result i32)))Returns: i32
How many players this session has, a playing host included. 0 when this is not a network game, which is how a mod tells the difference. Spectators are not counted.
(import "gearbox:net" "self_peer" (func (result i32)))Returns: i32
This machine's own peer id. 0 means this is not a network game, or this is a dedicated host holding no seat -- a host that plays has an ordinary peer id like anyone else, so do not use this to tell host from client. is_host is that question.
(import "gearbox:net" "is_host" (func (result i32)))Returns: i32
Whether this copy is the authoritative one. A mod that computes anything the game depends on must do it here and send the result, not compute it separately on each machine.
Import module wasi_snapshot_preview1. Requires the WasiStub capability in your manifest.
(import "wasi_snapshot_preview1" "fd_write" (func (param i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
iovs |
i32 |
|
iovs_len |
i32 |
|
nwritten |
i32 |
Returns: i32
Writes to fd 1 or 2 only, and the bytes go to the mod log where the user can see them. Any other fd returns EBADF. This is how print() in an interpreted mod reaches you.
(import "wasi_snapshot_preview1" "proc_exit" (func (param i32)))| Parameter | Type | |
|---|---|---|
code |
i32 |
Returns: nothing
Traps the mod. A runtime calling exit() must not return into code that believes the process is gone.
(import "wasi_snapshot_preview1" "random_get" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
buf |
i32 |
|
buf_len |
i32 |
Returns: i32
DETERMINISTIC pseudo-random bytes, seeded from your mod id -- not OS entropy. Real entropy is a machine fingerprint and would make self-play and save replay irreproducible. Two mods get different streams; one mod gets the same stream every run. Do not use for anything security-relevant.
(import "wasi_snapshot_preview1" "clock_time_get" (func (param i32 i64 i32) (result i32)))| Parameter | Type | |
|---|---|---|
clock_id |
i32 |
|
precision |
i64 |
|
time |
i32 |
Returns: i32
Returns the turn number expressed as nanoseconds, not the wall clock. Monotonic and coarse. A mod cannot learn the real date, the timezone, or how long anything took -- all of which are fingerprints.
(import "wasi_snapshot_preview1" "environ_sizes_get" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
count |
i32 |
|
buf_size |
i32 |
Returns: i32
Always reports zero variables. There is no environment.
(import "wasi_snapshot_preview1" "environ_get" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
environ |
i32 |
|
buf |
i32 |
Returns: i32
No-op; there is no environment to write.
(import "wasi_snapshot_preview1" "args_sizes_get" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
count |
i32 |
|
buf_size |
i32 |
Returns: i32
Always reports zero arguments. Reports success rather than failing, because runtimes commonly abort at startup if argv cannot be read.
(import "wasi_snapshot_preview1" "args_get" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
argv |
i32 |
|
buf |
i32 |
Returns: i32
No-op; there are no arguments.
(import "wasi_snapshot_preview1" "fd_close" (func (param i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
Returns: i32
EBADF. There are no real descriptors.
(import "wasi_snapshot_preview1" "fd_fdstat_get" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
stat |
i32 |
Returns: i32
ENOTCAPABLE.
(import "wasi_snapshot_preview1" "fd_prestat_get" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
prestat |
i32 |
Returns: i32
ENOTCAPABLE. No preopened directories, so no filesystem root exists to walk.
(import "wasi_snapshot_preview1" "fd_prestat_dir_name" (func (param i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
path |
i32 |
|
path_len |
i32 |
Returns: i32
ENOTCAPABLE.
(import "wasi_snapshot_preview1" "fd_read" (func (param i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
iovs |
i32 |
|
iovs_len |
i32 |
|
nread |
i32 |
Returns: i32
ENOTCAPABLE. There is no stdin and no file to read.
(import "wasi_snapshot_preview1" "fd_seek" (func (param i32 i64 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
offset |
i64 |
|
whence |
i32 |
|
newoffset |
i32 |
Returns: i32
EBADF.
(import "wasi_snapshot_preview1" "path_open" (func (param i32 i32 i32 i32 i32 i64 i64 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
dirfd |
i32 |
|
dirflags |
i32 |
|
path |
i32 |
|
path_len |
i32 |
|
oflags |
i32 |
|
fs_rights_base |
i64 |
|
fs_rights_inheriting |
i64 |
|
fdflags |
i32 |
|
fd |
i32 |
Returns: i32
ENOTCAPABLE, always. Opening a file is refused rather than stubbed -- this is the single import that would turn the shim into the hole the sandbox exists to prevent.
(import "wasi_snapshot_preview1" "clock_res_get" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
id |
i32 |
|
out |
i32 |
Returns: i32
Reports a fixed, coarse resolution matching clock_time_get's one-tick-per-turn granularity. Claiming anything finer would be a lie a runtime might act on.
(import "wasi_snapshot_preview1" "sched_yield" (func (result i32)))Returns: i32
Succeeds and does nothing. A mod is single-threaded; there is nothing to yield to.
(import "wasi_snapshot_preview1" "fd_advise" (func (param i32 i64 i64 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
offset |
i64 |
|
len |
i64 |
|
advice |
i32 |
Returns: i32
Refused (EBADF). There is no filesystem.
(import "wasi_snapshot_preview1" "fd_allocate" (func (param i32 i64 i64) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
offset |
i64 |
|
len |
i64 |
Returns: i32
Refused (EBADF). There is no filesystem.
(import "wasi_snapshot_preview1" "fd_datasync" (func (param i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
Returns: i32
Refused (EBADF). There is no filesystem.
(import "wasi_snapshot_preview1" "fd_sync" (func (param i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
Returns: i32
Refused (EBADF). There is no filesystem.
(import "wasi_snapshot_preview1" "fd_fdstat_set_flags" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
flags |
i32 |
Returns: i32
Refused (EBADF). There is no filesystem.
(import "wasi_snapshot_preview1" "fd_filestat_get" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
out |
i32 |
Returns: i32
Refused (EBADF). File metadata would describe a filesystem the mod cannot reach.
(import "wasi_snapshot_preview1" "fd_tell" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
out |
i32 |
Returns: i32
Refused (EBADF). There is no filesystem.
(import "wasi_snapshot_preview1" "fd_renumber" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
from |
i32 |
|
to |
i32 |
Returns: i32
Refused (EBADF). There are no descriptors to renumber.
(import "wasi_snapshot_preview1" "fd_filestat_set_size" (func (param i32 i64) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
size |
i64 |
Returns: i32
Refused (EBADF). There is no filesystem.
(import "wasi_snapshot_preview1" "fd_filestat_set_times" (func (param i32 i64 i64 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
atim |
i64 |
|
mtim |
i64 |
|
fst_flags |
i32 |
Returns: i32
Refused (EBADF). There is no filesystem.
(import "wasi_snapshot_preview1" "fd_pread" (func (param i32 i32 i32 i64 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
iovs |
i32 |
|
iovs_len |
i32 |
|
offset |
i64 |
|
nread |
i32 |
Returns: i32
Refused (EBADF). Reading is not provided; assets come from the Assets module instead.
(import "wasi_snapshot_preview1" "fd_pwrite" (func (param i32 i32 i32 i64 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
iovs |
i32 |
|
iovs_len |
i32 |
|
offset |
i64 |
|
nwritten |
i32 |
Returns: i32
Refused (EBADF). A mod cannot write files; use the host log.
(import "wasi_snapshot_preview1" "fd_readdir" (func (param i32 i32 i32 i64 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
buf |
i32 |
|
buf_len |
i32 |
|
cookie |
i64 |
|
bufused |
i32 |
Returns: i32
Refused (EBADF). Listing a directory would reveal a filesystem the sandbox denies.
(import "wasi_snapshot_preview1" "path_create_directory" (func (param i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
path |
i32 |
|
path_len |
i32 |
Returns: i32
Refused (ENOTCAPABLE). There is no filesystem, by design.
(import "wasi_snapshot_preview1" "path_remove_directory" (func (param i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
path |
i32 |
|
path_len |
i32 |
Returns: i32
Refused (ENOTCAPABLE). There is no filesystem, by design.
(import "wasi_snapshot_preview1" "path_unlink_file" (func (param i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
path |
i32 |
|
path_len |
i32 |
Returns: i32
Refused (ENOTCAPABLE). There is no filesystem, by design.
(import "wasi_snapshot_preview1" "path_filestat_get" (func (param i32 i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
flags |
i32 |
|
path |
i32 |
|
path_len |
i32 |
|
out |
i32 |
Returns: i32
Refused (ENOTCAPABLE). Answering would tell a mod whether a path exists on your machine.
(import "wasi_snapshot_preview1" "path_symlink" (func (param i32 i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
old_path |
i32 |
|
old_path_len |
i32 |
|
fd |
i32 |
|
new_path |
i32 |
|
new_path_len |
i32 |
Returns: i32
Refused (ENOTCAPABLE). There is no filesystem, by design.
(import "wasi_snapshot_preview1" "path_readlink" (func (param i32 i32 i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
path |
i32 |
|
path_len |
i32 |
|
buf |
i32 |
|
buf_len |
i32 |
|
bufused |
i32 |
Returns: i32
Refused (ENOTCAPABLE). There is no filesystem, by design.
(import "wasi_snapshot_preview1" "path_rename" (func (param i32 i32 i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
old_path |
i32 |
|
old_path_len |
i32 |
|
new_fd |
i32 |
|
new_path |
i32 |
|
new_path_len |
i32 |
Returns: i32
Refused (ENOTCAPABLE). There is no filesystem, by design.
(import "wasi_snapshot_preview1" "path_link" (func (param i32 i32 i32 i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
old_fd |
i32 |
|
old_flags |
i32 |
|
old_path |
i32 |
|
old_path_len |
i32 |
|
new_fd |
i32 |
|
new_path |
i32 |
|
new_path_len |
i32 |
Returns: i32
Refused (ENOTCAPABLE). There is no filesystem, by design.
(import "wasi_snapshot_preview1" "path_filestat_set_times" (func (param i32 i32 i32 i32 i64 i64 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
flags |
i32 |
|
path |
i32 |
|
path_len |
i32 |
|
atim |
i64 |
|
mtim |
i64 |
|
fst_flags |
i32 |
Returns: i32
Refused (ENOTCAPABLE). There is no filesystem, by design.
(import "wasi_snapshot_preview1" "poll_oneoff" (func (param i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
in |
i32 |
|
out |
i32 |
|
nsubscriptions |
i32 |
|
nevents |
i32 |
Returns: i32
Refused (ENOTCAPABLE). There is nothing to poll: no files, no sockets, no timers a mod may wait on.
(import "wasi_snapshot_preview1" "sock_accept" (func (param i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
flags |
i32 |
|
out_fd |
i32 |
Returns: i32
Refused (ENOTCAPABLE). A mod has no network access, which is much of the point of the sandbox.
(import "wasi_snapshot_preview1" "sock_recv" (func (param i32 i32 i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
ri_data |
i32 |
|
ri_data_len |
i32 |
|
ri_flags |
i32 |
|
ro_datalen |
i32 |
|
ro_flags |
i32 |
Returns: i32
Refused (ENOTCAPABLE). A mod has no network access.
(import "wasi_snapshot_preview1" "sock_send" (func (param i32 i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
si_data |
i32 |
|
si_data_len |
i32 |
|
si_flags |
i32 |
|
so_datalen |
i32 |
Returns: i32
Refused (ENOTCAPABLE). A mod has no network access.
(import "wasi_snapshot_preview1" "sock_shutdown" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
fd |
i32 |
|
how |
i32 |
Returns: i32
Refused (EBADF). A mod has no network access.
Import module gearbox:storage. Requires the Storage capability in your manifest.
(import "gearbox:storage" "get" (func (param i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
key |
i32 |
pointer into your memory |
key_len |
i32 |
byte length |
buf |
i32 |
pointer into your memory |
cap |
i32 |
byte length |
Returns: i32
Reads one of your own keys. Two-call sizing: returns the full value length and writes at most cap bytes. Returns GEARBOX_INVALID if the key is absent -- which is NOT the same as a zero-length value, so you can tell 'never stored' from 'stored empty'. Values are arbitrary bytes, not text.
(import "gearbox:storage" "set" (func (param i32 i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
key |
i32 |
pointer into your memory |
key_len |
i32 |
byte length |
value |
i32 |
pointer into your memory |
value_len |
i32 |
byte length |
Returns: i32
Stores bytes under one of your own keys. Returns 1 on success, 0 if a quota was exceeded (256 keys, 128-byte keys, 16 KiB per value, 64 KiB total per mod) -- the reason is written to your log. Not written to disk immediately: the store is flushed at turn boundaries and on unload, because a mod may call this from a draw hook.
(import "gearbox:storage" "remove" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
key |
i32 |
pointer into your memory |
key_len |
i32 |
byte length |
Returns: i32
Deletes one of your own keys. Returns 1 if it existed, 0 if it did not.
Import module gearbox:map. Requires the Map capability in your manifest.
(import "gearbox:map" "width" (func (result i32)))Returns: i32
Width of the province map in pixels. 0 when no world is loaded.
(import "gearbox:map" "height" (func (result i32)))Returns: i32
Height of the province map in pixels. 0 when no world is loaded.
(import "gearbox:map" "province_count" (func (result i32)))Returns: i32
How many provinces the loaded map has. 0 when no world is loaded.
(import "gearbox:map" "province_at" (func (param i32) (result i32)))| Parameter | Type | |
|---|---|---|
index |
i32 |
Returns: i32
Province handle at an index in [0, province_count). Returns GEARBOX_INVALID if out of range. The order is stable across runs, unlike the game's internal storage, so an index is safe to remember within a session.
(import "gearbox:map" "province_name" (func (param i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
province |
i32 |
opaque province handle |
buf |
i32 |
pointer into your memory |
cap |
i32 |
byte length |
Returns: i32
The province's name. Two-call sizing: returns the full length and writes at most cap bytes. Empty for an unknown province.
(import "gearbox:map" "province_center_x" (func (param i32) (result f64)))| Parameter | Type | |
|---|---|---|
province |
i32 |
opaque province handle |
Returns: f64
X pixel coordinate of the province's centre. 0 for an unknown province.
(import "gearbox:map" "province_center_y" (func (param i32) (result f64)))| Parameter | Type | |
|---|---|---|
province |
i32 |
opaque province handle |
Returns: f64
Y pixel coordinate of the province's centre. 0 for an unknown province.
(import "gearbox:map" "province_is_land" (func (param i32) (result i32)))| Parameter | Type | |
|---|---|---|
province |
i32 |
opaque province handle |
Returns: i32
1 if the province is land, 0 if it is sea or unknown. Sampled at the province centre.
(import "gearbox:map" "province_neighbor_count" (func (param i32) (result i32)))| Parameter | Type | |
|---|---|---|
province |
i32 |
opaque province handle |
Returns: i32
How many provinces border this one. 0 for an unknown province.
(import "gearbox:map" "province_neighbor_at" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
province |
i32 |
opaque province handle |
index |
i32 |
Returns: i32
The bordering province at an index in [0, province_neighbor_count). GEARBOX_INVALID if out of range. Adjacency is computed once when the map loads, so walking it is cheap.
Import module gearbox:diplomacy. Requires the Diplomacy capability in your manifest.
(import "gearbox:diplomacy" "at_war" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
a |
i32 |
opaque country handle |
b |
i32 |
opaque country handle |
Returns: i32
1 if the two countries are at war. Relations are symmetric, so the argument order does not matter. 0 for unknown countries or for a country with itself.
(import "gearbox:diplomacy" "allied" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
a |
i32 |
opaque country handle |
b |
i32 |
opaque country handle |
Returns: i32
1 if the two countries are allied.
(import "gearbox:diplomacy" "non_aggression" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
a |
i32 |
opaque country handle |
b |
i32 |
opaque country handle |
Returns: i32
1 if the two countries have a non-aggression pact.
(import "gearbox:diplomacy" "guaranteed" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
a |
i32 |
opaque country handle |
b |
i32 |
opaque country handle |
Returns: i32
1 if the first country guarantees the second.
(import "gearbox:diplomacy" "propose_war" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
attacker |
i32 |
opaque country handle |
defender |
i32 |
opaque country handle |
Returns: i32
PROPOSES a declaration of war, and returns 1 only if the game accepted it. It is routed through the same code path any other actor uses, so guarantee chains and war consequences follow exactly as normal -- a mod cannot produce a diplomatic state the game itself could not reach. Refused (0) if either country is unknown, they are the same country, or they are already at war. Either outcome is written to your mod log, so a player can see after the fact that a mod started a war.
Import module gearbox:gamestate.write. Requires the GameState.Write capability in your manifest.
(import "gearbox:gamestate.write" "set_country_treasury" (func (param i32 f64) (result i32)))| Parameter | Type | |
|---|---|---|
country |
i32 |
opaque country handle |
value |
f64 |
Returns: i32
Sets a country's treasury outright. Returns 1 on success, 0 if the country is unknown or the value is not finite and within +/-1e12 -- NaN or infinity would silently poison every later calculation, so they are refused rather than stored.
(import "gearbox:gamestate.write" "add_country_treasury" (func (param i32 f64) (result i32)))| Parameter | Type | |
|---|---|---|
country |
i32 |
opaque country handle |
delta |
f64 |
Returns: i32
Adds to a country's treasury. Usually what you want instead of set: it composes with whatever the economy did this turn. Refused (0) if the result would leave the sane range.
(import "gearbox:gamestate.write" "set_province_owner" (func (param i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
province |
i32 |
opaque province handle |
country |
i32 |
opaque country handle |
Returns: i32
Transfers a province to another country. Routed through the same code the game's own ceasefires use, so the province, the ownership lookup, the per-pixel country map and both countries' pixel lists all stay consistent -- and the previous owner's troops in that province are disbanded, as they are for any other transfer. Returns 0 if either handle is unknown or the country already owns it. Always written to your mod log: territory changing hands is the most consequential thing a mod can do.
(import "gearbox:gamestate.write" "set_province_population" (func (param i32 i64) (result i32)))| Parameter | Type | |
|---|---|---|
province |
i32 |
opaque province handle |
value |
i64 |
Returns: i32
Sets a province's population. Returns 0 if the province is unknown, the value is negative, or it exceeds 100 billion. The game stores population in two places -- a map and a dense array used by the population texture -- and this updates both, which is why it exists as an import rather than being something a mod could do by other means.
Import module gearbox:neural. Requires the Neural capability in your manifest.
(import "gearbox:neural" "feature_count" (func (result i32)))Returns: i32
How many floats are in the AI's feature vector. 0 when there is no AI or no world.
(import "gearbox:neural" "features" (func (param i32 i32 i32) (result i32)))| Parameter | Type | |
|---|---|---|
country |
i32 |
opaque country handle |
buf |
i32 |
pointer into your memory |
cap |
i32 |
byte length |
Returns: i32
Copies the feature vector the AI would see for a country, as 32-bit floats. Two-call sizing, but note cap counts FLOATS and the buffer must therefore be cap*4 bytes. This is a snapshot: writing to your copy does not affect the AI.
(import "gearbox:neural" "reward_count" (func (result i32)))Returns: i32
How many reward channels the AI tracks (economy, politics, war, navy).
(import "gearbox:neural" "reward_mean" (func (param i32) (result f64)))| Parameter | Type | |
|---|---|---|
index |
i32 |
Returns: f64
The running mean reward for one channel, indexed in [0, reward_count). 0 if out of range. OBSERVE ONLY: this capability has no import that writes to the model, the optimiser state or the reward history, which is deliberate -- a trained model is hours of work and a mod that could quietly retrain it is not something a user can meaningfully consent to.
Functions you provide. Only mod_load is required; a missing
optional export is simply not called.
(func (export "mod_load") (result i32) ...)Required: yes. Capability: none
Called once when your mod is enabled, before anything else. Return 0 to accept the load; non-zero refuses it and the value is shown to the user. There is no autorun, so this runs every session the user enables you -- never assume prior state.
(func (export "mod_unload") ...)Required: no. Capability: none
Called when disabled, reloaded, or at shutdown. Release what you hold. Your state does not survive a reload and there is no hook to serialise it.
(func (export "mod_pre_turn") (param i32) ...)Required: no. Capability: GameProcess
Called before the host processes a turn. Only invoked if GameProcess is granted.
(func (export "mod_post_turn") (param i32) ...)Required: no. Capability: GameProcess
Called after the host processes a turn. Only invoked if GameProcess is granted.
(func (export "mod_draw_panel") (param i32 i32 i32) ...)Required: no. Capability: UI
Called once per frame per visible panel you registered. Never called when headless. Re-issue all your draw calls every frame; the command list is cleared between frames.
28 bytes on wasm32. Layout is part of the ABI:
fields are only appended, never reordered. Write your own struct
size into size before calling env — the host writes at most
that many bytes, so an older mod is safe against a newer host.
| Offset | Field | Type | |
|---|---|---|---|
| 0 | size |
u32 |
You write sizeof(gearbox_env_t) here before calling env |
| 4 | gearbox_major |
u32 |
|
| 8 | gearbox_minor |
u32 |
|
| 12 | host_version |
u32 |
(major<<16) |
| 16 | platform |
u8 |
enum:platform |
| 17 | is_web |
u8 |
1 under Emscripten. Fuel is NOT enforced there. |
| 18 | is_headless |
u8 |
1 when there is no renderer. UI imports no-op. |
| 19 | net_role |
u8 |
enum:net_role. 0 in singleplayer, which is what an older mod reading this byte as reserved already saw. |
| 20 | screen_w |
u32 |
0 when headless |
| 24 | screen_h |
u32 |
0 when headless |
log_level — TRACE=0, INFO=1, WARN=2, ERROR=3
platform — UNKNOWN=0, WINDOWS=1, MACOS=2, LINUX=3, WEB=4
net_role — STANDALONE=0, CLIENT=1, SERVER=2, HOST_PLAYER=3