Scubywasm API
C ABI for WebAssembly agents and engine
Loading...
Searching...
No Matches
Scubywasm C APIs

This documentation covers the C-level APIs used by Scubywasm:

  • the agent ABI that a WebAssembly agent module must export, and
  • the engine API used by hosts/tools to run rounds and query game state.

Game rules and project overview are documented in README.md.

Start here

Agent ABI (WASM modules)

This ABI describes what an agent module must export so it can be driven by the host. Although the ABI is expressed in C (for precise types and calling conventions), agents do not have to be authored in C. You may write an agent in any language that can be compiled to WASM, as long as the resulting module exports the required entry points with compatible signatures and semantics.

What the header provides

The header documentation is the single source of truth for:

  • The required exported functions (the full API surface).
  • Parameter and data type semantics.
  • The host-driven call pattern (initialization, per-tick updates, action queries, shutdown).

If you implement the exported functions with the documented behavior, your WASM module is a valid Scubywasm agent.

Minimal example implementation

#include "scubywasm_agent.h"

#include <stddef.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C"
{
#endif

__attribute__((import_module("debug"), import_name("debug_log"))) void
host_debug_log(uint32_t ptr, uint32_t len);

static void log(const char *s)
{
    uint32_t n = 0;
    while (s[n] != '\0')
    {
        n++;
    }

    host_debug_log((uint32_t)(uintptr_t)s, n);
}

struct Context *init_agent(uint32_t /*n_agents*/,
                           uint32_t /*agent_multiplicity*/,
                           uint32_t /*seed*/)
{
    log("hello from freestanding agent");

    return NULL;
}

void free_context(struct Context * /*ctx*/)
{
}

void set_config_parameter(struct Context * /*ctx*/,
                          enum ConfigParameter /*p*/,
                          float /*value*/)
{
}

void clear_world_state(struct Context * /*ctx*/)
{
}

void update_ship(struct Context * /*ctx*/,
                 uint32_t /*agent_id*/,
                 int32_t /*hp*/,
                 float /*x*/,
                 float /*y*/,
                 float /*heading*/)
{
}

void update_shot(struct Context * /*ctx*/,
                 uint32_t /*agent_id*/,
                 int32_t /*lifetime*/,
                 float /*x*/,
                 float /*y*/,
                 float /*heading*/)
{
}

void update_score(struct Context * /*ctx*/,
                  uint32_t /*agent_id*/,
                  int32_t /*score*/)
{
}

uint32_t
make_action(struct Context * /*ctx*/, uint32_t /*agent_id*/, uint32_t /*tick*/)
{
    return ACTION_THRUST | ACTION_TURN_LEFT | ACTION_FIRE;
}

#ifdef __cplusplus
}
#endif

Engine API (hosts and tools)

The engine API is used to run a round: create a context, add ships, process per-tick actions, advance time, and observe state (poses, shots, alive status, score).

The engine.h documentation also explains the FREESTANDING build mode and the singleton argument buffers (e.g., get_pose_buffer(), get_config_buffer()) that exist primarily for WASM/freestanding usage.