Camera cutscenes without a mod: keyframes, interpolation and spectator tricks
Two ways to move a camera in vanilla — a ticking teleport function, or the timeline registry. What each is good for, and the smoothing that stops it looking robotic.
There is no camera object in vanilla, so a cutscene is one of two illusions.
Method 1: teleport the player every tick
The old, universal way. Put the player in spectator, then move them along a path:
gamemode spectator @s
tp @s 100.0 70.0 200.0 -90.0 10.0
one tp per tick from a function chain. It works on every version and needs nothing special. The problems are all about smoothness:
- 20 keyframes per second. A ten-second shot is 200
tplines. - Linear steps look mechanical. Real camera moves ease in and out.
- Rotation wraps badly. Going from yaw 170 to -170 is a 20-degree turn, but naive
interpolation spins 340 degrees the wrong way. Normalise the angle difference into the range -180…180 before stepping.
Generating those lines is what a keyframe tool is for — you place a handful of positions and it emits the per-tick function with easing applied.
Easing
The difference between amateur and watchable is the interpolation curve. Between two keyframes, with t from 0 to 1:
linear t
ease-in-out t < 0.5 ? 2t² : 1 − 2(1−t)²
smoothstep t² × (3 − 2t)
smoothstep is the safe default. Apply it to position and rotation together or the camera arrives before it finishes turning.
Method 2: the timeline registry
Newer versions add a timeline format that describes the whole shot as data rather than as hundreds of teleports:
data/<namespace>/timeline/intro.json
Keyframes with times and interpolation modes, played with a single command. Advantages:
- Far smaller. Six keyframes instead of two hundred teleports.
- Interpolation is native, so no manual easing maths.
- Frame-rate independent — it does not stutter the way a per-tick teleport does on a
loaded server.
The cost is that it only exists on recent versions, so a map targeting older clients still needs method 1.
Keeping the player put
Both methods fight two things:
- Player input. Spectator lets the player fly away mid-shot. Re-teleporting every tick
overrides it, which is one reason the brute-force method persists.
- Chunk loading. A camera flying somewhere unloaded shows void.
/forceloadthe path
before the shot and remove it after.
Hiding the HUD
/gamerule doImmediateRespawn, spectator mode and F1 get you most of the way. For a clean frame, a resource pack that blanks the HUD sprites removes the crosshair and hotbar without the player pressing anything — see the HUD guide.
Place keyframes on a path and export either a per-tick function or a timeline JSON with the Cutscene & Timeline Builders.