Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

FalkT

Treue Seele

Beiträge: 125

Wohnort: AC

  • Private Nachricht senden

31

16.02.2011, 17:35

Hi zusammen,

in der Spieleentwicklung begegnet einem eigentlich ständig das Credo, man solle zeitbasierte Frame-Updates verwenden, statt statischen Updates. Das sei professioneller und angenehmer für den User.
Ich habe in den letzten Jahren viele Spiele entwickelt, beruflich und in meiner Freizeit, und ich habe immer wieder die Erfahrung gemacht, dass statische Updates mehr Vor- als Nachteile haben:

- Als Nutzer sehe ich keinen Usability-Unterschied ob das Spiel nun für einen Moment etwas langsamer läuft, oder ob ich durch Ruckler Reaktionszeit verpasse

Ich überlege deshalb, in Zukunft vollständig auf zeit-basierte Updates zu verzichten, es sei denn, ich stelle vorher fest, dass im speziellen Fall zeitbasierte Updates mehr Sinn machen. Ich muss dazu sagen, dass es in meinem Fall vor allem um Flash-Games geht, die haben nämlich eine fest eingestellte Frame-Rate, die nicht überschritten wird, auch wenn der Rechner mehr leisten könnte. FPS Bremsen kann man aber natürlich auch in anderen Sprachen einbauen..

Wie seht ihr das?
Leider sind viele wichtige Aspekte bisher nicht genannt worden.

1. Threading:
Sinnvolles Threading funktioniert nur asynchron und über time-based updates.
Als Beispiel läuft der Render-Thread mit 87.5fps, Physik mit 44.3fps und die Spiellogik mit 60fps ( 3 Kerne mit je 100% CPU - Last ).
Ansonsten landet man irgendwo in einer Realisierung mit Barriers, also einen Haupthread mit 100% CPU-Last und die anderen Kerne werden kaum benutzt
und der langsamste Thread hält alles auf.

2. Input-System:
Jegliche Form von User-Input sollte normalerweise pro Zeiteinheit konfiguriert werden,
denn ein Spieler, Auto bewegt sich doch mit X meter pro Sekunde, nicht mit X meter pro Frame.
Nichts ist schlimmer, als wenn die (gefühlte) Mausempfindlichkeit von der Frame-Rate abhängt.

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

32

16.02.2011, 18:27

@BlueCobold, dann sag mir bitte wie dein Ansatz ausschaut, wenn wir folgendes Szenario haben:
2D Spiel. Beim Tastendruck auf die Pfeiltasten wird eine Beschleunigung in diese Richtung angelegt. Der Spieler drückt nun für 1 Sek auf links drückt, dann 1 Sec auf Oben, 1 Sec auf Rechts und schießlich 1 Sec auf Unten.
Wie würdest du das bei deinem Ansatz machen? Ggf fehlt mir einfach die Vorstellungskraft wie du das geschlossen lösen willst, ohne dass sich die Beschleunigung ändert (Weil für mich ergibt sich da: 1. sec a = (-1,0), 2. sec a=(0,1), 3. sec a=(1,0), 4 sec a=(0,-1)).
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

33

16.02.2011, 18:35

Ist es nicht. Gegenbeispiele gibt es hier alle paar Wochen ("warum bewegt sich nichts, wenn mein Spiel hohe FPS hat?" oder "warum bewegen sich meine Spielfiguren unterschiedlich schnell auf verschiedenen Rechnern?").

Das passiert beides nicht, wenn man bei den Bewegungen die Frametime einrechnet und die Framerate auf vernünftige Werte begrenzt.

@Jonathan_Klein im Prinzip hast du recht, aber je nach Situation können sich die Instabilitäten schon bemerkbarmachen, indem z.B. der Sprung immer unterschiedlich lang ist (was ggf. schon nervig sein kann, wenn die Unterschiede sehr deutlich sind).

Na, so unstabil wird es ja wohl kaum sein. Und so knapp ist auch kein Spiel bemessen, sonst würde man ja auch jedesmal daneben springen, wenn man bei 30 FPS ein Frame zu früh oder zu spät abgesprungen ist.
Lieber dumm fragen, als dumm bleiben!

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

34

16.02.2011, 19:39

@BlueCobold, dann sag mir bitte wie dein Ansatz ausschaut, wenn wir folgendes Szenario haben:
2D Spiel. Beim Tastendruck auf die Pfeiltasten wird eine Beschleunigung in diese Richtung angelegt. Der Spieler drückt nun für 1 Sek auf links drückt, dann 1 Sec auf Oben, 1 Sec auf Rechts und schießlich 1 Sec auf Unten.
Wie würdest du das bei deinem Ansatz machen? Ggf fehlt mir einfach die Vorstellungskraft wie du das geschlossen lösen willst, ohne dass sich die Beschleunigung ändert (Weil für mich ergibt sich da: 1. sec a = (-1,0), 2. sec a=(0,1), 3. sec a=(1,0), 4 sec a=(0,-1)).

Ich sehe nicht, wo sich da jetzt die Beschleunigung ändern sollte zwischen den Tasten-Aktionen. Klar, bei jeder Tasten-Aktion wird eine andere (statische!) Beschleunigung aktiviert. Und? Dann gilt von Sekunde 0 bis Sekunde 1 die Beschleunigung X und von Sekunde 1 bis Sekunde 2 die Beschleunigung Y. Da ändert sich für 30-120 Frames überhaupt gar nichts, was irgendwie irgendwelcher zusätzlicher Zwischenschritte für eine Berechnung oder Frametime-(un)abhängige Additionen auf die aktuelle Position benötigen würde. Aber klar, jeder Tasten-Druck würde eine neue Sequenz einer Bewegung nach der schon erwähnten Formel
d = t * ( v_0 + 0.5 * t * a )
auslösen. Absolut stabil und bedarf nur einer Änderung von v_0 und a zum Zeitpunkt des Tastendrucks, die man aber ohnehin durchführen muss, egal welchen Ansatz man verwendet. Das hat aber nichts mit "veränderlicher Beschleunigung" zu tun, die man z.B. in einem Magnetfeld proportional zum Abstand der Magnete hätte, denn ist diese Beschleunigung erst einmal aktiviert, dann gilt sie statisch für jeden berechneten Frame, egal ob das 30 oder 120 FPS sind.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlueCobold« (16.02.2011, 19:45)


Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

35

16.02.2011, 20:31

BlueCobold dann betrachte doch mal die Beschleunigung über die gesamte Zeit (die 4 Sekunden)? Ist sie da konstant? Nein? Also was ist sie dann?
Wenn nun die Zeitintervalle nicht so gleichmäßig sindund die Änderungen öfter auftreten, so ist auch dieser Ansatz nicht deterministisch im Sinne von "nach einer Zeit wird für n-verschiedene Simulationsdurchläuf bei genau gleicher Steuereingabe das gleiche Ergebnis erzielt". Sprich dein Ansatz erfüllt durchaus deine Angaben, aber nur wenn es keine Änderungen gibt. Sobald es Änderungen gibt, ist auch dieser Ansatz iterativ (mit unterschiedlichen Schrittlängen) und damit per se instabil (wobei es schon vernachlässigbarer ist als beim Ansatz 2 (siehe oben).
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

daG

Treue Seele

Beiträge: 130

Wohnort: Hamburg

  • Private Nachricht senden

36

16.02.2011, 20:41

Ich glaub kaum einer hat BlueCobold verstanden bzw das Problem welches sich ergibt, wenn ein Spiel auf einem anderen Rechner mit einer anderen Framerate läuft ^^ Ich glaub ich wäre da auch ein wenig angepisst nach dem 10ten mal erklären :D

Ich benutzt z.B. für mein aktuelles Projekt auch Timeframes die eine mit einem Zahl von 0.0 bis 1.0 (basierend auf der bereits Vergangenen Zeit) angeben wie weit eine Aktion fortgeschritten ist (1.0 == abgeschlossen). Vorteil ist, ich kann z.B. die Zeit des Spiels beschleunigen oder drosseln. Auch die Pausierung des Spiels funktioniert darüber.

Keine Ahnung ob es die beste Lösung ist, aber hier mal ein kleine Erklärung wie ich es gelöst habe:

Für eine Zeit basierte Aktion (z.b. einer Bewegung) erzeuge ich eine neue Instanz der Timeframe Klasse mit der Anzahl der benötigten "Ticks" (ich rechne die echte Zeit in Ticks um. Zur Zeit einfach: 1 Tick == 1 ms) bis diese Aktion abgeschlossen sein wird. Die Timeframe Klasse merkt sich dann die Startzeit.

Die Formel wäre dann vereinfacht z.B: position.X = (ziel.X - start.X) * timeframe.Progress;

Ich hoffe ich konnte es halbwegs verständlich machen ^^

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

37

16.02.2011, 20:44

@Nox:
Wir reden selbst dann aber noch immer nicht über eine veränderliche Beschleunigung, sondern über vier verschiedene Beschleunigungen. Und *das* Problem hätte man bei *jedem* anderen Ansatz auch. Wo genau ist jetzt das Problem über das du da eigentlich redest?
Und doch, die Simulation bleibt bei meinem Ansatz absolut deterministisch und gibt *immer* genau das Ergebnis aus, was raus kommen sollte, unabhängig von der Anzahl der Änderungen und auch unabhängig von numerischen Fehlern, die anderswo in jedem Fall auftauchen (auch wenn der Fehler nur 1% ist, auf 100 Pixel macht das immerhin 1 Pixel falsch positioniert und sowas kann unter Umständen eben doch blöd aussehen, wenn bei einem Geschicklichkeitsspiel die Gegenstände plötzlich in der Wand sitzen). Die Anzahl der Änderungen ist schnurz-piep-egal. Ich frag mich ohnehin, wie ihr in der Lage seid über meinen Ansatz zu urteilen, wenn ihr ihn kontinuierlich absichtlich falsch interpretiert.
Ich habe es jetzt schon wie oft gesagt, dass er numerisch stabil *und* zeit-deterministisch ist?

Aber ja, bei sehr kleiner Schritt-Länge wird er iterativ und damit genauso instabil wie andere Verfahren auch. Da diese Änderungen aber so gut wie *nie* öfter als alle ein bis zwanzig Sekunden auftreten, macht das 30 bis 120 Frames in einer einzelnen Sekunde, in denen bei mir absolut nichts iterativ berechnet werden muss, was bei anderen Ansätzen aber eben immer der Fall ist, auch wenn die Änderungen nur alle paar Sekunden kommen. Und genau da liegt der massive Unterschied. Die Aussage: "Aber dein Konzept is auch Mist, wenn man sehr kleine Intervalle hat", die ist in etwa so als würde jemand sagen: "Aber wenn du auf der Autobahn spielst, dann ist das auch gefährlich". Klar, aber ich muss ja nicht auf der Autobahn spielen, wenn es nicht notwendig ist. Das macht es eben aus.
Was man nicht vermeiden kann, das kann man eben nicht vermeiden. Dennoch sollte man das vermeiden, was man vermeiden kann. Ich mache genau das, während die "x+=const" oder "x+=framtime*cost" Ansätze es gar nicht erst versuchen.


@daG:
Auf einem ähnlichen Prinzip funktionieren meine Umsetzungen auch, allerdings ohne ein Intervall zwischen 0 und 1, sondern mit einer Startzeit und nach oben offenen Zeitspanne. Vorteile sind (im Normalfall) numerische Stabilität, freie Skalierbarkeit (auch negativ) der Zeit-Achse bei gleicher FPS-Anzahl und vor allem Zeit-Determinismus, unabhängig von irgendwelchen FPS.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 9 mal editiert, zuletzt von »BlueCobold« (16.02.2011, 21:05)


daG

Treue Seele

Beiträge: 130

Wohnort: Hamburg

  • Private Nachricht senden

38

16.02.2011, 20:54

Auf einem ähnlichen Prinzip funktionieren meine Umsetzungen auch, allerdings ohne ein Intervall zwischen 0 und 1, sondern mit einer Startzeit und nach oben offenen Zeitspanne. Vorteile sind numerische Stabilität, frei Skalierbarkeit (auch negativ) der Zeit-Achse bei gleicher FPS-Anzahl und vor allem Zeit-Determinismus, unabhängig von irgendwelchen FPS.


Ja, ist bei mir ja soweit ich dich verstanden hab auch nicht anders. Ich hab die Startzeit und die Aktuelle Zeit (die ja nach oben offen ist) der timeframe.Progress Wert ist halt einfacher zum Rechnen. 0 == noch nicht bewegt, 0.5 == halber Weg, 1.0 == angekommen.

Falls jetzt aber mehrere Aktionen in einer Warteschleife sind (bei mir muss sich die Einheit z.B. von Feld zu Feld bewegen) dann können die evtl überschüssigen Ticks dem nächsten Timeframe angehängt werden. Dadurch sollte es ja deterministisch sein...

39

16.02.2011, 20:57

Irgendwie sind das doch jetzt 2 verschiedene Probleme. Einmal berechnet man die neue Position anhand der Startposition und einmal anhand der Position im letzten Frame. Ob dabei die Zeit in konstanten oder variablen Schritten läuft ist doch egal, man kann beide Ansätze mit beiden benutzen.
Und Fließkommaungenauigkeiten hat man genauso bei festen Zeitdeltas, die hat man sobald man mal nicht sehr günstige Zahlen hat immer.

Der Vorteil, wenn man die neue Position anhaand der Startposition ausrechnet ist "einfach nur", dass man diese Ungenauigkeiten nicht Frame pro Frame addiert, sondern nur einmal macht.
Lieber dumm fragen, als dumm bleiben!

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

40

16.02.2011, 20:57

Siehste, diesen "halbe Weg" und "angekommen" gibt es bei mir eben nicht. Oder nur in manchen Teilen.
Mit einer solchen "Warteschleife" arbeite ich ebenfalls bei den Teilen, die eine feste "Endzeit" haben und diese lassen sich dann prima deterministisch ebenfalls ausrechnen. Dadurch ergeben sich dann eben auch die unterschiedlich langen Intervalle der Simulation. Aber da können eben gut und gern mal mehrere Sekunden ohne zusätzliche Berechnung komplett übersprungen werden.
Freut mich zu hören, dass das noch jemand so macht :)

@Jonathan:
Nein. Während du für die Berechnung eines iterativen Systems mit einem Intervall von 0.02 Sekunden für eine Bewegung über eine Sekunde 50 Berechnungen machen musst, so muss mein System (und das von daG) eben nur eine einzelne Berechnung durchführen. Der Vorteil der gesparten Rechenzeit und numerischer Fehler sollte offensichtlich sein.
Die *Probleme* sind identisch, aber die *Lösungen* sind unterschiedlich.
Dass die gleichen numerischen Probleme bei ungünstiger Problemstellung (50 Änderungen der Ausgangssituation pro Sekunde) natürlich auf die gleiche Ausartung der Werte stößt, das sollte jedem bewusst sein, siehe mein vorangegangener Post.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlueCobold« (16.02.2011, 21:03)


Werbeanzeige