Skip to content

API Entity Presentation and Sounds

Piggo41 edited this page Oct 12, 2026 · 2 revisions

Entity presentation and sounds

Lua API / Entities / Entity presentation and sounds

Presentation controls how an entity is drawn and heard. It remains independent of collision, targeting, health, and other gameplay state.

Presentation, animation, and sounds

The optional render table sets presentation defaults without changing collision, targeting, health, or saved entity data.

Field Default Meaning
visible true Initial model and native-pickup visibility.
shadowRadius 0, or 0.15 for pickups Vanilla shadow radius in blocks, 0–16.
fireOverlay true Whether a burning entity draws the vanilla fire overlay.
pickupBobbing true Bob a custom pickup model; valid only for pickups.
pickupSpin true Spin a custom pickup model; valid only for pickups.

Entity handles expose transient, per-instance presentation controls:

Method Effect
playAnimation(clip, options?) Select a clip from the appearance's animation asset. Options are speed (0–100, default 1), startTime in seconds (0–3600, default 0), and restart (default false). Returns false when the entity has no animation asset.
stopAnimation() Clear the per-instance selection and return whether one was active. The appearance's declared default clip applies again.
getAnimation() Return a detached { clip, speed, time } snapshot, or nil.
setVisible(visible) Override visibility for this instance.
setVisualOffset(x, y, z) Set a local render offset in blocks; each component is -16–16.
setVisualRotation(yaw, pitch, roll) Add visual rotation in degrees after the entity's facing.
setVisualScale(x, y, z) Set visual-only scale; each component is 0–64.
resetVisuals() Restore declared visibility and the identity offset, rotation, and scale.

Calling playAnimation again with the same clip and speed keeps its current clock unless restart = true. Clip names must exactly match the registered animation asset. An unavailable clip is reported by the renderer and the appearance's default clip is used. The clip's authored loop mode still controls whether it loops, stops contributing after one play, or holds its last frame. onPose runs after the selected clip. Animation selection and visual overrides are not saved; each loaded instance starts from its declaration defaults.

onInteract = function(ctx)
    ctx.entity:playAnimation("animation.machine.open", { restart = true })
    ctx.entity:setVisualRotation(0, 0, 8)
    return betamoon.callbackResults.handled
end

Use sounds to bind registered sound events to entity behavior. A binding can be a sound-event reference or key, false, or a table with event and optional volume (0–1), pitch (0.01–4), and range (0.01–1024 blocks) overrides. Register the sound event before the entity. Entity sounds are positional and require mono OGG or WAV clips.

local machineHum = betamoon.soundEvents:add {
    key = "mymod:entity/machine/hum",
    sound = "mymod:entity/machine/hum",
    volume = 0.35,
    range = 12
}
local machineClang = betamoon.soundEvents:add {
    key = "mymod:entity/machine/clang",
    sound = "mymod:entity/machine/clang"
}

betamoon.entities:add {
    key = "mymod:entity/machine",
    appearance = { model = "mymod:entity/machine", texture = "mymod:entity/machine" },
    sounds = {
        ambient = { event = machineHum, intervalTicks = { min = 80, max = 140 } },
        hurt = machineClang
    }
}
Binding Trigger Additional options
ambient Repeated while the entity simulates. intervalTicks: fixed integer or { min, max }, default 80–160, bounds 1–72000.
hurt Accepted nonfatal damage that loses health, or accepted nonfatal native damage when health is unavailable. —
death Fatal damage, once. —
step Grounded horizontal travel. distance: blocks between sounds, default 1, range 0.1–16.
impact Each projectile collision before onImpact. —
pickup Full pickup collection before onPickup. —

entity:playSound(event, options?) emits a registered sound event once at the entity's current position. Its optional volume, pitch, and range fields replace event defaults. It works on any entity handle and returns false if the entity is already dead or detached from its world. A true result means the presentation request was accepted; it does not guarantee audible output. Playback is client-local, so unavailable or muted audio does not prevent gameplay callbacks from running and the sound is not sent to remote players.

Clone this wiki locally