RTS-Spiel wird asynchron



  • Hallo!

    Ich schreibe derzeitig an einem Echtzeitstrategiespiel, das heißt, so etwas in der Richtung soll es einmal werden, wenn es fertig ist.

    Die Struktur soll wie folgt sein:
    ein Netzwerkthread, der stets nur die Realen Koordinaten jedes Objektes behandelt, und so abselut synchron ist, und ein Graphikthread, der zwar asynchron ist, aber dessen Koordinaten immer wieder auf die, vom Synchronen Thread berechneten Koordinaten gesetzt werden. Um das zu machen, berechne ich im Netzwerkthread die Neuen Koordinaten, erhalte die Befehle(und weise die Koordinaten zu), und frage die Kollisionen ab.
    Hier beginnt das Problem: die Kollisionen machen das ganze Asynchron, ohne Kollisionen ist das ganze Synchron(bzw. wirkt zumindest mit dem Bloßen Auge so).

    Doch genug der Worte, hier der Code: http://phpfi.com/126398
    Falls es jemand kompilieren will, www.dagere.de/rts.rar.

    Könnte mich jemand bitte hinweise, wo der Fehler liegt? Ich seh irgendwie abselut nicht den Grund, wieso die Realen Koordinaten nicht synchron sind, weil die werden ja nur in dem Teil sofort nach dem Senden berechnet. Anfangs hatte ich ja noch die Kollisionsabfrage im Mainthread, aber nun werden die Realen Koordinaten ja außerhalb des Mainthreads nicht angerührt.



  • Ich habe zwar den code nur überflogen, aber der Fehler hört sich nach nem Deadlock an. Kommentier mal alle

    SDL_LockMutex(mutex);
    und
    SDL_UnlockMutex(mutex);
    aus und berichte mal was dann passiert.

    Ach und, dein 2. Link funktioniert (zumindest bei mir) nicht.


  • Mod

    ganz ohne mir den code anzusehen kann ich dir sagen, dass man bei rts spielen meistens nur die commandos über das netzwerk schickt, die simulationen die dann auf den rechnern laufen müssen absolut vorhersagbar sein und dann ist es einfach: gleiche eingabe/commandos -> gleiche simulation -> synchron.



  • Benutzt du float Berechnungen? f'`8k

    Bye, TGGC (\-/ returns)



  • An rapso's Beitrag angehängt:

    - das Spiel wird in viele kleine Runden aufgeteilt
    - du musst immer wissen, in welcher Runde du bist
    - mit den Befehlen wird die Zeit ( = Runden-ID) mitgeschickt, zu der sie ausgeführt werden sollen
    - Befehle müssen auf allen Rechnern in der gleichen Reihenfolge ausgeführt werden



  • Hallo!

    Danke erstmal für eure Antworten.

    Der Korrekte Link lautet: http://www.dagere.de/RTS.rar

    - das Spiel wird in viele kleine Runden aufgeteilt
    - du musst immer wissen, in welcher Runde du bist
    - mit den Befehlen wird die Zeit ( = Runden-ID) mitgeschickt, zu der sie ausgeführt werden sollen
    - Befehle müssen auf allen Rechnern in der gleichen Reihenfolge ausgeführt werden

    Bei mir gibt es Realkoordinaten, und die werden jeden Netzwerkdurchlauf, d.h. ein paar mal pro sekunde aktuallisiert. Befehle werden NUR beim Senden/Empfangen ausgewertet, und deshalb sollten sie eigentlich funktionieren.

    ganz ohne mir den code anzusehen kann ich dir sagen, dass man bei rts spielen meistens nur die commandos über das netzwerk schickt, die simulationen die dann auf den rechnern laufen müssen absolut vorhersagbar sein und dann ist es einfach: gleiche eingabe/commandos -> gleiche simulation -> synchron.

    Ich kriege die Simulationen leider nicht absolut synchron, da immer die Zeit mit reinspielt, und entweder man ließt die Zeit per SDL_GetTicks aus(was leicht ungenau ist) oder man versucht die selbe Framerate hinzubekommen, was aber auch wieder nur über Zeitmessen mit SDL_GetTicks möglich ist, was wieder zum genannten Problem führt.

    Benutzt du float Berechnungen?

    Sozusagen, ich addiere Vergangene Zeit/10, und das kann prinzipiell schon asynchron werden, denn SDL_GetTicks() ist ja, laut ein paar gegoogelten Websites, nicht besonders genau. Leider lässt sich dieser Befehl nicht umgehen. Einzige Möglichkeit wäre also, die vergangene Zeit auf dem Server zu nehmen, zum Clienten zu schicken, und dann diese zu benutzen, statt einer selbst gemessenen Zeit. Ich hege aber Zweifel, das der Fehler dort liegt, denn es geht hier nicht mal um 1 oder 2 Pixel, sondern um 40 oder 50(Augenmaß).

    Ich habe zwar den code nur überflogen, aber der Fehler hört sich nach nem Deadlock an. Kommentier mal alle

    SDL_LockMutex(mutex);
    und
    SDL_UnlockMutex(mutex);
    aus und berichte mal was dann passiert.

    Ganz einfach: das ganze stürzt ab, weil von verschiedenen Threads gleichzeitig auf eine Variable zugegriffen wird...



  • DaGeRe schrieb:

    - das Spiel wird in viele kleine Runden aufgeteilt
    - du musst immer wissen, in welcher Runde du bist
    - mit den Befehlen wird die Zeit ( = Runden-ID) mitgeschickt, zu der sie ausgeführt werden sollen
    - Befehle müssen auf allen Rechnern in der gleichen Reihenfolge ausgeführt werden

    Bei mir gibt es Realkoordinaten, und die werden jeden Netzwerkdurchlauf, d.h. ein paar mal pro sekunde aktuallisiert. Befehle werden NUR beim Senden/Empfangen ausgewertet, und deshalb sollten sie eigentlich funktionieren.

    Ich verstehe ehrlich gesagt nicht, was du damit ausdrücken willst. Was heißt "ein paar mal pro Sekunde"? Eine Zeiteinheit hat bei der Berechnung des Spieles nichts verloren. Die gemessene Zeit kann man nutzen um eine Pause von 2ms einzulegen oder um festzustellen, dass man gleich zwei Runden weiterrechnen muss. Aber für alle Befehle und logischen Berechnungen gibt es nur eine Zeiteinheit, die "Runden-ID". Eine Einheit geht pro Runden-ID so und so viel weiter, der Befehl x muss auf allen Rechnern in der Runde y ausgeführt werden, usw.

    Auch ist mir jetzt noch nicht klar geworden, was du unter "Realkoordinaten" verstehst, kannst du das mal ausführen?

    Konkrete Frage: Ist dein Spiel denn jetzt in Runden (oder nenn es Logik-Steps, Logik-Frames, ...) aufgeteilt?



  • DaGeRe schrieb:

    Ich hege aber Zweifel, das der Fehler dort liegt, denn es geht hier nicht mal um 1 oder 2 Pixel, sondern um 40 oder 50(Augenmaß).

    Es kann sich ja mit der Zeit aufaddieren. Also mit floats wird es vermutlich nie wirklich funktionieren. f'`8k

    Bye, TGGC (\-/ returns)


Anmelden zum Antworten