server.event
fn new_bus #
fn new_bus() &Bus
fn new_context #
fn new_context[T](val T) Context[T]
new_context wraps val in a fresh, uncancelled Context.
fn Priority.from #
fn Priority.from[W](input W) !Priority
interface Handler #
interface Handler {
mut:
on_player_join(mut ctx Context[JoinData])
on_player_quit(mut ctx Context[QuitData])
on_player_chat(mut ctx Context[ChatData])
on_player_command(mut ctx Context[CommandData])
on_start_break(mut ctx Context[StartBreakData])
on_block_break(mut ctx Context[BlockBreakData])
on_block_place(mut ctx Context[BlockPlaceData])
on_player_interact(mut ctx Context[InteractData])
on_item_use(mut ctx Context[ItemUseData])
on_player_attack(mut ctx Context[AttackData])
on_player_hurt(mut ctx Context[HurtData])
on_player_death(mut ctx Context[DeathData])
on_player_respawn(mut ctx Context[RespawnData])
on_player_move(mut ctx Context[MoveData])
on_gamemode_change(mut ctx Context[GameModeChangeData])
on_entity_spawn(mut ctx Context[EntitySpawnData])
on_entity_despawn(mut ctx Context[EntityDespawnData])
on_item_consume(mut ctx Context[ItemConsumeData])
on_world_load(mut ctx Context[WorldLoadData])
on_world_unload(mut ctx Context[WorldUnloadData])
on_effect_add(mut ctx Context[EffectAddData])
on_effect_remove(mut ctx Context[EffectRemoveData])
}
Handler receives server events through mutable Context values. Embed NopHandler and override only the events you need.
Handlers run synchronously on the thread that dispatches them, so they must stay short and non-blocking. World events may run on the owning world thread; blocking there stalls all other work for that world.
Cancellation only has an effect when the dispatch site checks it before applying the action. Some events are observational and fire after the outcome has already occurred.
fn (Context[T]) cancel #
fn (mut c Context[T]) cancel()
cancel marks the event as cancelled. Whether that stops anything is up to the code that dispatched the Context.
fn (Context[T]) is_cancelled #
fn (c &Context[T]) is_cancelled() bool
is_cancelled reports whether any handler cancelled the event.
enum Priority #
enum Priority {
lowest
low
normal
high
highest
monitor
}
Priority orders handlers on the Bus. Lowest runs first so highest and monitor see the final state. Monitor handlers are expected to observe only.
struct AttackData #
struct AttackData {
pub:
victim_runtime_id u64
critical bool
pub mut:
player player.View
damage f32
knockback_force f32
knockback_height f32
}
AttackData is dispatched when a player attacks an entity. player is the attacker, victim_runtime_id the target. Editing damage changes the hit; cancelling it deals no damage and no knockback.
struct BlockBreakData #
struct BlockBreakData {
pub:
x int
y int
z int
block_id int
pub mut:
player player.View
}
BlockBreakData is dispatched before a block is broken. block_id is the block being removed. Cancelling it leaves the block in place.
struct BlockPlaceData #
struct BlockPlaceData {
pub:
x int
y int
z int
block_id int
pub mut:
player player.View
}
BlockPlaceData is dispatched before a block is placed. block_id is the block being placed. Cancelling it stops the placement.
struct Bus #
struct Bus {
mut:
mutex &sync.Mutex = sync.new_mutex()
handlers []Registered
}
Bus fans a dispatched Context out to every registered handler in priority order. It is the single event pipe the session code talks to; external code registers and unregisters through Server.register_event/unregister_event, never the bus directly.
register()/unregister() are copy on write: they build an entirely new handlers slice (never append/remove in place) and swap it in under mutex. Every dispatch method takes the same mutex only to copy the current slice reference, then iterates that snapshot with no further locking. This makes concurrent register and dispatch safe without requiring dispatch to be confined to one thread which, for this bus specifically, it isn't: player_join/quit/chat/command and friends are fired directly from whatever session/connection thread is handling that packet, not funneled through a single actor.
Dispatch methods invoke handlers synchronously on the calling thread. See Handler for each event's dispatch context and cancellation behavior.
fn (Bus) register #
fn (mut b Bus) register(handler Handler, priority Priority)
register adds a handler at the given priority. Builds a new slice and swaps it in , never mutates the published slice in place, so a dispatch already iterating the previous slice is unaffected.
fn (Bus) unregister #
fn (mut b Bus) unregister(handler Handler)
unregister removes every registration matching handler. Same copy on write shape as register(): builds a new slice without the matching entries and swaps it in, never mutating the published slice in place.
fn (Bus) len #
fn (mut b Bus) len() int
len reports how many handlers are registered.
fn (Bus) player_join #
fn (mut b Bus) player_join(mut ctx Context[JoinData])
fn (Bus) player_quit #
fn (mut b Bus) player_quit(mut ctx Context[QuitData])
fn (Bus) player_chat #
fn (mut b Bus) player_chat(mut ctx Context[ChatData])
fn (Bus) player_command #
fn (mut b Bus) player_command(mut ctx Context[CommandData])
fn (Bus) start_break #
fn (mut b Bus) start_break(mut ctx Context[StartBreakData])
fn (Bus) block_break #
fn (mut b Bus) block_break(mut ctx Context[BlockBreakData])
fn (Bus) block_place #
fn (mut b Bus) block_place(mut ctx Context[BlockPlaceData])
fn (Bus) player_interact #
fn (mut b Bus) player_interact(mut ctx Context[InteractData])
fn (Bus) item_use #
fn (mut b Bus) item_use(mut ctx Context[ItemUseData])
fn (Bus) item_consume #
fn (mut b Bus) item_consume(mut ctx Context[ItemConsumeData])
fn (Bus) player_attack #
fn (mut b Bus) player_attack(mut ctx Context[AttackData])
fn (Bus) player_hurt #
fn (mut b Bus) player_hurt(mut ctx Context[HurtData])
fn (Bus) player_death #
fn (mut b Bus) player_death(mut ctx Context[DeathData])
fn (Bus) player_respawn #
fn (mut b Bus) player_respawn(mut ctx Context[RespawnData])
fn (Bus) player_move #
fn (mut b Bus) player_move(mut ctx Context[MoveData])
fn (Bus) gamemode_change #
fn (mut b Bus) gamemode_change(mut ctx Context[GameModeChangeData])
fn (Bus) entity_spawn #
fn (mut b Bus) entity_spawn(mut ctx Context[EntitySpawnData])
fn (Bus) entity_despawn #
fn (mut b Bus) entity_despawn(mut ctx Context[EntityDespawnData])
fn (Bus) world_load #
fn (mut b Bus) world_load(mut ctx Context[WorldLoadData])
fn (Bus) world_unload #
fn (mut b Bus) world_unload(mut ctx Context[WorldUnloadData])
fn (Bus) effect_add #
fn (mut b Bus) effect_add(mut ctx Context[EffectAddData])
fn (Bus) effect_remove #
fn (mut b Bus) effect_remove(mut ctx Context[EffectRemoveData])
struct ChatData #
struct ChatData {
pub mut:
player player.View
message string
}
ChatData is dispatched for a public chat message. Cancelling it drops the message; editing message rewrites what everyone sees.
struct CommandData #
struct CommandData {
pub mut:
player player.View
command string
}
CommandData is dispatched before a player command runs. Cancelling it stops the command; editing command rewrites what is executed.
struct Context #
struct Context[T] {
pub mut:
cancelled bool
val T
}
Context wraps the subject of an event and lets handlers cancel the outcome or mutate the subject in place. Callers dispatch a Context through the Bus, then read back is_cancelled() and the possibly modified val to decide what happens.
struct DeathData #
struct DeathData {
pub:
params []string
pub mut:
player player.View
message_key string
}
DeathData is dispatched when a player dies. message_key/params are the death broadcast; cancelling it suppresses the broadcast, editing message_key rewrites it.
struct EffectAddData #
struct EffectAddData {
pub:
effect_name string
level int
duration_ticks int
pub mut:
player player.View
}
EffectAddData is dispatched before an effect is applied to a player. Cancelling it rejects the effect entirely. effect_name/level/duration_ticks are primitives rather than the effect.Effect/Type themselves.
struct EffectRemoveData #
struct EffectRemoveData {
pub:
effect_name string
pub mut:
player player.View
}
EffectRemoveData is dispatched before an effect is removed from a player, whether it expired naturally or was removed early. Cancelling it keeps the effect active.
struct EntityDespawnData #
struct EntityDespawnData {
pub:
identifier string
x f32
y f32
z f32
}
EntityDespawnData is dispatched after a non player entity is removed from the world (died, expired or was otherwise despawned). Observational only, cancelling has no effect.
struct EntitySpawnData #
struct EntitySpawnData {
pub:
identifier string
x f32
y f32
z f32
}
EntitySpawnData is dispatched before a non player entity is spawned. Cancelling it stops the spawn entirely.
struct GameModeChangeData #
struct GameModeChangeData {
pub mut:
player player.View
mode int
}
GameModeChangeData is dispatched before a player's gamemode changes. Editing mode changes the target gamemode; cancelling it keeps the current one.
struct HurtData #
struct HurtData {
pub:
attacker_name string
pub mut:
player player.View
amount f32
}
HurtData is dispatched when a player takes damage. player is the victim, attacker_name the source. Editing amount changes the damage; cancelling it negates the damage entirely.
struct InteractData #
struct InteractData {
pub:
x int
y int
z int
face int
pub mut:
player player.View
}
InteractData is dispatched when a player right clicks a block, before any placement is decided. Cancelling it stops the interaction and any place that would follow.
struct ItemConsumeData #
struct ItemConsumeData {
pub:
item_name string
pub mut:
player player.View
}
ItemConsumeData is dispatched right before a held item is consumed (e.g. eating food, drinking a potion). Cancelling it keeps the item.
struct ItemUseData #
struct ItemUseData {
pub:
item_name string
meta int
on_block bool
x int
y int
z int
pub mut:
player player.View
}
ItemUseData is dispatched right before a held item's effect is applied, either in the air (e.g. a goat horn's sound) or on a block (e.g. bone meal advancing a crop's growth). on_block reports which; x/y/z are only meaningful when on_block is true. Cancelling it stops the effect.
struct JoinData #
struct JoinData {
pub mut:
player player.View
message string
}
JoinData is dispatched right after a player finishes spawning. Cancelling it suppresses the broadcast join message; editing message changes it.
struct MoveData #
struct MoveData {
pub:
x f32
y f32
z f32
pub mut:
player player.View
}
MoveData is dispatched when a player moves. Editing x/y/z is ignored; cancel rejects the movement and snaps the player back to where they were.
struct NopHandler #
struct NopHandler {}
NopHandler is an embeddable no-op implementation of Handler. Embed it so a listener satisfies the whole interface while only defining the handlers it actually needs.
fn (NopHandler) on_player_join #
fn (mut h NopHandler) on_player_join(mut ctx Context[JoinData])
fn (NopHandler) on_player_quit #
fn (mut h NopHandler) on_player_quit(mut ctx Context[QuitData])
fn (NopHandler) on_player_chat #
fn (mut h NopHandler) on_player_chat(mut ctx Context[ChatData])
fn (NopHandler) on_player_command #
fn (mut h NopHandler) on_player_command(mut ctx Context[CommandData])
fn (NopHandler) on_start_break #
fn (mut h NopHandler) on_start_break(mut ctx Context[StartBreakData])
fn (NopHandler) on_block_break #
fn (mut h NopHandler) on_block_break(mut ctx Context[BlockBreakData])
fn (NopHandler) on_block_place #
fn (mut h NopHandler) on_block_place(mut ctx Context[BlockPlaceData])
fn (NopHandler) on_player_interact #
fn (mut h NopHandler) on_player_interact(mut ctx Context[InteractData])
fn (NopHandler) on_item_use #
fn (mut h NopHandler) on_item_use(mut ctx Context[ItemUseData])
fn (NopHandler) on_player_attack #
fn (mut h NopHandler) on_player_attack(mut ctx Context[AttackData])
fn (NopHandler) on_player_hurt #
fn (mut h NopHandler) on_player_hurt(mut ctx Context[HurtData])
fn (NopHandler) on_player_death #
fn (mut h NopHandler) on_player_death(mut ctx Context[DeathData])
fn (NopHandler) on_player_respawn #
fn (mut h NopHandler) on_player_respawn(mut ctx Context[RespawnData])
fn (NopHandler) on_player_move #
fn (mut h NopHandler) on_player_move(mut ctx Context[MoveData])
fn (NopHandler) on_gamemode_change #
fn (mut h NopHandler) on_gamemode_change(mut ctx Context[GameModeChangeData])
fn (NopHandler) on_entity_spawn #
fn (mut h NopHandler) on_entity_spawn(mut ctx Context[EntitySpawnData])
fn (NopHandler) on_entity_despawn #
fn (mut h NopHandler) on_entity_despawn(mut ctx Context[EntityDespawnData])
fn (NopHandler) on_item_consume #
fn (mut h NopHandler) on_item_consume(mut ctx Context[ItemConsumeData])
fn (NopHandler) on_world_load #
fn (mut h NopHandler) on_world_load(mut ctx Context[WorldLoadData])
fn (NopHandler) on_world_unload #
fn (mut h NopHandler) on_world_unload(mut ctx Context[WorldUnloadData])
fn (NopHandler) on_effect_add #
fn (mut h NopHandler) on_effect_add(mut ctx Context[EffectAddData])
fn (NopHandler) on_effect_remove #
fn (mut h NopHandler) on_effect_remove(mut ctx Context[EffectRemoveData])
struct QuitData #
struct QuitData {
pub mut:
player player.View
message string
}
QuitData is dispatched when a spawned player leaves. Same rules as JoinData.
struct RespawnData #
struct RespawnData {
pub mut:
player player.View
x f32
y f32
z f32
}
RespawnData is dispatched before a player respawns. Handlers may move the respawn point by editing x/y/z (e.g. to send players back to a lobby).
struct StartBreakData #
struct StartBreakData {
pub:
x int
y int
z int
face int
pub mut:
player player.View
}
StartBreakData is dispatched the moment a player left clicks a block before any break timer starts, separate from BlockBreakData which only fires once the break actually completes.
struct WorldLoadData #
struct WorldLoadData {
pub:
name string
pub mut:
player player.View
}
WorldLoadData is dispatched after a world is created or loaded and registered. The world already exists by the time this fires, cancelling has no effect.
struct WorldUnloadData #
struct WorldUnloadData {
pub:
name string
pub mut:
player player.View
}
WorldUnloadData is dispatched before a loaded world is unloaded. Cancelling it keeps the world loaded.
- fn new_bus
- fn new_context
- fn Priority.from
- interface Handler
- type Context[T]
- enum Priority
- struct AttackData
- struct BlockBreakData
- struct BlockPlaceData
- struct Bus
- fn register
- fn unregister
- fn len
- fn player_join
- fn player_quit
- fn player_chat
- fn player_command
- fn start_break
- fn block_break
- fn block_place
- fn player_interact
- fn item_use
- fn item_consume
- fn player_attack
- fn player_hurt
- fn player_death
- fn player_respawn
- fn player_move
- fn gamemode_change
- fn entity_spawn
- fn entity_despawn
- fn world_load
- fn world_unload
- fn effect_add
- fn effect_remove
- struct ChatData
- struct CommandData
- struct Context
- struct DeathData
- struct EffectAddData
- struct EffectRemoveData
- struct EntityDespawnData
- struct EntitySpawnData
- struct GameModeChangeData
- struct HurtData
- struct InteractData
- struct ItemConsumeData
- struct ItemUseData
- struct JoinData
- struct MoveData
- struct NopHandler
- fn on_player_join
- fn on_player_quit
- fn on_player_chat
- fn on_player_command
- fn on_start_break
- fn on_block_break
- fn on_block_place
- fn on_player_interact
- fn on_item_use
- fn on_player_attack
- fn on_player_hurt
- fn on_player_death
- fn on_player_respawn
- fn on_player_move
- fn on_gamemode_change
- fn on_entity_spawn
- fn on_entity_despawn
- fn on_item_consume
- fn on_world_load
- fn on_world_unload
- fn on_effect_add
- fn on_effect_remove
- struct QuitData
- struct RespawnData
- struct StartBreakData
- struct WorldLoadData
- struct WorldUnloadData