--- name: game_loop kind: function lang: cpp domain: gamedev version: "0.1.0" purity: impure signature: "loop_run(SDL_Window*, const LoopCfg&) -> void" description: "Game loop fixed-timestep estilo Glenn Fiedler ('Fix Your Timestep'). Desacopla simulacion (on_fixed_update con dt fijo) de renderizado (on_render con factor de interpolacion). Acumulador con cap anti spiral-of-death. Branch automatico desktop (while loop bloqueante) vs __EMSCRIPTEN__ (emscripten_set_main_loop). Issue 0072b." tags: [gamedev, game-loop, sdl3, wasm, fixed-timestep] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [] example: | struct State { bool quit = false; float t = 0; }; State st; fn::game::LoopCfg cfg; cfg.user = &st; cfg.on_fixed_update = [](void* u, float dt) { auto s = (State*)u; s->t += dt; }; cfg.on_render = [](void* u, float interp) { // render with interp factor between [0, 1) }; cfg.should_quit = [](void* u) { return ((State*)u)->quit; }; fn::game::loop_run(window, cfg); tested: false tests: [] test_file_path: "" file_path: "cpp/functions/gamedev/game_loop.cpp" params: - name: window desc: "SDL_Window activo (no usado actualmente; reservado para futuras integraciones swap/vsync)." - name: cfg desc: "LoopCfg con fixed_dt (default 1/60), max_steps_per_frame (cap), callbacks on_fixed_update/on_render/should_quit y user pointer." output: "Bloquea hasta should_quit==true (desktop). En WASM retorna inmediatamente y registra emscripten_set_main_loop." --- # game_loop Loop canonico para apps gamedev del registry. Garantiza que la simulacion corra a `fixed_dt` constante (default 60 Hz) independientemente del framerate de render, y expone factor `interp` para que el renderer interpole posiciones entre estados de fisica. Detalles: - `frame_time` se cap a `fixed_dt * max_steps_per_frame` para evitar la espiral de la muerte cuando el debugger pausa. - En `__EMSCRIPTEN__` el estado del acumulador vive en variable static (`g_rt`) — solo un loop activo por modulo WASM. - `should_quit` se consulta antes de cada frame; en WASM dispara `emscripten_cancel_main_loop`. - `loop_run` retorna sin hacer nada si ambos callbacks son nulos.