Quick answer: Anything that moves a body or reads physics state belongs in _physics_process (fixed step). Camera follow, animation, UI go in _process (per-frame). Don’t split logic across the two.
A character’s movement reads input in _process and applies velocity in _physics_process. At high refresh rates the character feels jittery — sometimes a frame’s input is missed, sometimes counted twice.
Two Clocks
- _process(delta): runs once per rendered frame — variable rate, often 60–144 Hz.
- _physics_process(delta): runs at a fixed step (default 60 Hz). Delta is constant.
At 144Hz they don’t line up — some _process frames have no preceding _physics_process step, others have multiple. Logic split between them sees a moving target.
Pick One Per Concern
- Body movement, queries, forces: _physics_process.
- Camera follow, UI, animations: _process (using the body’s interpolated transform).
- Input: read in the consumer’s process — for character control, that’s _physics_process.
Physics Interpolation
Enable Project Settings → Physics → Common → Physics Interpolation. CharacterBody2D/3D positions are then smoothly interpolated to render frames — smooth visuals at any refresh rate without moving the logic to _process.
Verifying
The character moves smoothly at 60, 120, 144Hz with no jitter. Input never skips. The camera tracks without stutter on a high-refresh monitor.
“_process is per-frame; _physics_process is fixed-step. Don’t straddle the two with one logical concern.”
Physics Interpolation is the single biggest QoL improvement for high-refresh players — turn it on early.