Your own movement is simulated from real input; other players’ input is guessed from their observed motion.
| Function | Returns |
|---|---|
prediction.self(ticks) |
Your snapshot ticks ahead, 0 being now |
prediction.self_path(from, to) |
Your snapshots across [from, to] |
prediction.self_with_input(input, ticks) |
A one-off simulation holding a custom input |
prediction.player(entity_id, ticks) |
Another player’s snapshot |
prediction.player_path(entity_id, from, to) |
Another player’s snapshots across a range |
prediction.velocity(entity_id) |
De-smeared per-tick velocity as vec3 |
A snapshot is
{pos, velocity, min, max, on_ground, fall_distance, horizontal_collision}, where pos,
velocity and the min/max bounding-box corners are vec3.
input is {forward, backward, left, right, jump, sneak, sprint}; omitted keys are false.
Simulations are cached per client tick and stepped lazily, so asking for tick 5 and then tick
8 only simulates three more. Tick 1200 is the exclusive cap, and anything past 1199 returns
nil.
Remote players arrive interpolated, which makes their raw per-tick delta unreliable.
prediction.velocity recovers the true motion and is what the simulation seeds from.
module:event("render_3d", function(render)
for _, p in ipairs(world:players() or {}) do
if not p:is_self() and p:distance() < 20 then
local s = prediction.player(p:id(), 10)
if s then
render.box(s.min, s.max, 0x80FF4040, 2)
end
end
end
end)