Skip to content

server.world

Constants #

const biome_ocean = 0
const biome_desert = 2
const biome_extreme_hills = 3
const biome_forest = 4
const biome_taiga = 5
const biome_swampland = 6
const biome_river = 7
const biome_hell = 8
const biome_the_end = 9
const biome_ice_plains = 12
const biome_extreme_hills_edge = 20
const biome_birch_forest = 27
const biome_snowy_taiga = 30
const state_kind_byte = 0
const state_kind_string = 1
const state_kind_int = 2
const air = new_block('minecraft:air')

Network IDs must match data/block_palette.nbt (FNV1a-32 of the canonical little-endian block state NBT). Values verified against the palette dump: air=-604749536 stone=-2144268767 grass_block=-567203660 bedrock(infiniburn_bit=0)=-173245189 dirt=-2108756090

const stone = new_block('minecraft:stone')
const grass_block = new_block('minecraft:grass_block')
const bedrock = new_block_with_states('minecraft:bedrock', [
	BlockState{
		key:        'infiniburn_bit'
		kind:       state_kind_byte
		byte_value: 0
	},
])
const dirt = new_block('minecraft:dirt')
const netherrack = new_block('minecraft:netherrack')
const end_stone = new_block('minecraft:end_stone')
const obsidian = new_block('minecraft:obsidian')
const coal_ore = new_block('minecraft:coal_ore')
const iron_ore = new_block('minecraft:iron_ore')
const gold_ore = new_block('minecraft:gold_ore')
const diamond_ore = new_block('minecraft:diamond_ore')
const emerald_ore = new_block('minecraft:emerald_ore')
const copper_ore = new_block('minecraft:copper_ore')
const redstone_ore = new_block('minecraft:redstone_ore')
const lapis_ore = new_block('minecraft:lapis_ore')
const coal_block = new_block('minecraft:coal_block')
const iron_block = new_block('minecraft:iron_block')
const gold_block = new_block('minecraft:gold_block')
const diamond_block = new_block('minecraft:diamond_block')
const emerald_block = new_block('minecraft:emerald_block')
const copper_block = new_block('minecraft:copper_block')
const redstone_block = new_block('minecraft:redstone_block')
const lapis_block = new_block('minecraft:lapis_block')
const cobblestone = new_block('minecraft:cobblestone')
const sand = new_block('minecraft:sand')
const red_sand = new_block('minecraft:red_sand')
const gravel = new_block('minecraft:gravel')
const sandstone = new_block('minecraft:sandstone')
const andesite = new_block('minecraft:andesite')
const polished_andesite = new_block('minecraft:polished_andesite')
const diorite = new_block('minecraft:diorite')
const polished_diorite = new_block('minecraft:polished_diorite')
const granite = new_block('minecraft:granite')
const polished_granite = new_block('minecraft:polished_granite')
const ice = new_block('minecraft:ice')
const snow = new_block('minecraft:snow')
const clay = new_block('minecraft:clay')
const mossy_cobblestone = new_block('minecraft:mossy_cobblestone')
const packed_ice = new_block('minecraft:packed_ice')
const blue_ice = new_block('minecraft:blue_ice')
const cobbled_deepslate = new_block('minecraft:cobbled_deepslate')
const tuff = new_block('minecraft:tuff')
const calcite = new_block('minecraft:calcite')
const smooth_basalt = new_block('minecraft:smooth_basalt')
const dripstone_block = new_block('minecraft:dripstone_block')
const soul_sand = new_block('minecraft:soul_sand')
const soul_soil = new_block('minecraft:soul_soil')
const glowstone = new_block('minecraft:glowstone')
const magma_block = new_block('minecraft:magma')
const purpur_block = new_block_with_states('minecraft:purpur_block', [
	BlockState{
		key:        'pillar_axis'
		kind:       state_kind_string
		string_val: 'y'
	},
])

Purpur is a pillar in the palette even when it is not laid out as one, so it only resolves with the axis it is placed on.

const end_bricks = new_block('minecraft:end_bricks')
const water = new_block_with_states('minecraft:water', [
	BlockState{
		key:       'liquid_depth'
		kind:      state_kind_int
		int_value: 0
	},
])
const lava = new_block_with_states('minecraft:lava', [
	BlockState{
		key:       'liquid_depth'
		kind:      state_kind_int
		int_value: 0
	},
])
const oak_log = new_block_with_states('minecraft:oak_log', [
	BlockState{
		key:        'pillar_axis'
		kind:       state_kind_string
		string_val: 'y'
	},
])
const oak_leaves = new_block_with_states('minecraft:oak_leaves', [
	BlockState{
		key:        'persistent_bit'
		kind:       state_kind_byte
		byte_value: 0
	},
	BlockState{
		key:        'update_bit'
		kind:       state_kind_byte
		byte_value: 0
	},
])
const spruce_log = new_block_with_states('minecraft:spruce_log', [
	BlockState{
		key:        'pillar_axis'
		kind:       state_kind_string
		string_val: 'y'
	},
])
const spruce_leaves = new_block_with_states('minecraft:spruce_leaves', [
	BlockState{
		key:        'persistent_bit'
		kind:       state_kind_byte
		byte_value: 0
	},
	BlockState{
		key:        'update_bit'
		kind:       state_kind_byte
		byte_value: 0
	},
])
const dimension_min_y = -64
const dimension_subchunk_count = 24
const dimension_max_y = dimension_min_y + dimension_subchunk_count * 16 - 1
const plains_biome_id = 1
const overworld = Dimension{
	id:                0
	min_y:             dimension_min_y
	subchunk_count:    dimension_subchunk_count
	default_generator: 'normal'
}
const nether = Dimension{
	id:                1
	min_y:             0
	subchunk_count:    8
	default_generator: 'nether'
}
const the_end = Dimension{
	id:                2
	min_y:             0
	subchunk_count:    16
	default_generator: 'end'
}
const nether_lava_level = 31

---- Nether ----

The Nether generator is intentionally compact: bedrock shell, a lava sea, rough lower and upper netherrack masses, and a wide traversable middle cavern. Extra nether biomes, structures, netherite and portals are out of scope.

const flat_spawn_y = -60
const void_spawn_y = 64
const max_volume = 256 * 256 * 256

max_volume caps how many blocks a single snapshot may capture so a bad min/max box can't allocate unbounded memory. 256256256 is generous for a minigame arena while still bounded.

fn absolute_boxes #

fn absolute_boxes(model BlockModel, x int, y int, z int) []AABB

fn absolute_boxes_with_neighbors #

fn absolute_boxes_with_neighbors(model BlockModel, neighbors map[int]BlockModel, x int, y int, z int) []AABB

fn block_from_id #

fn block_from_id(network_id int) Block

fn box #

fn box(min_x f32, min_y f32, min_z f32, max_x f32, max_y f32, max_z f32) AABB

fn capture #

fn capture(mut src BlockSource, box Box) !&Snapshot

capture reads every block in box from src into a fresh Snapshot. Returns an error if the box exceeds max_volume so a runaway box can't exhaust memory.

fn default_biome_for #

fn default_biome_for(dim Dimension) int

fn dimension_by_id #

fn dimension_by_id(id int) ?Dimension

fn dimension_by_name #

fn dimension_by_name(name string) ?Dimension

fn door_model #

fn door_model(facing_face int, open bool) BlockModel

fn empty_model #

fn empty_model() BlockModel

fn fence_gate_model #

fn fence_gate_model(facing_face int, open bool) BlockModel

fn fence_model #

fn fence_model() BlockModel

fn generate_flat #

fn generate_flat() Chunk

fn generate_void #

fn generate_void() Chunk

fn is_door_name #

fn is_door_name(name string) bool

fn is_fence_gate_name #

fn is_fence_gate_name(name string) bool

fn is_trapdoor_name #

fn is_trapdoor_name(name string) bool

fn ladder_model #

fn ladder_model(facing_face int) BlockModel

fn load_palette #

fn load_palette(path string) !&BlockPalette

load_palette reads the gzipped big-endian block palette NBT and indexes every block state both by its network id and by its canonical name+states key.

fn look_facing #

fn look_facing(yaw f32) Facing

look_facing maps a player yaw (degrees) to the horizontal direction the player is looking. Bedrock yaw: 0 = south, 90 = west, 180 = north, 270 = east.

fn new_block #

fn new_block(name string) Block

fn new_block_with_states #

fn new_block_with_states(name string, states []BlockState) Block

fn new_box #

fn new_box(x1 int, y1 int, z1 int, x2 int, y2 int, z2 int) Box

new_box normalizes the two corners so the caller need not order them.

fn new_chunk #

fn new_chunk() Chunk

fn new_chunk_dim #

fn new_chunk_dim(dim Dimension) Chunk

new_chunk_dim builds an empty Chunk sized for dim's height range.

fn new_generator #

fn new_generator(name string) Generator

fn new_generator_registry #

fn new_generator_registry() GeneratorRegistry

fn new_random #

fn new_random(seed u32) Random

fn slab_model #

fn slab_model(double bool, top bool) BlockModel

fn solid_model #

fn solid_model() BlockModel

fn stair_model #

fn stair_model(facing_face int, upside_down bool) BlockModel

fn thin_model #

fn thin_model() BlockModel

fn trapdoor_model #

fn trapdoor_model(facing_face int, open bool, top bool) BlockModel

fn wall_model #

fn wall_model(north string, east string, south string, west string, post bool) BlockModel

fn Facing.from #

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

fn ModelKind.from #

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

interface BlockSink #

interface BlockSink {
mut:
	set_block_id(id int, x int, y int, z int)
}

BlockSink writes a block by network id and broadcasts the change to viewers. Restore goes through this so a reset looks identical to normal block edits.

interface BlockSource #

interface BlockSource {
mut:
	get_block(x int, y int, z int) int
}

BlockSource reads block network ids from a world by absolute coordinates. Hub satisfies it; tests use an in-memory grid.

interface Generator #

interface Generator {
	spawn_y() int
	uses_blocks() bool
	generate(chunk_x int, chunk_z int) Chunk
	block_at(x int, y int, z int) int
	biome_at(x int, z int) int
}

type GeneratorFactory #

type GeneratorFactory = fn (dim Dimension) Generator

GeneratorFactory builds a fresh Generator sized for dim. Each lookup gets its own instance, mirroring entity.Registry's BehaviourFactory.

enum Facing #

enum Facing {
	down
	up
	north
	south
	east
	west
}

Facing is a canonical block direction, independent of the many per-block state encodings (cardinal_direction string, weirdo_direction int, ...).

enum ModelKind #

enum ModelKind {
	solid
	empty
	slab
	stair
	ladder
	thin
	fence
	wall
	fence_gate
	door
	trapdoor
}

struct AABB #

struct AABB {
pub:
	min_x f32
	min_y f32
	min_z f32
	max_x f32
	max_y f32
	max_z f32
}

fn (AABB) face_center_solid #

fn (b AABB) face_center_solid(face int) bool

fn (AABB) translated #

fn (b AABB) translated(x int, y int, z int) AABB

fn (AABB) overlaps #

fn (b AABB) overlaps(other AABB) bool

fn (AABB) offset_by #

fn (b AABB) offset_by(dx f32, dy f32, dz f32) AABB

offset_by shifts b along each axis by a floating point delta.

fn (AABB) offset_x #

fn (b AABB) offset_x(other AABB, delta f32) f32

offset_x clamps the requested X movement so b stops before entering other. The box is ignored unless they already overlap on Y and Z.

Resolve a full move by applying the axis offsets in sequence and translating the box after each one.

fn (AABB) offset_y #

fn (b AABB) offset_y(other AABB, delta f32) f32

offset_y clamps the requested Y movement so b stops before entering other. The box is ignored unless they already overlap on X and Z.

Resolve a full move by applying the axis offsets in sequence and translating the box after each one.

fn (AABB) offset_z #

fn (b AABB) offset_z(other AABB, delta f32) f32

offset_z clamps the requested Z movement so b stops before entering other. The box is ignored unless they already overlap on X and Y.

Resolve a full move by applying the axis offsets in sequence and translating the box after each one.

struct Block #

struct Block {
pub:
	name       string
	network_id int
}

struct BlockEntry #

struct BlockEntry {
pub:
	x  int
	y  int
	z  int
	id int
}

BlockEntry is one captured block's absolute position and id. Exposed so a caller can restore a snapshot across several bounded slices instead of only through one unbounded restore() pass.

struct BlockModel #

struct BlockModel {
pub:
	kind        ModelKind
	facing_face int
	top         bool
	double      bool
	upside_down bool
	open        bool
	wall_north  string
	wall_east   string
	wall_south  string
	wall_west   string
	post        bool
}

fn (BlockModel) boxes #

fn (m BlockModel) boxes() []AABB

fn (BlockModel) boxes_with_neighbors #

fn (m BlockModel) boxes_with_neighbors(neighbors map[int]BlockModel) []AABB

fn (BlockModel) face_solid #

fn (m BlockModel) face_solid(face int) bool

fn (BlockModel) face_center_solid #

fn (m BlockModel) face_center_solid(face int) bool

struct BlockPalette #

@[heap]
struct BlockPalette {
mut:
	by_id  map[int]BlockVariant
	by_key map[string]int
}

fn (BlockPalette) can_place_on_face #

fn (p &BlockPalette) can_place_on_face(id int, click_face int) bool

can_place_on_face reports whether a block may be placed from the clicked face. It only covers attachment families with face specific restrictions; unknown blocks stay permissive.

fn (BlockPalette) can_place_on_support #

fn (p &BlockPalette) can_place_on_support(id int, click_face int, support_id int) bool

fn (BlockPalette) carved_pumpkin_id #

fn (p &BlockPalette) carved_pumpkin_id(id int, click_face int) ?int

carved_pumpkin_id returns the carved_pumpkin id matching an uncarved pumpkin at id, facing the clicked horizontal face directly. Top and bottom faces can't carve a pumpkin.

fn (BlockPalette) connected_block #

fn (p &BlockPalette) connected_block(id int, neighbors NeighborBlockIDs) int

fn (BlockPalette) door_pair_id #

fn (p &BlockPalette) door_pair_id(id int) ?int

fn (BlockPalette) door_placement #

fn (p &BlockPalette) door_placement(id int, yaw f32, neighbors NeighborBlockIDs) ?DoorPlacement

fn (BlockPalette) door_toggled_pair #

fn (p &BlockPalette) door_toggled_pair(clicked_id int, pair_id int) ?DoorToggle

fn (BlockPalette) is_door_top #

fn (p &BlockPalette) is_door_top(id int) bool

fn (BlockPalette) len #

fn (p &BlockPalette) len() int

fn (BlockPalette) merged_slab #

fn (p &BlockPalette) merged_slab(existing_id int, placing_id int, click_face int, click_y f32, clicked bool) ?int

fn (BlockPalette) model #

fn (p &BlockPalette) model(id int) BlockModel

fn (BlockPalette) oriented #

fn (p &BlockPalette) oriented(id int, yaw f32, click_face int, click_y f32) int

oriented returns the network id the given block should be placed as, given the player's yaw and the clicked block face. Blocks with no known facing state are returned unchanged.

fn (BlockPalette) toggled_open #

fn (p &BlockPalette) toggled_open(id int) ?int

fn (BlockPalette) variant #

fn (p &BlockPalette) variant(id int) ?BlockVariant

fn (BlockPalette) with_state #

fn (p &BlockPalette) with_state(id int, key string, value string) ?int

with_state returns the network id of the same block with one state overridden. none when the id is unknown, the block lacks that state, or the resulting combination is not in the palette.

struct BlockState #

struct BlockState {
pub:
	key        string
	kind       int
	byte_value u8
	string_val string
	int_value  int
}

struct BlockVariant #

struct BlockVariant {
pub:
	name   string
	states map[string]string
}

BlockVariant is one entry of the canonical block palette - a block name plus its state values, every value normalized to its string form so variants can be compared and rebuilt regardless of the underlying NBT tag type.

struct Box #

struct Box {
pub:
	min_x int
	min_y int
	min_z int
	max_x int
	max_y int
	max_z int
}

Box is an axis-aligned block region, normalized so min <= max on every axis.

fn (Box) volume #

fn (b Box) volume() i64

volume is the number of blocks the box covers (inclusive on both corners). Computed in i64 so a huge box can't overflow int32 and slip past the cap.

struct Chunk #

struct Chunk {
mut:
	sections       [][]int
	min_y          int   = dimension_min_y
	subchunk_count int   = dimension_subchunk_count
	biomes         []int = []int{len: 256, init: plains_biome_id}
}

fn (Chunk) estimated_bytes #

fn (c &Chunk) estimated_bytes() i64

fn (Chunk) clone #

fn (c &Chunk) clone() Chunk

fn (Chunk) serialize_subchunk #

fn (c &Chunk) serialize_subchunk(abs_index int) ?[]u8

serialize_subchunk encodes a single subchunk (as used by SubChunkPacket responses to a SubChunkRequestPacket), addressed by its absolute Y index (block Y / 16 - e.g. -4 for the overworld's bottom section). Returns none if abs_index falls outside this chunk's height range.

fn (Chunk) set_biome #

fn (mut c Chunk) set_biome(x int, z int, biome_id int)

set_biome assigns the biome id for column (x, z), applied to the full height of the chunk.

fn (Chunk) biome_id #

fn (c &Chunk) biome_id(x int, z int) int

biome_id returns the biome id previously set for column (x, z).

fn (Chunk) set_block #

fn (mut c Chunk) set_block(x int, y int, z int, b Block)

fn (Chunk) set_section #

fn (mut c Chunk) set_section(index int, ids []int)

fn (Chunk) block_id #

fn (c &Chunk) block_id(x int, y int, z int) int

fn (Chunk) height_map #

fn (c &Chunk) height_map() []int

fn (Chunk) section_count #

fn (c &Chunk) section_count() int

fn (Chunk) serialize #

fn (c &Chunk) serialize() []u8

fn (Chunk) serialize_biomes #

fn (c &Chunk) serialize_biomes() []u8

serialize_biomes encodes c.biomes (a per-column x/z grid) as one PalettedStorage, replicated across every y in a subchunk - same format as serialize_section, just varying by (x, z) only, not y.

struct Dimension #

struct Dimension {
pub:
	id                int
	min_y             int
	subchunk_count    int
	default_generator string
}

Dimension describes one Bedrock dimension's world height bounds, network id and default generator. min_y/subchunk_count size every Chunk generated or loaded for it.

fn (Dimension) max_y #

fn (d Dimension) max_y() int

fn (Dimension) name #

fn (d Dimension) name() string

struct DoorPlacement #

struct DoorPlacement {
pub:
	lower int
	upper int
}

struct DoorToggle #

struct DoorToggle {
pub:
	clicked int
	pair    int
}

struct EndGenerator #

struct EndGenerator {
	dim Dimension = the_end
}

fn (EndGenerator) spawn_y #

fn (g EndGenerator) spawn_y() int

fn (EndGenerator) uses_blocks #

fn (g EndGenerator) uses_blocks() bool

fn (EndGenerator) generate #

fn (g EndGenerator) generate(chunk_x int, chunk_z int) Chunk

fn (EndGenerator) block_at #

fn (g EndGenerator) block_at(x int, y int, z int) int

fn (EndGenerator) biome_at #

fn (g EndGenerator) biome_at(x int, z int) int

struct FlatGenerator #

struct FlatGenerator {
	dim Dimension = overworld
}

fn (FlatGenerator) spawn_y #

fn (g FlatGenerator) spawn_y() int

fn (FlatGenerator) uses_blocks #

fn (g FlatGenerator) uses_blocks() bool

fn (FlatGenerator) generate #

fn (g FlatGenerator) generate(chunk_x int, chunk_z int) Chunk

fn (FlatGenerator) block_at #

fn (g FlatGenerator) block_at(x int, y int, z int) int

fn (FlatGenerator) biome_at #

fn (g FlatGenerator) biome_at(x int, z int) int

struct GeneratorRegistry #

struct GeneratorRegistry {
mut:
	factories map[string]GeneratorFactory
}

fn (GeneratorRegistry) register #

fn (mut r GeneratorRegistry) register(name string, factory GeneratorFactory)

fn (GeneratorRegistry) create #

fn (r &GeneratorRegistry) create(name string, dim Dimension) ?Generator

create resolves name to a Generator sized for dim. An empty name or the literal name "default" both mean "whatever this dimension's own default generator is" (dim.default_generator - 'normal' for overworld, 'nether' for nether, 'end' for end), so callers (e.g. /world create ... default) don't need to know each dimension's concrete generator name.

fn (GeneratorRegistry) names #

fn (r &GeneratorRegistry) names() []string

struct NeighborBlockIDs #

struct NeighborBlockIDs {
pub:
	north int
	east  int
	south int
	west  int
	above int
	below int
}

struct NetherGenerator #

struct NetherGenerator {
	dim Dimension = nether
}

fn (NetherGenerator) spawn_y #

fn (g NetherGenerator) spawn_y() int

fn (NetherGenerator) uses_blocks #

fn (g NetherGenerator) uses_blocks() bool

fn (NetherGenerator) generate #

fn (g NetherGenerator) generate(chunk_x int, chunk_z int) Chunk

fn (NetherGenerator) block_at #

fn (g NetherGenerator) block_at(x int, y int, z int) int

fn (NetherGenerator) biome_at #

fn (g NetherGenerator) biome_at(x int, z int) int

struct NormalGenerator #

struct NormalGenerator {
	dim Dimension = overworld
}

fn (NormalGenerator) uses_blocks #

fn (g NormalGenerator) uses_blocks() bool

fn (NormalGenerator) biome_at #

fn (g NormalGenerator) biome_at(x int, z int) int

fn (NormalGenerator) block_at #

fn (g NormalGenerator) block_at(x int, y int, z int) int

fn (NormalGenerator) spawn_y #

fn (g NormalGenerator) spawn_y() int

fn (NormalGenerator) generate #

fn (g NormalGenerator) generate(chunk_x int, chunk_z int) Chunk

struct Random #

struct Random {
mut:
	x u32
	y u32
	z u32
	w u32
}

Random is a xorshift128 pseudo random generator. Chunk population has to be reproducible, so populators seed one of these from the chunk coordinates alone rather than drawing from a shared global source.

fn (Random) set_seed #

fn (mut r Random) set_seed(seed u32)

fn (Random) next_int #

fn (mut r Random) next_int() int

next_int returns a non negative value spread over the full positive int range.

fn (Random) next_float #

fn (mut r Random) next_float() f64

fn (Random) next_bounded_int #

fn (mut r Random) next_bounded_int(bound int) int

fn (Random) next_range #

fn (mut r Random) next_range(start int, end int) int

next_range returns a value in [start, end].

struct Snapshot #

@[heap]
struct Snapshot {
pub:
	box Box
mut:
	ids []int
}

Snapshot holds the block ids of a Box captured at some point in time. It is a flat array so a full restore is a single linear pass. Memory cost is 4 bytes per block - a 64^3 arena is ~1 MB.

fn (Snapshot) restore #

fn (s &Snapshot) restore(mut sink BlockSink)

restore writes every captured block back through sink in the same order it was captured, so viewers see the arena reset to its saved state.

fn (Snapshot) len #

fn (s &Snapshot) len() int

len is the number of blocks stored in the snapshot.

fn (Snapshot) entry_at #

fn (s &Snapshot) entry_at(i int) BlockEntry

entry_at returns the block captured at flat index i, in the same order capture and restore already iterate: y outermost, then x, then z.

struct VoidGenerator #

struct VoidGenerator {
	dim Dimension = overworld
}

fn (VoidGenerator) spawn_y #

fn (g VoidGenerator) spawn_y() int

fn (VoidGenerator) uses_blocks #

fn (g VoidGenerator) uses_blocks() bool

fn (VoidGenerator) generate #

fn (g VoidGenerator) generate(chunk_x int, chunk_z int) Chunk

fn (VoidGenerator) block_at #

fn (g VoidGenerator) block_at(x int, y int, z int) int

fn (VoidGenerator) biome_at #

fn (g VoidGenerator) biome_at(x int, z int) int