World & Networking

aether-world-runtime

World lifecycle, chunk streaming, and multiplayer primitives

The aether-world-runtime crate manages the lifecycle of Aether worlds, including chunk-based streaming with LOD, tick scheduling, input buffering, client-side prediction, state synchronization, RPC dispatch, and session management.

Overview

A world runtime instance governs everything that happens inside a single world. It handles:

  • World lifecycle from boot through running to shutdown, driven by manifest configuration.
  • Chunk streaming that loads and unloads spatial chunks based on player proximity and LOD.
  • Tick scheduling for deterministic server-authoritative simulation.
  • Input buffering that collects player inputs and applies them at the correct tick.
  • Client-side prediction with server reconciliation for responsive movement.
  • State synchronization between server and connected clients.
  • RPC dispatch for client-to-server and server-to-client remote procedure calls.
  • Session management for player join, leave, and reconnection.

Key Types

WorldRuntime

The top-level runtime that drives a world each tick.

use aether_world_runtime::{WorldRuntime, WorldRuntimeConfig};

let config = WorldRuntimeConfig {
    tick_rate: 30,
    max_players: 64,
    chunk_load_radius: 3,
};
let runtime = WorldRuntime::new(config);

StreamingEngine

Manages chunk loading and eviction based on player view positions.

use aether_world_runtime::{StreamingEngine, StreamingConfig, PlayerView};

let config = StreamingConfig {
    load_radius: 3,
    unload_radius: 5,
    max_concurrent_loads: 4,
};
let mut streaming = StreamingEngine::new(config);

TickScheduler

Drives the fixed-rate simulation loop with deterministic tick numbering.

use aether_world_runtime::{TickScheduler, ServerTick};

let mut scheduler = TickScheduler::new(30); // 30 ticks per second
let tick: ServerTick = scheduler.advance();

InputBuffer

Collects player inputs and associates them with the correct simulation tick.

use aether_world_runtime::{InputBuffer, PlayerInput, PlayerId};

let mut buffer = InputBuffer::new();
buffer.push(PlayerInput {
    player: PlayerId(1),
    tick: current_tick,
    actions: vec![InputAction::MoveForward],
});

InterpolationBuffer

Buffers entity state snapshots for smooth client-side interpolation between server updates.

use aether_world_runtime::{InterpolationBuffer, EntityState};

let mut buffer = InterpolationBuffer::new();
buffer.push(server_tick, entity_state);
let interpolated = buffer.sample(render_time);

SessionManager

Tracks player sessions, handling join, leave, and reconnection events.

use aether_world_runtime::{SessionManager, PlayerSession, SessionState};

let mut sessions = SessionManager::new();
sessions.on_player_join(player_id);

RpcDispatcher

Routes RPC messages between client and server with direction-aware dispatch.

use aether_world_runtime::{RpcDispatcher, RpcRequest, RpcDirection};

let mut rpc = RpcDispatcher::new();
rpc.register("spawn_item", |req: RpcRequest| {
    // Handle on server
});

Usage Examples

World Boot Sequence

use aether_world_runtime::{
    WorldLifecycle, WorldRuntimeManifest, RuntimeState,
};

let manifest = WorldRuntimeManifest::load("world.json")?;
let mut lifecycle = WorldLifecycle::new(manifest);
lifecycle.boot()?;
assert_eq!(lifecycle.state(), RuntimeState::Running);

Event Distribution

use aether_world_runtime::{EventDispatcher, GameEvent, EventScope};

let mut events = EventDispatcher::new();
events.broadcast(GameEvent::WorldTick(tick), EventScope::AllPlayers);