System Functions
Core system functions for time, logging, randomness, and session management.
Time Functions
delta_time
Returns the time elapsed since the last tick in seconds.
Signature:
#![allow(unused)]
fn main() {
fn delta_time() -> f32
}
Returns: Time in seconds since last tick (typically 1/60 = 0.0167 at 60fps)
Example:
#![allow(unused)]
fn main() {
fn update() {
// Frame-rate independent movement
position.x += velocity.x * delta_time();
position.y += velocity.y * delta_time();
}
}
See Also: elapsed_time, tick_count
elapsed_time
Returns total elapsed time since game start in seconds.
Signature:
#![allow(unused)]
fn main() {
fn elapsed_time() -> f32
}
Returns: Total seconds since init() was called
Example:
#![allow(unused)]
fn main() {
fn render() {
// Pulsing effect
let pulse = (elapsed_time() * 2.0).sin() * 0.5 + 0.5;
set_color(rgba(255, 255, 255, (pulse * 255.0) as u8));
}
}
See Also: delta_time, tick_count
tick_count
Returns the current tick number (frame count).
Signature:
#![allow(unused)]
fn main() {
fn tick_count() -> u64
}
Returns: Number of ticks since game start
Example:
#![allow(unused)]
fn main() {
fn update() {
// Every second at 60fps
if tick_count() % 60 == 0 {
spawn_enemy();
}
// Every other tick
if tick_count() % 2 == 0 {
animate_water();
}
}
}
See Also: delta_time, elapsed_time
Logging
log
Outputs a message to the console for debugging.
Signature:
#![allow(unused)]
fn main() {
fn log(ptr: *const u8, len: u32)
}
Parameters:
| Name | Type | Description |
|---|---|---|
| ptr | *const u8 | Pointer to UTF-8 string data |
| len | u32 | Length of the string in bytes |
Example:
#![allow(unused)]
fn main() {
fn init() {
let msg = b"Game initialized!";
log(msg.as_ptr(), msg.len() as u32);
}
fn update() {
if player_died {
let msg = b"Player died";
log(msg.as_ptr(), msg.len() as u32);
}
}
}
Control Flow
quit
Exits the game and returns to the Nethercore library.
Signature:
#![allow(unused)]
fn main() {
fn quit()
}
Example:
#![allow(unused)]
fn main() {
fn update() {
// Quit on Start + Select held for 60 frames
if buttons_held(0) & ((1 << BUTTON_START) | (1 << BUTTON_SELECT)) != 0 {
quit_timer += 1;
if quit_timer >= 60 {
quit();
}
} else {
quit_timer = 0;
}
}
}
Randomness
random
Returns a deterministic random number from the host’s seeded RNG.
Signature:
#![allow(unused)]
fn main() {
fn random() -> u32
}
Returns: A random u32 value (0 to 4,294,967,295)
Constraints: Must use this for all randomness to maintain rollback determinism.
Example:
#![allow(unused)]
fn main() {
fn update() {
// Random integer in range [0, 320)
let spawn_x = (random() % 320) as f32;
// Random float 0.0 to 1.0
let rf = (random() as f32) / (u32::MAX as f32);
// Random bool
let coin_flip = random() & 1 == 0;
// Random float in range [min, max]
let min = 10.0;
let max = 50.0;
let rf = (random() as f32) / (u32::MAX as f32);
let value = min + rf * (max - min);
}
}
Warning: Never use external random sources (system time, etc.) — this breaks rollback determinism.
random_range
Returns a random integer in range [min, max).
Signature:
#![allow(unused)]
fn main() {
fn random_range(min: i32, max: i32) -> i32
}
Parameters:
| Name | Type | Description |
|---|---|---|
| min | i32 | Minimum value (inclusive) |
| max | i32 | Maximum value (exclusive) |
Returns: Random integer in range [min, max)
Example:
#![allow(unused)]
fn main() {
let spawn_x = random_range(0, 960); // 0 to 959
let damage = random_range(10, 21); // 10 to 20
}
random_f32
Returns a random float in range [0.0, 1.0).
Signature:
#![allow(unused)]
fn main() {
fn random_f32() -> f32
}
Returns: Random float in range [0.0, 1.0)
Example:
#![allow(unused)]
fn main() {
let t = random_f32(); // 0.0 to 0.999...
let color_variation = random_f32() * 0.2 - 0.1; // -0.1 to +0.1
}
random_f32_range
Returns a random float in range [min, max).
Signature:
#![allow(unused)]
fn main() {
fn random_f32_range(min: f32, max: f32) -> f32
}
Parameters:
| Name | Type | Description |
|---|---|---|
| min | f32 | Minimum value (inclusive) |
| max | f32 | Maximum value (exclusive) |
Returns: Random float in range [min, max)
Example:
#![allow(unused)]
fn main() {
let speed = random_f32_range(5.0, 15.0); // 5.0 to 14.999...
let angle = random_f32_range(0.0, 6.28); // 0 to 2π
}
Screen Constants
Fixed screen dimensions for the ZX console (540p resolution).
#![allow(unused)]
fn main() {
screen::WIDTH // 960
screen::HEIGHT // 540
}
Example:
#![allow(unused)]
fn main() {
// Center something on screen
let center_x = screen::WIDTH as f32 / 2.0;
let center_y = screen::HEIGHT as f32 / 2.0;
}
Session Functions
player_count
Returns the number of players in the current session.
Signature:
#![allow(unused)]
fn main() {
fn player_count() -> u32
}
Returns: Number of players (1-4)
Example:
#![allow(unused)]
fn main() {
fn update() {
// Process all players
for p in 0..player_count() {
process_player_input(p);
update_player_state(p);
}
}
fn render() {
// Draw viewport split for multiplayer
match player_count() {
1 => draw_fullscreen_viewport(0),
2 => {
draw_half_viewport(0, 0); // Left half
draw_half_viewport(1, 1); // Right half
}
_ => draw_quad_viewports(),
}
}
}
See Also: local_player_mask
local_player_mask
Returns a bitmask indicating which players are local to this client.
Signature:
#![allow(unused)]
fn main() {
fn local_player_mask() -> u32
}
Returns: Bitmask where bit N is set if player N is local
Example:
#![allow(unused)]
fn main() {
fn render() {
let mask = local_player_mask();
// Check if specific player is local
let p0_local = (mask & 1) != 0; // Player 0
let p1_local = (mask & 2) != 0; // Player 1
let p2_local = (mask & 4) != 0; // Player 2
let p3_local = (mask & 8) != 0; // Player 3
// Only show local player's UI
for p in 0..player_count() {
if (mask & (1 << p)) != 0 {
draw_player_ui(p);
}
}
}
}
Multiplayer Model
Nethercore supports up to 4 players in any combination:
- 4 local players (couch co-op)
- 1 local + 3 remote (online)
- 2 local + 2 remote (mixed)
All inputs are synchronized via GGRS rollback netcode. Your update() processes all players uniformly — the host handles synchronization automatically.
#![allow(unused)]
fn main() {
fn update() {
// This code works for any local/remote mix
for p in 0..player_count() {
let input = get_player_input(p);
update_player(p, input);
}
}
}