FyroxEngine/Fyrox · error

Infinite update loop detected! Most likely some of your…

Error message

Infinite update loop detected! Most likely some of your scripts causing infinite prefab instantiation!

What it means

Engine::handle_scripts loops calling scripts' on_update to let update-time logic (e.g. newly spawned scripts needing updates) converge, bounded by max_iterations. Reaching the final iteration without convergence triggers this warning, indicating scripts likely instantiate prefabs endlessly during update.

Solutions

  1. Gate spawning/update reactions behind flags or conditions so each trigger fires once
  2. Move continuous spawning to an explicit event or timer instead of unconditional on_update work
  3. Profile with logging to identify which script keeps re-triggering the update pass

Example fix

// before
fn on_update(&mut self, ctx: &mut ScriptContext) {
    ctx.scene.instantiate(ctx.resource.clone()); // every iteration
}
// after
fn on_update(&mut self, ctx: &mut ScriptContext) {
    if self.cooldown elapsed && self.should_spawn {
        self.should_spawn = false;
        ctx.scene.instantiate(ctx.resource.clone());
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// ensure on_update side effects are one-shot
if self.spawned_this_frame { return; }
self.spawned_this_frame = true;

Prevention

When it happens

Trigger: Scripts calling on_update handlers that spawn/instantiate new prefabs on every iteration, so the update loop never stabilizes within max_iterations.

Common situations: A spawn-on-update script that respawns each frame; update logic reacting to its own spawned objects' updates in a feedback cycle.

Related errors


AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10). Data as JSON: /api/errors/23f45b52c9e23cf2. Report an issue: GitHub.

Appendix: source

Thrown at fyrox-impl/src/engine/mod.rs:829

                    break 'update_loop;
                } else {
                    while let Some((handle, script_index)) = update_queue.pop_front() {
                        context.handle = handle;
                        context.script_index = script_index;

                        process_node_script(
                            "on_update",
                            script_index,
                            scripted_scene.handle,
                            &mut context,
                            error_queue,
                            &mut |script, context| script.on_update(context),
                        );
                    }
                }

                if update_loop_iteration == max_iterations - 1 {
                    Log::warn(
                        "Infinite update loop detected! Most likely some of \
                    your scripts causing infinite prefab instantiation!",
                    )
                }
            }

            // Dispatch script messages only when everything is initialized and updated. This has to
            // be done this way, because all those methods could spawn new messages. However, if a new
            // message is spawned directly in `on_message` the dispatcher will correctly handle it
            // on this frame, since it will be placed in the common queue anyway.
            scripted_scene.message_dispatcher.dispatch_messages(
                scene,
                scripted_scene.handle,
                plugins,
                resource_manager,
                dt,
                elapsed_time,
                &scripted_scene.message_sender,

View on GitHub (pinned to 76c91aad8e)