|
Scubywasm API
C ABI for WebAssembly agents and engine
|
#include <stdint.h>
Go to the source code of this file.
Data Structures | |
| struct | Config |
| Engine configuration. More... | |
| struct | Pose |
| Pose on the unit torus. More... | |
Enumerations | |
| enum | ActionFlags : unsigned int { ACTION_NONE = 0U , ACTION_THRUST = 1U , ACTION_TURN_LEFT = 2U , ACTION_TURN_RIGHT = 4U , ACTION_FIRE = 8U } |
| Action bitmask. More... | |
Functions | |
| struct Config * | get_config_buffer (void) |
| Return a pointer to a module-owned Config singleton buffer. | |
| void | set_default_config (struct Config *cfg) |
| Initialize a Config to engine defaults. | |
| struct Context * | create_context (const struct Config *cfg) |
| Create a new engine context (start a new round). | |
| void | free_context (struct Context *ctx) |
| Destroy a context created by create_context(). | |
| struct Pose * | get_pose_buffer (void) |
| Return a pointer to a module-owned Pose singleton buffer. | |
| uint32_t | add_agent (struct Context *ctx, const struct Pose *pose) |
| Add a new ship/agent to the round. | |
| int32_t | set_action (struct Context *ctx, uint32_t agent_id, enum ActionFlags flags) |
| Process an agent action for the next tick. | |
| uint32_t | tick (struct Context *ctx, uint32_t n_times) |
| Advance the simulation by one or more ticks. | |
| void | get_ship_pose (const struct Context *ctx, uint32_t agent_id, struct Pose *pose) |
| Get the current pose of a ship. | |
| int32_t | get_shot_pose (const struct Context *ctx, uint32_t agent_id, struct Pose *pose) |
| Get the current pose of the active shot of a ship. | |
| int32_t | is_alive (const struct Context *ctx, uint32_t agent_id) |
| Check whether a ship is alive. | |
| int32_t | get_score (const struct Context *ctx, uint32_t agent_id) |
| Get the current score of a ship. | |
Scubywasm engine ABI.
This header defines the C ABI of the Scubywasm engine (the simulation core). It is designed to be:
Typical call pattern
The engine is driven in three phases:
1) Configuration
2) Round execution
3) Shutdown
Hosted vs. freestanding builds
The compile-time macro FREESTANDING controls whether the engine provides helper APIs intended for WASM / freestanding use.
FREESTANDING is 1:FREESTANDING is 0:
Why singleton buffers exist (WASM use-case)
In WASM, the engine module owns its linear memory. External callers often cannot simply take the address of a host-allocated Pose/Config and pass it across the ABI boundary. The singleton buffer helpers solve this by letting the module provide stable storage:
This avoids requiring a general-purpose allocator inside the module and keeps argument passing simple and deterministic.
Coordinate conventions
The implicit coordinate conventions are:
x and y live on a unit torus with values in [0, 1).heading is in degrees in [0, 360) with:| struct Config |
Engine configuration.
This structure defines the relevant game dynamics and constraints that callers (and agents, indirectly) should use for planning (movement, turning, shooting, collision avoidance, etc.).
The configuration is provided exactly once during initialization via create_context() and is never changed thereafter for a given Context.
Typical usage:
In freestanding/WASM builds, callers typically use get_config_buffer() instead of stack/heap allocation.
| struct Pose |
Pose on the unit torus.
A pose describes position and orientation in the engine's 2D world:
x and y are coordinates on the unit torus in the interval [0, 1).heading is an orientation angle in degrees in [0, 360) with:In freestanding/WASM builds, callers typically populate a Pose via get_pose_buffer() (module-owned singleton storage) rather than passing a pointer to host-allocated memory.
| Data Fields | ||
|---|---|---|
| float | heading | Heading in degrees in [0, 360). |
| float | x | x-position in [0, 1). |
| float | y | y-position in [0, 1). |
| enum ActionFlags : unsigned int |
Action bitmask.
The engine interprets the argument of set_action() as a bitwise OR of these flags. Unless explicitly stated otherwise, flags are combinable.
Dynamics (turn rate, max velocity, shot velocity, lifetimes, etc.) are defined by the current configuration as provided via create_context() using Config.
ACTION_TURN_LEFT and ACTION_TURN_RIGHT are logically mutually exclusive. If a caller sets both, the engine may ignore both, pick one deterministically, or apply an engine-defined tie-breaker.
| Enumerator | |
|---|---|
| ACTION_NONE | Do nothing this tick. |
| ACTION_THRUST | Enable thrust for this tick. Ship speed is binary: either zero or the configured maximum. If |
| ACTION_TURN_LEFT | Turn left for this tick. Turning is binary: if |
| ACTION_TURN_RIGHT | Turn right for this tick. Turning is binary: if |
| ACTION_FIRE | Fire a shot. Shots travel with velocity |
| uint32_t add_agent | ( | struct Context * | ctx, |
| const struct Pose * | pose | ||
| ) |
Add a new ship/agent to the round.
Registers a new ship in ctx and assigns it a fresh 32-bit agent_id. The returned agent_id is the handle used by all other per-ship engine API calls (e.g., set_action(), get_ship_pose(), get_shot_pose(), is_alive(), get_score()).
This function is intended for round setup after create_context() and before the first tick().
| ctx | Engine context. |
| pose | Initial ship pose (see Pose). |
agent_id identifying the newly added ship. Agent IDs are not required to be zero-based nor sequential; callers must not assume any particular numbering scheme.ctx and pose must not be NULL.pose is typically populated via get_pose_buffer() (module-owned singleton storage). | struct Context * create_context | ( | const struct Config * | cfg | ) |
Create a new engine context (start a new round).
Allocates and initializes a fresh Context using the provided configuration. The returned context is independent from any other context and represents a single round.
| cfg | Immutable configuration for the new round. |
Context on success, or NULL on failure (for example, if static resources are exhausted in freestanding builds).cfg must not be NULL.| void free_context | ( | struct Context * | ctx | ) |
Destroy a context created by create_context().
Releases all resources owned by ctx.
| ctx | Context pointer returned by create_context(). If NULL, the function has no effect. |
| struct Config * get_config_buffer | ( | void | ) |
Return a pointer to a module-owned Config singleton buffer.
This helper exists for freestanding/WASM builds where the caller cannot conveniently allocate a Config inside the engine module. It provides module-owned storage that can be populated in-place and then passed to create_context().
Typical usage:
| struct Pose * get_pose_buffer | ( | void | ) |
Return a pointer to a module-owned Pose singleton buffer.
This helper exists for freestanding/WASM builds where the caller cannot conveniently allocate a Pose inside the engine module. The returned buffer can be used to pass poses into the engine without directly interacting with the module's linear memory allocation scheme.
Typical usage:
| int32_t get_score | ( | const struct Context * | ctx, |
| uint32_t | agent_id | ||
| ) |
Get the current score of a ship.
Returns the score accumulated by agent_id in the current round. Score updates occur during tick() (e.g., when shots hit or ships are destroyed), so callers typically query scores after advancing the simulation.
| ctx | Engine context. |
| agent_id | Ship/agent identifier. |
ctx must not be NULL.| void get_ship_pose | ( | const struct Context * | ctx, |
| uint32_t | agent_id, | ||
| struct Pose * | pose | ||
| ) |
Get the current pose of a ship.
Writes the current ship pose (position on the unit torus and heading) of agent_id into pose.
| ctx | Engine context. |
| agent_id | Ship/agent identifier. |
| pose | Output pointer receiving the ship pose. |
ctx and pose must not be NULL.| int32_t get_shot_pose | ( | const struct Context * | ctx, |
| uint32_t | agent_id, | ||
| struct Pose * | pose | ||
| ) |
Get the current pose of the active shot of a ship.
If agent_id currently has an active shot, writes its pose into pose and returns the remaining lifetime of that shot (in ticks). If no shot is active, returns 0.
| ctx | Engine context. |
| agent_id | Ship/agent identifier (shot owner). |
| pose | Output pointer receiving the shot pose if a shot is active. |
ctx and pose must not be NULL.pose are unspecified.| int32_t is_alive | ( | const struct Context * | ctx, |
| uint32_t | agent_id | ||
| ) |
Check whether a ship is alive.
A ship is either alive (1) or not alive (0). Ships may transition from alive to not alive during tick() (e.g., due to collisions).
| ctx | Engine context. |
| agent_id | Ship/agent identifier. |
1 if the ship is alive, 0 if it is not alive.ctx must not be NULL.| int32_t set_action | ( | struct Context * | ctx, |
| uint32_t | agent_id, | ||
| enum ActionFlags | flags | ||
| ) |
Process an agent action for the next tick.
Interprets flags as a bitwise OR of ActionFlags and updates the corresponding state in ctx immediately (ship kinematics and, if requested and allowed, shot creation), using the configuration embedded in the context (see Config).
Call this exactly once per ship per simulation tick, before calling tick().
agent_id within a single tick. The function performs immediate state updates; repeated calls will stack effects in engine-defined ways. Nothing good comes of it.| ctx | Engine context. |
| agent_id | Ship/agent identifier. |
| flags | Bitmask of ActionFlags. |
| void set_default_config | ( | struct Config * | cfg | ) |
Initialize a Config to engine defaults.
Writes a complete default configuration into cfg. Callers may override individual fields afterwards before passing the configuration to create_context().
| cfg | Output pointer to the configuration to initialize. |
cfg must not be NULL.| uint32_t tick | ( | struct Context * | ctx, |
| uint32_t | n_times | ||
| ) |
Advance the simulation by one or more ticks.
Advances the engine state in ctx by n_times simulation ticks. This updates all time-dependent state (ship/shot motion, lifetimes, collisions, scoring, etc.).
tick() may be called repeatedly without any additional setup. In particular, if no new actions are processed via set_action(), the simulation simply continues from the current ship state.
| ctx | Engine context. |
| n_times | Number of ticks to simulate. |
ctx must not be NULL.