Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Cheat Sheet

All Nethercore ZX FFI functions on one page.


System

#![allow(unused)]
fn main() {
delta_time() -> f32                    // Seconds since last tick
elapsed_time() -> f32                  // Total seconds since start
tick_count() -> u64                    // Current tick number
log(ptr, len)                          // Log message to console
quit()                                 // Exit to library
random() -> u32                        // Deterministic random u32
random_range(min, max) -> i32          // Random i32 in [min, max)
random_f32() -> f32                    // Random f32 in [0.0, 1.0)
random_f32_range(min, max) -> f32      // Random f32 in [min, max)
player_count() -> u32                  // Number of players (1-4)
local_player_mask() -> u32             // Bitmask of local players
}

Screen Constants: screen::WIDTH=960, screen::HEIGHT=540


Configuration (Init-Only)

#![allow(unused)]
fn main() {
set_tick_rate(fps)                     // 0=24, 1=30, 2=60, 3=120
set_clear_color(0xRRGGBBAA)            // Background color
// render_mode set via nether.toml     // 0=Lambert, 1=Matcap, 2=MR, 3=SS
}

Input

#![allow(unused)]
fn main() {
// Buttons (player: 0-3, button: 0-13)
button_held(player, button) -> u32     // 1 if held
button_pressed(player, button) -> u32  // 1 if just pressed
button_released(player, button) -> u32 // 1 if just released
buttons_held(player) -> u32            // Bitmask of held
buttons_pressed(player) -> u32         // Bitmask of pressed
buttons_released(player) -> u32        // Bitmask of released

// Sticks (-1.0 to 1.0)
left_stick_x(player) -> f32
left_stick_y(player) -> f32
right_stick_x(player) -> f32
right_stick_y(player) -> f32
left_stick(player, &mut x, &mut y)     // Both axes
right_stick(player, &mut x, &mut y)

// Triggers (0.0 to 1.0)
trigger_left(player) -> f32
trigger_right(player) -> f32
}

Button Constants: UP=0, DOWN=1, LEFT=2, RIGHT=3, A=4, B=5, X=6, Y=7, LB=8, RB=9, L3=10, R3=11, START=12, SELECT=13


Camera

#![allow(unused)]
fn main() {
camera_set(x, y, z, target_x, target_y, target_z)
camera_fov(degrees)                    // Default: 60
push_view_matrix(m0..m15)              // Custom 4x4 view matrix
push_projection_matrix(m0..m15)        // Custom 4x4 projection
}

Transforms

#![allow(unused)]
fn main() {
push_identity()                        // Reset to identity
transform_set(matrix_ptr)              // Set from 4x4 matrix
push_translate(x, y, z)
push_rotate_x(degrees)
push_rotate_y(degrees)
push_rotate_z(degrees)
push_rotate(degrees, axis_x, axis_y, axis_z)
push_scale(x, y, z)
push_scale_uniform(s)
}

Render State

#![allow(unused)]
fn main() {
set_color(0xRRGGBBAA)                  // Tint color
cull_mode(mode)                        // 0=none (default), 1=back, 2=front
texture_filter(filter)                 // 0=nearest, 1=linear
uniform_alpha(level)                   // 0-15 dither alpha
dither_offset(x, y)                    // 0-3 pattern offset
z_index(n)                             // 2D ordering within pass (0=back, higher=front)
}

Render Passes (Execution Barriers)

#![allow(unused)]
fn main() {
begin_pass(clear_depth)                // New pass with optional depth clear
begin_pass_stencil_write(ref_val, clear_depth)  // Create stencil mask
begin_pass_stencil_test(ref_val, clear_depth)   // Render inside mask
begin_pass_full(...)                   // Full control (8 params)
}

Use Cases:

  • FPS viewmodels: begin_pass(1) clears depth, gun renders on top
  • Portals: begin_pass_stencil_write(1,0) then begin_pass_stencil_test(1,1)

Textures

#![allow(unused)]
fn main() {
load_texture(w, h, pixels_ptr) -> u32  // Init-only, returns handle
texture_bind(handle)                   // Bind to slot 0
texture_bind_slot(handle, slot)        // Bind to slot 0-3
matcap_blend_mode(slot, mode)          // 0=mul, 1=add, 2=hsv
}

Meshes

#![allow(unused)]
fn main() {
// Retained (init-only)
load_mesh(data_ptr, vertex_count, format) -> u32
load_mesh_indexed(data_ptr, vcount, idx_ptr, icount, fmt) -> u32
load_mesh_packed(data_ptr, vertex_count, format) -> u32
load_mesh_indexed_packed(data_ptr, vcount, idx_ptr, icount, fmt) -> u32
draw_mesh(handle)

// Immediate
draw_triangles(data_ptr, vertex_count, format)
draw_triangles_indexed(data_ptr, vcount, idx_ptr, icount, fmt)
}

Vertex Formats: POS=0, UV=1, COLOR=2, UV_COLOR=3, NORMAL=4, UV_NORMAL=5, COLOR_NORMAL=6, UV_COLOR_NORMAL=7, SKINNED=8, TANGENT=16 (combine with NORMAL)


Procedural Meshes (Init-Only)

#![allow(unused)]
fn main() {
cube(sx, sy, sz) -> u32
sphere(radius, segments, rings) -> u32
cylinder(r_bot, r_top, height, segments) -> u32
plane(sx, sz, subdiv_x, subdiv_z) -> u32
torus(major_r, minor_r, major_seg, minor_seg) -> u32
capsule(radius, height, segments, rings) -> u32

// With explicit UV naming (same behavior)
cube_uv, sphere_uv, cylinder_uv, plane_uv, torus_uv, capsule_uv
}

Materials

#![allow(unused)]
fn main() {
// Mode 2 (Metallic-Roughness)
material_metallic(value)               // 0.0-1.0
material_roughness(value)              // 0.0-1.0
material_emissive(value)               // Glow intensity
material_rim(intensity, power)         // Rim light
material_albedo(texture)               // Bind to slot 0
material_mre(texture)                  // Bind MRE to slot 1
material_normal(texture)               // Bind normal map to slot 3

// Mode 3 (Specular-Shininess)
material_shininess(value)              // 0.0-1.0 → 1-256
material_specular(0xRRGGBBAA)          // Specular color

// Override flags
use_uniform_color(enabled)
use_uniform_metallic(enabled)
use_uniform_roughness(enabled)
use_uniform_emissive(enabled)
skip_normal_map(skip)                  // 0=use normal map, 1=use vertex normal
}

Lighting

#![allow(unused)]
fn main() {
// Directional lights (index 0-3)
light_set(index, dir_x, dir_y, dir_z)
light_color(index, 0xRRGGBBAA)
light_intensity(index, intensity)      // 0.0-8.0
light_enable(index)
light_disable(index)

// Point lights
light_set_point(index, x, y, z)
light_range(index, range)
}

Environment Processing Unit (EPU)

The EPU renders procedural environment backgrounds and provides ambient/reflection lighting via a packed 128-byte configuration (8 x 128-bit instructions).

Push API

#![allow(unused)]
fn main() {
fn environment_index(env_id: u32);
fn epu_set(config_ptr: *const u64);
fn draw_epu();
}

Config Layout

  • 16 x u64 (128 bytes total): hi0, lo0, hi1, lo1, ... hi7, lo7

Instruction Layout (128-bit per layer)

u64 hi [bits 127..64]:
  [127:123] opcode     (5)
  [122:120] region     (3)  - SKY=4, WALLS=2, FLOOR=1, ALL=7
  [119:117] blend      (3)  - ADD=0, MULTIPLY=1, MAX=2, LERP=3, SCREEN=4, HSV_MOD=5, MIN=6, OVERLAY=7
  [116:112] meta5      (5)  - (domain_id<<3)|variant_id; use 0 when unused
  [111:88]  color_a    (24) - RGB24 primary color
  [87:64]   color_b    (24) - RGB24 secondary color

u64 lo [bits 63..0]:
  [63:56]   intensity  (8)
  [55:48]   param_a    (8)
  [47:40]   param_b    (8)
  [39:32]   param_c    (8)
  [31:24]   param_d    (8)
  [23:8]    direction  (16) - octahedral encoded (u8,u8)
  [7:4]     alpha_a    (4)
  [3:0]     alpha_b    (4)

Opcodes (current shaders)

NOP=0x00, RAMP=0x01, SECTOR=0x02, SILHOUETTE=0x03, SPLIT=0x04, CELL=0x05, PATCHES=0x06, APERTURE=0x07, DECAL=0x08, GRID=0x09, SCATTER=0x0A, FLOW=0x0B, TRACE=0x0C, VEIL=0x0D, ATMOSPHERE=0x0E, PLANE=0x0F, CELESTIAL=0x10, PORTAL=0x11, LOBE=0x12, BAND=0x13.

See EPU API Reference and EPU Feature Catalog.


2D Drawing

Note: Use set_color(0xRRGGBBAA) before drawing to set the tint color. Source coordinates (src_*) are UV values (0.0-1.0), not pixels.

#![allow(unused)]
fn main() {
// Sprites (use set_color() for tinting)
draw_sprite(x, y, w, h)
draw_sprite_region(x, y, w, h, src_x, src_y, src_w, src_h)  // UV coords (0.0-1.0)
draw_sprite_ex(x, y, w, h, src_x, src_y, src_w, src_h, ox, oy, angle)

// Primitives (use set_color() for color)
draw_rect(x, y, w, h)
draw_line(x1, y1, x2, y2, thickness)
draw_circle(x, y, radius)                      // Filled, 16 segments
draw_circle_outline(x, y, radius, thickness)

// Text (use set_color() for color)
draw_text(ptr, len, x, y, size)
text_width(ptr, len, size) -> f32              // Measure text width
load_font(tex, char_w, char_h, first_cp, count) -> u32
load_font_ex(tex, widths_ptr, char_h, first_cp, count) -> u32
font_bind(handle)
}

Billboards

Note: Use set_color(0xRRGGBBAA) before drawing to set the tint color. UV coordinates are 0.0-1.0.

#![allow(unused)]
fn main() {
draw_billboard(w, h, mode)             // mode: 1=sphere, 2=cylY, 3=cylX, 4=cylZ
draw_billboard_region(w, h, sx, sy, sw, sh, mode)  // UV coords (0.0-1.0)
}

Skinning

#![allow(unused)]
fn main() {
load_skeleton(inverse_bind_ptr, bone_count) -> u32  // Init-only
skeleton_bind(skeleton)                // 0 to disable
set_bones(matrices_ptr, count)         // 12 floats per bone (3x4)
set_bones_4x4(matrices_ptr, count)     // 16 floats per bone (4x4)
}

Animation

#![allow(unused)]
fn main() {
keyframes_load(data_ptr, byte_size) -> u32  // Init-only
rom_keyframes(id_ptr, id_len) -> u32        // Init-only
keyframes_bone_count(handle) -> u32
keyframes_frame_count(handle) -> u32
keyframe_bind(handle, frame_index)          // GPU-side, no CPU decode
keyframe_read(handle, frame_index, out_ptr) // Read to WASM for blending
}

Audio (SFX)

#![allow(unused)]
fn main() {
load_sound(data_ptr, byte_len) -> u32  // Init-only, 22kHz 16-bit mono
play_sound(sound, volume, pan)         // Auto-select channel
channel_play(ch, sound, vol, pan, loop)
channel_set(ch, volume, pan)
channel_stop(ch)
}

Unified Music API (PCM + XM Tracker)

Works with both PCM sounds and XM tracker modules. Handle type detected by bit 31 (0=PCM, 1=tracker).

#![allow(unused)]
fn main() {
// Loading (init-only)
rom_tracker(id_ptr, id_len) -> u32     // Load XM from ROM (returns tracker handle)
load_tracker(data_ptr, len) -> u32     // Load XM from raw data

// Playback (works for both PCM and tracker)
music_play(handle, volume, looping)    // Start playing (auto-stops other type)
music_stop()                            // Stop all music
music_pause(paused)                     // 0=resume, 1=pause (tracker only)
music_set_volume(volume)                // 0.0-1.0
music_is_playing() -> u32               // 1 if playing
music_type() -> u32                     // 0=none, 1=PCM, 2=tracker

// Position (tracker-specific, no-op for PCM)
music_jump(order, row)                  // Jump to position
music_position() -> u32                 // Tracker: (order << 16) | row, PCM: sample pos
music_length(handle) -> u32             // Tracker: orders, PCM: samples
music_set_speed(speed)                  // Ticks per row (1-31)
music_set_tempo(bpm)                    // BPM (32-255)

// Query
music_info(handle) -> u32               // Tracker: (ch<<24)|(pat<<16)|(inst<<8)|len
music_name(handle, out_ptr, max) -> u32 // Tracker only (returns 0 for PCM)
}

Note: PCM and tracker music are mutually exclusive. Starting one stops the other. Load samples via rom_sound() before rom_tracker() to map tracker instruments.


Save Data

#![allow(unused)]
fn main() {
save(slot, data_ptr, data_len) -> u32  // 0=ok, 1=bad slot, 2=too big
load(slot, data_ptr, max_len) -> u32   // Returns bytes read
delete(slot) -> u32                    // 0=ok, 1=bad slot
}

ROM Loading (Init-Only)

#![allow(unused)]
fn main() {
rom_texture(id_ptr, id_len) -> u32
rom_mesh(id_ptr, id_len) -> u32
rom_skeleton(id_ptr, id_len) -> u32
rom_font(id_ptr, id_len) -> u32
rom_sound(id_ptr, id_len) -> u32
rom_keyframes(id_ptr, id_len) -> u32
rom_tracker(id_ptr, id_len) -> u32     // Load XM tracker
rom_data_len(id_ptr, id_len) -> u32
rom_data(id_ptr, id_len, out_ptr, max_len) -> u32
}

Debug

#![allow(unused)]
fn main() {
// Registration (init-only)
debug_register_i8/i16/i32(name_ptr, name_len, ptr)
debug_register_u8/u16/u32(name_ptr, name_len, ptr)
debug_register_f32(name_ptr, name_len, ptr)
debug_register_bool(name_ptr, name_len, ptr)
debug_register_i32_range(name_ptr, name_len, ptr, min, max)
debug_register_f32_range(name_ptr, name_len, ptr, min, max)
debug_register_u8_range/u16_range/i16_range(...)
debug_register_vec2/vec3/rect/color(name_ptr, name_len, ptr)
debug_register_fixed_i16_q8/i32_q8/i32_q16/i32_q24(...)

// Watch (read-only)
debug_watch_i8/i16/i32/u8/u16/u32/f32/bool(name_ptr, name_len, ptr)
debug_watch_vec2/vec3/rect/color(name_ptr, name_len, ptr)

// Groups
debug_group_begin(name_ptr, name_len)
debug_group_end()

// Frame control
debug_is_paused() -> i32               // 1 if paused
debug_get_time_scale() -> f32          // 1.0 = normal
}

Keyboard: F2=settings, F3=stats, F4=inspector, F5=pause, F6=step, F7/F8=time scale, `=EPU panel (ZX), F12=network