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.Session, mut hub Hub, cfg conf.Config, log &logger.Logger) &NetworkSession
fn new_console_sender #
fn new_console_sender(mut hub Hub, log &logger.Logger) &ConsoleSender
fn new_hub #
fn new_hub(data gamedata.GameData) &Hub
fn State.from #
fn State.from[W](input W) !State
interface WorldJob #
interface WorldJob {
run(mut h Hub)
}
enum State #
enum State {
handshake
login
resource_packs
play
closed
}
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) broadcast_message #
fn (mut c ConsoleSender) broadcast_message(text string)
fn (ConsoleSender) broadcast_title #
fn (mut c ConsoleSender) broadcast_title(kind int, text string)
fn (ConsoleSender) clear_inventory #
fn (mut c ConsoleSender) clear_inventory()
fn (ConsoleSender) clear_scoreboard #
fn (mut c ConsoleSender) clear_scoreboard()
fn (ConsoleSender) find_player #
fn (mut c ConsoleSender) find_player(name string) ?cmd.Sender
fn (ConsoleSender) give_item #
fn (mut c ConsoleSender) give_item(id string, count int) bool
fn (ConsoleSender) has_permission #
fn (c &ConsoleSender) has_permission(name string) bool
fn (ConsoleSender) is_player #
fn (c &ConsoleSender) is_player() bool
fn (ConsoleSender) kill #
fn (mut c ConsoleSender) kill()
fn (ConsoleSender) name #
fn (c &ConsoleSender) name() string
fn (ConsoleSender) place_water #
fn (mut c ConsoleSender) place_water(x int, y int, z int)
fn (ConsoleSender) position #
fn (mut c ConsoleSender) position() (f32, f32, f32)
fn (ConsoleSender) send_form #
fn (mut c ConsoleSender) send_form(f form.Form) !
fn (ConsoleSender) send_message #
fn (mut c ConsoleSender) send_message(message string) !
fn (ConsoleSender) send_translation #
fn (mut c ConsoleSender) send_translation(key string, parameters []string) !
fn (ConsoleSender) set_difficulty #
fn (mut c ConsoleSender) set_difficulty(value int)
fn (ConsoleSender) set_gamemode #
fn (mut c ConsoleSender) set_gamemode(mode int)
fn (ConsoleSender) set_operator #
fn (mut c ConsoleSender) set_operator(value bool)
The console itself is never a valid target for these (find_player never resolves to a ConsoleSender) but every Sender must implement the full interface.
fn (ConsoleSender) show_scoreboard #
fn (mut c ConsoleSender) show_scoreboard(title string, lines []string)
fn (ConsoleSender) show_title #
fn (mut c ConsoleSender) show_title(kind int, text string)
fn (ConsoleSender) teleport #
fn (mut c ConsoleSender) teleport(x f32, y f32, z f32)
fn (ConsoleSender) whitelist_add #
fn (mut c ConsoleSender) whitelist_add(name string)
fn (ConsoleSender) whitelist_enabled #
fn (c &ConsoleSender) whitelist_enabled() bool
fn (ConsoleSender) whitelist_names #
fn (c &ConsoleSender) whitelist_names() []string
fn (ConsoleSender) whitelist_remove #
fn (mut c ConsoleSender) whitelist_remove(name string)
fn (ConsoleSender) whitelist_set_enabled #
fn (mut c ConsoleSender) whitelist_set_enabled(value bool)
fn (ConsoleSender) world_create #
fn (mut c ConsoleSender) world_create(name string, dimension string, generator string) !
fn (ConsoleSender) world_delete #
fn (mut c ConsoleSender) world_delete(name string) !
fn (ConsoleSender) world_info #
fn (mut c ConsoleSender) world_info(name string) ?cmd.WorldSummary
fn (ConsoleSender) world_load #
fn (mut c ConsoleSender) world_load(name string) !
fn (ConsoleSender) world_names #
fn (mut c ConsoleSender) world_names() []string
fn (ConsoleSender) world_teleport #
fn (mut c ConsoleSender) world_teleport(name string) !
struct Hub #
struct Hub {
mut:
sessions map[u64]&NetworkSession
mutex &sync.Mutex = sync.new_mutex()
next_runtime_id u64 = 1
// jobs is the only door into gameplay-mutable state that spans sessions
// (combat, targeted /gamemode, etc.). run_jobs() is the sole consumer.
jobs chan WorldJob = chan WorldJob{cap: 256}
tps_bits &stdatomic.AtomicVal[u64] = stdatomic.new_atomic[u64](math.f64_bits(20.0))
load_bits &stdatomic.AtomicVal[u64] = stdatomic.new_atomic[u64](0)
online_count &stdatomic.AtomicVal[u64] = stdatomic.new_atomic[u64](0)
pub mut:
world_time int
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 }
entities &entity.Manager = unsafe { nil }
liquids &liquid.LiquidManager = 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()
current_tick i64
started_at i64
worlds map[string]&db.World
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'
packs &resource.PackRegistry = unsafe { nil }
palette &blockworld.BlockPalette = unsafe { nil }
ops permission.OpList
player_grants permission.PlayerGrants
whitelist permission.Whitelist
// needs vedrock.yml storage.
difficulty int = protocol.difficulty_easy
}
fn (Hub) add #
fn (mut h Hub) add(target &NetworkSession)
fn (Hub) add_world #
fn (mut h Hub) add_world(loaded_world &db.World)
add_world registers a loaded world under its name. The first world added becomes the default unless one is already set.
fn (Hub) allocate_runtime_id #
fn (mut h Hub) allocate_runtime_id() u64
fn (Hub) broadcast #
fn (mut h Hub) broadcast(p protocol.Packet)
fn (Hub) broadcast_except #
fn (mut h Hub) broadcast_except(runtime_id u64, p protocol.Packet)
fn (Hub) broadcast_message #
fn (mut h Hub) broadcast_message(text string)
broadcast_message sends a raw chat line to every connected player. Part of the plugin.ServerView surface.
fn (Hub) broadcast_near #
fn (mut h Hub) broadcast_near(x f32, y f32, z f32, radius f32, p protocol.Packet)
broadcast_near delivers p only to players whose position is within radius of the point (x, y, z). Used by the entity Manager for view-distance culling so spawn and move packets never reach players too far away to render the entity. Distance is compared squared to skip the sqrt.
fn (Hub) build_generator #
fn (h &Hub) build_generator(w &db.World) blockworld.Generator
build_generator resolves a world's own generator by name and dimension through the registry.
fn (Hub) capture_area #
fn (mut h Hub) capture_area(x1 int, y1 int, z1 int, x2 int, y2 int, z2 int) ?&arena.Snapshot
capture_area snapshots the block ids over the box between the two corners in the default world. See arena.max_volume for the size cap.
fn (Hub) close_worlds #
fn (mut h Hub) close_worlds()
close_worlds flushes and releases every loaded world's LevelDB handles. Called once on shutdown after all sessions are disconnected.
fn (Hub) collision_boxes #
fn (mut h Hub) collision_boxes(x int, y int, z int) []world.AABB
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) custom_block_names #
fn (mut h Hub) custom_block_names() []string
fn (Hub) custom_entity_names #
fn (mut h Hub) custom_entity_names() []string
fn (Hub) custom_item_names #
fn (mut h Hub) custom_item_names() []string
fn (Hub) default_world #
fn (mut h Hub) default_world() ?&db.World
default_world returns the world new players spawn into, or none when no world could be loaded.
fn (Hub) delete_world #
fn (mut h Hub) delete_world(name string) !
delete_world unloads the named world and removes its on-disk folder. Refuses the default world and any world that still has players in it. The LevelDB handle is always closed before the files are touched.
fn (Hub) disconnect_all #
fn (mut h Hub) disconnect_all(message string)
fn (Hub) entity_type_names #
fn (mut h Hub) entity_type_names() []string
entity_type_names lists every summonable entity type.
fn (Hub) generator_type_names #
fn (mut h Hub) generator_type_names() []string
generator_type_names lists every registered generator name. Part of the plugin.ServerView surface.
fn (Hub) get_block #
fn (mut h Hub) get_block(x int, y int, z int) int
get_block returns the block network id at a position in the default world, preferring a saved override and otherwise falling back to the generator so untouched terrain reads correctly.
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_world #
fn (mut h Hub) load_world(name string) !string
fn (Hub) next_enchantment_id #
fn (mut h Hub) next_enchantment_id() int
next_enchantment_id returns the next free id in the custom enchantment range.
fn (Hub) on_block_changed #
fn (mut h Hub) on_block_changed(x int, y int, z int)
on_block_changed notifies the liquid manager that a block edit happened so nearby water re-evaluates its flow. Cheap and non-blocking - dropped under a full actor queue since the periodic liquid tick will catch up anyway.
fn (Hub) online_count #
fn (mut h Hub) online_count() int
online_count is the plugin.ServerView alias for count().
fn (Hub) place_water #
fn (mut h Hub) place_water(x int, y int, z int)
place_water sets a water source at the position and enqueues the spread. The write and every spread step run on the actor thread via the liquid tick.
fn (Hub) player_names #
fn (mut h Hub) player_names() []string
player_names lists the display names of every connected player. Part of the plugin.ServerView surface.
fn (Hub) players_in_world #
fn (mut h Hub) players_in_world(name string) int
players_in_world counts the connected players whose active world matches name.
fn (Hub) register_custom_block #
fn (mut h Hub) register_custom_block(def block.CustomBlockDefinition) int
register_custom_block registers a data-driven block definition, allocates its runtime id and adds a matching block class so gameplay lookups (hardness, identifiers) work server-side.
fn (Hub) register_custom_entity #
fn (mut h Hub) register_custom_entity(def entity.CustomEntityDefinition, factory entity.BehaviourFactory) bool
register_custom_entity registers a custom entity type: the definition goes into the AvailableActorIdentifiers list and the factory into the entity registry under the definition's short name, so /summon and spawn_entity work with it.
fn (Hub) register_custom_item #
fn (mut h Hub) register_custom_item(def item.CustomItemDefinition) int
register_custom_item registers a data-driven item definition, allocates its runtime id and exposes it to the item class registry and the numeric id lookup so inventories and creative content resolve it like a vanilla item.
fn (Hub) register_enchantment #
fn (mut h Hub) register_enchantment(e enchant.Enchantment) bool
register_enchantment adds an enchantment to the shared registry, returning false when its id or name is already taken.
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. Part of the plugin.ServerView surface.
fn (Hub) remove #
fn (mut h Hub) remove(runtime_id u64)
fn (Hub) restore_area #
fn (mut h Hub) restore_area(snapshot &arena.Snapshot)
restore_area writes a snapshot back through the block write path so viewers see the arena reset.
fn (Hub) session_by_name #
fn (mut h Hub) session_by_name(name string) ?&NetworkSession
fn (Hub) session_by_runtime #
fn (mut h Hub) session_by_runtime(runtime_id u64) ?&NetworkSession
fn (Hub) set_block #
fn (mut h Hub) set_block(name string, x int, y int, z int) bool
set_block sets a block by namespaced id in the default world and broadcasts the change. Returns false if name isn't a known block. The name is resolved synchronously; the write itself is routed through the actor thread.
fn (Hub) set_block_id #
fn (mut h Hub) set_block_id(id int, x int, y int, z int)
set_block_id writes a raw block network id, used by arena restore. It routes through the same actor-thread write path as set_block.
fn (Hub) set_default_world #
fn (mut h Hub) set_default_world(name string)
fn (Hub) set_world_config #
fn (mut h Hub) set_world_config(worlds_dir string, generator string)
set_world_config records where worlds live on disk and the default generator used for worlds created at runtime. Called once at boot from load_worlds.
fn (Hub) spawn_entity #
fn (mut h Hub) spawn_entity(name string, x f32, y f32, z f32) bool
spawn_entity spawns a registered entity type by name at the given position. Returns false if the type is unknown. Part of the plugin.ServerView surface.
fn (Hub) submit #
fn (mut h Hub) submit(job WorldJob)
submit queues a WorldJob for run_jobs() to execute. Blocks if the queue is full.
fn (Hub) tps #
fn (mut h Hub) tps() f64
fn (Hub) try_submit #
fn (mut h Hub) try_submit(job WorldJob) bool
try_submit queues a job without blocking, returning false if the actor queue is full. Used for high-frequency, client- or plugin-driven jobs (attacks, respawns, block edits) so a flood of them can never back up connection threads or stall the tick loop - the excess job is simply dropped.
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.
fn (Hub) uptime_seconds #
fn (h &Hub) uptime_seconds() i64
fn (Hub) world #
fn (mut h Hub) world(name string) ?&db.World
fn (Hub) world_count #
fn (mut h Hub) world_count() int
fn (Hub) world_info #
fn (mut h Hub) world_info(name string) ?WorldInfo
world_info gathers a snapshot for the named world, or none when it isn't loaded.
struct NetworkSession #
struct NetworkSession {
mut:
transport &network.Session = unsafe { nil }
hub &Hub = unsafe { nil }
state State = .handshake
cfg conf.Config
world &db.World = unsafe { nil }
generator world.Generator = world.VoidGenerator{}
// world_mutex guards world and generator - both are swapped from the Hub
// job thread on a world change while the session thread reads them.
world_mutex &sync.Mutex = sync.new_mutex()
identity auth.Identity
encryption_enabled bool
runtime_id u64
pos_mutex &sync.Mutex = sync.new_mutex()
position types.Vector3
pitch f32
yaw f32
head_yaw f32
spawned bool
inv_opened bool
game_mode int
health f32 = 20.0
prev_y f32
vy f32
dead bool
held_item types.ItemStackWrapper
held_slot int
inv_stacks map[int]types.ItemStack
inv_slots map[int]int
inv_next_id int = 1
pending_creative ?types.ItemStack
loaded_items []playerdb.InvItem
pending_radius int
perm permission.Permissible
give_next_slot int
next_form_id int
pending_forms map[int]form.Form
last_place_ms i64
effects effect.Manager
has_last_death bool
last_death_pos types.Vector3
view_radius int
last_chunk_x int
last_chunk_z int
chunk_cache map[u64]world.Chunk
sent_chunks map[u64]bool
chunk_cache_mutex &sync.Mutex = sync.new_mutex()
chunk_stream_mutex &sync.Mutex = sync.new_mutex()
cooldown_until map[string]i64
pub mut:
log &logger.Logger = unsafe { nil }
}
fn (NetworkSession) add_effect #
fn (mut s NetworkSession) add_effect(e effect.Effect)
fn (NetworkSession) broadcast_message #
fn (mut s NetworkSession) broadcast_message(text string)
fn (NetworkSession) broadcast_title #
fn (mut s NetworkSession) broadcast_title(kind int, text string)
fn (NetworkSession) clear_inventory #
fn (mut s NetworkSession) clear_inventory()
fn (NetworkSession) clear_scoreboard #
fn (mut s NetworkSession) clear_scoreboard()
fn (NetworkSession) deliver #
fn (mut s NetworkSession) deliver(p protocol.Packet)
fn (NetworkSession) disconnect #
fn (mut s NetworkSession) disconnect(message string)
fn (NetworkSession) find_player #
fn (mut s NetworkSession) find_player(name string) ?cmd.Sender
fn (NetworkSession) give_item #
fn (mut s NetworkSession) give_item(id string, count int) bool
fn (NetworkSession) handle_loop #
fn (mut s NetworkSession) handle_loop()
fn (NetworkSession) has_permission #
fn (s &NetworkSession) has_permission(name string) bool
fn (NetworkSession) is_player #
fn (s &NetworkSession) is_player() bool
fn (NetworkSession) kill #
fn (mut s NetworkSession) kill()
fn (NetworkSession) name #
fn (s &NetworkSession) name() string
fn (NetworkSession) place_water #
fn (mut s NetworkSession) place_water(x int, y int, z int)
place_water sets a water source at the block position and starts its spread. Routes through the actor thread via Hub.place_water.
fn (NetworkSession) position #
fn (mut s NetworkSession) position() (f32, f32, f32)
teleport
fn (NetworkSession) refresh_abilities #
fn (mut s NetworkSession) refresh_abilities()
fn (NetworkSession) refresh_available_commands #
fn (mut s NetworkSession) refresh_available_commands()
refresh_available_commands resends the client's command list. The client only reads permission-gated visibility once (Command.execute checks it live, but the client-side autocomplete/menu does not) - anything that changes what s.perm can do after spawn (op/deop today, a future rank/VIP permission grant tomorrow) must call this or the player's command list stays stale until they reconnect.
fn (NetworkSession) remove_effect #
fn (mut s NetworkSession) remove_effect(typ effect.Type)
fn (NetworkSession) send_form #
fn (mut s NetworkSession) send_form(f form.Form) !
fn (NetworkSession) set_difficulty #
fn (mut s NetworkSession) set_difficulty(value int)
fn (NetworkSession) set_operator #
fn (mut s NetworkSession) set_operator(value bool)
fn (NetworkSession) show_scoreboard #
fn (mut s NetworkSession) show_scoreboard(title string, lines []string)
fn (NetworkSession) show_title #
fn (mut s NetworkSession) show_title(kind int, text string)
fn (NetworkSession) teleport #
fn (mut s NetworkSession) teleport(x f32, y f32, z f32)
fn (NetworkSession) teleport_to_world #
fn (mut s NetworkSession) teleport_to_world(name string, x f32, y f32, z f32)
teleport_to_world moves the player into another loaded world at the given position. No-op on the hub thread if the world is not loaded.
fn (NetworkSession) whitelist_add #
fn (mut s NetworkSession) whitelist_add(name string)
fn (NetworkSession) whitelist_enabled #
fn (s &NetworkSession) whitelist_enabled() bool
fn (NetworkSession) whitelist_names #
fn (s &NetworkSession) whitelist_names() []string
fn (NetworkSession) whitelist_remove #
fn (mut s NetworkSession) whitelist_remove(name string)
fn (NetworkSession) whitelist_set_enabled #
fn (mut s NetworkSession) whitelist_set_enabled(value bool)
fn (NetworkSession) world_create #
fn (mut s NetworkSession) world_create(name string, dimension string, generator string) !
fn (NetworkSession) world_delete #
fn (mut s NetworkSession) world_delete(name string) !
fn (NetworkSession) world_info #
fn (mut s NetworkSession) world_info(name string) ?cmd.WorldSummary
fn (NetworkSession) world_load #
fn (mut s NetworkSession) world_load(name string) !
fn (NetworkSession) world_name #
fn (s &NetworkSession) world_name() string
fn (NetworkSession) world_names #
fn (mut s NetworkSession) world_names() []string
world_admin wires the /world command's needs onto the Hub. Create/delete only touch the worlds map (never a player's active world), so they run directly on the Hub which already guards that map. Teleport goes through the existing TeleportJob so the world swap happens on the actor thread.
fn (NetworkSession) world_teleport #
fn (mut s NetworkSession) world_teleport(name string) !
struct TickJob #
struct TickJob {
pub:
tick i64
world_time int
tps f64
load f64
}
TickJob contains the per tick server state passed from tick_loop to Hub. Each snapshot includes the current world time, tps and tick load.
tick_loop owns the 20 Hz tick cadence and calculates the tps and load metrics on its own thread. It submits one TickJob per tick instead of modifying Hub's fields directly.
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.
- Constants
- fn new
- fn new_console_sender
- fn new_hub
- fn State.from
- interface WorldJob
- enum State
- struct ConsoleSender
- fn broadcast_message
- fn broadcast_title
- fn clear_inventory
- fn clear_scoreboard
- fn find_player
- fn give_item
- fn has_permission
- fn is_player
- fn kill
- fn name
- fn place_water
- fn position
- fn send_form
- fn send_message
- fn send_translation
- fn set_difficulty
- fn set_gamemode
- fn set_operator
- fn show_scoreboard
- fn show_title
- fn teleport
- fn whitelist_add
- fn whitelist_enabled
- fn whitelist_names
- fn whitelist_remove
- fn whitelist_set_enabled
- fn world_create
- fn world_delete
- fn world_info
- fn world_load
- fn world_names
- fn world_teleport
- struct Hub
- fn add
- fn add_world
- fn allocate_runtime_id
- fn broadcast
- fn broadcast_except
- fn broadcast_message
- fn broadcast_near
- fn build_generator
- fn capture_area
- fn close_worlds
- fn collision_boxes
- fn count
- fn create_world
- fn custom_block_names
- fn custom_entity_names
- fn custom_item_names
- fn default_world
- fn delete_world
- fn disconnect_all
- fn entity_type_names
- fn generator_type_names
- fn get_block
- fn list_worlds
- fn load
- fn load_world
- fn next_enchantment_id
- fn on_block_changed
- fn online_count
- fn place_water
- fn player_names
- fn players_in_world
- fn register_custom_block
- fn register_custom_entity
- fn register_custom_item
- fn register_enchantment
- fn register_generator
- fn remove
- fn restore_area
- fn session_by_name
- fn session_by_runtime
- fn set_block
- fn set_block_id
- fn set_default_world
- fn set_world_config
- fn spawn_entity
- fn submit
- fn tps
- fn try_submit
- fn unload_world
- fn uptime_seconds
- fn world
- fn world_count
- fn world_info
- struct NetworkSession
- fn add_effect
- fn broadcast_message
- fn broadcast_title
- fn clear_inventory
- fn clear_scoreboard
- fn deliver
- fn disconnect
- fn find_player
- fn give_item
- fn handle_loop
- fn has_permission
- fn is_player
- fn kill
- fn name
- fn place_water
- fn position
- fn refresh_abilities
- fn refresh_available_commands
- fn remove_effect
- fn send_form
- fn set_difficulty
- fn set_operator
- fn show_scoreboard
- fn show_title
- fn teleport
- fn teleport_to_world
- fn whitelist_add
- fn whitelist_enabled
- fn whitelist_names
- fn whitelist_remove
- fn whitelist_set_enabled
- fn world_create
- fn world_delete
- fn world_info
- fn world_load
- fn world_name
- fn world_names
- fn world_teleport
- struct TickJob
- struct WorldInfo