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 #
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 #
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 #
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 #
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 #
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 #
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 #
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
- Constants
- fn new
- fn new_chunk_service
- fn new_console_sender
- fn new_hub
- fn EnqueueResult.from
- fn State.from
- fn WorldLifecycle.from
- interface DamageSource
- interface WorldTransaction
- type WorldRuntime
- type WorldScheduler
- type WorldTxHandle
- enum State
- struct AttackDamageSource
- struct ChunkResult
- struct ChunkServiceMetrics
- struct ConsoleSender
- struct DrowningDamageSource
- struct EntityConfig
- struct EntityRef
- struct FakeTransport
- struct FallDamageSource
- struct FireDamageSource
- struct Hub
- fn active_chunk_generation_count
- fn broadcast
- fn cancel_task
- fn chunk_cache_totals
- fn close_worlds
- fn count
- fn create_world
- fn disconnect_all
- fn dispatch_command
- fn flush_worlds
- fn list_worlds
- fn load
- fn load_configured_worlds
- fn load_or_create_world
- fn load_world
- fn persist_pressure_warnings
- fn player_ref
- fn player_refs
- fn register_command
- fn register_event
- fn register_generator
- fn request_tick_all
- fn run_delayed
- fn run_repeating
- fn run_task
- fn scheduler_heartbeat
- fn set_conf_file
- fn set_current_tick
- fn set_initial_difficulty
- fn set_lang
- fn set_load
- fn set_ops
- fn set_packs
- fn set_palette
- fn set_player_data_provider
- fn set_player_grants
- fn set_tps
- fn set_whitelist
- fn tps
- fn unload_world
- fn unregister_command
- fn unregister_event
- fn uptime_seconds
- fn wait_for_sessions_to_leave
- fn world_handle
- struct HubOptions
- struct LavaDamageSource
- struct MagicDamageSource
- struct MobAttackDamageSource
- struct NetworkSession
- struct PlayerRef
- struct ProjectileDamageSource
- struct VoidDamageSource
- struct World
- struct WorldChunkService
- struct WorldInfo
- struct WorldMetrics
- struct WorldTaskHandler