Skip to content

server.session

Constants #

const players_dir = 'players'
const player_eye_height = f32(1.62)
const player_half_width = f32(0.3)
const player_height = f32(1.8)

fn new #

fn new(mut transport network.Transport, mut hub Hub, cfg conf.Config, log &logger.Logger) &NetworkSession

fn new_chunk_service #

fn new_chunk_service(generator world.Generator) &WorldChunkService

fn new_console_sender #

fn new_console_sender(mut hub Hub, log &logger.Logger) &ConsoleSender

fn new_hub #

fn new_hub(data gamedata.GameData, opts HubOptions) &Hub

fn EnqueueResult.from #

fn EnqueueResult.from[W](input W) !EnqueueResult

fn State.from #

fn State.from[W](input W) !State

fn WorldLifecycle.from #

fn WorldLifecycle.from[W](input W) !WorldLifecycle

interface DamageSource #

interface DamageSource {
	// ignored_by_fire_resistance reports whether the fire_resistance effect
	// completely blocks this damage (fire, lava).
	ignored_by_fire_resistance() bool
	// reduced_by_resistance reports whether the resistance effect's damage
	// multiplier applies to this source.
	reduced_by_resistance() bool
	// attacker_label is the display string used for the player_hurt event's
	// informational attacker_name field. Empty for sources with no
	// attacker (fall, void, drowning, fire, lava).
	attacker_label() string
	// death_message_key returns the %death.attack.* translation key and its
	// ordered parameters for a victim named victim_name.
	death_message_key(victim_name string) (string, []string)
}

DamageSource identifies what caused damage dealt to a player. It decides fire resistance immunity and resistance effect reduction & supplies the %death.attack.* translation key-parameters for the death message.

interface WorldTransaction #

interface WorldTransaction {
	block_at(x int, y int, z int) world.Block
mut:
	set_block(x int, y int, z int, b world.Block) !
	players() []PlayerRef
	spawn_entity(config EntityConfig) !EntityRef
}

WorldTransaction is the public transaction surface passed to World.exec. Its operations run on the owning world thread, allowing several reads and mutations to execute in order without additional queue round trips.

fn (WorldRuntime) player_count #

fn (wr &WorldRuntime) player_count() i64

player_count returns the latest published player count for this world. It is thread safe and does not block on the world actor.

fn (WorldScheduler) cancel #

fn (mut s WorldScheduler) cancel(id int)

cancel stops and removes the task with the given id, if present. Safe to call from any thread.

fn (WorldTxHandle) block_at #

fn (h &WorldTxHandle) block_at(x int, y int, z int) world.Block

fn (WorldTxHandle) set_block #

fn (mut h WorldTxHandle) set_block(x int, y int, z int, b world.Block) !

fn (WorldTxHandle) players #

fn (mut h WorldTxHandle) players() []PlayerRef

fn (WorldTxHandle) spawn_entity #

fn (mut h WorldTxHandle) spawn_entity(config EntityConfig) !EntityRef

spawn_entity validates and spawns an entity directly within the current world transaction, avoiding an additional task and result round trip.

enum State #

enum State {
	handshake
	login
	resource_packs
	play
	closed
}

struct AttackDamageSource #

struct AttackDamageSource {
pub:
	attacker_name string
}

AttackDamageSource is damage from another entity's melee attack.

fn (AttackDamageSource) ignored_by_fire_resistance #

fn (s AttackDamageSource) ignored_by_fire_resistance() bool

fn (AttackDamageSource) reduced_by_resistance #

fn (s AttackDamageSource) reduced_by_resistance() bool

fn (AttackDamageSource) attacker_label #

fn (s AttackDamageSource) attacker_label() string

fn (AttackDamageSource) death_message_key #

fn (s AttackDamageSource) death_message_key(victim_name string) (string, []string)

struct ChunkResult #

struct ChunkResult {
pub:
	chunk         world.Chunk
	serialized    []u8
	section_count int
	cancelled     bool
}

ChunkResult is what request() delivers: a chunk or cancelled if the service shut down before generation ran.

serialized/section_count are the chunk's wire format bytes, computed once at generation time.

struct ChunkServiceMetrics #

struct ChunkServiceMetrics {
pub:
	cached_chunks         int
	cached_bytes_estimate i64
	cache_budget_bytes    i64
	inflight_requests     int
	oldest_inflight_age   time.Duration
	active_workers        i64
	worker_limit          int
	queue_depth           i64
	requests_total        i64
	dedup_hits_total      i64
}

A snapshot of one world's chunk generation health.

struct ConsoleSender #

@[heap]
struct ConsoleSender {
mut:
	hub &Hub
pub mut:
	log &logger.Logger = unsafe { nil }
}

ConsoleSender adapts the server console to the cmd.Sender interface. It has every permission and writes command output to the server log.

fn (ConsoleSender) name #

fn (c &ConsoleSender) name() string

struct DrowningDamageSource #

struct DrowningDamageSource {}

DrowningDamageSource is damage from running out of breath underwater.

fn (DrowningDamageSource) ignored_by_fire_resistance #

fn (s DrowningDamageSource) ignored_by_fire_resistance() bool

fn (DrowningDamageSource) reduced_by_resistance #

fn (s DrowningDamageSource) reduced_by_resistance() bool

fn (DrowningDamageSource) attacker_label #

fn (s DrowningDamageSource) attacker_label() string

fn (DrowningDamageSource) death_message_key #

fn (s DrowningDamageSource) death_message_key(victim_name string) (string, []string)

struct EntityConfig #

struct EntityConfig {
pub:
	type_name string
	pos       types.Vector3
}

EntityConfig identifies a registered entity type and its spawn position. Entities are created through the registry by name rather than from caller provided Behaviour instances.

struct EntityRef #

struct EntityRef {
	runtime_id u64
	world_     World
}

EntityRef is a stale checked reference to a non-player entity. Its operations run on the owning world thread without exposing raw entity pointers across threads.

Runtime IDs are process wide and never reused, so registration alone is sufficient to determine whether the reference is still valid.

fn (EntityRef) world #

fn (e EntityRef) world() World

world is the World captured at construction.

fn (EntityRef) valid #

fn (e EntityRef) valid() bool

valid reports whether the entity is still registered in its world, a despawned or never existing runtime id reports false.

fn (EntityRef) position #

fn (e EntityRef) position() !types.Vector3

fn (EntityRef) teleport #

fn (e EntityRef) teleport(pos types.Vector3) !

fn (EntityRef) damage #

fn (e EntityRef) damage(amount f32, fatal bool, source_runtime_id u64) !

fn (EntityRef) close #

fn (e EntityRef) close() !

close despawns the entity and tells viewers to drop it, the same path a normal death does.

struct FakeTransport #

@[heap]
struct FakeTransport {
pub mut:
	sent        []protocol.Packet
	sent_notify chan bool = chan bool{cap: 256}
}

FakeTransport is an in memory network.Transport for tests: send/send_batch record packets instead of writing to a socket, so a test can construct a bare NetworkSession and assert on what it actually sent, with no real connection. It's also NetworkSession's zero-value transport default.

Delivery now happens on a session's own outbound writer thread rather than synchronously inside deliver(), so a test observing sent from another thread has to wait for that thread to actually run. sent_notify carries one wakeup per completed send/send_batch so a waiter can block on the real event instead of polling sent.len on a timer.

fn (FakeTransport) send #

fn (mut t FakeTransport) send(p protocol.Packet) !

fn (FakeTransport) send_batch #

fn (mut t FakeTransport) send_batch(packets []protocol.Packet) !

fn (FakeTransport) read #

fn (mut t FakeTransport) read() ![]protocol.Packet

fn (FakeTransport) remote_addr #

fn (t &FakeTransport) remote_addr() string

fn (FakeTransport) close #

fn (mut t FakeTransport) close()

fn (FakeTransport) mark_logged_in #

fn (mut t FakeTransport) mark_logged_in()

fn (FakeTransport) enable_compression #

fn (mut t FakeTransport) enable_compression(threshold int)

fn (FakeTransport) enable_encryption #

fn (mut t FakeTransport) enable_encryption(mut ctx encryption.Context)

fn (FakeTransport) disable_encryption #

fn (t &FakeTransport) disable_encryption() bool

struct FallDamageSource #

struct FallDamageSource {}

FallDamageSource is damage from falling too far.

fn (FallDamageSource) ignored_by_fire_resistance #

fn (s FallDamageSource) ignored_by_fire_resistance() bool

fn (FallDamageSource) reduced_by_resistance #

fn (s FallDamageSource) reduced_by_resistance() bool

fn (FallDamageSource) attacker_label #

fn (s FallDamageSource) attacker_label() string

fn (FallDamageSource) death_message_key #

fn (s FallDamageSource) death_message_key(victim_name string) (string, []string)

struct FireDamageSource #

struct FireDamageSource {}

FireDamageSource is damage from burning while on fire.

fn (FireDamageSource) ignored_by_fire_resistance #

fn (s FireDamageSource) ignored_by_fire_resistance() bool

fn (FireDamageSource) reduced_by_resistance #

fn (s FireDamageSource) reduced_by_resistance() bool

fn (FireDamageSource) attacker_label #

fn (s FireDamageSource) attacker_label() string

fn (FireDamageSource) death_message_key #

fn (s FireDamageSource) death_message_key(victim_name string) (string, []string)

struct Hub #

@[heap]
struct Hub {
mut:
	sessions        map[u64]&NetworkSession
	pending_names   map[string]bool
	mutex           &sync.Mutex               = sync.new_mutex()
	next_runtime_id u64                       = 1
	tps_bits        &stdatomic.AtomicVal[u64] = stdatomic.new_atomic[u64](math.f64_bits(20.0))
	// config_mutex guards server global mutable config: ops, whitelist and
	// difficulty. Every read or write including the one time boot load via
	// set_ops/set_whitelist/set_difficulty, goes through the locked accessors
	// below.
	config_mutex                  &sync.Mutex               = sync.new_mutex()
	load_bits                     &stdatomic.AtomicVal[u64] = stdatomic.new_atomic[u64](0)
	online_count                  &stdatomic.AtomicVal[u64] = stdatomic.new_atomic[u64](0)
	active_chunk_generation_count &stdatomic.AtomicVal[i64] = stdatomic.new_atomic[i64](0)
	// current_tick_bits backs current_tick()/set_current_tick(). Written
	// directly from server.v's tick loop while other threads still read it
	// (blocks.v's cooldown tracking, movement.v's tick check), so it's an
	// atomic like the other tick metrics.
	current_tick_bits &stdatomic.AtomicVal[i64] = stdatomic.new_atomic[i64](0)
	// world_registry owns loaded world runtimes and their lifecycle. Hub
	// routes named lookups through it instead of storing raw worlds directly.
	world_registry &WorldRegistry = unsafe { nil }
	// session_wg tracks sessions from registration until leave completes.
	// wait_for_sessions_to_leave blocks until every session has finished
	// leaving including saving player data and removing itself.
	session_wg         &sync.WaitGroup = sync.new_waitgroup()
	oidc_verifier      auth.Verifier
	data               gamedata.GameData
	items              item.Registry                = item.new_registry()
	blocks             block.Registry               = block.new_registry()
	lang               &language.Lang               = unsafe { nil }
	commands           cmd.Registry                 = cmd.new_registry()
	events             &event.Bus                   = unsafe { nil }
	scheduler          &scheduler.Scheduler         = unsafe { nil }
	entity_registry    entity.Registry              = entity.new_registry()
	custom_items       item.CustomRegistry          = item.new_custom_registry()
	custom_blocks      block.CustomRegistry         = block.new_custom_registry()
	custom_entities    entity.CustomRegistry        = entity.new_custom_registry()
	enchantments       enchant.Registry             = enchant.new_registry()
	generators         blockworld.GeneratorRegistry = blockworld.new_generator_registry()
	started_at         i64
	default_world_name string
	// worlds_dir is the on-disk root for world folders and world_generator the
	// fallback generator name for freshly created worlds. Both are set at boot.
	worlds_dir      string = 'worlds'
	world_generator string = 'flat'
	// world_factory creates/opens/lists/deletes named world backends.
	// Defaults to db.LevelDBFactory the first time set_world_config runs,
	// unless HubOptions already supplied one at construction time.
	world_factory ?db.Factory
	packs         &resourcepack.PackRegistry = unsafe { nil }
	palette       &blockworld.BlockPalette   = unsafe { nil }
	ops           permission.OpList
	player_grants permission.PlayerGrants
	whitelist     permission.Whitelist
	difficulty    int = proto.difficulty_easy
	// conf_file is the path to this instance's own settings file (set from
	// conf.Config.config_file, not a shared default) so runtime difficulty
	// changes persist back to the correct per instance file.
	conf_file string
	// player_data_provider stores/loads player save data. Defaults to
	// FileProvider(players_dir) unless HubOptions supplied one; server.new()
	// overrides the default's directory with conf.Config.players_dir once
	// that's known, the same way it overrides ops/whitelist/difficulty.
	player_data_provider playerdb.Provider
}

Hub contains the server's actor-model internals rather than its public API. It remains a public type only so Server can hold a reference to it across package boundaries; the field itself and most Hub methods stay private.

Users should access these capabilities through Server, World, PlayerRef, EntityRef and WorldTransaction instead.

fn (Hub) active_chunk_generation_count #

fn (mut h Hub) active_chunk_generation_count() i64

active_chunk_generation_count reports how many sessions currently have a chunk generation batch in flight.

fn (Hub) broadcast #

fn (mut h Hub) broadcast(p protocol.Packet)

fn (Hub) cancel_task #

fn (mut h Hub) cancel_task(id int)

cancel_task stops and removes the scheduled task with the given id if it is still queued. A caller holding the TaskHandler itself can call its own cancel() directly instead; this is the by-id path for a caller that only kept the id.

fn (Hub) chunk_cache_totals #

fn (mut h Hub) chunk_cache_totals() (int, i64)

chunk_cache_totals aggregates every loaded world's WorldChunkService cache into one entry count and estimated byte total.

fn (Hub) close_worlds #

fn (mut h Hub) close_worlds()

close_worlds shuts down and releases every loaded world's runtime. Called once on shutdown after all sessions are disconnected. Runtimes are removed from the registry before shutdown, so new named lookups cannot find a world that is stopping.

fn (Hub) count #

fn (mut h Hub) count() int

fn (Hub) create_world #

fn (mut h Hub) create_world(name string, dim blockworld.Dimension, generator string) !string

create_world creates a fresh empty world on disk and registers it as loaded. Refuses to clobber an already-loaded or already-on-disk world. Safe to call off the actor thread - it only adds to the worlds map, never mutates a player's active world.

fn (Hub) disconnect_all #

fn (mut h Hub) disconnect_all(message string)

fn (Hub) dispatch_command #

fn (mut h Hub) dispatch_command(line string, mut sender cmd.Sender, ctx cmd.Context) !

dispatch_command runs line against the shared command registry as sender. The console loop and in game chat's prefix both funnel through here.

fn (Hub) flush_worlds #

fn (mut h Hub) flush_worlds() []string

flush_worlds durably flushes every loaded world's queued override/tile writes to disk. Writes otherwise only become durable on a graceful shutdown (close_worlds). Calling this periodically bounds how much a crash or forced kill can lose to the flush interval instead of however long the server has been running since it last shut down cleanly. Returns one "world: error" message per world that failed to flush rather than stopping at the first failure, so one bad store doesn't hide the rest.

fn (Hub) list_worlds #

fn (mut h Hub) list_worlds() []string

list_worlds returns the names of every loaded world.

fn (Hub) load #

fn (mut h Hub) load() f64

fn (Hub) load_configured_worlds #

fn (mut h Hub) load_configured_worlds(worlds_dir string, default_world string, load_all bool, generator string, log &logger.Logger, lang &language.Lang)

load_configured_worlds loads the default world and, when enabled, every other stored world, then sets the configured default as Hub's active world.

Keeping this boot time orchestration inside the session package prevents raw world storage types from leaking into Server's public surface.

fn (Hub) load_or_create_world #

fn (mut h Hub) load_or_create_world(name string, dim blockworld.Dimension, generator string) !string

load_or_create_world loads name from storage when it already exists there or creates it fresh otherwise.

fn (Hub) load_world #

fn (mut h Hub) load_world(name string) !string

fn (Hub) persist_pressure_warnings #

fn (mut h Hub) persist_pressure_warnings() []string

persist_pressure_warnings returns a warning for each loaded world whose persistence backlog has reached the high water mark. Logging is kept outside db.World so the database layer remains logger independent.

fn (Hub) player_ref #

fn (mut h Hub) player_ref(name string) ?PlayerRef

player_ref looks up the player currently connected under name and returns a PlayerRef for their current world membership generation.

fn (Hub) player_refs #

fn (mut h Hub) player_refs() []PlayerRef

player_refs returns a PlayerRef for every currently connected session. The lookup reads session state directly and doesn't involve a world actor.

fn (Hub) register_command #

fn (mut h Hub) register_command(command cmd.Command)

register_command adds command to the shared command registry, available immediately to every connected session and the console.

fn (Hub) register_event #

fn (mut h Hub) register_event(handler event.Handler, priority event.Priority)

fn (Hub) register_generator #

fn (mut h Hub) register_generator(name string, factory fn (dim blockworld.Dimension) blockworld.Generator)

register_generator adds or overrides a named world generator, reachable through Server.register_generator.

fn (Hub) request_tick_all #

fn (mut h Hub) request_tick_all(n i64)

request_tick_all pulses every loaded world's own coalesced tick wakeup.

fn (Hub) run_delayed #

fn (mut h Hub) run_delayed(task scheduler.Task, delay i64) &scheduler.TaskHandler

run_delayed queues task to run once, delay ticks from now.

fn (Hub) run_repeating #

fn (mut h Hub) run_repeating(task scheduler.Task, period i64) &scheduler.TaskHandler

run_repeating queues task to run every period ticks, starting next tick.

fn (Hub) run_task #

fn (mut h Hub) run_task(task scheduler.Task) &scheduler.TaskHandler

run_task queues task to run on the next tick.

fn (Hub) scheduler_heartbeat #

fn (mut h Hub) scheduler_heartbeat(tick i64)

scheduler_heartbeat advances the scheduler's clock and runs every task due at or before tick. Called once per server tick from the tick loop.

fn (Hub) set_conf_file #

fn (mut h Hub) set_conf_file(path string)

fn (Hub) set_current_tick #

fn (mut h Hub) set_current_tick(v i64)

fn (Hub) set_initial_difficulty #

fn (mut h Hub) set_initial_difficulty(value int)

fn (Hub) set_lang #

fn (mut h Hub) set_lang(lang &language.Lang)

The following set_* methods are Hub's boot configuration surface. Each one is called exactly once, from server.v's new(), after new_hub() returns and before the listener starts accepting connections.

fn (Hub) set_load #

fn (mut h Hub) set_load(v f64)

fn (Hub) set_ops #

fn (mut h Hub) set_ops(ops permission.OpList)

fn (Hub) set_packs #

fn (mut h Hub) set_packs(packs &resourcepack.PackRegistry)

fn (Hub) set_palette #

fn (mut h Hub) set_palette(palette &blockworld.BlockPalette)

fn (Hub) set_player_data_provider #

fn (mut h Hub) set_player_data_provider(provider playerdb.Provider)

fn (Hub) set_player_grants #

fn (mut h Hub) set_player_grants(grants permission.PlayerGrants)

fn (Hub) set_tps #

fn (mut h Hub) set_tps(v f64)

set_tps/set_load are called directly from server.v's tick loop.

fn (Hub) set_whitelist #

fn (mut h Hub) set_whitelist(wl permission.Whitelist)

fn (Hub) tps #

fn (mut h Hub) tps() f64

fn (Hub) unload_world #

fn (mut h Hub) unload_world(name string) !

unload_world flushes and releases a loaded world without deleting its files. Refuses the default world and any world that still has players in it.

The registry entry is removed only after the world closes successfully. If closing fails, the world remains registered but inert preventing its still open store from being reopened through a later load/create attempt.

fn (Hub) unregister_command #

fn (mut h Hub) unregister_command(name string)

unregister_command removes a previously registered command and any aliases pointing to it by name.

fn (Hub) unregister_event #

fn (mut h Hub) unregister_event(handler event.Handler)

fn (Hub) uptime_seconds #

fn (h &Hub) uptime_seconds() i64

fn (Hub) wait_for_sessions_to_leave #

fn (mut h Hub) wait_for_sessions_to_leave()

fn (Hub) world_handle #

fn (mut h Hub) world_handle(name string) ?World

world_handle wraps the world loaded under name in a public World or returns none if no such world is loaded.

struct HubOptions #

@[params]
struct HubOptions {
pub:
	commands             ?cmd.Registry
	entity_registry      ?entity.Registry
	world_factory        ?db.Factory
	player_data_provider ?playerdb.Provider
	auth_verifier        ?auth.Verifier
}

HubOptions overrides Hub's default subsystems. Every field left unset falls back to Vedrock's builtin default, so new_hub(data) still boots a working default server.

struct LavaDamageSource #

struct LavaDamageSource {}

LavaDamageSource is damage from touching lava.

fn (LavaDamageSource) ignored_by_fire_resistance #

fn (s LavaDamageSource) ignored_by_fire_resistance() bool

fn (LavaDamageSource) reduced_by_resistance #

fn (s LavaDamageSource) reduced_by_resistance() bool

fn (LavaDamageSource) attacker_label #

fn (s LavaDamageSource) attacker_label() string

fn (LavaDamageSource) death_message_key #

fn (s LavaDamageSource) death_message_key(victim_name string) (string, []string)

struct MagicDamageSource #

struct MagicDamageSource {}

MagicDamageSource is damage from a potion/status effect (instant damage, poison, wither, etc.).

fn (MagicDamageSource) ignored_by_fire_resistance #

fn (s MagicDamageSource) ignored_by_fire_resistance() bool

fn (MagicDamageSource) reduced_by_resistance #

fn (s MagicDamageSource) reduced_by_resistance() bool

fn (MagicDamageSource) attacker_label #

fn (s MagicDamageSource) attacker_label() string

fn (MagicDamageSource) death_message_key #

fn (s MagicDamageSource) death_message_key(victim_name string) (string, []string)

struct MobAttackDamageSource #

struct MobAttackDamageSource {
pub:
	attacker_name string
}

MobAttackDamageSource is damage from a hostile mob's own melee attack. Kept distinct from AttackDamageSource and ProjectileDamageSource.

fn (MobAttackDamageSource) ignored_by_fire_resistance #

fn (s MobAttackDamageSource) ignored_by_fire_resistance() bool

fn (MobAttackDamageSource) reduced_by_resistance #

fn (s MobAttackDamageSource) reduced_by_resistance() bool

fn (MobAttackDamageSource) attacker_label #

fn (s MobAttackDamageSource) attacker_label() string

fn (MobAttackDamageSource) death_message_key #

fn (s MobAttackDamageSource) death_message_key(victim_name string) (string, []string)

struct NetworkSession #

@[heap]
struct NetworkSession {
mut:
	// player holds the gamestate fields.
	player    &player.Player    = unsafe { nil }
	transport network.Transport = FakeTransport{}
	breaking  ?BreakProgress
	// breaking_mutex guards breaking, written by the session thread and
	// advanced by the owning world thread once per tick.
	breaking_mutex &sync.Mutex = sync.new_mutex()
	hub            &Hub        = unsafe { nil }
	state          State       = .handshake
	cfg            conf.Config
	world          &db.World       = unsafe { nil }
	generator      world.Generator = world.VoidGenerator{}
	// world_runtime is the mutation routing counterpart to world.
	world_runtime &WorldRuntime = unsafe { nil }
	// world_epoch increments whenever the session changes runtime. World tasks
	// capture it at submission and drop stale work after a world switch.
	world_epoch i64
	// world_mutex guards world/generator/world_runtime/world_epoch.
	world_mutex                 &sync.Mutex = sync.new_mutex()
	encryption_enabled          bool
	runtime_id                  u64
	spawned                     bool
	inv_opened                  bool
	open_container_pos          ?types.BlockPosition
	open_container_slot_net_ids map[int]int
	open_container_mutex        &sync.Mutex = sync.new_mutex()
	movement_mutex              &sync.Mutex = sync.new_mutex()
	pending_movement            ?MovementSnapshot
	movement_scheduled          bool
	pending_radius              int
	give_next_slot              int
	next_form_id                int
	pending_forms               map[int]form.Form
	forms_mutex                 &sync.Mutex = sync.new_mutex()
	last_place_ms               i64
	view_radius                 int
	last_chunk_x                int
	last_chunk_z                int
	sent_chunks                 map[u64]bool
	chunk_stream_mutex          &sync.Mutex = sync.new_mutex()
	chunk_gen_mutex             &sync.Mutex = sync.new_mutex()
	transfer_mutex              &sync.Mutex = sync.new_mutex()
	cooldown_until              map[string]i64
	// Per session outbound delivery state. Packet queuing and writer lifecycle
	// are managed in outbound.v.
	outbound      chan OutboundMessage = chan OutboundMessage{cap: outbound_queue_capacity}
	outbound_done chan bool            = chan bool{cap: 1}
	// outbound_abort wakes an idle writer with nothing queued, so
	// close_outbound_once can always make it exit, not just when it's
	// mid send. See outbound.v.
	outbound_abort chan bool = chan bool{cap: 1}
	// writer_exited fires once the writer loop actually returns. Tests use
	// this to know the writer thread is gone, since outbound_done only
	// proves close_outbound_once ran, not that the writer itself exited.
	writer_exited chan bool   = chan bool{cap: 1}
	close_mutex   &sync.Mutex = sync.new_mutex()
	close_started bool
	// outbound_closing is set the moment a graceful disconnect is
	// accepted. Different from close_started: closing means no new
	// packets are accepted, but the disconnect message still has to
	// drain; close_started means the transport is actually closed.
	outbound_closing bool
	// outbound_bootstrap is true while a real connection still owns transport
	// writes during bootstrap. activate_outbound clears it once and only before
	// closing begins; test sessions default to the active state.
	outbound_bootstrap bool
	writer_mutex       &sync.Mutex = sync.new_mutex()
	writer_started     bool
	// handler is a per session attachment point, set via
	// set_handler(h). It receives the same event.Handler calls as the global
	// Bus for event dispatch sites that explicitly check it.
	handler ?event.Handler
pub mut:
	log &logger.Logger = unsafe { nil }
}

NetworkSession contains per connection transport and threading state. It remains a public type only where required across package boundaries; most of its methods stay private.

External callers should interact with players through PlayerRef.

fn (NetworkSession) handle_loop #

fn (mut s NetworkSession) handle_loop()

A read error or a is_connection_closed write error both mean the connection is already gone, so handle_loop aborts outbound delivery immediately instead of trying to drain it gracefully.

struct PlayerRef #

struct PlayerRef {
	runtime_id u64
	epoch      i64
	name_      string
	world_     World
}

PlayerRef is a stale checked reference to a player. It remains valid only for the world membership generation captured when it was created.

Operations fail if the player disconnects or changes worlds, preventing stale references from resolving to another session or membership.

fn (PlayerRef) name #

fn (p PlayerRef) name() string

fn (PlayerRef) world #

fn (p PlayerRef) world() World

fn (PlayerRef) position #

fn (p PlayerRef) position() !types.Vector3

fn (PlayerRef) send_message #

fn (p PlayerRef) send_message(message string) !

fn (PlayerRef) teleport #

fn (p PlayerRef) teleport(pos types.Vector3) !

fn (PlayerRef) teleport_to #

fn (p PlayerRef) teleport_to(w World, pos types.Vector3) !

fn (PlayerRef) give_item #

fn (p PlayerRef) give_item(id string, count int) !

fn (PlayerRef) set_gamemode #

fn (p PlayerRef) set_gamemode(mode int) !

fn (PlayerRef) disconnect #

fn (p PlayerRef) disconnect(message string) !

struct ProjectileDamageSource #

struct ProjectileDamageSource {
pub:
	attacker_name string
}

ProjectileDamageSource is damage from a projectile.

fn (ProjectileDamageSource) ignored_by_fire_resistance #

fn (s ProjectileDamageSource) ignored_by_fire_resistance() bool

fn (ProjectileDamageSource) reduced_by_resistance #

fn (s ProjectileDamageSource) reduced_by_resistance() bool

fn (ProjectileDamageSource) attacker_label #

fn (s ProjectileDamageSource) attacker_label() string

fn (ProjectileDamageSource) death_message_key #

fn (s ProjectileDamageSource) death_message_key(victim_name string) (string, []string)

struct VoidDamageSource #

struct VoidDamageSource {}

VoidDamageSource is damage from falling below the world.

fn (VoidDamageSource) ignored_by_fire_resistance #

fn (s VoidDamageSource) ignored_by_fire_resistance() bool

fn (VoidDamageSource) reduced_by_resistance #

fn (s VoidDamageSource) reduced_by_resistance() bool

fn (VoidDamageSource) attacker_label #

fn (s VoidDamageSource) attacker_label() string

fn (VoidDamageSource) death_message_key #

fn (s VoidDamageSource) death_message_key(victim_name string) (string, []string)

struct World #

struct World {
mut:
	runtime &WorldRuntime
}

World is a public handle for a loaded world. Its methods route mutations through the owning world thread without exposing runtime or storage internals.

Player and entity access will be added once safe reference types exist. World time is omitted because it is currently global, not owned per world.

fn (World) block_at #

fn (w World) block_at(x int, y int, z int) world.Block

block_at returns the stored block override at pos, falling back to the world's configured generator. Both sources are safe to read off thread, so no world actor call is needed.

fn (World) cancel_task #

fn (mut w World) cancel_task(id int)

cancel_task stops a previously scheduled world task from running again.

fn (World) current_tick #

fn (w World) current_tick() i64

current_tick is this world's own simulation clock, safe to read from any thread. It never requires a round trip through the actor, so it stays readable even while that actor is stuck, the same reason WorldMetrics exists.

fn (World) dimension #

fn (w World) dimension() world.Dimension

fn (World) entities #

fn (mut w World) entities() []EntityRef

entities returns an EntityRef for every non-player entity currently registered in this world. If the world is shutting down, it returns an empty slice.

fn (World) entity_ref #

fn (mut w World) entity_ref(runtime_id u64) ?EntityRef

entity_ref looks up runtime_id in this world's entity manager and returns an EntityRef for it or none if no such entity is currently registered here.

fn (World) exec #

fn (mut w World) exec(f fn (mut tx WorldTransaction) !) !

exec runs "f" as one ordered transaction on the owning world thread. Operations inside the callback can't interleave with other world tasks and callback errors are returned by exec.

Keep callbacks short, synchronous and world local. Blocking work stalls the entire world and calling PlayerRef or EntityRef methods from inside the callback would deadlock by starting a nested world transaction.

To return a value from the callback, use a channel. Mutable closure captures are copied in V and don't update the enclosing variable.

fn (World) metrics #

fn (mut w World) metrics() WorldMetrics

metrics returns a snapshot of this world's runtime metrics including queue pressure, tick timing, persistence backlog and chunk generation load. It is thread safe and does not block on the world actor.

fn (World) name #

fn (w World) name() string

fn (World) player_count #

fn (w World) player_count() i64

player_count returns the current number of players in this world. It is a thread safe snapshot and does not require a world actor round trip.

fn (World) players #

fn (mut w World) players() []PlayerRef

players returns a PlayerRef for every player currently registered in this world. The lookup runs through the world's actor owned player registry.

If the world is shutting down, players returns an empty slice.

fn (World) run_delayed #

fn (mut w World) run_delayed(f fn (mut tx WorldTransaction), delay i64) &WorldTaskHandler

run_delayed queues "f" to run once, delay simulated ticks of this world from now.

fn (World) run_repeating #

fn (mut w World) run_repeating(f fn (mut tx WorldTransaction), period i64) &WorldTaskHandler

run_repeating queues "f" to run every period simulated ticks of this world starting on the next step.

fn (World) run_task #

fn (mut w World) run_task(f fn (mut tx WorldTransaction)) &WorldTaskHandler

run_task schedules f to run on this world's actor thread on its next simulated step.

The callback must remain short and non blocking. A slow callback stalls only this world. Scheduled callbacks are fire and forget.

fn (World) set_block #

fn (mut w World) set_block(x int, y int, z int, b world.Block) !

set_block applies an authoritative block change through the owning world thread.

fn (World) spawn_y #

fn (w World) spawn_y() int

spawn_y returns the configured generator's spawn height for this world. The generator can be resolved from thread safe world and registry state, so no world actor call is required.

struct WorldChunkService #

@[heap]
struct WorldChunkService {
mut:
	generator world.Generator
	mutex     &sync.Mutex = sync.new_mutex()
	closed    bool
	cache     map[u64]ChunkCacheEntry
	// cache_bytes: running total of every entry's bytes. cache_seq: bumped
	// on every hit/insert, so the entry with the smallest last_used is
	// always the least recently used.
	cache_bytes i64
	cache_seq   i64
	// Defaults to chunk_service_cache_budget_bytes; overridable in tests so
	// eviction can be exercised without allocating hundreds of MB.
	budget_bytes i64 = chunk_service_cache_budget_bytes
	inflight     map[u64]&ChunkRequest
	jobs         chan ChunkGenJob = chan ChunkGenJob{cap: chunk_gen_queue_capacity}
	stop         chan bool        = chan bool{cap: chunk_gen_worker_count}

	published_active_workers &stdatomic.AtomicVal[i64] = stdatomic.new_atomic[i64](0)
	published_queue_depth    &stdatomic.AtomicVal[i64] = stdatomic.new_atomic[i64](0)
	published_requests_total &stdatomic.AtomicVal[i64] = stdatomic.new_atomic[i64](0)
	published_dedup_hits     &stdatomic.AtomicVal[i64] = stdatomic.new_atomic[i64](0)
}

WorldChunkService is one world's chunk generation authority. Sessions call request() instead of generating chunks themselves, so N requests for the same column collapse into one generation and total concurrent generation work stays capped at chunk_gen_worker_count.

Not routed through the world actor: request() runs on session threads directly. Sending generation through wr.jobs would stall the whole world's actor on chunk work which defeats the point.

fn (WorldChunkService) request #

fn (mut svc WorldChunkService) request(cx int, cz int) chan ChunkResult

request returns a channel that resolves to (cx, cz)'s chunk: instantly if cached, attached to an already running generation if one exists or queued as a new one. Never blocks the caller beyond a full job queue. Safe to call from any thread.

fn (WorldChunkService) shutdown #

fn (mut svc WorldChunkService) shutdown()

shutdown stops every worker and cancels any waiter still stuck on an in flight request then refuses further requests.

fn (WorldChunkService) metrics #

fn (mut svc WorldChunkService) metrics() ChunkServiceMetrics

struct WorldInfo #

struct WorldInfo {
pub:
	name       string
	generator  string
	dimension  string
	overrides  int
	is_default bool
	players    int
}

WorldInfo is a read-only snapshot describing a loaded world.

struct WorldMetrics #

struct WorldMetrics {
pub:
	world_name                     string
	queued_tasks                   int
	oldest_queued_task_age         time.Duration
	current_tick                   i64
	tick_runs                      i64
	simulated_steps                i64
	catchup_events                 i64
	tick_overruns                  i64
	last_tick_duration             time.Duration
	longest_task_duration          time.Duration
	longest_task_name              string
	scheduled_backlog              int
	liquid_backlog                 int
	entity_count                   int
	player_count                   i64
	outbound_overflow_count        i64
	outbound_peak_depth            i64
	persist_pending_count          int
	persist_oldest_pending_ms      i64
	persist_enqueued_total         i64
	persist_committed_total        i64
	persist_pressure_level         int
	persist_high_water_threshold   int
	persist_hard_ceiling_threshold int
	persist_last_write_ms          i64
	persist_longest_write_ms       i64
	persist_consecutive_errors     i64
	chunk_cached_count             int
	chunk_cached_bytes             i64
	chunk_cache_budget_bytes       i64
	chunk_inflight_count           int
	chunk_oldest_inflight_ms       i64
	chunk_active_workers           i64
	chunk_worker_limit             int
	chunk_queue_depth              i64
	chunk_requests_total           i64
	chunk_dedup_hits_total         i64
	actor_running                  bool
}

WorldMetrics is a point in time reading of one world's runtime health, meant to answer why a world fell behind: whether it is buried in queued tasks, stuck simulating one slow task or genuinely under heavy load from entities, liquids or scheduled block updates.

struct WorldTaskHandler #

@[heap]
struct WorldTaskHandler {
	id     int
	delay  i64
	period i64
mut:
	task      WorldTask
	next_run  i64
	cancelled bool
}

WorldTaskHandler is the world scheduler's live record of a queued task, returned from every World.run_* call so the caller can cancel it later. delay/period are in this world's own simulated ticks.

fn (WorldTaskHandler) id #

fn (h &WorldTaskHandler) id() int

fn (WorldTaskHandler) is_cancelled #

fn (h &WorldTaskHandler) is_cancelled() bool

fn (WorldTaskHandler) cancel #

fn (mut h WorldTaskHandler) cancel()

cancel stops the task from running again. A repeating task won't fire after this; a pending delayed task never fires.

fn (WorldTaskHandler) is_repeating #

fn (h &WorldTaskHandler) is_repeating() bool