Skip to content

server.entity

Constants #

const custom_entity_runtime_id_start = 10000

Runtime ids for custom entity types start above the vanilla list so they never collide with it.

fn new_custom_registry #

fn new_custom_registry() CustomRegistry

fn new_manager #

fn new_manager(host Host) &Manager

fn new_registry #

fn new_registry() Registry

fn register_defaults #

fn register_defaults(mut r Registry)

register_defaults registers the entity types Vedrock ships with.

interface Behaviour #

interface Behaviour {
	identifier() string
mut:
	tick(mut e Entity)
}

Behaviour drives an Entity's per-tick logic, mirroring dragonfly's Behaviour interface. identifier() returns the network type id used when the entity is spawned for clients; tick() runs once per server tick before physics is applied. A Behaviour mutates the Entity directly (velocity, kill, etc.).

interface Host #

interface Host {
mut:
	broadcast(p protocol.Packet)
	broadcast_near(x f32, y f32, z f32, radius f32, p protocol.Packet)
	allocate_runtime_id() u64
	get_block(x int, y int, z int) int
	collision_boxes(x int, y int, z int) []world.AABB
}

Host is the slice of the server the entity Manager needs: a broadcaster to send actor packets to every viewer, a radius-limited broadcaster for view-distance culling, the shared runtime-id allocator so entities and players never collide in id space, and a block query for collision. Hub satisfies it.

type BehaviourFactory #

type BehaviourFactory = fn () Behaviour

BehaviourFactory builds a fresh Behaviour for a registered entity type. Each spawn gets its own instance so per-entity behaviour state stays isolated.

struct CustomEntityDefinition #

struct CustomEntityDefinition {
pub mut:
	id            string
	summonable    bool = true
	has_spawn_egg bool
	runtime_id    int
}

CustomEntityDefinition describes an entity type a plugin registers. The definition ends up in the AvailableActorIdentifiersPacket idlist so the client accepts AddActor packets with the custom identifier.

fn (CustomEntityDefinition) short_name #

fn (d &CustomEntityDefinition) short_name() string

short_name derives the registry name from the namespaced id, e.g. 'myplugin:fire_golem' -> 'fire_golem'.

struct CustomRegistry #

struct CustomRegistry {
mut:
	defs    []CustomEntityDefinition
	ids     map[string]int
	next_id int = custom_entity_runtime_id_start
}

CustomRegistry owns every registered custom entity definition and hands out runtime ids sequentially, starting at custom_entity_runtime_id_start.

fn (CustomRegistry) register #

fn (mut r CustomRegistry) register(def CustomEntityDefinition) bool

register allocates a runtime id for def and stores it, returning false when the id was already registered.

fn (CustomRegistry) all #

fn (r &CustomRegistry) all() []CustomEntityDefinition

fn (CustomRegistry) len #

fn (r &CustomRegistry) len() int

fn (CustomRegistry) names #

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

fn (CustomRegistry) identifiers_nbt #

fn (r &CustomRegistry) identifiers_nbt() nbt.RootTag

identifiers_nbt builds the AvailableActorIdentifiers root tag: an idlist of one compound per custom entity, in the format the client expects.

struct Entity #

@[heap]
struct Entity {
pub:
	unique_id  i64
	runtime_id u64
	identifier string // network type id, e.g. 'minecraft:pig'
pub mut:
	pos        types.Vector3
	velocity   types.Vector3
	pitch      f32
	yaw        f32
	head_yaw   f32
	floor_y    f32
	on_ground  bool
	no_gravity bool
	health     f32 = 20.0
	dead       bool
	age        i64
	behaviour  Behaviour
}

Entity is a non-player actor living in the world - a mob, item or projectile. It is the Vedrock counterpart to dragonfly's Ent: shared state plus a pluggable Behaviour that drives its per-tick logic. Players stay as NetworkSession; this system covers everything else the client renders as an actor.

fn (Entity) position #

fn (e &Entity) position() types.Vector3

position returns the entity's current position.

fn (Entity) is_dead #

fn (e &Entity) is_dead() bool

is_dead reports whether the entity is scheduled for removal.

fn (Entity) kill #

fn (mut e Entity) kill()

kill marks the entity dead. The Manager removes and despawns it on the next tick.

fn (Entity) set_velocity #

fn (mut e Entity) set_velocity(v types.Vector3)

set_velocity replaces the entity's velocity (blocks/tick).

fn (Entity) teleport #

fn (mut e Entity) teleport(pos types.Vector3)

teleport moves the entity to pos and resets its ground clamp there.

fn (Entity) spawn_packet #

fn (e &Entity) spawn_packet() &protocol.AddActorPacket

spawn_packet builds the AddActorPacket that makes this entity appear for a viewer. Public so the session layer can send it to players joining late.

fn (Entity) move_packet #

fn (e &Entity) move_packet() &protocol.MoveActorAbsolutePacket

move_packet builds the movement update broadcast each tick the entity moves.

fn (Entity) despawn_packet #

fn (e &Entity) despawn_packet() &protocol.RemoveActorPacket

despawn_packet builds the RemoveActorPacket that removes this entity from a viewer.

struct Manager #

@[heap]
struct Manager {
mut:
	mutex    &sync.Mutex = sync.new_mutex()
	entities map[u64]&Entity
	host     Host
}

Manager owns every live non-player Entity. spawn/despawn are safe from any thread (mutex-guarded); tick() runs once per server tick on the Hub actor thread, the same place player state is mutated.

fn (Manager) spawn #

fn (mut m Manager) spawn(behaviour Behaviour, pos types.Vector3) &Entity

spawn creates an entity driven by behaviour at pos, registers it and broadcasts its appearance to all viewers. Returns the live Entity.

fn (Manager) despawn #

fn (mut m Manager) despawn(runtime_id u64)

despawn removes the entity with runtime_id and tells viewers to drop it.

fn (Manager) count #

fn (mut m Manager) count() int

count reports how many entities are alive.

fn (Manager) snapshot #

fn (mut m Manager) snapshot() []&Entity

snapshot returns a stable copy of the live entity list. Used to send existing entities to a player who just joined.

fn (Manager) tick #

fn (mut m Manager) tick()

tick advances every entity one server tick: run its Behaviour, apply physics, remove the dead, and broadcast movement for the ones that moved.

struct PassiveBehaviour #

struct PassiveBehaviour {
	network_id string
}

PassiveBehaviour is a do-nothing behaviour for stationary/idle mobs. Physics still applies, so the entity falls to floor_y and rests there.

fn (PassiveBehaviour) identifier #

fn (b &PassiveBehaviour) identifier() string

fn (PassiveBehaviour) tick #

fn (mut b PassiveBehaviour) tick(mut e Entity)

struct ProjectileBehaviour #

struct ProjectileBehaviour {
	network_id string
	max_age    i64 = 100
}

ProjectileBehaviour flies with its initial velocity and despawns when it hits the ground or outlives max_age ticks - the shape of a snowball or egg.

fn (ProjectileBehaviour) identifier #

fn (b &ProjectileBehaviour) identifier() string

fn (ProjectileBehaviour) tick #

fn (mut b ProjectileBehaviour) tick(mut e Entity)

struct Registry #

struct Registry {
mut:
	factories map[string]BehaviourFactory
}

Registry maps short type names (e.g. 'pig') to Behaviour factories. It is the lookup /summon and plugins use to spawn entities by name.

fn (Registry) register #

fn (mut r Registry) register(name string, factory BehaviourFactory)

register adds a named entity type. Re-registering a name overwrites it.

fn (Registry) create #

fn (r &Registry) create(name string) ?Behaviour

create builds a new Behaviour for name, or none if the type is unknown.

fn (Registry) names #

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

names lists every registered type name.