The engine's stable ABI is a small C header, engine/capi/include/sky_api.h. The SwiftUI editor is built on it, and any language with a C FFI (Swift, Python, Rust, C#, Zig, JavaScript) can embed the engine with it.
Design
Skywalker C API — the stable ABI boundary of the engine.
Why a C API? It is the one interface every language can call without a custom
toolchain: Swift (the macOS editor), Python, Rust, C#, Zig, JavaScript (via FFI)...
It is intentionally narrow: most functionality is reached through sky_call_tool,
the exact same tool surface that agents use over MCP. Only latency-critical paths
(rendering, camera, picking, dragging, input) get dedicated functions.
Ownership: strings returned as char* are heap-allocated and MUST be released with
sky_string_free(). Input strings are borrowed for the duration of the call.
Threading: all functions must be called from the thread that created the engine,
except where noted.
Returns an MCP CallToolResult JSON: {"content":[...],"isError":bool,"structuredContent":{...}}
typedef struct SkyPendingCall SkyPendingCall;
Non-blocking variant for tools that run slow external programs (design apps). Runs the quick part * on the calling (engine) thread. Returns the final result JSON, or NULL when the tool deferred slow * work: then *pending is set. Call sky_pending_run(pending) on ANY thread (it may take seconds), and * afterwards sky_pending_finish on the engine thread, which returns the result JSON and frees it.
void sky_camera_pan(SkyEngine* engine, float dx, float dy); /* fractions of viewport height */ void sky_camera_zoom(SkyEngine* engine, float factor); /* <1 zooms in */ uint64_t sky_pick(SkyEngine* engine, float x, float y, int width, int height); /* 0 = nothing */ void sky_set_selection(SkyEngine* engine, const uint64_t* ids, int count, const char* actor);
int sky_get_selection(SkyEngine* engine, uint64_t* out_ids, int capacity); /* returns count */ void sky_drag_begin(SkyEngine* engine, uint64_t entity, float x, float y, int width, int height);
void sky_drag_update(SkyEngine* engine, float x, float y, int width, int height);
int sky_gizmo_hover(SkyEngine* engine, float x, float y, int width, int height); /* axis or -1 */ int sky_gizmo_begin(SkyEngine* engine, float x, float y, int width, int height); /* 1 if a handle was grabbed */ void sky_gizmo_drag(SkyEngine* engine, float x, float y, int width, int height, int snapping);
void sky_gizmo_end(SkyEngine* engine);
void sky_set_view_scene_camera(SkyEngine* engine, int on);
1 = viewport looks through the scene's primary camera, 0 = editor orbit camera.
Mouse while playing. x, y: cursor position in the viewport, 0..1 from the top-left. dx, dy: movement since the last call in pixels, +y DOWN as on screen (the engine flips it). button: 0 left, 1 right, 2 middle.
void sky_input_mouse_button(SkyEngine* engine, int button, int down);
Typed characters (UTF-8) for UI text fields; delivered with the next tick.
void sky_input_gamepad(SkyEngine* engine, int index, int connected, const char* name, const SkyGamepad* state);
Gamepads. Call once per frame for every connected controller (index 0..3) and once with connected = 0 when one leaves. Sticks -1..1 with +y up, triggers 0..1. buttons is a bitmask in this order: bit 0 south (A / Cross), 1 east (B / Circle), 2 west (X / Square), 3 north (Y / Triangle), 4 left shoulder, 5 right shoulder, 6 left trigger, 7 right trigger, 8 select, 9 start, 10 left stick click, 11 right stick click, 12-15 dpad up/down/left/right, 16 guide.