Quick answer: Godot 4 Tween.set_loops(0) playing once instead of looping infinitely? 0 means once, not infinite - use -1 for unlimited loops.
Tween should loop forever. Set loops to 0 because 'infinite'. Plays exactly once.
Use -1 for infinite
tween.set_loops(-1)Negative loops mean infinite. Zero means default (one iteration).
Verify by ticking once
Run the tween for 5 seconds and check tween.is_running(). Should be true; if false, the loops are wrong.
Read the API doc carefully
Godot's set_loops semantics differ from many other tween libraries. Document the project convention.
“API semantics differ across libraries. Read once; document; don't re-discover.”
Wrap common tween patterns in helpers (pulse, fade-in-out, infinite-spin). The helper encodes the right loop value; calls become safe.