Builtin Library
README.md
debris
Timed entity despawn — Roblox Debris:AddItem(instance, lifetime)
analog. Wraps the internal __debris.* FFI with a typed Luau surface
and installs it as the debris global via the prelude.
Collapses the common task.delay + entity.despawn pattern into one
centrally-introspectable call. Use for transient entities — bullet
tracers, hit FX, dropped pickups, tween-completion cleanups, ragdoll
cleanup.
API
| Call | Effect |
|---|---|
debris.add(id, lifetime?) -> handle | Schedule despawn after lifetime seconds (default 10). Returns a cancel handle, or 0 if the id can't be resolved. Calling again on the same entity replaces the prior deadline. Negative or zero lifetime despawns immediately. |
debris.cancel(handleOrId) -> boolean | Cancel a pending despawn. Accepts a handle or an entity id / name / proxy. Returns true if a record was removed. |
debris.pending(id) -> number? | Seconds remaining before despawn, or nil if not scheduled. |
debris.list() -> { { id, remainingSecs, handle } } | Snapshot every pending entry as a flat array. Order is not stable. |
debris.count() -> number | Number of currently pending entries. |
entity(id):AddDebris(lifetime?) | Entity-proxy convenience; equivalent to debris.add(id, lifetime). Accepts both colon and dot call styles. |
Semantics
- Idempotent: a second
add(id, lifetime)replaces the prior deadline. The latest call's handle is the only handle that resolves to a live entry. - Despawn through any other path drops the pending record
silently — registered at the
despawn_entity_nowchokepoint soentity.despawn, parent cascade, andworld.loadreset all clean up automatically. No "despawn(invalid)" errors. - Single tick per frame:
tick(dt)runs alongsidetask_scheduler::tickinworld_context::post_update. No new Bevy schedule node. - Save / load round-trip: pending entries are snapshotted into
world settings as
debris.pendingatworld.saveand restored atworld.load. The saved value is seconds-remaining, so timers resume from where they paused regardless of wall-clock gap between save and load.
Examples
-- Bullet tracer
local bullet = entity.spawn("Bullet")
debris.add(bullet.id, 2.0)
-- Cancel before deadline
local handle = debris.add(target.id, 5)
debris.cancel(handle)
-- Entity-proxy convenience
entity.spawn("Pickup"):AddDebris(30)
-- Introspection
for _, info in debris.list() do
print(entity(info.id).name, "despawns in", info.remainingSecs)
end
See docs/specs/scripting-api.md for the canonical reference.