Skip to content

API Entity Projectiles and Pickups

Piggo41 edited this page Oct 12, 2026 · 2 revisions

Projectiles and pickups

Lua API / Entities / Projectiles and pickups

Projectile and pickup kinds add specialized simulation and callbacks while retaining the common entity declaration, lifecycle, data, and presentation systems.

Projectiles

Use kind = "projectile" with an optional projectile table:

local bolt = betamoon.entities:add {
    key = "mymod:entity/bolt",
    kind = "projectile",
    appearance = { model = "mymod:entity/bolt", texture = "mymod:entity/bolt" },
    projectile = { speed = 2, gravity = 0.01, damage = 4, lifetimeTicks = 100 },
    onImpact = function(ctx)
        return "default"
    end
}
Field Default Meaning
speed 1.5 Initial blocks per tick, greater than zero and at most 16.
gravity 0.03 Downward acceleration per tick, 0–1.
drag 0.99 Motion multiplier per tick, 0–1.
lifetimeTicks 80 Maximum life, 1–1000000 ticks.
damage 0 Default integer damage on an entity hit.
ownerGraceTicks 5 Ticks before the projectile can hit its launching entity.
alignToVelocity true Set false to keep Lua-controlled yaw and pitch instead of turning toward motion.

onImpact(ctx) receives entity, owner when known, position, world, and either target or block (x, y, z, face). Return "default"/nil for default damage and removal, "remove", "bounce", "stick", or "continue". A custom projectile can be fired by an item with use.projectile = projectileType or its namespaced key; the item can also declare use.ammunition and use.cooldown.

Lua can launch the same projectile from an entity callback and preserve attribution:

local bolt, reason = ctx.world:spawnEntity(boltType, {
    position = ctx.entity:getPosition(),
    rotation = ctx.entity:getRotation(),
    owner = ctx.entity
})

ownerGraceTicks, onImpact(ctx).owner, projectile:getOwner(), and damage attribution use that owner. Players and BetaMoon entities also expose a stable player:<name> or entity:<identity> value through getOwnerIdentity() and resolve again after save/load when loaded in the same world. A loaded native or modded entity can provide transient projectile attribution, but that relationship is not persisted across reloads.

Pickups

Use kind = "pickup" and pickup = { item = itemReferenceOrId }. Optional count defaults to 1 (1–64), damage to 0, and delayTicks to 0 (0–1200). Pickups move, bob, and enter player inventories like dropped items. Partial inventory acceptance leaves the remainder in the world. onPickup(ctx) runs once after the entire remaining stack has been collected; it receives entity, player, and world for a post-collection reaction.

A pickup needs no model appearance: without one, BetaMoon uses the native dropped-item renderer. Supplying appearance uses the same custom model system as other entities. For a custom pickup model, render.pickupBobbing and render.pickupSpin default to true and may be disabled independently. They do not change native item rendering.

entity:getPickupStack() returns a detached { id, count, damage } snapshot. entity:collect(player) tries native inventory collection and returns whether any items transferred. This action is useful when lifecycle = "manual" disables automatic pickup.

betamoon.entities:add {
    key = "mymod:entity/coin_drop",
    kind = "pickup",
    pickup = { item = 264, count = 2, delayTicks = 20 }
}

Clone this wiki locally