framerate-unabhängige GameLoop

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Re: framerate-unabhängige GameLoop

Beitrag von AND51 »

@ 7x7

ymmd!!!!!!!111 :allright:
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Re: framerate-unabhängige GameLoop

Beitrag von ZeHa »

Also so witzig war sein Witz jetzt echt nicht - und dazu noch ist er einfach schlichtweg falsch.

Wie ich schrieb, es geht hier um Pacman- und Waponez-Clones, die laufen auch auf 'ner 500 MHz Maschine.
Und jetzt kommt der Hammer: Die von mir vorgestellte GameLoop hat sogar genau den Sinn und Zweck, daß sich so ein Spiel selbst auf einem langsameren Rechner möglichst gleich verhält. Aber ich glaube, das habt ihr beiden bis jetzt noch nicht verstanden.
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: framerate-unabhängige GameLoop

Beitrag von PMV »

Mal zum aktuellen Stand meiner Entwicklung ... ist zwar noch nicht
abgeschlossen, aber zumindest mal die resultierenden Bewegungs-
abläufe konnte ich nun mir anschauen und zwischen Single-
und Multithread Variante vergleichen. Wohlgemerkt, gleicher Code,
lediglich die Loops werden bei Singlethread ignoriert und sofort verlassen,
da drum rum ja die Mainloop ist. <)

Aufbau ist relativ einfach. 3 Threads:
1. Maus, Tastatur und die Berechnung der Kameraposition/ Drehung
2. Logik des gesamten Spiels
3. Updaten der Entitypositionen, Auruf von RenderWorld() und Flipbuffers()
+ komplette Fensterbehandlung (die muss noch gesplittet werden um die Logik aus zu lagern in Thread 2)

Singlethread ist ein Kern voll ausgelastet ... oh wie unerwartet ...
im Multicore Betrieb waren es zwei Kerne + ein dritter ein wenig.
Wobei die zwei Kerne nie voll ausgelastet waren, aber ich weis nicht
in viel Luft nach oben noch ist ... nur so viel ... wo vorher 30 FPS
waren, hab ich nun die vollen 60 erreicht. Sprich im Multicore hab ich
zu jedem Zeitpunkt die gewünschte Framerate erreicht. <)

Und keine Probleme. Es läuft super flüssig. Sogar flüssiger als die Version
noch davor, aber gut, ich hab das Timing ja nun auch umgestellt auf
1 ms Auflösung anstelle von 16ms. Und nun kann man endlich weit
schauen, ohne das die FPS runter geht, weil OGRE das mit der CPU
berechnet. Ich bin begeistert. <)

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Re: framerate-unabhängige GameLoop

Beitrag von ZeHa »

Okay, das mit dem Sprung von 30 auf 60 FPS wundert mich stark. Normalerweise benötigt das Rendering den mit Abstand größten Teil der gesamten Loop - das hast Du aber nicht parallelisiert. Daher gehe ich davon aus, daß Du entweder extrem viel KI-Zeug drin hast, oder eben ein grafisch so simples Spiel, welches null Renderzeit benötigt. Dann aber wären die 60 FPS ja kein Problem gewesen.

Zudem, was bedeutet bei Dir "Logik des gesamten Spiels"? Und was ist bei Dir dann das "Updaten der Entitypositionen"?
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: framerate-unabhängige GameLoop

Beitrag von PMV »

Du solltest mal nach mir und PureBasic auf YouTube suchen ... ich weis
zwar nicht, was du für ein Spiel erwartest ... aber es ist definitiv nichts,
was heutige Rechner mal nebenher berechnen können. :lol:
Zumal ich es noch nie geschaft hab, ein Projekt "klein" zu halten. Die
Menge an Objekten, die da zu verarbeiten sind ... hat schon nen Gewicht. :mrgreen:
Mit Multithreading schlag ich mich ja auch nicht zum Spaß rum. :wink:

So viel erst mal zum Thema, das Rendering verbraucht am meisten.
Wobei, OGRE3D scheint (wie schon mehrfach erwähnt) beim "herraus
zoomen" von Entities viel mit der CPU zu machen. Wenn man also
hoch über der Karte steht, oder besser gesagt, die gesamte Karte
überblickt, dann verbraucht das Rendering tatsächlich sehr viel. Und
genau deswegen ist es so wichtig, das ich einen extra Grafikthread hab.
Und nein, es liegt nicht darann, das die Menge an Polygonen dann mehr
ist ... es ist die Anzahl der Entities, die "kleiner" werden ... ich hab
da schon ein paar sachen getestet um dem Verhalten auf den Zahn zu
fühlen. Erst mit StaticGeometry (was mit PB4.6x kommt), wird das
zumindest weniger werden.

Entity ... das sind die grafischen 3D-Objekte ... mit updaten meine ich
den Aufruf von EntityLocate(), sobald sich die Position eines Objektes
geändert hat. Der Grafikthread ruft als einziger die Engine3D-Befehle auf.
Dazu gehören z.B. LocateEntity(), EntityLookAt(), HideEntity(), RotateEntity(),
ResizeEntity(), CameraLocate(), RotateCamera(), RenderWorld() und natürlich
auch FlipBuffers() und DisplayTransparentSprite() für den Mauszeiger.

Im Inputthread sind die Befehle für Maus und Tastatur enthalten, das heißt
hier werden die Befehle ExamineKeyboard(), ExamineMouse(), MouseX(),
MouseY(), MouseButton(), KeyboardPushed() und KeyboardReleased()
abgefragt und das Ergebnis jeweils in globale Variablen geschrieben bzw.
bei gewünschten Aktionen Variablen auf +1 gesetzt, damit der Logikthread
weis, dass da was gewünscht ist.

Was verstehst du eigentlich unter "Logik eines Spiels"? Ich hab keine Ahnung,
wie ich das Beschrieben soll. Halt alles andere, was ich nun noch nicht
aufgezählt hab. Z.B. die Berechnung aller Koordinaten mittels "Timebased
Movemend", Pathfinding, und halt die eigentliche Logik des Spiels. :|

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: framerate-unabhängige GameLoop

Beitrag von PMV »

Nur der Vollständigkeit ... hässlich wird das ganze dann, wenn der
Logikthread nicht mehr hinter her kommt und Zeiten von wesentlich
mehr als 30ms benötigt. Dann tritt das von dir erwartete
Verhalten auf: Die Objekte fangen an zu zittern. Das hab ich nun
zumindest beobachten können, wenn ich den Debugger aktiviere.
Ohne Debugger hab ich es noch nicht geschaft, meinen Rechner
zum schwitzen zu bringen. :lol: ... erst mal schauen, ab welcher
Wiederholrate es sichtlich nervt ... wenn sich raus stellt, das dies
bei bereits 30 Loops pro Sekunde auftritt, muss ich auf jeden Fall
eine spezielle Lösung dafür finden. Doch auch so muss ich mir noch
überlegen, was ich mache, wenn der Logikthread nicht mehr wirklich
nach kommt.

Vermutlich werd ich dann den Grafikthread tatsächlich mit dem
Logikthread 1:1 Syncronisieren müssen, um das Zittern zu
unterdrücken. Naja ich fang jetzt mal nicht mit lautem Nachdenken
an. Ich kann mich ja melden, wenn ich weiter bin. :)

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: framerate-unabhängige GameLoop

Beitrag von Thorium »

PMV hat geschrieben: Vermutlich werd ich dann den Grafikthread tatsächlich mit dem
Logikthread 1:1 Syncronisieren müssen, um das Zittern zu
unterdrücken. Naja ich fang jetzt mal nicht mit lautem Nachdenken
an. Ich kann mich ja melden, wenn ich weiter bin. :)
Ich hatte das auch mal so gemacht wie du. Grafik in einen Thread und Spiellogik in einen. War aber langsamer als alles in einem zu haben, wegen dem Syncronisationsoverhead.

Seiddem mach ich das nicht mehr. Wie gesagt ich lasse lieber mehrere Aufgaben Parallel abarbeiten. Bzw. mehrere Threads an der gleichen Aufgabe werkeln, jeder halt eine Teilmenge. Der Performancevorteil sollte dabei erheblich höher sein. Deine Verdopplung von 30 FPS auf 60 FPS wundert mich auch etwas.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: framerate-unabhängige GameLoop

Beitrag von PMV »

Ich wunder mich schon seit langer Zeit, warum PB-OGRE3D so viel mit der
CPU macht. Doch ändern kann ich's ja nicht. Und interessieren tuts auch
nicht wirklich jemanden ... hatte das ja mal im englischen Forum gemeldet.
Aber keine Rückmeldung so weit ich mich erinnere. Hat aber schon was,
wenn eine kleine Karte von 50x50 Kacheln (jeweils 2 Dreiecke) schon
ausreicht, um nen i7 Core aus zu reitzen. Da bleibt kein Platz für andere
Dinge.

Overhead hab ich kaum welchen. Lediglich die Queue bremst noch alles
etwas aus, weil ich aktuell noch jeden Zugriff darauf sperre, obwohl das
quatsch ist. Aber so lang ich noch diverse andere Bugs drinn hab, will ich
die nicht anfassen. :lol:

Heut hab ich's zum ersten mal geschafft, mein Spiel wieder komplett durch
zu spielen, ohne das es mir mit Multithreading abgeschmiert ist. Manchmal
könnt ich mir auch echt selber in den Arsch beisen.
:coderselixir:

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Re: framerate-unabhängige GameLoop

Beitrag von ZeHa »

Okay, mit Ogre hab ich bisher noch nicht wirklich was gemacht, da kann ich jetzt nicht viel mitreden.

Bei mir ist die "Logik des Spiels" (eigentlich ein etwas ungenauer Begriff, da ja letztendlich alles Logik ist, was man programmiert :mrgreen: ) halt schlichtweg das Updaten - und das Updaten ist bei mir im wesentlichen das Anpassen der Positionen aufgrund der Gehrichtung und -geschwindigkeit und der damit verbundene Kollisionscheck, welcher dementsprechend nochmals die Positionen korrigiert oder eben andere Dinge auslöst. Aber das geschieht bei mir eben alles Frame für Frame, somit muß ich das Rendern und das Updaten wie gesagt sowieso streng sequentiell machen. Somit habe ich keine Aufteilung wie Du mit Schritt 2 und 3 :)

Und du siehst auch schon, wirklich viel ist das nicht, das Verhältnis Renderzeit zu Updatezeit beträgt bei meinen Spielen meist 90:10.
Klar, bei größeren Maps mit vielen Objekten (so wie in Deinen "Strategiespielen") kommt da evtl. schon ganz ordentlich was zusammen, aber das kann man ja dann evtl. wieder durch Aufteilen in Segmente/Quadtrees/etc optimieren. Und sowas ließe sich dann natürlich auch sehr gut, wie von Thorium beschrieben, parallelisieren :)
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: framerate-unabhängige GameLoop

Beitrag von PMV »

Ich hab die Karte für die Kollisionserkennung in Segmente unterteilt,
doch auch das macht nur ab einer gewissen größe der Karte Sinn.

Die Logik ist bei kleinen Karten praktisch garnicht zu spühren. Doch
bei meiner "größeren" Testkarte braucht RenderWorld() bereits 4-5ms,
obwohl diese ansonsten leer ist. Das bei einer total alten Geforce 8400 GS
könnte man noch verstehen, doch selbst bei einer Radeon 5670 HD sind
es immer noch ~4ms. Befinde ich mich weit über der Karte bzw. kann sie
komplett überblicken, dann sind es sogar über 10ms bei beiden. Und dabei
wird die CPU mächtig verheitzt. Erste tests mit StaticGeometry sind
aber positiv verlaufen. Richtig einbauen und dann testen werd ich das aber
frühstens mit der nächsten Final, vermutlich sogar erst mit der Finalen 4.61

Der Logikthread ist zu dem Zeitpunkt im Leerlauf und dümpelt beim Aufruf
von Delay(5) bei max. 5,1ms herrum. Mit vielen Objekten geht er dann
mal hoch auf 1,2ms (da wird das Delay(5) nicht mehr aufgerufen) ... und
das sind schon die von mir als Ziel gesetzten realistischen Scenarien. Wir
sprächen hier von hunderten von Objekten, wo normal nur nen paar Duzend
gebraucht werden. Parallelisieren kann man also bei den typischen Dingen
nicht viel, weil der Overhead überwiegen würde. Und du siehst, das
Verhältnis zwischen Rendering und dem Rest ist ein etwas anderes.
Ich bin echt mal auf die Performance am Ende gespannt, wenn ich sogar
tausende Objekte darstellen könnte, das wäre ja was >:)

Threads kann ich dann nur noch bei Aktionen einbinden, die in einzelnen
Frames auftauchen ... so z.B. das Updaten der Wegknoten. Da hier aber
die ganze Zeit drauf zugegriffen wird, klingt das einfacher als es ist. :lol:
Und die PB Linked Liste will ich dafür um jeden Preis benutzten. Da hat
sich Freak schon so viel mühe mit dem Speichermanagement gegeben,
da will ich davon auch profitieren. :lol: Ne effiziente Idee hab ich aber
auch schon, doch die gehört hier ja nun überhaupt nicht hin. :mrgreen:

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Antworten