Jump to content
Unity Insider Forum

MOBA Netzwerkmodell


Sargon

Recommended Posts

Guten Abend liebe Unity-Insider Community,

 

Ich habe eine Frage bezüglich dem theoretischen Aufbau eines MOBAs, da ich in den Weiten des

Internets zwar einiges gefunden habe, aber spezifisches zu meinem Spielprinzip und einigen Gameplayfragen nicht auffindbar war.

Das Spiel um das es geht, enthält die Basis die man eben von solchen Spielen verlangt:

Helden auswählen, Bewegen/Angreifen per Rechtsklick, Spells ausführen und Items kaufen.

 

Ich habe nicht vor Unity oder Photon Networking zu benutzen, lieber meinen eigenen Lowlevel-Netzwerkcode. Mein derzeitiger Ansatz wäre ein autoritäres Netzwerkmodell.

Momentan sieht das so aus, dass der Client 15 mal die Sekunde eine Client request sendet, welche Information über den angeforderten Aktionen vom Spieler (Client) enthält:

 

public struct ClientRequest
{
public int myHeroId;

public Vector3 moveTarget; // Rechtsklick Bewegen
public int attackTargetActorId; // Rechtsklick Angreifen

public int castSpellIndex, // Spell ausführen
		castSpellTargetActorId; // Spell Ausführungsziel

public int buyItemIndex,
		sellItemIndex;
}

 

Diese Nachrichten werden von einem Server empfangen, welcher die Client request prüft und auf die Welt anwendet. Gleichzeitig sendet der Server 15 mal die Sekunde Nachrichten an die Clients mit einem Server command für jeden Actor im Spiel:

 

public struct ServerCommand
{
public int toHeroId;

public Vector3 currentPosition;
public int castSpellIndex,
		castSpellTargetActorId;

public int buyItemIndex,
		sellItemIndex;
}

 

Der Client wendet direkt das Server command auf die Welt an.

Dieses autoritäre Netzwerkmodell schien mir bisher vollkommen in Ordnung, aber ein paar Sachen lassen mich zweifeln. Zu Beginn wäre da die mögliche Desynchronität was zum einen das Empfangen/Verloren gehen von Nachrichten angeht, aber auch das serverseitige und clientseitige Ausführen von Spells, wodurch vielleicht Berechnungsunterschiede entstehen können (Floating point calculations je nach Prozessorstruktur).

 

Die andere Möglichkeit die mir einfallen würde, wäre das Senden der Infos aller Actors im Spiel vom Server zu allen Clients.Hier wäre mir jedoch nicht klar wie dann das in Kenntnis setzen über ausgeführte Spells passieren würde, da soetwas ja dann nur auf dem Server passieren würde, der Client müsste dennoch aber Effekte und Cooldowns anzeigen.

 

Ich freue mich über Ideen und Tipps darüber, welches Netzwerkmodell am besten geeignet ist, und wenn, wie das zweite richtig funktionieren würde.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Na dann herzlich willkommen.

 

Zu deiner Frage: ich bin nicht so tief drin im Netzwerkdschungel. Ich denke, wenn du das (Netzwerk-)Rad neu erfinden willst, wirst du dafür gute Gründe haben. Die gehen aber aus deinem Post nicht hervor. Na ja, egal.

 

Ein Hauptmanko bei Client-Server-Spielen ist, dass du dich nicht unbedingt auf die Transfer-Geschwindigkeit verlassen kannst. Dass die Kommunikation 15 mal pro Sekunde klappt, ist zwar möglich, aber nicht garantiert. Daraus leiten sich dann so Konzepte ab wie das Extrapolieren von Bewegungen von Player und Gegnern bis zum nächsten Update via Server.

 

Aber da gibt es hier massig Experten, die mehr Erfahrung haben.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es gibt einige fertige Lösungen, die besser sind als Photon:

http://forum.unity3d.com/threads/superpowered-cross-platform-networking-library-including-windows-universal-apps.286900/

 

Ich würde dir empfehlen dir diese mal anzuschauen bzw auf 5.1 und UNET zu warten (das mache ich gerade).

 

Das authoritative Server Model ist üblich und eigentlich auch am meisten benutzt. Ich würde dir auch dazu raten.

 

Erstmal:

Zu Beginn eines Spiels solltest du sichergehen, dass alles synchron ist. Also wenn alle Spieler fertig geladen haben erst die "Simulation" starten.

Dann bedenke, dass der Server immer das letzte Wort hat. Du kannst also alle Sachen, die vom Server kommen direkt oder interpoliert auf die Client Szene applizieren. Da die Befehle nur 15 mal pro Sekunde kommen und nicht mit 60 Frames, wirst du ein Stocken bemerken. Um das zu verhindern musst du zwischen den Server Updates interpolieren. z.B. kannst du deinen Client alle Berechnungen durchführen lassen. Wenn überall der gleiche Code läuft sollten sich die Unterschiede im nichtbemerkbaren Rahmen halten. Trotzdem solltest du natürlich fleißig interpolieren.

 

Wegen des Sendens:

Du hast ja sicher einen Inputcontroller.

Da kannst du dann als Client die Inputs an deine Spielfigur weiterleiten aber zugleich einen RPC beim Server machen mit welchem du den Input verschickst.

Der Server wird üblicherweise den Status abhängig vom Client Input in der Serverszene anpassen und dann synchronisieren (15 mal die Sekunde zum Beispiel).

Die Inputs zu senden ist nicht viel Traffic.

Die Synchronisierung allerdings schon! Da musst du darauf achten, dass möglichst wenig synchronisiert wird und nur wenn es (signifikante) Veränderungen gab.

 

Du merkst, es ist alles nicht ganz so einfach, deswegen gibts ja fertige Lösungen.

Es gibt aber auch haufenweise Tutorials im Internet zu finden =)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Vielen Dank für die Antworten.

Auf UNet kann ich mich leider nicht verlassen, der Netzwerkpart ist Teil eines größeren Projektes,

da muss ich meine Deadline einhalten, auch andere Lösungen lass ich da lieber weg. Ich glaube das eine Lowlevel-Implementierung

nicht der falsche Weg ist, natürlich anstrengender aber ich mag Herausforderungen :rolleyes:. Mein neuer Ansatz ist (mit Hilfe von Skee) das senden der Kommandos vom Server in State- und Request updates zu teilen. Das heißt alle States (Position/Rotation/...) werden per UDP an die Clients verschickt und die wichtigen Sachen wie Spellcasts und anderes per TCP. Damit wäre der Packetloss -was die wichtigen Sachen betrifft- Geschichte, genause wie Desync.

Interpolieren der States auf dem Client ist natürlich miteinkalkuliert, Client Prediction der Bewegung ist in MOBAs mit Bodyblocking leider nicht möglich, aber es gibt sicher Möglichkeiten soetwas miteinzubringen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...