π¦ ABI Reference β Functions and Usage Contract
This document describes the public C-ABI exposed by Vulfram and the contract expected from hosts and language bindings.
It is intended for:
- Binding authors (N-API,
mlua,PyO3, etc.) - Advanced users integrating Vulfram at a low level
1. Global Conventions
1.1 Return Type: `VulframResult (u32)`
All vulfram_* functions return a u32 status code:
0β success (VULFRAM_SUCCESS)- non-zero β error (
VulframResultenum)
Bindings should translate errors into the host language (throw, return error, etc.).
1.2 Threading and Reentrancy
- All ABI calls are main-thread only.
- Do not call Vulfram from multiple threads at the same time.
1.3 WASM Mode Differences (Browser)
- Browser-only:
vulfram_init()fails ifwindowis not available. - Canvas required:
cmd-window-createneedscanvasId(DOM canvas). - Window APIs are limited: some window commands (position, size, decorations, icon, state) are not supported in WASM and return errors.
- Event loop is the browser: input events come from DOM listeners and are delivered via
vulfram_receive_events.
1.4 Serialization Format
All structured data crossing the ABI uses MessagePack:
- Commands (
vulfram_send_queue) - Responses (
vulfram_receive_queue) - Events (
vulfram_receive_events) - Profiling (
vulfram_get_profiling)
1.5 Output Buffers (`out_ptr`, `out_length`)
Several functions return data through pointer-out parameters:
c
u32 vulfram_xxx(uint8_t** out_ptr, size_t* out_length);
Contract:
- The core allocates a buffer and returns pointer + length.
- The binding copies it into host memory.
- The binding frees the core buffer using the provided mechanism.
Notes on current transports:
- WASM: the JS wrapper calls
result.free()after copying the data. - N-API: the core buffer is converted into a Node.js
Buffer(Rust takes back ownership). - Bun FFI: data is copied into a
Buffer, but there is currently no explicit free call exposed in the FFI surface (add one if you need to avoid leaks).
The game/app code never touches raw pointers directly.
2. Function List
2.1 Initialization and Shutdown
c
u32 vulfram_init(void);
u32 vulfram_dispose(void);
vulfram_init()initializes global state and must be called once.vulfram_dispose()frees resources and ends the session.
2.2 Command Queue (Host β Core)
c
u32 vulfram_send_queue(const uint8_t* buffer, size_t length);
bufferis a MessagePack batch of commands.- Commands are processed on the next
vulfram_tick.
2.3 Response Queue (Core β Host)
c
u32 vulfram_receive_queue(uint8_t** out_ptr, size_t* out_length);
- Returns a MessagePack batch of responses (ACKs, errors, info).
out_length == 0means βno responses availableβ.- Calling this consumes the internal response queue.
2.4 Event Queue (Input / Window)
c
u32 vulfram_receive_events(uint8_t** out_ptr, size_t* out_length);
- Returns a MessagePack batch of input and window events.
- Same ownership rules as
vulfram_receive_queue.
2.5 Upload Raw Blobs
c
u32 vulfram_upload_buffer(uint64_t id,
uint32_t type,
const uint8_t* buffer,
size_t length);
- Uploads heavy data (meshes, textures, etc.) into the core.
idis the host-chosenBufferIdreferenced by laterCreate*commands.- Uploads are one-shot: consumed and then freed.
2.6 Advance the Core
c
u32 vulfram_tick(uint64_t time, uint32_t delta_time);
This drives the entire engine for one frame:
- Processes queued commands
- Updates internal state
- Collects input/window events
- Executes rendering
- Prepares responses/events/profiling for the host
2.7 Profiling Data
c
u32 vulfram_get_profiling(uint8_t** out_ptr, size_t* out_length);
Returns a MessagePack blob with timing and counters for the last frame.
3. Recommended Frame Loop
A safe and common order per frame:
- Update host logic
- Upload blobs (optional)
vulfram_send_queuevulfram_tickvulfram_receive_queuevulfram_receive_eventsvulfram_get_profiling(optional)
4. Error Handling Guidelines
- Any non-zero return should be surfaced as an error to the host.
- For details, poll
vulfram_receive_queuefor structured error responses.
5. Common Binding Pitfalls
- Skipping copy/free of output buffers β memory leaks.
- Calling from multiple threads β undefined behavior.
- Reusing
BufferIds without cleanup β upload conflicts.
Documentation Vulfram Core