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

Superwayne

Treue Seele

  • »Superwayne« ist der Autor dieses Themas

Beiträge: 242

Beruf: Student & App Entwickler (Xamarin)

  • Private Nachricht senden

1

23.06.2016, 13:18

Multiplayer - Inventar synchronisieren

Moin,

Ich entwickle momentan mit Unity ein Multiplayer Spiel. Nun weiß ich allerdings nicht so recht, wie ich das Inventar am besten mit dem Server synchronisiere.

Momentan werden Items serverseitig aufgesammelt. Das heißt der Spieler bewegt sich zum Item und der Server schickt eine Nachricht an den Spieler, dass er es aufgesammelt hat. Allerdings weiß der Server nicht, ob der Spieler überhaupt Platz im Inventar hat, wenn die Nachricht bei ihm ankommt .
Zum Beispiel: Der Spieler hat noch einen freien Slot im Inventar, das wird dem Server auch mitgeteilt. Nun läuft der Spieler zu einem Item und sortiert währenddessen sein Inventar um, so dass das Inventar nun voll ist (z.B. indem er ein Item auf zwei Stapel aufteilt). Der Server hat das Update des Inventars noch nicht erhalten, schickt also dem Spieler die Nachricht, dass er das Item aufsammelt und löscht es auf dem Server, damit es kein anderer Spieler mehr aufsammeln kann. Nun ist das Item weg, der Spieler konnte es durch sein volles Inventar allerdings nicht aufsammeln.

Wie lässt sich das Problem vermeiden/lösen? Schickt der Client wider eine Nachricht an den Server, dass er das Item nicht aufsammeln konnte und der Server spawnt das Item erneut?

Jar

Treue Seele

Beiträge: 197

Wohnort: Lübeck

Beruf: Softwareentwickler

  • Private Nachricht senden

2

23.06.2016, 13:30

Wenn du das Item aufsammelst sollte der Server vielleicht vorher den Clienten fragen ob er Platz hat.

Das Bestätigen von Nachrichten sollte generell immer gemacht werden, wenn es sonst zu unsauberen Zuständen kommen kann.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Jar« (23.06.2016, 15:12)


KeksX

Community-Fossil

Beiträge: 2 107

Beruf: Game Designer

  • Private Nachricht senden

3

23.06.2016, 14:52

Ein Weg ist, eine Variable zu erstellen, die festhält, ob der Spieler Platz im Inventar hat. Diese syncst du via Server.

BEVOR ein Spieler nun Sachen aufnimmt, überprüfst du mit Hilfe dieser Variable, ob er das kann. (Zuerst im Client, um Traffic zu sparen. Wenn Client ok sagt, überprüft der Server. Gibt es hier ein Mismatch hast du ein gutes Indiz für einen Cheater. Traue niemals dem Client!)
WIP Website: kevinheese.de

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

4

23.06.2016, 15:30

Lest ihr die Frage eigentlich, bevor ihr antwortet?

Du solltest das neusortieren des Inventars auch auf dem Server machen. So erkennst du auf dem Server, ob noch platz da ist und bietest dem Client weniger Möglichkeiten zu Cheaten.
Im Endeffekt liegen die Inventardaten also auf dem Server. Der Client sendet dann lediglich "Item von Position 13 nach 25 verschieben", "Stack an Position 8 halbieren", etc.

KeksX

Community-Fossil

Beiträge: 2 107

Beruf: Game Designer

  • Private Nachricht senden

5

23.06.2016, 17:13

Verstehe jetzt nicht, wo das sich von meiner Antwort unterscheidet. Außer dass du einen anderen Fall (Stacks bewegen) genommen hast. Das Prinzip ist das gleiche: Eine Vorab-Überprüfung auf dem Client, um Traffic zu sparen, und dann das tatsächliche bookkeeping auf dem Server.
Und dass die Variable auf dem Server syncst(mit dem SyncVar keyword) ist in Unity equivalent zu "Im Endeffekt liegen die Inventardaten auf dem Server".

Der Kern ist eben, dass der Server die Logik innehält und der Client nur auf die Server-Ergebnisse reagiert. Sodass der Fall "Der Server hat das Update nicht erhalten" gar nicht erst eintreten kann. Der Server muss alles wissen. Der Client nicht (immer; kommt auf die Architektur an).
WIP Website: kevinheese.de

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

6

23.06.2016, 17:39

Naja er beschreibt im Prinzip eine Race-Condition (was wenn der Spieler das inventar neu soritert, bevor der Server mit aufheben des Items fertig ist?) und du sagst, dass er prüfen muss, ob Platz ist, bevor der Server anfängt das Item aufzuheben.

Mit deiner neuen Antwort und dem 3. Lesen der alten, sehe ich jetzt aber auch, dass du das im Prinzip richtig gemeint hast, aber zumindest ich es eben erst nach dem 3. Lesen so verstanden hab.

Superwayne

Treue Seele

  • »Superwayne« ist der Autor dieses Themas

Beiträge: 242

Beruf: Student & App Entwickler (Xamarin)

  • Private Nachricht senden

7

23.06.2016, 19:12

Du solltest das neusortieren des Inventars auch auf dem Server machen. So erkennst du auf dem Server, ob noch platz da ist und bietest dem Client weniger Möglichkeiten zu Cheaten.
Im Endeffekt liegen die Inventardaten also auf dem Server. Der Client sendet dann lediglich "Item von Position 13 nach 25 verschieben", "Stack an Position 8 halbieren", etc.


Das hatte ich auch schon überlegt, wollte aber die Wartezeit beim Sortieren des Inventars vermeiden. Der Fall, dass der Spieler beim Aufsammeln neu sortiert, ist vermutlich sehr selten der Fall, aber wenn dann Items weg sind, ist der Spieler vermutlich nicht begeistert.


Naja er beschreibt im Prinzip eine Race-Condition (was wenn der Spieler das inventar neu soritert, bevor der Server mit aufheben des Items fertig ist?)...


Genau das ist das Problem. Da hilft leider keine Abfrage an den Spieler, ob das Inventar voll ist, weil sich das in der Zwischenzeit ändern kann.

Schwanke jetzt dazwischen, die Sortierung serverseitig umzusetzen oder eine Nachricht an den Server zu schicken, dass ein Item fälschlicherweise aufgesammelt wurde, damit es auf dem Server neu gespawnt wird. Quasi Verzögerung im Inventar vs. Items die kurz verschwinden und dann wieder auftauchen.

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

8

23.06.2016, 20:21

Eine Verzögerung hast du nicht unbedingt. Auf dem Client kannst du das Inventar ja ohne Verzögerung anzeigen.
Wenn der Server dann allerdings sagt, dass die Aktion ungültig war, musst du eben wieder auf Clientseite die Änderung rückgängig machen.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

9

23.06.2016, 22:08

Ich würde mir überhaupt keine Gedanken über eine Verzögerung machen. Einfach mal implementieren. Dann wirst Du merken, dass "Item verschwindet vom Boden" und "Item taucht im Inventar auf" so nahe beieinander liegen, dass ein Mensch das gar nicht unterscheiden kann. Die Prüfung, ob es in's Inventar aufgenommen werden kann, sollte wie schon vorher erwähnt, rein auf dem Server erfolgen. Alle Änderungen am Inventar müssen *immer* auf dem Server passieren. Der Client stellt nur Requests. Da kann sich "zwischenzeitlich" also überhaupt gar nichts ändern, weil der Server immer den aktuellen Zustand kennt. Und falls Dir jemand erzählen will, dass das mit Netzwerk nicht schnell genug geht, lass ihn reden. Ich habe an einem MMORPG-Server mitgearbeitet. Der war in Java geschrieben. Die Clients in C++. 3500 Spieler online und kein Problem irgendeiner Art mit Inventar- oder Pickup-Verwaltung. Zusätzlich auch noch in TCP.
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« (23.06.2016, 22:14)


Superwayne

Treue Seele

  • »Superwayne« ist der Autor dieses Themas

Beiträge: 242

Beruf: Student & App Entwickler (Xamarin)

  • Private Nachricht senden

10

24.06.2016, 00:30

Ich würde mir überhaupt keine Gedanken über eine Verzögerung machen. Einfach mal implementieren. Dann wirst Du merken, dass "Item verschwindet vom Boden" und "Item taucht im Inventar auf" so nahe beieinander liegen, dass ein Mensch das gar nicht unterscheiden kann. Die Prüfung, ob es in's Inventar aufgenommen werden kann, sollte wie schon vorher erwähnt, rein auf dem Server erfolgen. Alle Änderungen am Inventar müssen *immer* auf dem Server passieren. Der Client stellt nur Requests. Da kann sich "zwischenzeitlich" also überhaupt gar nichts ändern, weil der Server immer den aktuellen Zustand kennt. Und falls Dir jemand erzählen will, dass das mit Netzwerk nicht schnell genug geht, lass ihn reden. Ich habe an einem MMORPG-Server mitgearbeitet. Der war in Java geschrieben. Die Clients in C++. 3500 Spieler online und kein Problem irgendeiner Art mit Inventar- oder Pickup-Verwaltung. Zusätzlich auch noch in TCP.


Das heißt die Sortierung würde da auch komplett auf dem Server passieren? Sprich der Client fragt an "Ich möchte X Stück von Item A von Slot 1 nach Slot 2 verschieben", der Server überprüft die Anfrage, führt sie aus und bestätigt dann?
Nicht wie Sylence vorgeschlagen hat, dass der Client die Änderung im Inventar erst mal macht und dem Server Bescheid sagt und der Server schickt dann ggf. eine Nachricht, dass die Änderung ungültig war?

Werbeanzeige