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

Graphics Configuration

Console configuration and render state functions.

Configuration (Init-Only)

These functions must be called in init() and cannot be changed at runtime.

set_tick_rate

Sets the game’s tick rate (updates per second).

Signature:

#![allow(unused)]
fn main() {
fn set_tick_rate(fps: u32)
}

Parameters:

ValueTick Rate
024 fps
130 fps
260 fps - default
3120 fps

Constraints: Init-only. Affects GGRS synchronization.

Example:

#![allow(unused)]
fn main() {
fn init() {
    set_tick_rate(2); // 60 fps
}
}

set_clear_color

Sets the background clear color.

Signature:

#![allow(unused)]
fn main() {
fn set_clear_color(color: u32)
}

Parameters:

NameTypeDescription
coloru32RGBA color as 0xRRGGBBAA

Constraints: Init-only. Default is 0x000000FF (black).

Example:

#![allow(unused)]
fn main() {
fn init() {
    set_clear_color(0x1a1a2eFF); // Dark blue
    set_clear_color(0x87CEEBFF); // Sky blue
}
}

render_mode

Sets the rendering mode (shader pipeline).

Signature:

#![allow(unused)]
fn main() {
fn render_mode(mode: u32)
}

Parameters:

ValueModeDescription
0LambertSimple diffuse shading
1MatcapPre-baked lighting via matcap textures
2Metallic-RoughnessPBR-style Blinn-Phong with MRE textures
3Specular-ShininessTraditional Blinn-Phong

Constraints: Init-only. Default is mode 0 (Lambert).

Example:

#![allow(unused)]
fn main() {
fn init() {
    render_mode(2); // PBR-style lighting
}
}

See Also: Render Modes Guide


Render State

These functions can be called anytime during render() to change draw state.

set_color

Sets the uniform tint color for subsequent draws.

Signature:

#![allow(unused)]
fn main() {
fn set_color(color: u32)
}

Parameters:

NameTypeDescription
coloru32RGBA color as 0xRRGGBBAA

Example:

#![allow(unused)]
fn main() {
fn render() {
    // White (no tint)
    set_color(0xFFFFFFFF);
    draw_mesh(model);

    // Red tint
    set_color(0xFF0000FF);
    draw_mesh(enemy);

    // 50% transparent
    set_color(0xFFFFFF80);
    draw_mesh(ghost);
}
}

cull_mode

Sets face culling mode.

Signature:

#![allow(unused)]
fn main() {
fn cull_mode(mode: u32)
}

Parameters:

ValueModeDescription
0NoneDraw both sides (default)
1BackCull back faces
2FrontCull front faces

Example:

#![allow(unused)]
fn main() {
fn render() {
    // Normal geometry
    cull_mode(1); // Back-face culling
    draw_mesh(solid_object);

    // Skybox (inside-out)
    cull_mode(2); // Front-face culling
    draw_mesh(skybox);

    // Double-sided foliage
    cull_mode(0); // No culling
    draw_mesh(leaves);
}
}

texture_filter

Sets texture filtering mode.

Signature:

#![allow(unused)]
fn main() {
fn texture_filter(filter: u32)
}

Parameters:

ValueModeDescription
0NearestPixelated (retro look)
1LinearSmooth (modern look)

Example:

#![allow(unused)]
fn main() {
fn render() {
    // Pixel art sprites
    texture_filter(0);
    set_color(0xFFFFFFFF);
    draw_sprite(0.0, 0.0, 64.0, 64.0);

    // Photo textures
    texture_filter(1);
    draw_mesh(realistic_model);
}
}

uniform_alpha

Sets the dither alpha level for PS1-style transparency.

Signature:

#![allow(unused)]
fn main() {
fn uniform_alpha(level: u32)
}

Parameters:

NameTypeDescription
levelu32Alpha level 0-15 (0 = invisible, 15 = opaque)

Example:

#![allow(unused)]
fn main() {
fn render() {
    // Fade in effect
    let alpha = (fade_progress * 15.0) as u32;
    uniform_alpha(alpha);
    draw_mesh(fading_object);

    // Reset to fully opaque
    uniform_alpha(15);
}
}

See Also: dither_offset


dither_offset

Sets the dither pattern offset for animated dithering.

Signature:

#![allow(unused)]
fn main() {
fn dither_offset(x: u32, y: u32)
}

Parameters:

NameTypeDescription
xu32X offset 0-3
yu32Y offset 0-3

Example:

#![allow(unused)]
fn main() {
fn render() {
    // Animate dither pattern for shimmer effect
    let frame = tick_count() as u32;
    dither_offset(frame % 4, (frame / 4) % 4);
}
}

Render Passes (Execution Barriers)

Render passes provide execution barriers with configurable depth and stencil state. Commands in pass N are guaranteed to complete before commands in pass N+1 begin.

begin_pass

Starts a new render pass with standard depth testing (depth enabled, compare LESS, write ON).

Signature:

#![allow(unused)]
fn main() {
fn begin_pass(clear_depth: u32)
}

Parameters:

NameTypeDescription
clear_depthu321 to clear depth buffer, 0 to preserve

Example:

#![allow(unused)]
fn main() {
fn render() {
    // Draw world normally
    draw_mesh(world);

    // Start new pass, clear depth to draw gun on top
    begin_pass(1);
    draw_mesh(fps_gun);
}
}

begin_pass_stencil_write

Starts a stencil write pass for mask creation. Depth is disabled, stencil writes reference value on pass.

Signature:

#![allow(unused)]
fn main() {
fn begin_pass_stencil_write(ref_value: u32, clear_depth: u32)
}

Parameters:

NameTypeDescription
ref_valueu32Stencil reference value to write (0-255)
clear_depthu321 to clear depth buffer, 0 to preserve

Example: See Portal Effect below.


begin_pass_stencil_test

Starts a stencil test pass to render only where stencil equals reference. Depth testing is enabled.

Signature:

#![allow(unused)]
fn main() {
fn begin_pass_stencil_test(ref_value: u32, clear_depth: u32)
}

Parameters:

NameTypeDescription
ref_valueu32Stencil reference value to test against (0-255)
clear_depthu321 to clear depth buffer (for portal interiors), 0 to preserve

Example: See Portal Effect below.


begin_pass_full

Starts a pass with full control over depth and stencil state.

Signature:

#![allow(unused)]
fn main() {
fn begin_pass_full(
    depth_compare: u32,
    depth_write: u32,
    clear_depth: u32,
    stencil_compare: u32,
    stencil_ref: u32,
    stencil_pass_op: u32,
    stencil_fail_op: u32,
    stencil_depth_fail_op: u32,
)
}

Compare Function Constants:

ConstantValueDescription
compare::NEVER1Never pass
compare::LESS2Pass if src < dst
compare::EQUAL3Pass if src == dst
compare::LESS_EQUAL4Pass if src <= dst
compare::GREATER5Pass if src > dst
compare::NOT_EQUAL6Pass if src != dst
compare::GREATER_EQUAL7Pass if src >= dst
compare::ALWAYS8Always pass

Stencil Operation Constants:

ConstantValueDescription
stencil_op::KEEP0Keep current value
stencil_op::ZERO1Set to zero
stencil_op::REPLACE2Replace with ref value
stencil_op::INCREMENT_CLAMP3Increment, clamp to max
stencil_op::DECREMENT_CLAMP4Decrement, clamp to 0
stencil_op::INVERT5Bitwise invert
stencil_op::INCREMENT_WRAP6Increment, wrap to 0
stencil_op::DECREMENT_WRAP7Decrement, wrap to max

z_index

Sets the Z-order index for 2D draw ordering within a pass. Higher values draw on top.

Signature:

#![allow(unused)]
fn main() {
fn z_index(n: u32)
}

Parameters:

NameTypeDescription
nu32Z-order index (0-255)

Example:

#![allow(unused)]
fn main() {
fn render() {
    // Background (lowest)
    z_index(0);
    set_color(bg_color);
    draw_sprite(bg_x, bg_y, bg_w, bg_h);

    // Game objects
    z_index(1);
    set_color(obj_color);
    draw_sprite(obj_x, obj_y, obj_w, obj_h);

    // UI on top
    z_index(2);
    set_color(ui_color);
    draw_sprite(ui_x, ui_y, ui_w, ui_h);
}
}

Viewport

Functions for split-screen rendering. Each player can have their own viewport region.

viewport

Set the viewport for subsequent draw calls.

Signature:

#![allow(unused)]
fn main() {
fn viewport(x: u32, y: u32, width: u32, height: u32)
}

Parameters:

NameTypeDescription
xu32Left edge of viewport in screen pixels
yu32Top edge of viewport in screen pixels
widthu32Width of viewport in screen pixels
heightu32Height of viewport in screen pixels

Behavior:

  • Camera aspect ratio automatically adjusts to viewport dimensions
  • 2D coordinates (draw_sprite, draw_text, etc.) become viewport-relative
  • Native resolution is 960×540

Example:

#![allow(unused)]
fn main() {
fn render() {
    // 2-player horizontal split

    // Left half (player 1)
    viewport(0, 0, 480, 540);
    camera_position(p1.x, p1.y, p1.z);
    draw_mesh(world);
    set_color(0xFFFFFFFF);
    draw_text_str("P1", 10.0, 10.0, 16.0);

    // Right half (player 2)
    viewport(480, 0, 480, 540);
    camera_position(p2.x, p2.y, p2.z);
    draw_mesh(world);
    set_color(0xFFFFFFFF);
    draw_text_str("P2", 10.0, 10.0, 16.0);

    // Reset to fullscreen for shared UI
    viewport_clear();
    set_color(0xFFFFFFFF);
    draw_text_str("SCORE: 1000", 400.0, 10.0, 16.0);
}
}

viewport_clear

Reset viewport to fullscreen (960×540).

Signature:

#![allow(unused)]
fn main() {
fn viewport_clear()
}

Example:

#![allow(unused)]
fn main() {
fn render() {
    // Draw player viewports...
    viewport(0, 0, 480, 540);
    // ... render player 1 ...

    viewport(480, 0, 480, 540);
    // ... render player 2 ...

    // Back to fullscreen for UI overlay
    viewport_clear();
    z_index(10);
    set_color(0x00000080);
    draw_rect(0.0, 500.0, 960.0, 40.0);  // Bottom bar
}
}

Stencil Portal Example

#![allow(unused)]
fn main() {
fn render() {
    // 1. Draw main world
    draw_mesh(main_world);

    // 2. Write portal shape to stencil buffer (invisible)
    begin_pass_stencil_write(1, 0);
    draw_mesh(portal_quad);

    // 3. Draw portal interior (only where stencil == 1, clear depth)
    begin_pass_stencil_test(1, 1);
    draw_mesh(other_world);

    // 4. Return to normal rendering
    begin_pass(0);
    draw_mesh(portal_frame);
}
}

Complete Example

#![allow(unused)]
fn main() {
fn init() {
    // Configure console
    set_tick_rate(2);         // 60 fps
    set_clear_color(0x1a1a2eFF);
    render_mode(2);           // PBR lighting
}

fn render() {
    // Draw 3D scene (depth testing is enabled by default)
    cull_mode(1);  // Enable back-face culling for performance
    texture_filter(1);

    set_color(0xFFFFFFFF);
    draw_mesh(level);
    draw_mesh(player);

    // Draw semi-transparent water using dithering
    uniform_alpha(8);  // 50% alpha via ordered dithering
    set_color(0x4080FFFF);
    draw_mesh(water);
    uniform_alpha(15);  // Reset to fully opaque

    // Draw UI (2D draws are always on top via z_index)
    texture_filter(0);
    z_index(1);
    set_color(0xFFFFFFFF);
    draw_sprite(10.0, 10.0, 200.0, 50.0);
}
}