mmofacts.com

Serverseitige software

gepostet vor 15 Jahre, 5 Monate von nerdfactor

ich beschäftige mich seit einiger zeit mit browsergames und ihrer entwicklung. nur theoretisch, nicht das ich die zeit oder lust hätte tatsächlich etwas zu entwickeln.

da ich nirgendwo eine anleitung gefunden habe wie der austausch von daten zwischen server und client abläuft, musste ich mir das irgendwie selber zusammen reimen.

wenn ich davon ausgehe, das spiel in php zu schreiben und eine mysql datenbank benutze, sieht es für mich so aus, als würde bei jedem seitenaufruf für jeden spieler die daten wieder und wieder aus der datenbank über das php script an den user weitergeleitet. wie es eigentlich normal für webseiten ist. ereignisse, die stattfinden während der spieler nicht online ist, werden dann mit cronjobs oder ähnlichen indirekten verfahren abgearbeitet. (berichtigt mich bitte wenn die überlegung falsch ist)

mir erscheint das irgendwie recht umständlich, die daten immer wieder zwischen datenbank, server und user hin und her zu schaufeln. gibt es keine sinnvolle lösung die daten in einer stetig laufenden software auf dem server bereit zu halten, die dann den php server und die datenbank ersetzt und den transfer der daten an den user übernimmt? die könnte dann auch alle ereignisse sofort intern berechnen wenn sie auftreten und müsste nicht von außen angestoßen werden.

ich würde mich freuen, wenn ihr mir da auf die sprünge helfen könntet und vielleicht einige möglichkeiten zeigt wie man so eine serverseitige spielesoftware umsetzen könnte (in Java, C# oder anderen sprachen).

gepostet vor 15 Jahre, 5 Monate von DrakeL

Original von nerdfactor

mir erscheint das irgendwie recht umständlich, die daten immer wieder zwischen datenbank, server und user hin und her zu schaufeln. gibt es keine sinnvolle lösung die daten in einer stetig laufenden software auf dem server bereit zu halten, die dann den php server und die datenbank ersetzt und den transfer der daten an den user übernimmt? die könnte dann auch alle ereignisse sofort intern berechnen wenn sie auftreten und müsste nicht von außen angestoßen werden.

Dafür nimmt man beispielsweise Memcache oder Allgemein einen Cache. Daten die sich nie/selten ändern, muss man nicht zwangsläufig immer aus der Datenbank holen.

ich würde mich freuen, wenn ihr mir da auf die sprünge helfen könntet und vielleicht einige möglichkeiten zeigt wie man so eine serverseitige spielesoftware umsetzen könnte (in Java, C# oder anderen sprachen).

Lässt sich schwer Allgemein sagen. Ganz Allgemein würde ich sagen: wie jede andere Software auch. :)

gepostet vor 15 Jahre, 5 Monate von Bringer

Original von nerdfactor

mir erscheint das irgendwie recht umständlich, die daten immer wieder zwischen datenbank, server und user hin und her zu schaufeln. gibt es keine sinnvolle lösung die daten in einer stetig laufenden software auf dem server bereit zu halten, die dann den php server und die datenbank ersetzt und den transfer der daten an den user übernimmt? die könnte dann auch alle ereignisse sofort intern berechnen wenn sie auftreten und müsste nicht von außen angestoßen werden.

Also mal abgesehen davon das ohne Datenbank auch die Masse an Nutzerdaten, Einstellungen etc kaum ordentlich gelagert werden kann gibt es natürlich sinnvolle Lösungen. Mit PHP hat man bei diesem Ansatz allerdings denkbar schlechte Karten.

Wir haben eine solche "stetig laufende" Engine, aber auch die muss sich zwischendurch immer wieder mal einige Dinge aus der DB holen und einige Dinge zurückgeben - und vor allem gewährleisten, das bei einem Ausfall keine Daten verloren gehen.

Ich frage mich allerdings wie du dies meinst:

die könnte dann auch alle ereignisse sofort intern berechnen wenn sie auftreten und müsste nicht von außen angestoßen werden.

Natürlich könnte und kann sie alle Ereignisse sofort intern berechnen, aber irgendwo - zumindest bei Nutzeraktionen - muss ja ein Auslöser vorhanden sein und der kommt nunmal von außen. Alles andere wäre doch sinnfrei

gepostet vor 15 Jahre, 5 Monate von altertoby

bezüglich der serverseitigen Umsetzung kann ich dir ein paar Schlagwörter geben...

Du brauchst ein Programm, dass die Daten ständig im Speicher behält...dafür bietet sich ein WindowsService an, aber ein enfaches Consolen-Programm tut auch seinen Dienst. Um mit der Außenwelt zu kommunizieren kannst du dann einen eigenen kleinen Webserver schreiben (in der .Net - Welt relativ einfach... ) oder du benutzt z.B. WCF (da ist z.B. der Vorteil, dass du auch schnell andere Transportwege (Tcp, InProc,...) in Betrieb nehmen kannst... z.B. für ein Admin-Panel oder um mehrere Server zu verknüpfen).

Aber im Endeffekt gibst du trozdem immer alle Daten zurück. Um dies zu verhindern bleibt dir nur die Möglichkeit, einige Daten auf dem Clienten teilweise zu speichern, und die restlichen dann per Ajax (oder dergleichen) zu laden. Der Ajax weg harmoniert auch sehr gut mit den beiden serverseitigen Methoden von oben: Bei WCF kannst du als ResponseFormat einfach JSON auswählen und gibst dann einfach deine eigenen Objekte zurück (z.B. ein User-Objekt,...) und WCF übernimmt dann die Serialization für dich (und gibt passendes JSON zurück).

Beim eigenen Webserver musst du die Objekte zwar selber serilisieren, aber das ist mit dem DataContractJsonSerializer kein Problem.

Ich denke, dass ist einer der besten Wege um möglichst viel Last dem Server abzunehmen und auf den Clienten auszulagern.

gepostet vor 15 Jahre, 5 Monate von nerdfactor

Original von DrakeL

Dafür nimmt man beispielsweise Memcache oder Allgemein einen Cache. Daten die sich nie/selten ändern, muss man nicht zwangsläufig immer aus der Datenbank holen.

ich möchte ja positionen und werte von spielern haben. die ändern sich ja alle nase lang. zumindest die kann man dann wohl kaum chachen.

Original von Bringer

Also mal abgesehen davon das ohne Datenbank auch die Masse an Nutzerdaten, Einstellungen etc kaum ordentlich gelagert werden kann gibt es natürlich sinnvolle Lösungen. Mit PHP hat man bei diesem Ansatz allerdings denkbar schlechte Karten.

Wir haben eine solche "stetig laufende" Engine, aber auch die muss sich zwischendurch immer wieder mal einige Dinge aus der DB holen und einige Dinge zurückgeben - und vor allem gewährleisten, das bei einem Ausfall keine Daten verloren gehen.

das auch eine stetig laufende software die daten irgendwo mal zwischenspeichern sollte und sie sich die daten irgendwo auch mal her holen musste ist klar. ohne datenbank kommt man nicht aus. aber sie muss halt nicht alle paar sekunden die gesamte datenmenge an den server schicken, sondern nur dann wenn der mal wieder zwischenspeichert oder wegen wartung etc. neu gestartet wurde.

Original von Bringer

Ich frage mich allerdings wie du dies meinst:

die könnte dann auch alle ereignisse sofort intern berechnen wenn sie auftreten und müsste nicht von außen angestoßen werden.

Natürlich könnte und kann sie alle Ereignisse sofort intern berechnen, aber irgendwo - zumindest bei Nutzeraktionen - muss ja ein Auslöser vorhanden sein und der kommt nunmal von außen. Alles andere wäre doch sinnfrei

wenn ein spieler eine aktion startet die irgendwann in der zukunft stattfindet muss die ja irgendwann berechnet werden. entweder in dem moment wo sie ausgelöst wird, was irgendwie komisch wäre, da das ereignis dann zu früh berechnet wird. oder sie wird dann berechnet, wenn der spieler das nächste mal online kommt, was auch komisch wäre, da das ereignis dann zu spät berechnet wird.

im optimalfall wird das ereignis berechnet wenn es auftritt. und das geht nur wenn die software auf dem server eine warteschleife hat und die ereignisse dann berechnet wenn sie fällig sind (oder so ähnlich), oder wenn eine dritte kraft von außen in regelmäßigen abständen, die berechnung aller ereignisse anstößt. diese dritte kraft (cronjobs z.b.) müssten aber jede sekunde ausgelöst werden, um so exakt zu berechnen, wie es die stetig laufende software könnte.

könntest du beschreiben wie deine "engine" funktioniert bringer?

gepostet vor 15 Jahre, 5 Monate von Bringer

Original von nerdfactor

im optimalfall wird das ereignis berechnet wenn es auftritt. und das geht nur wenn die software auf dem server eine warteschleife hat und die ereignisse dann berechnet wenn sie fällig sind (oder so ähnlich), oder wenn eine dritte kraft von außen in regelmäßigen abständen, die berechnung aller ereignisse anstößt. diese dritte kraft (cronjobs z.b.) müssten aber jede sekunde ausgelöst werden, um so exakt zu berechnen, wie es die stetig laufende software könnte.

Im Optimalfall werden die Ereignisse dann nicht dann berechnet, wenn sie auftreten, sondern dann, wenn ungenutzte Leistung vorhanden ist, bzw die Serverlast es zulässt. Das ist jedoch grade bei Browserspielen nicht immer möglich. Dort hat man per se sehr viele kleine Anfragen und Datenmengen von außen, das das Berechnen beim Auftreten u.U. zu ekelhaft langen Ladezeiten führt.

2 Beispiele:

Eine Useraktion löst bei vielen Spielen eine Wartezeit aus, z.B. bei der "Arbeit" oder beim aussenden einer "Armee" zum Gegner. Es wäre doch doof nun zu warten bis die Armee beim Gegner eintrifft und erst dann die Berechnung des Kampfes zu starten, oder abzuwarten bis die 8 Std Arbeit des Spielers abgelaufen sind.

-Im Fall der Arbeit wird sich das Ergebnis wohl zumeist eh nicht mehr verändern, eine Gehaltserhöhung wärend der Arbeit wird in den meisten Fällen nicht eintreten, bringt keinen besonderen Mehrwert und wird ergo bei der Entwicklung gar nicht ermöglicht.
Die Engine hat also 8 Std Zeit, für das berechnen des Arbeitsergebnisses. Entweder erledigt man es sofort (ist ja eh nichts aufwendiges) - oder aber lässt es irgendwann während dieser 8 Std in einem Teillast oder Leerlaufzustand berechnen. Der User wird davon eh nichts merken.

- Bei der Armee wirds difficiler - möglicherweise hat der Gegner seine Basis verändert oder Verteidigungstruppen aufgestellt während meine Armee 10 min. durch die Wüste gezogen ist. In dem Fall habe ich 2 mögliche Optionen:
1. Berechnen während die Armee sich "eigentlich" noch bewegt und danach nur noch überprüfen ob sich beim Gegner zwischenzeitlich was verändert hatte. Wenn nein ausliefern, wenn ja MIST - dann muss die Enine eben gleich nochmal mit den nun aktuellen Daten rechnen.
2. Berechnen wenn die Armee angekommen ist, dann aber unabhängig von Serverauslastung und der Zeit die der User genervt vor dem Rechner sitzt und wartet. (Kann durchaus geschehen - in einer frühen Version unseres momentanen Projektes dauerte eine Kampfberechnung bis zur Auslieferung an den User bis zu 10 Sekunden)

Gut ist z.B., wenn eine Highscoreliste nicht jedesmal dann berechnet wird, wenn der Spieler sie aufruft (bei 100k Spielern auf einem Server kann das schon problemathisch werden). Allerdings ist das aus Sicht des Spielers wiederum nicht so toll, deshalb steckt man bspw. feste Zeitgrenzen innerhalb derer berechnet werden muss, sagen wir eine Std - sorgt aber dafür, dass das Programm auch mal 5 oder 10 Minuten durch diese Grenzen bricht wenn die Last gerade zu hoch ist. Wenn nach oder innerhalb dieser Zeit immer noch kein geigneter Lastzustand entstanden ist, dann muss man eben in den sauren Apfel eines Laggs beissen und die Berechnung dennoch starten. Man sieht also: Optimal aus unserer Sicht ist nicht = Optimal aus Usersicht.

In groben Zügen arbeitet unsere Engine ähnlich. Wir warten nicht auf spezifische Anfragen, sondern bereiten vieles vor um es dann bei Anfrage auszuliefern. Geht natürlich nicht überall - z.B. bei Kämpfen oder Einkäufen. Wir sparen uns zwar den Overhead jedesmal eine Auslage bei einem NPC-Händler zu generieren wenn ein User sie anfordert - innerhalb eines bestimmten Zeitabstandes wird dynamisch eine neue Auslage erstellt die gecacht und bei Anfrage nur noch ausgeliefert wird, aber der Prozess des Einkaufens selbst ist nicht vorbereitbar.

Mit tieferen und vor allem technikbezogeneren Darstellungen kann ich nicht dienen. Mein Job ist nicht das Prorammieren, ich habe nur das Konzept unseres Spiels in großen Teilen mitentworfen und dadurch viel mit unseren Codern zu tun gehabt.

PS: Bei Cronjobs fehlt dazu die Dynamik - außerdem sind sie denkbar ungeeignet für sekündliche Jobs und würden dabei in den meisten Fällen massiven Overhead vom Damm brechen wenn ich mich nicht arg täusche.

gepostet vor 15 Jahre, 5 Monate von nerdfactor

da sieht man, das ich mich nur theoretisch mit dem thema beschäftige und nicht selber entwickel

die auslastung der rechenleistung habe ich nicht beachtet, und wenn man sie beachtet ist deine darstellung natürlich logisch.

Auf diese Diskussion antworten