Netzwerktechnik zu einem mmorpg

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

Mathias-Kwiatkowski

Betreff: Netzwerktechnik zu einem mmorpg

BeitragMi, Okt 20, 2010 8:48
Antworten mit Zitat
Benutzer-Profile anzeigen
hi, leute ich möchte nun kein mmorpg programmieren, aber möchte gerne wissen was für eine technik dahintersteckt. ich weiss von wow das es mehrere server gibt und jeder einzelne parst sachen von a nach b

aber wie sieht es beim benutzer aus wie schickt man am besten daten zum server z.b. koordinaten so das es flüssig zum server kommt und auch zu allen anderen clients.


also meine frage is es wenn ich mich als spieler bewege werden dann schon daten gesendet? und in welchen abständen?

oder wird erst der komplette code ausgeführt also so z.b.

repeat

_spiel mechanik usw..


_daten senden zum server
_daten empdangen vom server
forever

also wie macht man es richtig?

Xaymar

ehemals "Cgamer"

BeitragMi, Okt 20, 2010 9:53
Antworten mit Zitat
Benutzer-Profile anzeigen
da du ja schon das beispiel wow angibst kann ich dir da ja auch dagen wie das dort(zumindest mit MaNGOS) gemacht wird.

Spieler steht -> (falls bewegt)STOP nachricht senden, mit aktueller position
Spieler dreht -> Neue rotation senden. 1 mal alle 1/2 Sekunde.
Spieler bewegt sich -> (anfang)aktuelle position und rotation (1sekunde abstand)HEARTBEAT nachricht, das der Server den Spieler weiter bewegen soll
usw.

Kannst dir ja den MaNGOS source code laden und ansehen.
Warbseite

Mathias-Kwiatkowski

BeitragMi, Okt 20, 2010 10:59
Antworten mit Zitat
Benutzer-Profile anzeigen
das is natürlich eine einfache lösung, aber auf jedenfall traffik schonend. gut ich möchte nun nich wirklich eine der emu's laden oder ansehen, aber habe das prinzip verstanden. klingt recht logisch. danke

Lastmayday

BeitragMi, Okt 20, 2010 13:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Stichwort Keyframing:

viele wollen eine vorausschauende Netzwerktechnik basteln, das Problem ist das es bei ruckartigen Bewegungen zum springen der Figur kommt. Normalerweise wird von Spieler A die Bewegung an den Server gesendet der diese dann wieder an die anderen Spieler leitet, wobei aber der Spieler nachgezogen wird. Wenn jetzt Spieler A anhält wird aktualisiert ein stopp gesendet. Es ist wichtig das man mindestens alle 250ms eine Aktualisierung sendet wegen den Lags (damit der Spieler anhält und nicht in die Gegner rein rennt).

Die Spieleobjekte werden in Listen und Arrays gespeichert und haben ein ID Field. So kann man das Objekt einfach mit der ID Nummer in die Array speichern und bei einer Aktualisierung über Netzwerk schnell wiederfinden.

Bei der Netzwerktechnik gibt es die Unterscheidung zwischen statischen, linear bewegten und ständig bewegten Objekten. Dazu kommen noch die Itemobjekte, die in den Taschen lagern. Außerdem gibt es noch Objekttypen-Sammlungen die die Standard Eigenschaften jedes Objekts halten.

Zur Sichtbarkeit der Objekte wird nur alle 3 – 5 Sekunden geprüft ob Objekte vom Spieler gesehen werden. So besitzt der Spieler listen welche Objekte / Mobs er aktuell sieht die überhaupt einer näheren abfrage würdig sind. Auch prüft nicht der Spieler was er sieht, sondern das Objekt prüft ob es gesehen wird. [warum? Listen werden langsamer je größer sie sind, da es typischerweise wenige Spieler gibt und viele Objekte ist das so Rum die beste Lösung, auch gibt es noch andere Vorteile]


etwas psydocode:
BlitzMax: [AUSKLAPPEN]
'objekte laden
'spielerdaten laden

While Not varexit
'offeneslots regeln
For slots = EachIn slotlist
'login abarbeiten
'nachrichten empfangen
Next
'objekte abarbeiten und versenden
Wend

'spielerdaten speichern


mfg Lastmayday

tft

BeitragMi, Okt 20, 2010 14:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

die idee mit dem " Das Object Prüft" hört sich interesant an. Kanst du das näher erleutern?

Gruss TFT
TFT
https://www.sourcemagic.ch
Monkey,HTML5,CSS3,W 10 64 Bit, 32 GB Ram, GTX Titan, W8 ist Müll !!!!!!

Jolinah

BeitragMi, Okt 20, 2010 14:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo

Bei einer richtigen Client-Server-Architektur ist übrigens der Server meist autoritär. Das heisst der Server verwaltet alle bewegenden Objekte bzw. komplett alles. Die Clients senden nur ihre Tastatur/Joystick-Eingaben etc... (Das schützt schon mal grundlegend vor dem Cheaten).

Der Server sendet dann bei Action-Games z.b. 20 mal pro Sekunde die Positionen (am besten nur dann wenn sich auch was geändert hat) an den Client. Bei MMOGs kann es auch weniger sein, da dort die Bewegung in den meisten Fällen etwas weniger wichtig ist. Etwas fehlt aber noch, sonst würden die Figuren trotz 20 Updates pro Sekunde umher springen/ruckeln.

Der Client führt eine Interpolation durch. Das heisst er spielt das ganze Geschehen leicht verzögert ab, kann dadurch aber flüssige Bewegungen errechnen. Angenommen 20 Updates/Sekunde, das heisst es kommt alle 50ms eine Nachricht. Optimal wäre es dann alles 100ms in der Vergangenheit anzuzeigen (so könnte auch mal ein Paket fehlen und es ruckelt immer noch nicht gleich). Der Client sieht also effektiv alles 100ms später, aber das fällt nicht wirklich auf.

Wenn nun z.B. 3 Pakete ankamen:

1. Zur Zeit 0, mit dem Wert 200
2. Zur Zeit 50, mit dem Wert 100
3. Zur Zeit 100, mit dem Wert 200

und die aktuelle Zeit 125 ist, dann Zieht man 100ms ab, da man ja alles 100ms in der Vergangenheit anzeigen will und bekommt somit die Zeit 25. Bei 25 kam aber kein Paket an, also errechnet man nun aus dem Paket 1 und 2 den Wert für die Zeit 25:

- 25 liegt genau in der Mitte von 0 und 50, somit ist der Faktor 0.5.
- Vom ersten Wert zum zweiten beträgt die Differenz -100: 100 - 200 = -100
- Das heisst wir nehmen hier auch nur die Hälfe: -100 * 0.5 = -50
- Aber diese -50 sind relativ, also addiert man wieder die vorherige Position drauf: -50 + 200 = 150

Das heisst zur Zeit 25 beträgt der Wert 150. Auf diese Art lässt sich also zu jeder Zeit berechnen wo das Objekt vor 100ms war, auch wenn nur alle 50ms ein neuer Wert kommt. Das eignet sich jedoch nur für Objekte die sich mehr oder weniger linear bewegen. Erhöht man die Anzahl Pakete pro Sekunde kann man aber auch flüssigere/rundere Bewegungen hinbekommen, nur wird dann auch die Netzlast erhöht.

Zusätzlich gäbe es dann beim Server noch Lag-Kompensation und beim Client das so genannte "Client prediction" (durch die 100ms gibt es eine kleine Eingabe-Verzögerung. Die Figur bewegt sich erst 100ms + Ping später, mit der Client prediction wird der eigene Spieler wieder ausgeglichen, damit er das Gefühl hat es wird sofort auf seine Eingaben reagiert). Aber das alles zu erklären würde wohl den Rahmen sprengen...

Hoffe ich konnte helfen.. Wink

Lastmayday

BeitragMi, Okt 20, 2010 15:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Natürlich:

als Beispiel nehme ich mal den Enemy:

da ich sowieso jeden Enemy abarbeiten muss, prüfe ich ob dieser vom Spieler gesehen wird
in der Anzahl der Type Durchläufe wäre das jetzt egal, nur wird eine Type langsamer je größer diese ist.
Sagen wir mal 10 Spieler gegen 1000 Enemys
ob jetzt 10 * 1000 oder 1000 * 10 gerechnet wird, ist egal, nur sind die 10 Spieler schneller abgefragt als 1000 Enemys.

Da ich jetzt aber weitere Listen beim Spieler und Enemy habe muss ich nur alle 3-5 Sekunden abfragen ob ein Enemy in der nähe vom Spieler ist. Dann wird geprüft ob der Enemy in dieser liste ist. Befindet sich der Spieler NICHT in der liste wird dieser eingetragen und ein create Befehl für den Enemy an den Client geschickt. Ist der Spieler in der liste wird der Enemy aktuell gehalten. Verlässt der Spieler den Sichtbereich wird aus der liste entfernt und ein delete Befehl für den Enemy an den Client gesendet.

Die 'Contains' Funktion ist in bmax schneller als eine Prüfung mit einer selbstgebauten For schleife.

Des weiteren braucht man keine extra 'send()' Funktion die das senden abhandelt, da es alles in einem auf wasch mit der Bewegung und dem zielen erledigt wird. Auch kann leicht Regionen integrieren was zur folge hat das ein Objekt überhaupt nicht mehr mit dem Spieler in Berührung kommt, wenn dieser sich wo anders in der Welt bewegt . (2d Array)

auszug aus meinem Server:
BlitzMax: [AUSKLAPPEN]
    For Local enemy:Senemy = EachIn Senemy.list

'bewegung abhandeln

'ziel und schusstechnik abhandeln


If networkupdatetimer > networkupdatespeed Then
If enemy.delme = False Then
For Local player:Splayer = EachIn Splayer.list
If player.x < enemy.x + range And player.x > enemy.x - range And player.y < enemy.y + range And player.y > enemy.y - range Then
If enemy.visionlist.Contains(player) Then
enemy.sendupdate(player.client)
Else
enemy.sendcreate(player.client)
enemy.visionlist.AddLast(player)
EndIf

If Not player.enemylist.Contains(enemy) Then player.enemylist.AddLast(enemy)
Else
If enemy.visionlist.Contains(player) Then
enemy.visionlist.Remove(player)
enemy.senddelete(player.client)
End If

If player.enemylist.Contains(enemy) Then player.enemylist.remove(enemy)
EndIf
Next
EndIf
EndIf
Next


mfg Lastmayday

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group