Entwicklung & Code
Game Loops: Spiele und Animationen richtig in Takt bringen
Erfahrene Entwicklerinnen und Entwickler kennen verschiedene Paradigmen, mit Ereignissen umzugehen: Request-Response-Zyklen in Webservern, Event-Handler in GUI-Anwendungen oder die sequenzielle Verarbeitung in CLI-Tools. All diese eventgetriebenen Ansätze haben eines gemeinsam: Sie reagieren auf externe Ereignisse und kehren danach in einen Wartezustand zurück. Ein Webserver wartet auf HTTP-Requests, eine Desktopanwendung auf Mausklicks oder Tastatureingaben.
Weiterlesen nach der Anzeige

Golo Roden ist Gründer und CTO von the native web GmbH. Er beschäftigt sich mit der Konzeption und Entwicklung von Web- und Cloud-Anwendungen sowie -APIs, mit einem Schwerpunkt auf Event-getriebenen und Service-basierten verteilten Architekturen. Sein Leitsatz lautet, dass Softwareentwicklung kein Selbstzweck ist, sondern immer einer zugrundeliegenden Fachlichkeit folgen muss.
Bei der Spieleentwicklung funktionieren diese Paradigmen jedoch nicht. Ein Spiel muss kontinuierlich aktiv sein, auch wenn Spieler gerade keine Eingaben machen. Objekte bewegen sich weiter, Animationen laufen, Gegner agieren, physikalische Simulationen berechnen die nächsten Zustände. Die Spielwelt existiert unabhängig von Benutzerinteraktionen und entwickelt sich permanent weiter.
Diese fundamentale Anforderung führt zum Konzept Game Loop: einer Endlosschleife, die kontinuierlich den Spielzustand aktualisiert und das Ergebnis auf den Bildschirm rendert. Während ein Webserver zwischen Requests untätig ist, läuft eine Game Loop ununterbrochen mit idealerweise sechzig oder mehr Iterationen pro Sekunde.
Auch für Entwicklerinnen und Entwickler außerhalb der Spielebranche bietet das Konzept interessante Perspektiven. Echtzeitvisualisierungen, Simulationen, IoT-Devices oder Robotik-Software teilen viele Anforderungen mit Spielen: kontinuierliche Verarbeitung, präzises Timing und Reaktion auf Inputs bei laufendem System. Die im Folgenden diskutierten Patterns sind direkt übertragbar.
Das grundlegende Konzept der Game Loop
Eine Game Loop besteht im Kern aus drei Phasen, die sich wiederholen: Eingaben verarbeiten, den Spielzustand aktualisieren und das Bild rendern. In der ersten Phase liest die Engine Tastatureingaben, Mausbewegungen oder Controller-Aktionen ein. Die zweite Phase berechnet die Konsequenzen: Charaktere bewegen sich, Projektile fliegen, Kollisionen ereignen sich. Die dritte Phase visualisiert den aktualisierten Zustand.
Dieser Ablauf unterscheidet sich grundlegend von eventgetriebenen Architekturen. Während dort ein Button-Click-Handler aufgerufen wird, seine Aufgabe erledigt und anschließend die Kontrolle zurückgibt, behält die Game Loop permanent die Kontrolle über den Programmfluss. Sie ist die oberste Instanz, die alle anderen Systeme orchestriert.
Weiterlesen nach der Anzeige
Die konzeptionell einfachste Implementierung sieht in Pseudocode so aus:
func main() {
initialize()
for {
processInput()
updateGameState()
render()
}
}
Dieser naive Ansatz hat ein gravierendes Problem: Er läuft nur so schnell, wie die Hardware es zulässt. Auf einem leistungsstarken Rechner könnte die Schleife tausende Male pro Sekunde laufen, auf schwächerer Hardware vielleicht nur dreißig Mal. Das führt zu inkonsistentem Spielverhalten.
Das Problem der unkontrollierten Geschwindigkeit
Angenommen, eine Spielfigur soll sich mit fünf Metern pro Sekunde nach rechts bewegen. Jeder Schleifendurchlauf erhöht die Position um einen festen Wert. Wenn die Schleife auf Computer A tausendmal pro Sekunde läuft, auf Computer B aber nur sechzig Mal, bewegt sich der Charakter auf A mehr als sechzehnmal so schnell – ein inkonsistentes, völlig unspielbares Verhalten.
Dieses Problem betrifft nicht nur Bewegungen, denn die Loop-Frequenz beeinflusst auch Physikberechnungen, Animationen und Timings für Spielmechaniken – also alle zeitabhängigen Vorgänge. Ältere Spiele aus den 1980er und frühen 1990er Jahren litten massiv unter diesem Effekt. Viele DOS-Spiele sind auf modernen Systemen unbenutzbar, weil sie mit mehreren tausend FPS und damit 100-fach zu schnell ablaufen.
Die Lösung liegt in der expliziten Kontrolle der Ausführungsgeschwindigkeit. Die Game Loop muss die Zeit berücksichtigen und ihre Berechnungen entsprechend anpassen. Es gibt dafür verschiedene Ansätze mit unterschiedlichen Trade-offs.
Fixed Time Step: Die einfache Lösung
Der naheliegendste Ansatz, der Fixed Time Step, ist die Begrenzung der Loop-Frequenz auf einen festen Wert, typischerweise 60 FPS (Frames per Second). Nach jedem Schleifendurchlauf wird die verstrichene Zeit gemessen. Wenn der Durchlauf weniger als 16,67 Millisekunden (1000 ms / 60) gedauert hat, wartet das Programm die restliche Zeit ab:
targetFrameTime := 16.67 // Millisekunden für 60 FPS
for {
frameStart := getCurrentTime()
processInput()
updateGameState()
render()
frameTime := getCurrentTime() - frameStart
if frameTime < targetFrameTime {
sleep(targetFrameTime - frameTime)
}
}
Bei diesem Ansatz kennen alle Berechnungen die exakte Zeitdauer eines Frames. Eine Bewegung von 5 Metern pro Sekunde bedeutet 5/60 = 0,0833 Meter pro Frame. Diese Konstanz vereinfacht die Spiellogik erheblich, da sie keine variablen Zeitwerte berücksichtigen muss.
Der Fixed Time Step führt zu deterministischem Verhalten. Bei identischen Eingaben produziert das Spiel auf unterschiedlicher Hardware exakt die gleichen Ergebnisse. Das ist besonders wichtig für Multiplayer-Spiele, Replays oder Debugging. Physik-Engines arbeiten ebenfalls lieber mit konstanten Zeitschritten, da variable Schrittweiten zu numerischen Instabilitäten führen können.
Allerdings hat dieser Ansatz einen fundamentalen Nachteil: Wenn ein Frame länger als die vorgesehene Zeit benötigt, bricht das Konzept zusammen. Auf schwächerer Hardware oder bei komplexen Szenen dauert die Berechnung vielleicht 25 Millisekunden statt 16,67. Das Spiel kann dann die Ziel-Framerate nicht halten und läuft in Zeitlupe ab – ein häufiges Phänomen bei anspruchsvollen Spielen auf Low-End-Systemen.
Zudem verschwendet das aktive Warten (Busy Waiting) CPU-Ressourcen. Moderne Sleep-Funktionen haben außerdem keine Millisekunden-Präzision, was zu Frame-Pacing-Problemen führen kann. Dennoch verwenden einige Spiele, besonders ältere oder retro-inspirierte Titel, diesen Ansatz wegen seiner Einfachheit.
Variable Time Step: Flexibilität mit Risiken
Eine flexiblere Lösung ist der Variable Time Step: Er misst die tatsächlich vergangene Zeit zwischen Frames und verwendet diesen Wert (Delta Time) für alle Berechnungen. Statt mit festen Werten zu rechnen, wird jede Veränderung mit der Delta-Zeit multipliziert. Eine Geschwindigkeit von 5 m/s wird zu position += 5.0 * deltaTime.
lastTime := getCurrentTime()
for {
currentTime := getCurrentTime()
deltaTime := currentTime - lastTime
lastTime = currentTime
processInput()
updateGameState(deltaTime)
render()
}
In diesem Modell passt sich das Spiel automatisch an die Hardwareleistung an. Ein schneller Computer produziert mehr Frames pro Sekunde mit kleineren Delta-Time-Werten, ein langsamer Computer weniger Frames mit größeren Deltas. Die Bewegungsgeschwindigkeiten bleiben konsistent, da 5 m/s * 0,016s und 5 m/s * 0,033s über mehrere Frames hinweg zum gleichen Ergebnis führen.
Der Variable Time Step hat jedoch ein gefährliches Problem: Er kann bei niedrigen Frame-Raten instabil werden. Wenn ein komplexer Frame 50 Millisekunden benötigt, ist deltaTime entsprechend groß. Physikberechnungen mit großen Zeitschritten sind numerisch ungenauer und können zu unplausiblen Ergebnissen führen – Objekte durchdringen sich, Kollisionen werden übersehen, die Simulation läuft komplett aus der Kontrolle.
Diese Instabilität führt zu noch komplexeren Berechnungen im nächsten Frame, was deltaTime weiter erhöht. Es entsteht eine positive Rückkopplung: Große Zeitschritte führen zu Instabilität, was mehr Rechenaufwand nach sich zieht, der zu noch größeren Zeitschritten führt. Dieses Phänomen wird als Spiral of Death bezeichnet und kann ein Spiel komplett unbenutzbar machen.
Zusätzlich erschwert der Variable Time Step das Testen und Debuggen. Unterschiedliche Hardware produziert leicht unterschiedliche Ergebnisse, was Race Conditions und Timing-abhängige Bugs schwer reproduzierbar macht. Multiplayer-Spiele haben mit diesem Ansatz erhebliche Synchronisationsprobleme, da verschiedene Clients unterschiedliche Zeitschritte verwenden.
Trotzdem nutzen viele moderne Spiele Variable Time Steps, weil sie mit Hardwarevielfalt besser umgehen können als Fixed Time Steps. Der nächste Schritt zeigt, wie sich die Vorteile beider Ansätze kombinieren lassen.
Entwicklung & Code
Hallo Developer, hallo heise, hallo C++
Willkommen bei der C++ Werkbank, meinem neuen C++ Blog hier bei heise Developer!
Weiterlesen nach der Anzeige
Ich bin Andreas Fertig. Seit vielen Jahren beschäftige ich mich mit der Programmiersprache C++. Mein Wissen teile ich im Rahmen von Trainings, Vorträgen und auch Artikeln wie in der iX oder meinem privaten Blog. Dort veröffentliche ich pro Monat einen Artikel zu C++ auf Englisch.

Andreas Fertig ist erfahrener C++-Trainer und Berater, der weltweit Präsenz- sowie Remote-Kurse anbietet. Er engagiert sich im C++-Standardisierungskomitee und spricht regelmäßig auf internationalen Konferenzen. Mit C++ Insights ( hat er ein international anerkanntes Tool entwickelt, das C++-Programmierenden hilft, C++ noch besser zu verstehen.
Die Neuerung für (C++)2026 ist, dass ihr diese Artikel ab sofort auch hier bei heise Developer und auf Deutsch lesen könnt.
Mir ist bewusst, dass ich mit dem Blog in die Fußstapfen von Rainer Grimm trete, den ich sehr geschätzt habe und der leider viel zu früh von uns gegangen ist. Uns beiden lagen C++ und Wissen teilen sehr am Herzen. Mit meinem Blog möchte ich das Thema C++ hier bei heise Developer weiterführen.
Was erwartet dich?
Wie der Name des Blogs (der Titel „C++ Werkbank“ verzichtet bewusst auf den Bindestrich) verrät, werde ich mich mit C++-Themen beschäftigen, die dir helfen sollen, deine C++-Kenntnisse zu verbessern und mit einem neuen Werkstück aus jedem Post zu gehen.
Da ich mich viel im Umfeld eingebetteter Systeme bewege, haben meine Artikel häufig einen Fokus auf Effizienz und Performance. Auch Aspekte wie Softwaredesign werden gelegentlich ein Thema sein. Wie in meinen Trainings werde ich auch immer wieder auf Fallstricke wie undefiniertes Verhalten hinweisen. Mein Ziel ist es immer selbst robusten Code zu schreiben, der lange leben kann, und genau das vermittle ich auch in meinen Beiträgen.
Weiterlesen nach der Anzeige
Als Mitglied im C++-Standardisierungskomitee werde ich gelegentlich auch über Neuerungen für den nächsten C++-Standard berichten.
Mehr über mich
Gerne kannst du mich auch schon vor dem ersten C++-Beitrag kennenlernen. Eine Übersicht meiner Social Media findest du hier.
Du bist an einem C++-Training für deine Firma interessiert? Hier findest du meine Trainings, welche selbstverständlich auf die Anforderungen deiner Firma und deines Teams angepasst werden können.
Andreas
(rme)
Entwicklung & Code
programmier.bar: Entwicklung von Headless Apps mit Rust
In dieser Podcastfolge der programmier.bar blicken Joachim Böhmer und Dennis Becker gemeinsam mit Marcel Koch, Softwareberater, Coach und Rust-Autor, über den Tellerrand klassischer Cross-Platform-Frameworks. Im Mittelpunkt steht das Konzept sogenannter Headless Apps und die Frage, wie sich Anwendungslogik unabhängig von konkreten UI-Technologien umsetzen lässt.
Weiterlesen nach der Anzeige
Headless Apps mit Rust
Die drei diskutieren, wie sich die Business-Logik einer Anwendung vollständig in Rust kapseln lässt, um sie plattformübergreifend einzusetzen – unabhängig davon, ob die Benutzeroberfläche mit Flutter, SwiftUI oder Jetpack Compose umgesetzt wird. Auch der Einsatz im Web über WebAssembly (Wasm) sowie auf Mikrocontrollern ist Teil der Betrachtung. Es geht um die Trennung von Core-Logik und UI für die Reduktion technologischer Abhängigkeiten.
Empfohlener redaktioneller Inhalt
Mit Ihrer Zustimmung wird hier ein externer Inhalt geladen.
In dieser Folge gibt es außerdem einen Architektur-Deep-Dive zu Headless Apps sowie zur Rolle von Rust in diesem Kontext, insbesondere mit Blick auf Performance, Memory Safety und Portabilität. Zudem stellt Marcel Koch das Crux-Framework von Red Badger vor, das den Datenaustausch zwischen dem Rust-Core und den jeweiligen UI-Shells automatisiert. Abschließend diskutieren die drei, in welchen Fällen sich der Mehraufwand einer Headless-Architektur lohnt und wann klassische Lösungen wie Flutter oder Kotlin Multiplatform die sinnvollere Wahl sind.
Die aktuelle Ausgabe des Podcasts steht auch im Blog der programmier.bar bereit: „Headless Apps mit Marcel Koch“. Fragen und Anregungen gerne per Mail oder via Mastodon, Bluesky, LinkedIn oder Instagram.
Weiterlesen nach der Anzeige
(mdo)
Entwicklung & Code
KI-Video- und -Bild-Ersteller Amuse am Ende, ComfyUI als Ersatz
Wer mit dem KI-Tool Amuse Bilder und Videos generiert, könnte sich über ausbleibende Aktualisierungen wundern. Das Projekt liegt offenbar auf Eis, ist aber seit Dezember als Open Source verfügbar. Als Alternative bietet sich ComfyUI an.
Weiterlesen nach der Anzeige
Genaue Hintergründe sind unbekannt, jedoch hat sich der Hauptentwickler hinter Amuse zurückgezogen. Die ursprünglich genutzte Domain amuse.ai steht inzwischen zum Verkauf. Der Quellcode ist unter Apache-2.0-Lizenz auf Github verfügbar. Allerdings sind zwei externe Abhängigkeiten vorhanden, für die Interessierte offenbar Lizenzen erstehen müssen. Die Entwicklung ist damit faktisch zum Erliegen gekommen.
Der bisherige Stand lässt sich weiterhin nutzen. Jedoch sind die Fähigkeiten der verfügbaren KI-Modelle rasch veraltet, aktuelle Modelle liefern etwa mehr, korrektere und natürlichere Details. Amuse hat die Bedienung massiv vereinfacht und auch Hardware-Beschleunigung auf Prozessoren mit ausreichend potenter GPU oder NPU angeboten.
Alternative KI-Tools
AMD wirbt inzwischen nicht mehr für Amuse, sondern prescht aktuell mit einer besseren Integration mit AMD ROCm 7.1.1 in ComfyUI vor. Dafür empfiehlt AMD etwa ein Ryzen AI Max+-System mit 128 GByte Speicher oder eine Radeon AI Pro R9700 in Verbindung mit 64 GByte RAM „für eine optimale Erfahrung“.
Die Alternative ComfyUI gibt es als Download für Windows, macOS oder als manuelle Installation über Github – die liefert auch die größte Unterstützung etwa für Nvidia, AMD, Intel, Apple Silicon oder Ascend mit. Auf der Release-Webseite von ComfyUI gibt es aber auch Portable-Versionen mit Optimierungen für AMD oder Nvidia, die keine Installation benötigen.
Das Web-Interface von ComfyUI ist für Umsteiger erst einmal gewöhnungsbedürftig, lässt sich jedoch nach kurzer Zeit ebenfalls einfach nutzen. Es stehen viel mehr Modelle als in Amuse zur Auswahl, insbesondere zahlreiche Videogeneratoren. Aber auch zur Klangerzeugung und zur Erstellung von KI-Bildern sind zahlreiche Modelle vorhanden. Die Installation etwa in der portablen Version ist ebenfalls ungewohnt. Fehlen Dateien für ein Modell, erscheint ein Dialog mit Schaltflächen zum Herunterladen. Davor steht in dem Dialog dann das Verzeichnis, in das die Datei unter dem „models“-Ordner des ComfyUI-Verzeichnisses gehört; dahin muss die jeweilige Datei einfach gespeichert werden.
Im Graphen auf dem Web-Interface kann man etwa den Prompt und Ausgabegröße in den einzelnen Elementen anpassen und dann die KI ihr Werk vollbringen lassen. Allerdings gelingt das etwa mit AMD Ryzen 7840HS/7640HS-Prozessoren mit ihren mit rund 10 TOPS „schnellen“ NPUs nicht, was unter Amuse kein Problem war. Allerdings waren die Prozessoren auch unter Amuse nicht offiziell unterstützt. Für die älteren Prozessoren bleibt also lediglich, bei Bedarf die ältere Software mit den veraltenden Modellen zu nutzen.
Weiterlesen nach der Anzeige
(dmk)
-
Entwicklung & Codevor 2 MonatenKommandozeile adé: Praktische, grafische Git-Verwaltung für den Mac
-
UX/UI & Webdesignvor 3 MonatenArndt Benedikt rebranded GreatVita › PAGE online
-
Künstliche Intelligenzvor 3 WochenSchnelles Boot statt Bus und Bahn: Was sich von London und New York lernen lässt
-
Entwicklung & Codevor 1 MonatKommentar: Anthropic verschenkt MCP – mit fragwürdigen Hintertüren
-
Künstliche Intelligenzvor 3 MonatenGoogle „Broadwing“: 400-MW-Gaskraftwerk speichert CO₂ tief unter der Erde
-
Apps & Mobile Entwicklungvor 2 MonatenHuawei Mate 80 Pro Max: Tandem-OLED mit 8.000 cd/m² für das Flaggschiff-Smartphone
-
Social Mediavor 1 MonatDie meistgehörten Gastfolgen 2025 im Feed & Fudder Podcast – Social Media, Recruiting und Karriere-Insights
-
Apps & Mobile Entwicklungvor 2 MonatenFast 5 GB pro mm²: Sandisk und Kioxia kommen mit höchster Bitdichte zum ISSCC
