Browsergame mit Django entwickeln?

Django, Flask, Bottle, WSGI, CGI…
Jutus
User
Beiträge: 5
Registriert: Freitag 18. Dezember 2009, 13:07

Hi,

ich habe vor ein Browsergame zu entwickeln und will dies mit Python tun. Da Django anscheinend das Framework für die Python Webentwicklung ist habe ich mir Django mal angesehen und bin ziemlich begeistert.

Besonders die Kommunikation zur Datenbank und aufgeräumte Struktur gefallen mir. Außerdem soll Django ein eingebauten Login System haben, welches mir auch eine menge Arbeit abnehmen könnte.

Jetzt ist allerdings die Frage ob sich Django auch für die Entwicklung eines Browsergames eignet. In einem alten Thread (http://www.python-forum.de/topic-12979. ... rowsergame) wurde schon mal darüber diskutiert und die meisten waren der Meinung Django wäre da keine gute Wahl. Allerdings wurden keine genauen Gründe genannt.

Also was genau würde gegen Django sprechen?
Trinkt mehr Milch!
BlackJack

@Jutus: Was soll es denn für ein Spiel werden. Ich denke davon hängt es auch ab.
Jutus
User
Beiträge: 5
Registriert: Freitag 18. Dezember 2009, 13:07

das ganze soll eine Wirtschaftssimulation werden. Spieler haben Ländereien auf denen sie Waren produzieren. Die Waren können untereinader gehandelt werden.

Die Zeit vergeht in Ticks. Jede Minute ist ein Tick. Hatte mir überlegt, dass der aktuelle Spielstand eines Spielers nicht nicht in jeden Tick ausgewertet wird sondern erst wenn es sein muss (Spieler loggt sich ein, oder anderer Spieler nimmt in irgendeiner Form Kontakt zum Spieler auf)
Zusätzlich wollte ich das Spiel einmal am Tag kurz offline Schalten und dein Script drüber laufen lassen. Dabei werden besondere Aktionen ausgewertet, z.B. neue Preise der Waren berechnet, Verträge ausgeführt usw.
Trinkt mehr Milch!
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Ich wüsste nicht, was gegen Django spricht. Du musst selbst wissen, ob dir Django flexibel genug ist und ob dir das ORM dafür ausreicht. Wenn mich nicht alles täuscht basiert pennergame auf Django und das ist ja eines der größten Browsergames.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Da das ein altes Posting von mir aus der Zeit, wo ich gerade mit Django anfing, ist, hier ein Update nach über zwei Jahren. Vorausschicken muss ich noch, dass ich keine echte praktische Erfahrung mit Browserspielen habe, nur eine Meinung als Software-Entwickler. Ich kenne noch nicht einmal viele davon.

Ich würde sagen, ein klassisches Spiel, welches auf einer Seite meist in Tabellenform einen Spielstand darstellt und bei dem dann Befehle über ein Formular geschickt werden, auf dass das Spiel dann seinen internen Stand, der meist in einer relationalen Datenbank repräsentiert ist, aktualisiert um darauf hin wieder eine neue Seite mit Statusinformationen anzuzeigen, lässt sich mit Django gut umsetzen.

Die Probleme, die ich in meinem Posting recht unstrukturiert zu thematisieren versuchte sind eher Randbereiche.

Ich suchte nach einem Weg, möglichst einfach ein PHP-Programm zu portieren, welches HTML-Templates und Anzeigelogik (nicht unbedingt Spiellogik) vermischte. Ich störte mich daran, dass es mit Rails, dessen Template-System ERB ja auch das Mischen von Text und Code erlaubt, viel einfacher sein würde, die Templates zu portieren. Baut man das ganze aber von Anfang an speziell für Django auf, kommt man erst gar nicht in diese Situation und hat diese Probleme.

Dennoch: Jinja bleibt eine interessante Alternative und Bottle, was ich später noch erwähnen werde, mit seinem super einfachen Template-System ebenfalls.

Gerne wird erzählt, dass der ORM, als der Teil von Django, der einem hilft, die Datensätze wie Objekte aufzufassen, nicht mächtig genug ist. Mit den Erweiterungen von Django 1.1 und 1.2 ist das glaube ich aber immer weniger ein Problem. SQLalchemy erscheint mir da deutlich komplizierter und man verliert das Admin-UI von Django, was mir auch bei einem Browserspiel für Tests und zur einfachen Korrektur von Fehlern sinnvoll erscheint.

Dennoch: Ich würde inzwischen wohl überhaupt keine relationale DB mehr benutzen, was natürlich den Admin-UI-Vorteil von Django relativiert, wieder Bottle ins Spiel bringt, aber dafür die SQLalchemy-Diskussion erübrigt.

Wie gesagt, ich kenne keine (modernen) Browserspiele, daher ist mein Stand immer noch, dass die Versuche in PHP (oder wie erwähnt in Pike und Coldfusion) echt katastrophal sind und tausende von Zeilen verschwendet werden, um mit unpassenden Technologien wie relationalen Datenbanken und maskenorientierten Batch-Prozessen wie vor 40 Jahren zu kämpfen.

In der Diskussion wurde ZODB/Durus und CouchDB erwähnt. Inzwischen kenne ich die drei Systeme soweit, dass ich mir eine Meinung zutraue: Alles nicht optimal. ZODB und Durus versuchen eine OODB zu sein, die eigentlich schon zu dem Zeitpunkt, als sie gebaut worden, tot hätten sein sollen, weil der Markt schon Mitte der 90er (leider) entschieden hatte, dass relationale DBs gegen OODBs gewonnen haben. Dabei war Gemstore richtig schick.

Inzwischen gibt es jedoch eine neue Generation von Entwicklern, die von der Entscheidung nichts mehr wusste und es ist die NOSQL-Bewegung entstanden und auf einmal sprießen überall Key-Value-Stores und andere einfache Datenspeicher aus dem Boden, die nicht im Hinblick auf ACID und kaufmännische Prozesse entworfen wurden, sondern im Hinblick auf Einfachheit und Skalierbarkeit.

Sollte ich in näherer Zukunft ein Browserspiel schreiben (was leider unwahrscheinlich ist) wäre mein Kandidat aus der Menge der NOSQL-DB-Anwärter MongoDB. Ich glaube, diese DB würde sich ausgesprochen gut für ein Postspiel (eine Spielform noch älter als Browserspiele, die ich aber besser kenne) eigenen und daher bestimmt auch für ihre moderne Fortsetzung.

Ein anderes Problem, über das ich geklagt hatte, waren Transaktionen. In einer relationalen DB könnte man das Problem bei sehr sorgfältiger Programmierung und einem ausreichend hohen Isolation Level in den Griff bekommen, aber es macht viele Dinge (jede Form von Ressourcen-Übertragung, vergleiche das klassische Account-Problem) schwer. Sie einfach zu ignorieren und ab und zu Fehler im Programm (die Spieler möglicherweise ausnutzen könnten) zu riskieren, ist aber IMHO auch keine Lösung.

Erschwerend kommt hinzu, dass NOSQL-Datenbanken ACID und Transaktionen in der Regel der Skalierbarkeit opfern (das CAP-Theorem sagt ja auch, man kann nicht alles haben) sodass die Wahl von MonoDB dieses Problem nicht nur nicht lösen würde, sondern noch verstärkt.

Ich habe mal versucht, in Redis (einem anderen NOSQL-Anwärter) durch geschickte Wahl der Reihenfolge der Befehle und eigenen Locks mit Timeouts Transaktionen zu bauen, doch das alles macht Fehler nur unwahrscheinlich, nicht unmöglich. Egal ob das für die Praxis reicht, mich macht so etwas unglücklich.

Daher würde ich einen der beiden radikalen Ansätze verfolgen:

Das Spiel wird von einem permanent laufenden Server ausgeführt. Nennen wir diesen "Application Server". Er hält den Spielstand. Er nimmt Befehle entgegen, die den Zustand ändern und Befehle, die nach dem (subjektiven) Zustand fragen. Er schreibt selbstständig das Spiel weiter. Dies ist fundamental anders als das Spiel in die Request-Response-Logik eines Webservers zu pressen, wo der Spielstand nur während eines Requests kurzfristig existiert und ansonsten in einer DB repräsentiert wird. Bis zu einer gewissen Anzahl von Spielern kann ich alle Befehle einfach serialisieren und habe keinerlei Transaktionsprobleme. Den Spielstand selbst könnte ich, wenn es mir zu gefährlich ist, ihn nur im Hauptspeicher zu halten, regelmäßig als Snapshot ablegen (so macht Redis es) oder einen Redo-Log (vergleiche die Idee von Prevayler) pflegen oder aber einen KV-Store (wie Redis oder MongoDB) benutzen. Herje, man könnte sogar eine OODB benutzen, denn genau für so einen Zweck wurde sie mal erdacht.

Weil der Server ja auch IO machen muss und dieses nicht parallel laufen darf (ansonsten hätte ich ja wieder Probleme mit Transaktionen), wäre vielleicht Tornado eine interessante Basis für den Server. Sobald aber einzelne Befehle so lang werden, dass ich sie nicht auf einmal ausführen kann, ohne dass das System stockt, müsste ich sie aufteilen und begebe mich in die Schlangengrube die da heißt CPS-Programmierung. Wer sich mal komplexere nodejs-Anwendungen anschaut, weiß, was ich meine. Man bräuchte jetzt Coroutinen auf Generatorbasis. Das total unbekannte Webrahmenwerk Diesel bautet so etwas zu bieten, ob das in der Praxis funktioniert, weiß ich jedoch nicht.

Der andere Ansatz wäre daher, Parallelität nicht um jeden Preis zu verhindern, sondern als Normalfall zu akzeptieren. Vielleicht gibt es eine brauchbare Actor-Implementierung für Python. Oder eine Implementierung von STM a la Clojure. In diese Richtung könnte man forschen. Beides erlaubt es, mit Datenstrukturen konfliktfrei in einer nebenläufigen Welt umzugehen, ohne dass es zu Deadlocks oder inkonsistenten Zuständen kommt und dennoch ist es für den Entwickler verständlich. Leider ist CPython äußerst ineffizient, wenn es mehrere parallele Threads ausführen soll und für diesen Ansatz wäre ich versucht, eine andere Programmiersprache zu wählen. Erlang (Actor-Modell) finde ich arg archaisch, wäre aber ein guter Kandidat. Ob Reia besser ist? Ich habe schon lange nicht mehr Io angeschaut, das kennt aber auch Actors. Scala oder Clojure selbst wären weitere Kandidaten. Und ich hatte neulich gesehen, dass jemand die STM-Implementierung von Clojure für JRuby portiert hat. Theoretisch könnte man das natürlich auch für Python machen, aber dann wären da wieder die Implementationsprobleme von CPython.

Bleibt man doch bei einem recht klassischen Ansatz und vergisst die ganzen "wie wäre es perfekt"-Überlegungen, bleibt noch eines zu sagen. Nach jedem Klick die Webseite neu zu laden scheint mir gerade bei einem Spiel schon lange nicht mehr der richtige Ansatz zu sein. Ich würde eher sagen, dass Spiel selbst läuft (mit genug JavaScript, welches man entweder selbst schreibt oder da wieder eine Bandbreite an Alternativen hat, die ein weiteres Posting dieser Länge wert wären) im Browser und kommuniziert mit dem Server per AJAX. Dies relativiert die Notwendigkeit für eine gute Template-Sprache sondern der Webserver muss nur noch in der Lage sein, auf bestimmte URLs mit JSON-formatierten Daten zu antworten. Hierfür brauche ich eigentlich Django nicht. Bottle scheint mir da eine einfachere Lösung zu sein. Okay, man hat das Admin-UI nicht mehr, aber wählt man da MongoDB als Backend, muss man sich eh etwas eigenes bauen. Für Redis gibt es übrigens ein Admin-UI basierend auf Bottle (nur so nebenbei).

Oder man sagt, weil man für die Client-Seite eh JavaScript beherrschen muss, kann man den Server ja auch mit JavaScript schreiben und dann empfehle ich Node.js. Siehe z.B. http://howtonode.org/express-mongodb. Definitiv nicht die am einfachsten zu programmierende Plattform (der notwendige CPS-Stil kann schnell entarten), aber dafür super von der Performance und extrem leichtgewichtig.

Viel Spaß bei deinem Browserspiel, das garantiert auch ohne all die komplexen Überlegungen, die ich hier angestellt habe, funktionieren wird.

Stefan
Benutzeravatar
DeKugelschieber
User
Beiträge: 82
Registriert: Sonntag 28. Februar 2010, 12:23
Kontaktdaten:

Hi,

mit BG´s hab ich Erfahrung (http://lastworld.de/), meins hab ich mit PHP + MySQL geschrieben. Ich weiß nicht was Django ist oder kann, aber generell ist es egal mit was du dein BG schreibst, du musst ja "nur" Daten verarbeiten und evt. Cronjobs stellen. Versuch doch erstmal z.B. den Login mit Python + Django zu schreiben, wenn das gut klappt und nicht ausartet würd ich es nehmen. Und dein Konzept mit der aktuallisierung der Daten ist super, mach ich genauso. Anders geht das auch garnicht, da du und der Server sonst zu viel arbeit hättest. Und letzendlich merkt das eh niemand, was nur nicht so toll ist, ist das z.B. evt. die Punkte und somit die Rangliste nicht immer aktuell sind. Aber das könntest du dann in der offlinezeit um Mitternacht oder so ja erledigen^^

MfG
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Hier ist vllt was interessantes für dich: http://www.python-forum.de/topic-19510.html

Sie haben mich persönlich auch schonmal im IRC angesprochen (nicht auf Freenode bzw. Python.de), war auch recht freundlich ;)
the more they change the more they stay the same
Jutus
User
Beiträge: 5
Registriert: Freitag 18. Dezember 2009, 13:07

@sma
Erstmal danke für die sehr ausführliche Antwort. Ich hatte eigentlich vor Django zusammen mit einer MySql Datenbank zu nutzen. Die NOSQL Datenbank hört sich recht interessant an. Ich werde mir das auf jeden Fall mal angucken.
Die ganze Seite per Java-Script zu erstellen und nur über Ajax mit dem Server zu kommunizieren hört sich für mich sehr aufwendig an. Ich würde da wohl doch eher den Klassischen Weg mit einer Template Engine nutzen und nur in besonderen fällen mit Ajax arbeiten.
Werde mir den Post wohl noch ein paar Mal durchlesen um alle Infos aufzunehmen.

@DeKugelschieber
Eines der Vorteile von Django ist ja, dass es ein Login-System integriert hat. Ich muss nur noch herausfinden wie es funktioniert.

@Dav1d
Danke für den Link. Im IRC war ich allerdings noch nie (glaube ich jedenfalls)
Trinkt mehr Milch!
Benutzeravatar
DeKugelschieber
User
Beiträge: 82
Registriert: Sonntag 28. Februar 2010, 12:23
Kontaktdaten:

sowas selber zu schreiben ist nicht schwer, ich weiß nicht ob ich da was fertiges benutzen würde, vorallem weil du ja nicht nur regestrieren muss, sondern auch startwerte usw. in der DB speichern musst (zb. Position auf der Karte oder wowas)
MfG DeKugelschieber
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

DeKugelschieber hat geschrieben:sowas selber zu schreiben ist nicht schwer, ich weiß nicht ob ich da was fertiges benutzen würde, vorallem weil du ja nicht nur regestrieren muss, sondern auch startwerte usw. in der DB speichern musst (zb. Position auf der Karte oder wowas)
Ja, aber wo ist das Problem? Das geht alles auch ganz prima mit der von Django mitgelieferten Authentifizierung.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Es gibt ja mehrere Denkschulen, wie man ein Problem angehen sollte. Ich finde, viel spricht dafür, mit dem gefühlt schwierigsten Punkt anzufangen, weil dort die Unsicherheit am größten ist, ob es klappt und wie lange es dauert, und man so im Laufe des Projekts, wenn die Sachen einfacher werden, eine immer größere Planungssicherheit bekommt.

Das vorausschickend würde ich nicht empfehlen, mit einer Login-Funktion zu beginnen, zumal Django so etwas ja gerade schon mitbringt. Login ist IMHO einfach. Das größte Problem sehe ich die Regeln (wenn man sie denn kennt) testbar und korrekt umzusetzen. Möchte ich testgetrieben arbeiten, ist eine spannende Frage, wie ich beispielsweise ein zufallsabhängiges Kampfsystem implementiere.

In jedem Fall würde ich versuchen, beim Spiel Darstellung, Steuerung und Logik strikt zu trennen. Die Motivation ist, dadurch einfachere Teilprobleme unabhängig voneinander lösen zu können. Idealerweise erhalte ich einen Kern, der komplett unabhängig von der Präsentation über Webseiten und die Steuerung durch Formulare ist. Und nur für den letzten Teil muss ich dann überhaupt eine Entscheidung pro/contra Django treffen.

Alles andere hielte ich für einen Hack a la (schlechtem) PHP, wo dann in einem Template SQL-Anfragen stehen, um Dinge und Sachen zu machen, die mal wieder garantiert nicht frei von Racing-Conditions sind und als Sahnehäubchen vielleicht sogar noch anfällig für SQL-Injections sind.

---

Hier ein triviales Beispiel.

Ich habe ein Spielfeld von 6x6 Zonen, von denen sechs nicht betretbar sind (das Spielfeld muss aber zusammenhängend bleiben) und die anderen Zonen einen Ressourcen-Wert zwischen 0 und 3 haben (verteile zufällig 5x0, 10x1, 10x2 und 5x3).

Hier ist so ein Spielfeld:

Code: Alles auswählen

    01 211
    23 132
    2023 1
    1 0232
    122012
     13 10
Ich habe 20 Spieler (namens A bis T), für die ich je sechs Einheiten ("Bots") zufällig auf die Zonen verteile.

Für die erste Zeile kann das so aussehen:

Code: Alles auswählen

    Zone-00 [0]  Zone-01 [1]  Zone-02 [-]  Zone-03 [2]  Zone-04 [1]  Zone-05 [1]
     - Bot[D]     - Bot[F]                  - Bot[C]     - Bot[C]     - Bot[A]
     - Bot[K]     - Bot[R]                  - Bot[I]                  - Bot[A]
     - Bot[L]                               - Bot[L]                  - Bot[B]
     - Bot[M]                               - Bot[P]                  - Bot[F]
     - Bot[M]                                                         - Bot[J]
     - Bot[N]                                                         - Bot[M]
Ein Bot kann sich jede Runde in eine der vier Nachbarzonen (nicht diagonal) bewegen. Stehen Bots zweiter Spieler (irgendwo) in der selben Zone, können sie Ressourcen ("Rs") tauschen. Ein Bot, der sich nicht bewegt, kann Rs gemäß des Werts der Zone abbauen. Diese werden dem Spieler gut geschrieben. Wo ein Bot steht, kann ein neuer Bot für 2R gebaut werden, der in dieser Runde nichts weiter machen kann. Für 2R kann ein Bot zu einem BuildBot oder BattleBot aufgerüstet werden. BuildBots existieren, um Pyramiden zu bauen. Pro Zone kann eine gebaut werden, wenn die Nachbarzonen noch keine enthalten. Pyramiden haben Stufen. Die erste Stufe kostet 1R, jede weitere ein R mehr. Pro R baut ein BuildBot eine Runde. Die Pyramide gehört, wer jeweils die letzte Stufe gebaut hat.

Spieler können untereinander verbündet sein. Wird der Bündnispartner angegriffen, verteidigen die eigenen Bots diesen. Greift der Bündnispartner an, wird das Bündnis aufgehoben. Pro Zone können Spieler andere Spieler angreifen. Ebenso können sie deklarieren, eine Zone gegen ankommende Spieler (außer Bündnispartner) zu verteidigen. Bots, die Rs abbauen, haben einen Kampfwert von 1. Bots, die solche angreifen, einen von 9. Bei Bot gegen Bot steht es 5:5, bei BattleBot gegen Bot (auch BuildBot) 7:3. Gibt es BattleBots, kämpfen zunächst diese. Für jeden Bot wird eine Zufallszahl 0..9 bestimmt. Ist diese kleiner als der Kampfwert, wird der andere Bot vernichtet. Hat eine Seite mindestens 3x so viele nicht arbeitende Bots wie die andere, gibt es +1 auf den Kampfwert. Wird eine Zone verteidigt, haben die Verteidiger +1. Es wird gekämpft, bis eine Seite vernichtet ist.

Das ganze lässt sich noch komplexer gestalten, doch ich musste das schon jetzt 2x umformulieren, um es simpel und noch simpler zu gestalten. Ob die Zahlenverhältnisse so passen, kann ich nicht sagen, denn ich habe mir das gerade alles nur ausgedacht.

Sich zu überlegen, wie die Anzeige für das Spiel sein muss, ist relativ einfach. Ich will die Zonen sehen und was sich in den Zonen befindet. Ich will Bündnispartner und mein Geld in Form von Ressourcen sehen und muss dann planen können, welche Bots ich was machen lasse. Diese Eingaben muss sich der Server bis zur nächsten Runde merken und dann ausführen.

Ein Datenmodell ist ebenfalls schnell entworfen. Ich baue ein `Game`, dies kennt `Player`s und `Zone`s, beide kennen `Bots`. Unabdingbar sind `Order`s für die Befehle.

Meine Kampfbeschreibung ist jedoch noch immer unterspezifiziert.

Und für alles, was Zufallsergebnisse braucht, muss man zum Testen z.B. über folgende Klasse gehen, dabei allerdings wissen, welche Würfe mit welchen Obergrenzen gemacht werden. Das sind eigentlich zu tief gehende Annahmen, aber ich habe keine bessere Idee, wie's gehen könnte.

Code: Alles auswählen

    class Dicer:
        def roll(n):
            return random.randrange(n)
    
    class TestDicer:
        def __init__(self, *numbers):
            self.numbers = iter(numbers)
    
        def roll(n):
            a, b = self.numbers.next()
            assert a == n
            return b
    
    dicer = TestDicer((10, 3), (10, 6))
    print(dicer.roll(10))
    print(dicer.roll(10))
Aber ich komme schon wieder ins Schwafeln... :)

Stefan
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

So, dann werde ich auch noch mal meinen Brei dazu geben.

Django? Nein.
Hilft dir bei einem Browser Game mMn nicht viel. Django ist meiner Meinung nach nett für CRUD und CMS artige Sachen. Für ein Browser Game würde ich vermutlich mehr oder weniger keine der Komponenten verwenden.

Was denn sonst?
Ich würde ziemlich sicher keine (SQL) Datenbank verwenden. Ich würde die gesamte Spiel Welt im Speicher behalten (RAM kostet ja nicht mehr die Welt) und zur persistierung Regelmässig auf die Festplatte synchronisieren. Anfang vermutlich einfach mit Pickle. Die Game Logik würde ich soweit wie möglich in festen Zeit Schritten in einem einzelnen Thread abhandeln. Eingaben würde ich über eine Message Queue laufen lassen. Das auslesen der Daten für die Spieler ist interessanter. Vermutlich würde ich da Anfangs vollständige Kopien der Welt erstellen und das ganze dann später optimieren.

Die ganze Anzeige und Steuer Logik würde ich vermutlich auch Clientseitig implementieren. Javascript ist nicht mal halb so böse wie oft angenommen wird. Das ganze hat den Vorteil das du eine konsistente Architektur hast. Um Clientseitigen Code kommst du vermutlich sowieso nicht.

Davon ein Browser Game wie eine normale Website zu entwickeln rate ich auf jeden Fall ab. Ich würde es auf jeden Fall wie ein Netzwerk Spiel entwickeln das Zufälligerweise mit einem Browser gesteuert wird. Würdest du Django für einen Quake3 oder Warcraft3 oder ... Server verwenden? Ich nicht.

Ich hoffe der Zusammenhang von meinen gemurmel ist halbwegs ersichtlich. Ich habe mehr oder weniger nur meine Gedanken nieder geschrieben.

Gruss,
Jonas
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

veers hat geschrieben:Django? Nein.
Hilft dir bei einem Browser Game mMn nicht viel. Django ist meiner Meinung nach nett für CRUD und CMS artige Sachen. Für ein Browser Game würde ich vermutlich mehr oder weniger keine der Komponenten verwenden.
Imho ist Django inzwischen auch schon für (fast) alles andere auch gut verwendbar. Du musst halt natürlich etwas mehr schreiben, aber auch nicht mehr als sonst wo…
Ich würde ziemlich sicher keine (SQL) Datenbank verwenden. Ich würde die gesamte Spiel Welt im Speicher behalten (RAM kostet ja nicht mehr die Welt) und zur persistierung Regelmässig auf die Festplatte synchronisieren. Anfang vermutlich einfach mit Pickle. Die Game Logik würde ich soweit wie möglich in festen Zeit Schritten in einem einzelnen Thread abhandeln. Eingaben würde ich über eine Message Queue laufen lassen. Das auslesen der Daten für die Spieler ist interessanter. Vermutlich würde ich da Anfangs vollständige Kopien der Welt erstellen und das ganze dann später optimieren.
Ich würd nicht alles im Ram halten, ist auch fürs syncen zwischen den Webservern doof, Mongodb oder so würde sich anbieten. Gamelogik in Threads? Ne danke lieber ne MessageQueue die bestimmte Tasks alle $X Minunten ausführen kann.

Just my 2¢
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

sma hat geschrieben:In der Diskussion wurde ZODB/Durus und CouchDB erwähnt. Inzwischen kenne ich die drei Systeme soweit, dass ich mir eine Meinung zutraue: Alles nicht optimal. ZODB und Durus versuchen eine OODB zu sein, die eigentlich schon zu dem Zeitpunkt, als sie gebaut worden, tot hätten sein sollen, weil der Markt schon Mitte der 90er (leider) entschieden hatte, dass relationale DBs gegen OODBs gewonnen haben. Dabei war Gemstore richtig schick.
Inwiefern ist das jetzt nicht optimal? Ich verstehe dein Argument nicht, dass sie deswegen schlecht sind, weil OODBs schon tot hätten sein sollen.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

apollo13 hat geschrieben:
veers hat geschrieben:Django? Nein.
Hilft dir bei einem Browser Game mMn nicht viel. Django ist meiner Meinung nach nett für CRUD und CMS artige Sachen. Für ein Browser Game würde ich vermutlich mehr oder weniger keine der Komponenten verwenden.
Imho ist Django inzwischen auch schon für (fast) alles andere auch gut verwendbar. Du musst halt natürlich etwas mehr schreiben, aber auch nicht mehr als sonst wo…
Durchaus, jedoch gibt es meiner Meinung nach in vielen Fällen optimalere Tools. Aber um ehrlich zu sein habe ich mit Django auch seit einem Jahr nichts mehr gemacht. Vielleicht ist die Template Engine nun ja auf dem Niveau von Jinja2 und der ORM vergleichbar mit SQLAlchemy. :wink:
apollo13 hat geschrieben:
veers hat geschrieben:Ich würde ziemlich sicher keine (SQL) Datenbank verwenden. Ich würde die gesamte Spiel Welt im Speicher behalten (RAM kostet ja nicht mehr die Welt) und zur persistierung Regelmässig auf die Festplatte synchronisieren. Anfang vermutlich einfach mit Pickle.
Ich würd nicht alles im Ram halten, ist auch fürs syncen zwischen den Webservern doof, Mongodb oder so würde sich anbieten.
Wenn dein Code dafür 10x schneller läuft könnte sich das durchaus Lohnen.

Auch der Aufwand ist meiner Meinung nach geringer. Wenn du einen Cluster betreiben willst würde ich versuchen die zuständigkeiten Aufzuteilen und nicht die Daten zu spiegeln und dann von mehreren Orten gleichzeitig zu bearbeiten. Shrading dürfte da um einiges besser Funktionieren. Insbesondere mit Mongodb welches keine Transaktionen oder Locking zu unterstützen scheint (oder habe ich da etwas übersehen?).
apollo13 hat geschrieben:Gamelogik in Threads? Ne danke lieber ne MessageQueue die bestimmte Tasks alle $X Minunten ausführen kann.
veers hat geschrieben:Die Game Logik würde ich soweit wie möglich in festen Zeit Schritten in einem einzelnen Thread abhandeln. Eingaben würde ich über eine Message Queue laufen lassen. Das auslesen der Daten für die Spieler ist interessanter. Vermutlich würde ich da Anfangs vollständige Kopien der Welt erstellen und das ganze dann später optimieren.
In einem Thread, nicht in Threads. Deine Message Queue muss ja von irgend wo abgearbeitet werden. :wink:
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

veers hat geschrieben:
apollo13 hat geschrieben:
veers hat geschrieben:Ich würde ziemlich sicher keine (SQL) Datenbank verwenden. Ich würde die gesamte Spiel Welt im Speicher behalten (RAM kostet ja nicht mehr die Welt) und zur persistierung Regelmässig auf die Festplatte synchronisieren. Anfang vermutlich einfach mit Pickle.
Ich würd nicht alles im Ram halten, ist auch fürs syncen zwischen den Webservern doof, Mongodb oder so würde sich anbieten.
Wenn dein Code dafür 10x schneller läuft könnte sich das durchaus Lohnen.
performance != skalieren, was hilft dir schneller, wenn du den server einfach mit requests wegkillen kannst und dann wegen deinem Memory nimmer skalieren kannst…
Insbesondere mit Mongodb welches keine Transaktionen oder Locking zu unterstützen scheint (oder habe ich da etwas übersehen?).
Ka, müsste man schauen wie viel man davon braucht etc…
apollo13 hat geschrieben:Gamelogik in Threads? Ne danke lieber ne MessageQueue die bestimmte Tasks alle $X Minunten ausführen kann.
veers hat geschrieben:Die Game Logik würde ich soweit wie möglich in festen Zeit Schritten in einem einzelnen Thread abhandeln. Eingaben würde ich über eine Message Queue laufen lassen. Das auslesen der Daten für die Spieler ist interessanter. Vermutlich würde ich da Anfangs vollständige Kopien der Welt erstellen und das ganze dann später optimieren.
In einem Thread, nicht in Threads. Deine Message Queue muss ja von irgend wo abgearbeitet werden. :wink:
In RabbitMQ we trust ;) Wie gesagt ich würde sowas von Anfang an so konzipieren, dass ich gerade solche Tasks leicht über die Server verteilen kann…
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

apollo13 hat geschrieben:
veers hat geschrieben:
apollo13 hat geschrieben:
veers hat geschrieben:Ich würde ziemlich sicher keine (SQL) Datenbank verwenden. Ich würde die gesamte Spiel Welt im Speicher behalten (RAM kostet ja nicht mehr die Welt) und zur persistierung Regelmässig auf die Festplatte synchronisieren. Anfang vermutlich einfach mit Pickle.
Ich würd nicht alles im Ram halten, ist auch fürs syncen zwischen den Webservern doof, Mongodb oder so würde sich anbieten.
Wenn dein Code dafür 10x schneller läuft könnte sich das durchaus Lohnen.
performance != skalieren, was hilft dir schneller, wenn du den server einfach mit requests wegkillen kannst und dann wegen deinem Memory nimmer skalieren kannst…
Wenn deine Welt wirklich so Massiv ist, dass das nicht mehr möglich ist, dann Teil sie in 2. Das Skaliert garantiert besser als ein Zentraler Keyvalue Store auf den mehrere Server schreiben die dann irgend wie Synchronisiert werden müssen. Mongodb o.ä. zu persistierung zu verwenden halte ich durchaus für Denkbar. Würde ich jedoch auch Aufschieben.
apollo13 hat geschrieben:
apollo13 hat geschrieben:Gamelogik in Threads? Ne danke lieber ne MessageQueue die bestimmte Tasks alle $X Minunten ausführen kann.
veers hat geschrieben:Die Game Logik würde ich soweit wie möglich in festen Zeit Schritten in einem einzelnen Thread abhandeln. Eingaben würde ich über eine Message Queue laufen lassen. Das auslesen der Daten für die Spieler ist interessanter. Vermutlich würde ich da Anfangs vollständige Kopien der Welt erstellen und das ganze dann später optimieren.
In einem Thread, nicht in Threads. Deine Message Queue muss ja von irgend wo abgearbeitet werden. :wink:
In RabbitMQ we trust ;) Wie gesagt ich würde sowas von Anfang an so konzipieren, dass ich gerade solche Tasks leicht über die Server verteilen kann…
Ich würde vermutlich erst auf RabbitMQ umsteigen wenn es nötig ist. Wenn die Architektur stimmt müsste sich die Middleware leicht auswechseln lassen.

Mein Ansatz wäre auf jeden Fall zuerst einmal das Spiel zum laufen zu bringen, und zu sehen ob meine Idee wirklich so Toll ist wie ich mir das Gedacht habe, und ob andere Leute diese auch so Toll finden. Dinge wie die MessageQueue, oder auch ein KeyValueStore lassen sich mit einer vernünftigen Architektur relativ leicht auswechseln, wenn die bestehenden an ihre grenze kommen. Zum einen weil ich, und ganz bestimmt nicht nur ich, viel zu schnell die Lust an so einem Projekt verliere wenn ich nicht in absehbarer Zeit ans eingemachte kann. Zum anderen sehe ich das ganze als Optimierung an. Optimieren ohne das Wahre Problem zu kennen halte ich für gefährlich.

Gruss,
Jonas
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

Nun von Anfang an RabbitMQ mit Django (jetzt mal nur als Beispiel) zu verwenden ist schon einmal einfacher als ne saubere Struktur zu schreiben, so dass man es später einbauen kann. Und ja je nach Projekt achte ich schon von Anfang an auf Skalierung…
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

apollo13 hat geschrieben:Nun von Anfang an RabbitMQ mit Django (jetzt mal nur als Beispiel) zu verwenden ist schon einmal einfacher als ne saubere Struktur zu schreiben, so dass man es später einbauen kann. Und ja je nach Projekt achte ich schon von Anfang an auf Skalierung…
Lose Kopplung ist für mich absolut essentiell für eine gute Architektur. Darauf würde ich RabbitMQ hin und MongoDB her nicht verzichten wollen. Gerade in einer dynamischen Sprache wie Python ist das auch nicht schrecklich aufwändig, und der Gewinn ist sehr gross (Verständlichkeit, Testbarkeit, Wartbarkeit, einfachere Zusammenarbeit).

Gruss,
Jonas
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

Klar deshalb ja auch RabbitMQ via celery, da hast dein loose coupling schon ;) Aber lassen wir das, das führt zu nix…
Antworten