the symptom, in your words

"A component added at runtime updates after every authored one"

✓ verified on 26.08.05
lane Writing gameplayposted

▸ SYMPTOM

A component you create at runtime writes per-frame input, and the input does nothing. The player does not move one unit. There is no error, no null, and no log line.

A direct property write from the same component lands perfectly. In one live case a runtime-created tool on the first object in the scene wrote Input.AnalogMove from both OnUpdate and OnFixedUpdate, exactly like the authored component beside it, and the player never moved, while EyeAngles (a direct property write that depends on no ordering) was correct the whole time. Verified on engine 26.08.05.

▸ CAUSE

Update order is a property of the authored scene, not of the object a component sits on. A component added at runtime through Components.GetOrCreate<T>() goes on the END of the update list. It still runs, but it runs after every component the scene authored.

For per-frame input that is too late. Movement code reads Input.AnalogMove earlier in the same frame, before the runtime component writes it, so the read sees the old value. The pairing is the diagnostic: the input write lands late while a direct property write like EyeAngles lands on time, because the property write depends on no ordering. The component runs, and it runs too late.

▸ FIX

Anything that injects per-frame input has to be reached from a component the scene authored. Creating the component at runtime is fine. Being updated by the engine at runtime is the problem.

  1. Have the authored component's OnUpdate and OnFixedUpdate call the runtime component's tick methods directly. Add a suspend flag so the two never write movement in the same frame.
  2. Authoring the component into the .scene file also works. It costs an editor restart, because a live editor does not reload a scene whose file changed underneath it.

Build one diagnostic once: print "did it run" (a tick count), "did the write land" (the resulting speed), and "how far off" on a single line. An injected input that produces no motion, no error, and no log is otherwise pure guesswork.

▸ WHY IT WORKS

Calling the runtime component from an authored component moves its tick back into authored update order, ahead of the movement code that reads the input. The engine's own late update slot for runtime-added components is the whole problem, so you stop relying on it. The suspend flag keeps the authored path and the runtime path from both writing movement in one frame, which would fight for the same input value.

Verified on engine 26.08.05: seen in a real project.
s&box moves fast; an undated fix is a liability. Spot a stale detail?
changelog
  • Published.

Want to know when new guides or fixes drop? Join the community to help build this out. Report gotchas, flag outdated fixes, or just lurk.

Join the Discord