Client particles
ClientHost::add_particle submits the API's ParticleOptions, a world position and
velocity to the ordinary client particle queue. The client must have a loaded player
and world. Non-finite numeric inputs are refused. A successful submission does not
promise a visible particle: provider availability, sprite sets, distance and the
player's particle settings still apply. This method is not available on ServerHost.
Particle options carry a ParticleKey, not an engine particle enum or a provider name.
Request the key with Registrar::particle_key during registration and retain it. The game resolves
provider identities once when content loads. ParticleOptions::simple(key) handles both vanilla
and custom sprite providers; custom providers still require an assets/<namespace>/particles/<path>.json
sprite set. All option constructors take the resolved key, including dust, item, trail,
vibration, shriek, sculk_charge and dust_transition. Use the corresponding vanilla key
for these parameter families. Sending an option performs no string parsing or registry scan.
For stack-derived breaking or eating particles, call
ClientHost::item_particle_options(&stack) and pass the returned options to
add_particle. This read resolves the ground model with seed 0, preserving all
layer particle sprites and resource-pack and stack-component overrides. It returns
None for invalid stacks or unavailable resources/provider. It is available in
Setup, Reloading and World, on native and wasm. Resolve again after resource reloads.
It allocates a sprite list only when called; it adds no per-tick work.
Bot movement and block collisions
PlayerRef::simulate_move predicts one server player's movement tick from
PlayerInput, using the game's movement implementation without replacing the
live player's body. It returns SimulatedMove with position, velocity, ground,
horizontal-collision and sprinting results. It refuses stale or inaccessible players,
dead players, spectators, riders and invalid numeric input. A supplied velocity is
input to the prediction, not a write to the player.
LevelRef::collision_boxes reads block collision boxes within a finite, ordered
axis-aligned box. It excludes entity and border collisions. A refused level or a
query covering more than 1,000,000 cells returns None; a valid query with no
collisions returns Some containing an empty vector. Keep queries bounded rather
than scanning a whole level each tick.
LevelRef::block_shape(host, state, pos, kind) reads an explicit BlockState's
outline or collision boxes with an empty context at a position in that level.
The supplied state can differ from the world's block, without changing it;
level-dependent shape inputs still come from the actual level. To query the
stored block, first read level.block_state(host, pos) and pass that state.
This server read returns block-local boxes, or None for an unknown state,
stale handle, closed level or client. Parked levels are supported.
These queries take typed handles for their natural receiver. There are no parallel UUID-only or dimension-string helpers.