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

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

21

13.07.2016, 12:26

Kleine Anmerkung: ich persönlich halte bei der Kommunikation vom Server an die Clients nichts von Ereignis basierten Systemen. Begründung: wenn die Befehle nicht in genau der gleichen Reihenfolge und Zeitpunkten ausgeführt werden, kommt es schnell zum berühmt berüchtigten OoS, was bei einem Ereignis basierten System entweder einer "recovery by full resync" Logik bedarf oder das Ende der Partie bedeutet. Bei einem zustandsbasierten System ist ein OoS hingegen weniger kritisch, da bei Erhalten der neuen Zustände die Unstimmigkeit quasi automatisch behoben wird.
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.

Jar

Treue Seele

Beiträge: 197

Wohnort: Lübeck

Beruf: Softwareentwickler

  • Private Nachricht senden

22

13.07.2016, 13:23

Hast du schonmal darüber nachgedacht, nicht einfach "beliebige Entities mit irgendwelchen Komponenten" zu synchronisieren, sondern genau die, die bei dir vorkommen und relevant sind? (Oder eher: Willst du eine Engine oder ein Spiel schreiben?)

Ich schreibe eine Engine für mein Spiel :) Die Entity Objekte werden nur anhand ihrer Componenten bestimmt und dann von einem System abgearbeitet. (Entity Component System)

Zum Beispiel, werden alle Entities die eine TransformComponent, VelocityComponent und eine DirectionComponent haben gleich behandelt. Bei allen wird die neue Position anhand einer Geschwindigkeit und einer Richtung berechnet.

Bspw. bei einem FPS wird das nur bei wenigen Teilen des Spiels in der Form möglich sein, allerdings hast du auch nicht geschrieben, was dein Spiel sein soll.

Also ich bin dabei einen 5 Spieler 2D RPG zu erstellen.
Wie schon irgendwo oben erwähnt berechnen die Clienten die Positionen der Spieler parallel zum Server. Das heißt die Informationen die der Server hat liegen immer etwas in der Vergangenheit. Durch zusätzliche Berechnungen anhand eines Timestamps prüft der Server ob die Spieler noch im Rahmen ihrer Möglichkeiten liegen.

Es werden nur Aktualisierungen geschickt, falls sich etwas nicht ändert, soll das Netzwerk auch nicht damit belastet werden.
Die Reihenfolge der Pakete spielt dabei auch keine erhebliche Rolle, da der Server die "richtige" Position der Entities kennt.

Bei wichtigen Ereignissen (Bsp: Pfeil soll Herz vom Gegner treffen) wird anhand des Timestamps geschaut ob der Pfeil den Gegner wirklich hätte treffen können.

Das Ziel des ganzen ECS ist es später möglichst schnell verschiedene Objekte und Gegner zu erstellen und neue Funktionalitäten hinzufügen zu können.

Edit:
Ein kleiner Nachtrag zu "beliebige Entities mit irgendwelchen Komponenten". Am Ende wird es im Projekt natürlich Klassen geben die vielleicht Hero oder Enemy heißen und von Entity ableiten.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Jar« (13.07.2016, 14:23) aus folgendem Grund: Nachtrag


Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

23

13.07.2016, 14:34

Wenn ich das richtig verstehe, begehst du mMn einen typischen Denkfehler: Annahme von perfekten Determinismus. Auch liest sich "die Informationen die der Server hat liegen immer etwas in der Vergangenheit" sehr gefährlich. Wenn dann sollte der Server immer der "aktuelle" sein.
Aber vielleicht verstehe ich dich ja falsch. Wie würde dein System mit folgender Situation umgehen:
P1 und P2 stehen sich gegenüber beide schießen und springen gleichzeitig. Was würde P1, was würde P2 und was der Server bei sehr großen Verzögerungen sehen und wie würde das Ganze ausgehen bei deinem System? Wie würde dein System mit Aufkumulierung kleiner Rundungsfehler (z.B. bei der Position) zurecht kommen?
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.

Jar

Treue Seele

Beiträge: 197

Wohnort: Lübeck

Beruf: Softwareentwickler

  • Private Nachricht senden

24

13.07.2016, 17:36

"die Informationen die der Server hat liegen immer etwas in der Vergangenheit" sehr gefährlich. Wenn dann sollte der Server immer der "aktuelle" sein.

Jaein, der Server gibt vor wie es zu sein hat.

Ich gebe den P1 und P2 mal ein paar Namen um es zu veranschaulichen. P1 = Nox, P2 = Jar (schöne kurze Namen wie ich finde)
Erstmal generell was ich mit in Vergangenheit liegen meine:

Der Server bekommt Input von allen Clients zuzüglich Timestamps.
Der Server updatet den Status der Welt.
Der Server schickt das Ergebnis (in diskreten Zeitschritten) an die Clients.

Client macht Eingaben und diese werden lokal schon mal berechnet. (Client Side Predicicion)
Client bekommt update vom Server und synchronisiert den Status seiner Welt mit der des Servers und interpoliert gegeben falls Positionen.

Du als Spieler hast dadurch den Effekt, dass du selbst im Präsenz bist. Alle anderen Figuren sind aber in der Vergangenheit.

Jetzt kommt dein dein Szenario und die Lösung:

Nox schießt auf Jar (Nox schickt Schussinfos + Timestamp an den Server)
Server rekonstruiert sich die Position von Jar zum übergebenen Zeitpunkt.
Server guckt ob Jar getroffen wurde. --> Wenn ja, Jar bekommt keine Schaden... ist ja sein Spiel :P

Jar schießt zur selben Zeit auf Nox (Jar schickt Schussinfos + Timestamp an den Server)
Server rekonstruiert sich die Position von Nox zum übergebenen Zeitpunkt.
Server guckt ob Nox getroffen wurde. --> Wenn ja, Nox bekommt Schaden.

...äquivalent läuft das Springen ab.

Der Server muss dafür natürlich einige Zeitschritte in die Vergangenheit gucken können (das habe ich vielleicht nicht erwähnt).
Genauso muss der Client in die Vergangenheit gucken können um mögliche Rücksetzungen des Servers 'smooth' zu interpolieren.
(Hacker läuft mit 1000 km/h, Server sagt Nö --> Hacker wird 'smooth' zurückgesetzt)

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

25

13.07.2016, 22:28

Bei dem System würde ich dann einfach die Timestamps manipulieren als "Hacker". Witzigerweise würden dann für den Gegenspieler deine Schüsse dann irgendwann ein paar "Meter" vor dir aufploppen, da ja der Gegenspieler eine alte Version vom Server bekommt, der ja anscheinend selbst nur eine alte Version von deiner "aktuellen" Version hat. (oder habe ich da was falsch verstanden ?( )
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.

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

26

14.07.2016, 08:55

... wenn man naiv an die Sache rangeht und beliebige Timestamps serverseitig akzeptiert.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Werbeanzeige