Zope als Browsergamebasis

Django, Flask, Bottle, WSGI, CGI…
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Phlegma hat geschrieben:Okay, vllt kann man sich die Queries mit den Expressions einfacher bauen und es ist zu mehreren Datenbanken kompatibel, doch letzteres brauche ich nicht umbedingt (PostgresSQL würde mir reichen) und mich macht das ewige PREPARE skeptisch, von PHP und MySQL internen Proceduren weiß ich, dass das zwar recht sicher ist, aber auch recht langsam. Ich möchte DB Kapatzitäten lieber anders nutzen.
Ich denke weniger das dir das Probleme bereiten wird. Vor allem nimmt es dir arbeit ab die du dafür ins Spiel investieren kannst. Am späteren optimieren wird es dich auch nicht hindern. :wink:

- Jonas
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Verschiedenes:

1. Eine Sprache, deren Syntax objektorientierte Konstrukte erlaubt, führt halt nicht automatisch dazu, dass deren Nutzer einen objektorientierten Software-Entwurf beherrschen. Zudem war es wohl wie BlackJack vermutet und PHP4 war noch aktuell.

2. Nach wie vor bin ich der Meinung, dass eine relationale Datenbank die Programmierung eines Spiels eher erschwert denn erleichtert und es wundert mich, dass Phlegma lieber low-level SQL programmieren möchte, als verfügbare Abstraktionen zu nutzen.

3. Ich halte ein gutes Mehrpersonenstrategiespiel für eine sehr anspruchsvolle Aufgabe und würde erwarten, dass man sich erst einmal darauf konzentriert, denn von Tag 1 Performance- und Installations-Aspekte in den Vordergrund stellt. Natürlich ist PHP weiter verbreitet, aber ein V-Server oder dedizierter Server ist nicht so viel teurer als ein Shared-PHP-Hoster und ungleich flexibler. Haben shared hoster nicht allgemein MySQL im Angebot?

4. Webseiten dienen bei einem Spiel letztlich nur zur Anzeige des Spielstands und dem, was seit dem letzten Besuch so passiert ist und das ist ein einfacher Report. Je nachdem, wie komfortabel das UI zur Eingabe der Befehle sein soll, verschiebt sich das Problem hier immer weiter Richtung JavaScript und erfordert möglicherweise kaum oder gar keine Funktion zum Erstellen der Seite auf dem Server. Dieser muss dann nur Daten im XML- oder JSON-Format bereitstellen. So wäre jedenfalls mein Ansatz. Somit wäre das, was PHP vielleicht am besten kann, nämlich Webseiten darstellen, mit das unwichtigste.

5. Das Web-Rahmenwerk ist IMHO egal, solange nicht das Spiel fertig ist und interessant genug, dass man es auch spielen wollen würde. Auf der Suche nach einer Datenbank wäre vielleicht auch ein Blick auf etwas wie CouchDB oder der DataStore der Google App Engine interessant. Das hängt jetzt ein bisschen von dem Spiel selsbt ab, wo ich nicht abschätzen kann, was sich Phlegma genau vorstellt.

6. Würde man z.B. das Brettspiel Risiko "ins Web" bringen wollen, bestünde das Datenmodell eine Menge von Ländern, in denen jeweils Truppen eines Spielers stehen. Spieler halten außerdem noch Karten auf der Hand, die sie gegen neue Truppen eintauschen können. Die Topologie der Länder kann man hart verdrahten und ebenso die Regel, wie viele neue Truppen man pro Kontinent bekommt. Das ist so einfach, dass sich das bequem auf die Google App Engine bringen lässt.

7. Veers letzte Aussage würde ich auch unterschreiben.

Phlegma, ich fände es klasse, ein bisschen mehr über das Spiel, das du bauen willst, zu erfahren und den Ansatz, wie du es umsetzen willst. Ich möchte gerne verstehen, warum so viele Leute SQL als besten Weg sehen und wie sie eigentlich (im Gegensatz zu mir) so ein Problem angehen.

Stefan
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

sma hat geschrieben:Ich möchte gerne verstehen, warum so viele Leute SQL als besten Weg sehen und wie sie eigentlich (im Gegensatz zu mir) so ein Problem angehen.
Hallo Stefan!

Wie du ja weißt, halte ich nicht sonderlich viel von ORMs. Und vielleicht interessiert es dich, wie ich dann meine Probleme löse.

Zuerst entwerfe ich ein Objektmodell, welches meine Probleme in die für mich am besten geeignete Abstraktionsebene hebt. Und dann versuche ich die Aufgaben auf die Objekte so zu verteilen, wie sie, meines Erachtens, am ressourcenschonendsten und trotzdem noch weitestgehend abstrakt gelöst werden können.

Um es mit einem kleinen Beispiel zu untermalen: Adressen

Es gibt bei einer Adressenverwaltung eine "Adressen"-Klasse. Weiters gibt es auch eine "Adresse"-Klassen. Wenn ich mit einer Adresse arbeiten möchte, dann nehme ich die "Adresse"-Klasse zur Hand und führe dort die Methode "load" aus. An diese Methode wird die "ID" der Adresse übergeben, die diese Instanz darstellen soll bzw. mit der gearbeitet werden soll. Wurden die Daten geändert, dann werden die Änderungen mit Hilfe der "save"-Methode wieder in die Datenbank gespeichert.

Eine Instanz der "Adressen"-Klasse hält alle Adressen zur Verfügung. Z.B. sind dort Methoden aufgehoben, um eine Adresse zu finden. Wenn ich nur herausfinden möchte, wieviele Adressen in der DB stehen, dann wird das über "Adressen" erledigt. Wenn ich eine Liste (z.B. "Vorname, Nachname, Ort") aller Adressen brauche, dann gibt es dort eine Methode, die mir diese Daten aus der DB ausliest und als Cursor zurückgibt. Oft brauche ich auch komplexer selektierte Daten, dann werden die Daten mehrerer Datenbanken ausgelesen und miteinander kombiniert. Die Daten werden dann meist als Liste zurück gegeben.

Wenn ich also eine einzelne Adresse bearbeite, dann arbeite ich mit einer Instanz der Klasse "Adresse". Wenn ich mit mehreren Adressen etwas tun möchte oder Informationen über mehrere Adressen abrufen möchte, dann arbeite ich mit einer Instanz der Klasse "Adressen".

So entscheide ich wann es günstiger ist, alles "in einem Rutsch" mit einer SQL-Anweisung zu erledigen, oder eine Adresse einzeln in die "Hand" zu nehmen um damit zu arbeiten. Außerdem ist es auf diese Art einfacher, mehr Leistung von der Datenbank erbringen zu lassen.
Wenn eine SQL-Anweisung umfangreich (viele Zeichen lang) wird, dann mache ich daraus eine View oder eine "Gespeicherte Prozedur", die direkt in der Datenbank ausgeführt wird. Erstens wird diese Abfrage dann vom Datenbanksystem optimiert und zum Aufrufen der View oder der Prozedur müssen weniger Zeichen über das Netzwerk übertragen werden.

Ich weiß nicht, ob dieses Beispiel gut ist... zumindest habe ich es versucht... ;-)

Es wird also abstrahiert, aber nicht so konsequent. Und es wird der Datenbank mehr Macht gegönnt. Die Frage der Kompatibilität zu anderen Datenbanken stellt sich bei meinen Anwendungen nicht.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
Phlegma
User
Beiträge: 20
Registriert: Samstag 24. Januar 2009, 12:05

Also gut. Vorweg nehmen wir als Basis OGame, dann brauch ich das Spielprinzip nicht erklären. Ich wünsche auch keine Diskussion darüber warum ich nun ein OGame-ähnliches Spiel will, das ist OT.

Nachdem ich ein lange Zeit (damals musst ich noch grundlegende Programmierung lernen) mit dem OpenSource UGamela 0.2 verbracht habe und auch an einigen Versionen in german UGamela (bis 0.5) gearbeitet habe, wurde mir klar, dass der Code Mist ist. Je mehr ich lerne desto mehr merke ich wie schlecht der Code wirklich war/ist. Daher meine Erfahrungen.

Ziel ist nun schon seit langem eine wirklich gute Basis zuschreiben. Dazu kommen eine grobe Veränderungen zu OGame und vor allem ein Haufen Flexibilität, Konfigurierbarkeit und Erweiterbarkeit. Davon wird es natürlich nicht einfacher und je mehr ich lerne desto eher weiß ich wie komplex das Ganze wirklich ist.

Nun zur wirklichen Angelegenheit zurück. Mein Focus liegt auf dem Herzstück des Spiels, der Kampfberechnung.
Der OGame-Kampf ist nicht nur Ressourcen-verschwendend, sondern auch noch unlogisch. Ziel ist vor allem ersteres Problem zu besiegen und den Kampf etwas logischer zu machen.

Kampfschema:
1. Schadensumme(SQL SUM())+Reduzierung bilden (wichtigster Aspekt)
2. Schiffe von oben herunter "totzählen", evtl. in zwei Gruppen (kleine/große Schiffe)

schön einfach, bei austarierten Faktoren gar nicht so unlogisch.
Nun wird es komplexer.

Die Schiffe können mit speziellen Modulen (e.g. Waffen) ausgerüstet werden, gerade dieser Teil soll extrem flexibel werden um möglichst gute Erweiterbarkeit zu erreichen.
Objektschema:
Flotte[Eigenschaften(coords usw)] <- Schiffe[Basiseigenschaften(Anzahl, Angriff, Def, ...)] <- Module mit Einfluss auf die Methoden des Schiffs, evtl auch die Eigenschaften SQL SUM Problem.

Die Verschachtelung dieser drei Objekttypen möchte ich abstrahieren, des weiteren möchte ich auch bestimmte Features in den unteren Ebenen einbauen können (Beispiel: Planeten bzw Sonnensysteme erhalten einen ähnlichen Aufbau, doch die Aktualisierung der Ressourcen soll auf unterster Ebene geschehen).

Ich wollte in PHP Objekte sparen, da dieser gerade nicht wenig Speicher im Threadram verbrauchen. Teils scheint mir auch manchmal ein direkter Algorithmus effizienter als ein riesen Objektgedöns, vor allem wenn das andauernd zum Zug kommt.

Mein Ansatz nahe an der DB zu arbeiten kam von einem Teamkollegen, mittlerweile weiß ich, dass die DB so schon gerne mal zum Bottleneck wird und man sie nicht überlasten sollte, dennoch ist es am effizientestem sehr nah an ihr zu bleiben, muss ja nicht gleich die ganze Businesslogik in MySQL Procedures stehen.
[url]http://ugamela-blog.pheelgood.net[/url]
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

http://steve-yegge.blogspot.com/2008/10 ... ttern.html lies das mal... Und vergiss Performance. Um die kannst du dich kümmern wenn du merkst wo das Problem liegt.

Und sma, bezüglich relationalen Datenbanken. Ein großer Vorteil davon sehe ich in der Transaktionsfähigkeit. Das ist ziemlich Mühsam wenn du es selber nachbauen willst.

- Jonas
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Benutzeravatar
Phlegma
User
Beiträge: 20
Registriert: Samstag 24. Januar 2009, 12:05

Schön, wenn ich mal viel Zeit habe lese ich das auch noch... oder magst du mir vllt eine spezifische Stelle sagen?

Achja, die Transaktionen brauche ich auch. Oder zumindest hätte ich gerne Transaktions.
Und vergiss Performance.
Hmm okay.
Um die kannst du dich kümmern wenn du merkst wo das Problem liegt.
Das glaube ich weniger, das Design kann ich dann nicht mehr ändern...
[url]http://ugamela-blog.pheelgood.net[/url]
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Phlegma hat geschrieben:
Und vergiss Performance.
Hmm okay.
Um die kannst du dich kümmern wenn du merkst wo das Problem liegt.
Das glaube ich weniger, das Design kann ich dann nicht mehr ändern...
Dann ist das design schlecht gewesen ;) Dann schreibst du eben alles neu. Passiert aber eher selten - sofern vernünftig gehandelt wird. :wink:
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Transaktionen sind in der Tat ein guter Punkt.

Ich hatte eine sehr lange Antwort geschrieben, in der ich über das Spiel selbst sinniere, den erspare ich euch aber lieber. Nur soviel: Transaktion != relationale Datenbank. ZODB, CouchDB oder Google's DataStore haben ebenfalls Transaktionen. und Clojure ist eine (der wenigen) Programmiersprache(n die ich kenne), die Transaktionen auf Objektebene haben.

In Python könnte man versuchen, damit durchzukommen, dass man alle Änderungen des Datenmodells serialisiert. Das funktioniert bei meinem Ansatz, mit Runden im Stunden oder Tagesbereich problemlos. Wenn man aber ein quasi kontinuierliches Spiel haben will, wird's schwierig.

Ich dachte, man könnte einfach Runden im Minutentakt machen. Doch angenommen, ich habe 5.000 Spieler und 100.000 Planeten und z.B. 10.000.000 Raumschiffe, schaffe ich es nie und nimmer, alles einmal pro Minute auch nur anzuschauen. Ich hätte für die Entscheidung, ob ein Raumschiff kämpfen, landen, fliegen soll, gerade mal 0.1ms.

Wie skaliert man so ein Spiel? Datenbanken können da auch keine Lösung sein, denn die sind um Größenordnungen langsamer.

Stefan
Benutzeravatar
Phlegma
User
Beiträge: 20
Registriert: Samstag 24. Januar 2009, 12:05

Hm, das wird jetzt dann langsam OT, hat auch nichts direkt mit Python zu tun, denn in PHP bau(t)e ich etwas Ähnliches.

Zahlen: 5000 Spieler: 50.000 Planeten, 100.000 Flotten, seehr viele Schiffe
Wichtig ist, dass die Interaktion nicht zu häufig ist, vor allem nicht flächendeckend. Die Transaktionen brauche ich gegen etwaige Race Conditions. Wichtig ist, dass das Spielprinzip auf die Implementierung optimiert ist, das heißt, das Spielprinzip profitiert von einfachen Vorgängen und verzichtet auf komplexere Probleme. Beispiel das bereits gezeigte Kampfsystem, das totzdem einen Kampf zwischen mehreren Spielern in zwei Parteien zulässt.

Ich komme nochmal zum OR-Mapper zurück. Ich habe grade erst verstanden was "relational" überhaupt bedeutet, so doof sich das auch anhört, aber bisher dachte ich damit sei nur die Tabellenform gemeint. Aber "Relation" heißt ja "Beziehung". Die Tabellen sind verknüpft. Dabei fällt mir auch, dass ich bisher nur einen Typ von Verknüpfung brauche: One to Many (to Many). Die OR-Mapper bieten eine Verallgemeinerung, die ich gar nicht benötige. Stattdessen baue ich mir meinen speziellen OR-Mapper selbst.
Habe auch ein paar schöne Berechtigungsdiagramme für User gesehn, dafür bräuchte ich schon eher einen OR-Mapper, fragt sich nun welcher. Bei diesen Bedingungen kann ich sogar auf die Transaktionen verzichten. Da verändert sich nicht viel gleichzeitig.
Ich suche also ein Framework, das mir bereits eine Userverwaltung bietet, an welches ich dann meinen speziellen Mapper anbauen kann.
[url]http://ugamela-blog.pheelgood.net[/url]
Benutzeravatar
Phlegma
User
Beiträge: 20
Registriert: Samstag 24. Januar 2009, 12:05

Jetzt hat es euch allen die Sprache verschlagen oder was? Warum?
Phlegma hat geschrieben:...
Ich suche also ein Framework, das mir bereits eine Userverwaltung bietet, an welches ich dann meinen speziellen Mapper anbauen kann.
Meinungen?
[url]http://ugamela-blog.pheelgood.net[/url]
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Phlegma hat geschrieben:Jetzt hat es euch allen die Sprache verschlagen oder was? Warum?
Weil alles bereits gesagt wurde was gesagt werden muss.
Phlegma hat geschrieben:Ich suche also ein Framework, das mir bereits eine Userverwaltung bietet, an welches ich dann meinen speziellen Mapper anbauen kann.
Wenn du das wirklich willst django. Ansonsten sqlalchemy. Damit hast du dir deine Usermodels auch schnell selbst gemacht.

- Jonas Wagner
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Benutzeravatar
Phlegma
User
Beiträge: 20
Registriert: Samstag 24. Januar 2009, 12:05

Gut.

Vielen Dank an alle!!

Ihr hört von mir sobald ich wirklich was rausbringe, kann aber in Python noch gut ein Jahr dauern.
[url]http://ugamela-blog.pheelgood.net[/url]
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Phlegma hat geschrieben:Hm, das wird jetzt dann langsam OT
Das sind die besten Diskussionen :)
Phlegma hat geschrieben:Zahlen: 5000 Spieler: 50.000 Planeten, 100.000 Flotten, seehr viele Schiffe. Wichtig ist, dass die Interaktion nicht zu häufig ist, vor allem nicht flächendeckend.
Ja, aber wie willst du das sicherstellen? Ich denke, das Spiel wie ich's vorgeschlagen hatte zu takten, funktioniert einfach nicht. Doch welchen Ansatz sonst? Mir würde noch eine "priority queue" zur "Wiedervorlage" von Aktionen einfallen, doch das enthebt das System ja nicht davon, letztlich doch 100.000 Flotten pro Minute zu bewegen. Oder muss man die Spielregeln so anpassen, dass z.B. jeder der Spieler maximal 3 Flotten pro Minute bewegen darf. Irgendwie finde ich nach wie vor die Idee gut, alles im Hauptspeicher zu halten und so die relativ langsamen Datenbank-Operationen aus der Zeit-Rechnung zu nehmen.
Phlegma hat geschrieben:Beispiel das bereits gezeigte Kampfsystem, das totzdem einen Kampf zwischen mehreren Spielern in zwei Parteien zulässt.
Das habe ich überhaupt nicht verstanden. Willst du da einen Zufallsfaktor einbauen? Was heißt totzählen? Gewinnt in einem Kampf einfach die größere/stärkere Flotte?

Ich wollte ursprünglich bei meiner Regelinterpretation Bündnisse beschreiben, doch das ist schon alles andere als trivial, den Algorithmus zum Aufteilen von N Spielern in N' Fraktionen zu beschreiben, sodass ich denke, dass wäre als Datenbank-Operationen richtig aufwendig.
Phlegma hat geschrieben:Ich komme nochmal zum OR-Mapper zurück. Ich habe grade erst verstanden was "relational" überhaupt bedeutet, so doof sich das auch anhört, aber bisher dachte ich damit sei nur die Tabellenform gemeint. Aber "Relation" heißt ja "Beziehung". Die Tabellen sind verknüpft.
Nein, eine relationale Datenbank besteht schon aus Tabellen (diese heißen verwirrenderweise Relationen) mit jeweils gleich strukturierten Datensätzen (oder Tupeln) auf denen dann Grundoperationen (selection, projection und cartesian product) definiert sind. Die letzte (auch Join genannt) verknüpft die Tupel zweiter Relationen und bildet eine neue Relation mit verknüpfen Tupel. Die Operation drückt dann das, was du als eine Beziehung bezeichnet hast, aus.

Die Relation aus einem Entity-Relationship-Modell ist nicht die Relation einer relationalen Datenbank. Letztere basiert auf der Theorie der relationalen Algebra. Und weil sie so schön theoretisch untermauert ist und Tabellen in vielen Fällen echt praktisch sind, hat sie sich durchgesetzt.

Es gibt noch objektorientierte, deduktive, hierarchische oder Netzwerk-Datenbanken.
Phlegma hat geschrieben:Dabei fällt mir auch, dass ich bisher nur einen Typ von Verknüpfung brauche: One to Many (to Many).
Das verwundert mich, denn z.B. ein Bündnis wäre eine N:M-Beziehung. Was du als Vorteil zu erkennen glaubst, ist die Beschränkung einer relationalen Datenbank, gar keine N:M-Beziehungen modellieren zu können. Man muss sich dort mit einer Hilfstabelle und zwei 1:N-Beziehungen behelfen. Auf die Abstraktion einer N:M-Beziehung verzichten zu wollen, ist IMHO ein Schritt in die falsche Richtung.
Phlegma hat geschrieben:Habe auch ein paar schöne Berechtigungsdiagramme für User gesehn, dafür bräuchte ich schon eher einen OR-Mapper, fragt sich nun welcher. Bei diesen Bedingungen kann ich sogar auf die Transaktionen verzichten. Da verändert sich nicht viel gleichzeitig.
Das klingt für mich auch äußerst fragwürdig.
Phlegma hat geschrieben:Ich suche also ein Framework, das mir bereits eine Userverwaltung bietet, an welches ich dann meinen speziellen Mapper anbauen kann.
Django bietet dir eine Benutzerverwaltung, allerdings erfordert der ORM, dass du nach Änderungen immer explizit speichern musst, was ich mit dem Attribut primitiv bezeichnen würde.

Eigentlich will man IMHO einen "persistence context" am Ende einer Operation automatisch sichern können und sich nicht Gedanken darüber machen müssen, was man nun wo wie geändert hat. Was Relationen zwischen Modellen angeht, wird Django 1.1 für dich ausreichend sein.

Stefan
Benutzeravatar
Phlegma
User
Beiträge: 20
Registriert: Samstag 24. Januar 2009, 12:05

sma hat geschrieben: ...
doch das enthebt das System ja nicht davon, letztlich doch 100.000 Flotten pro Minute zu bewegen.
Ganz falsch. Das geht bei einem Browsergame nicht. Ihr seid zu sehr an euer Mini-Snake in Python gewöhnt, bei dem alles in Echtzeit abläuft. Die Flotten werden keineswegs alle gleichzeitig bewegt. Stattdessen werden sie beim Start und beim Ankommen berechnet. Dafür braucht man einen Eventhandler oder gar Daemon. Wenn sich Flotten im Raum treffen sollen muss man die Positionen jedes Mal nachberechnen.

Das Problem liegt an den versch. Usern, die bei jedem Klick eine ganze Scriptinstanz auf dem Server starten. Pro User läuft quasi ein Thread, das muss coordiniert werden. Allzu leicht kommt es zu Race Conditions. Ich habe nur mit einem kleinen Daemon die Möglichkeit Dinge in Echtzeit zu berechnen, aber dieser hält niemals alle Flotten im Hauptspeicher.
Phlegma hat geschrieben:Beispiel das bereits gezeigte Kampfsystem, das totzdem einen Kampf zwischen mehreren Spielern in zwei Parteien zulässt.
Das habe ich überhaupt nicht verstanden. Willst du da einen Zufallsfaktor einbauen? Was heißt totzählen? Gewinnt in einem Kampf einfach die größere/stärkere Flotte?
Theoretisch gewinnt die stärkere Flotte. Ein Zufallsfaktor ist schnell eingebaut (zB Schaden mal rand(0.5,2)). Wie man den genau formuliert ist Sache des Balancings. "Totzählen" 5k Schaden, die drei größten Schiffe haben jeweils 2k Leben => 2 tot, 1 halb kaputt. Natürlich kann man auch das noch etwas komplexer gestalten. Der Schadensempfang bleibt dem typenspezifischen Schiffsobjekt überlassen oder den eingebauten Modulen.
Ich wollte ursprünglich bei meiner Regelinterpretation Bündnisse beschreiben, doch das ist schon alles andere als trivial, den Algorithmus zum Aufteilen von N Spielern in N' Fraktionen zu beschreiben, sodass ich denke, dass wäre als Datenbank-Operationen richtig aufwendig.
Versteh ich nicht. Was ist aufwendig?
Nein, eine relationale Datenbank besteht schon aus Tabellen (diese heißen verwirrenderweise Relationen) mit jeweils gleich strukturierten Datensätzen (oder Tupeln) auf denen dann Grundoperationen (selection, projection und cartesian product) definiert sind. Die letzte (auch Join genannt) verknüpft die Tupel zweiter Relationen und bildet eine neue Relation mit verknüpfen Tupel. Die Operation drückt dann das, was du als eine Beziehung bezeichnet hast, aus.

Die Relation aus einem Entity-Relationship-Modell ist nicht die Relation einer relationalen Datenbank. Letztere basiert auf der Theorie der relationalen Algebra. Und weil sie so schön theoretisch untermauert ist und Tabellen in vielen Fällen echt praktisch sind, hat sie sich durchgesetzt.

Es gibt noch objektorientierte, deduktive, hierarchische oder Netzwerk-Datenbanken.
Für mich hatte sich das eig. immer intuitiver angefühlt in der Datenbank, hatte auch bisher noch keine wirklichen Probleme die Daten in Objekte zu füllen. Algebra... aha.
Phlegma hat geschrieben:Dabei fällt mir auch, dass ich bisher nur einen Typ von Verknüpfung brauche: One to Many (to Many).
Das verwundert mich, denn z.B. ein Bündnis wäre eine N:M-Beziehung. Was du als Vorteil zu erkennen glaubst, ist die Beschränkung einer relationalen Datenbank, gar keine N:M-Beziehungen modellieren zu können. Man muss sich dort mit einer Hilfstabelle und zwei 1:N-Beziehungen behelfen. Auf die Abstraktion einer N:M-Beziehung verzichten zu wollen, ist IMHO ein Schritt in die falsche Richtung.
Hm vllt hab ich noch zu wenig mit OOP gemacht, aber eig. dachte ich da schon durchzusteigen, vllt hab ich auch nur zuviel mit SQL gearbeitet...
In welcher Beziehung stehen die Mitglieder einer Fraktion zur anderen? Sind es nicht nur die Fraktionen die in Kontakt treten und ihre Mitglieder dabei haben? Ich hätte die Mitglieder in ein Bündnis über Objekt geladen.
One to Many. Für den Rest nehme ich ein echtes ORM.
Phlegma hat geschrieben:Habe auch ein paar schöne Berechtigungsdiagramme für User gesehn, dafür bräuchte ich schon eher einen OR-Mapper, fragt sich nun welcher. Bei diesen Bedingungen kann ich sogar auf die Transaktionen verzichten. Da verändert sich nicht viel gleichzeitig.
Das klingt für mich auch äußerst fragwürdig.
?? Klarer ausdrücken bitte. Was ist fragwürdig. In den Usertabellen passiert quasi kaum eine Veränderung und wenn doch betrifft sie nur den User selbst. Seinen Namen kann er ändern, aber nicht seine ID..
... allerdings erfordert der ORM, dass du nach Änderungen immer explizit speichern musst, was ich mit dem Attribut primitiv bezeichnen würde.
Ja. Ich hab mir da etwas nettes ausgedacht: Ein automatisches Update am Ende des Scripts, bei PHP im Objektdestruktor. Natürlich nur veränderte Werte.
Was Relationen zwischen Modellen angeht, wird Django 1.1 für dich ausreichend sein.
:D schön. Ich werde mich mit Django anfreunden.
[url]http://ugamela-blog.pheelgood.net[/url]
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Phlegma, es geht doch laut deiner Aussage darum, dass das Spiel gefühlt in Echtzeit abläuft und nicht in diskreten Runden. Bei 5.000 Spielern, die theoretisch alle gleichzeitig handeln können, würden 5.000 Flotten, die in der selben Minute starten sollen, das Spiel auf einem üblichen Rechner gegen die Wand fahren, denn man hätte nur 12ms pro Flotte zur Verarbeitung.

Darauf zu hoffen, dass dieser theoretische Fall nicht eintreten wird, halte ich für keine gute Strategie. Daher fragte ich, ob man nicht eher mit Hilfe der Spielregeln so einen Fall ausschließen will. Alternativ kann man eine andere Architektur des System wählen, als die Verarbeitung von Requests in jeweils einem neuen Prozess (so wie es PHP immer und Python meist machen).

Eventhandler oder Demon sind meines Wissens Dinge, die es in PHP nicht gibt, welches ja nur einen HTTP-Request bearbeiten kann und dafür einen Prozess (oder Thread eines Prozesses) startet, nicht jedoch kontinuierlich ablaufende Programme erlaubt. Auch die Aussage "pro User läuft ein Thread" kann ich daher nicht nachvollziehen. Ist die Anfrage des Users bearbeitet, läuft da nichts auf dem Server weiter und hält insbesondere keinen Zustand. Dieser muss, soll er nicht verloren gehen, in einer Datenbank abgelegt werden.

Und dies macht den Ansatz ineffizient. Zugriff auf den Hauptspeicher eines System ist mindestens eine Größenordnung schneller und wäre daher eine Alternative. Dieses Verfahren ist natürlich nicht beliebig skalierbar, doch theoretische Skalierbarkeit nützt nichts, wenn man sich die notwendigen Computer nicht auch leisten kann/will.

Mit Python - und darauf will ich ja die ganze Zeit hinaus - ist man nicht auf das simple Request-Processing-Modell von PHP beschränkt und kann einen dedizierten Server für das Spiel schreiben, der dann den Spielstand im Hauptspeicher schnell zugreifbar hält. Der Preis für die Geschwindigkeit ist, dass man Transaktionen selbst bauen muss.

Ich muss gestehen, ich würde die Aufgabe lieber in Java + JavaScript angehen als in Python - einfach, weil Java grundsätzlich schneller wäre, Multithreading unterstützt und ich schon immer mal Terracotta ausprobieren wollte (zum Clustern der Systeme), aber Python würde prinzipiell funktionieren.

Zusammen mit der Google App Engine vielleicht sogar richtig gut.

Bündnisse im Kampf sind aufwendig. Annahme: Ein Spieler kann mit einem anderen Spieler verbündet sein. Dann unterstützen sich ihre Flotten im Kampf und greifen sich nicht automatisch an. Flotten nicht verbündeter Spieler kämpfen gegeneinander. Flotten können nur auf Planeten aufeinander treffen - ansonsten sind sie im Hyperraum. Auf einem Planeten können nun Flotten von N Spielern aufeinander treffen, sagen wir mal es sind A, B und C. C ist mit A und B verbündet. A greift B an, C würde B verteidigen, aber würde auch A nicht angreifen. Was nun? Das Bündnis zu A lösen? Es war aber Zufall, dass A B angegriffen hat und nicht B A. In diesem Fall müsste C das Bündnis mit B lösen. Also soll C beide Bündnisse lösen? Das wirkt sich dann aber auf die Kämpfe auf allen anderen Planeten aus. Oder werden (das wäre meine Präferenz) Bündnisse an Planeten gebunden? Wenn ich A, B, C und D habe und B ist mit A, C mit B, D mit C und A mit D verbündet, welche Bündnisse muss ich lösen? Alle? Gefällt mir nicht, kompliziertere Regeln sind aber eben komplizierter und wohl für die Spieler weniger einfach nachvollziehbar.

Fragwürdig finde ich, dass du (so habe ich das verstanden) sagt, dass du bei Dingen, die sich wahrscheinlich nicht zum selben Zeitpunkt ändern, keine Transaktionen brauchst. Es ist IMHO nicht maßgeblich, ob sich etwas selten oder häufig ändert. Wenn auch nur die kleinste Chance für einen Konflikt existiert, muss man ACI-Transaktionen benutzen. Angenommen, ein Spieler kennt die Zahl der Rohstoffe, die er verbauen kann. Dieses Attribut ist zwar privat für jeden Spieler, aber dieser eine Spieler kann ja (mit mehreren Browsern oder Programmen) mehrere Befehle quasi parallel abschicken und somit auszunutzen versuchen, dass es hier Racing-Conditions geben könnte, je nachdem wie das genau implementiert ist.

Stefan
Benutzeravatar
Phlegma
User
Beiträge: 20
Registriert: Samstag 24. Januar 2009, 12:05

sma hat geschrieben:Phlegma, es geht doch laut deiner Aussage darum, dass das Spiel gefühlt in Echtzeit abläuft und nicht in diskreten Runden. Bei 5.000 Spielern, die theoretisch alle gleichzeitig handeln können, würden 5.000 Flotten, die in der selben Minute starten sollen, das Spiel auf einem üblichen Rechner gegen die Wand fahren, denn man hätte nur 12ms pro Flotte zur Verarbeitung.
Bei 5k Spielern schicken niemals alle gleichzeitig eine Flotte ab. 5k Spieler sind zudem die Obergrenze für ein "Universum" davon sind auch niemals alle online. Natürlich gibt es Spitzen, dennoch ist mit einer Flotte gar nicht so viel Arbeit verbunden. Der Kampf ist wenn dann schwierig, da muss man vorsichtig sein. Notfalls lässt sich dieser auslagern.
Darauf zu hoffen, dass dieser theoretische Fall nicht eintreten wird, halte ich für keine gute Strategie.
Das ist eine Wahrscheinlichkeit die gegen Null tendiert. Wieso sollte ich mir über sowas sorgen machen? Genauso ist ein Forum überlastet wenn alle genau im selben Moment abschicken drücken... Auch das ist verdammt unwahrscheinlich.
Eventhandler oder Demon sind meines Wissens Dinge, die es in PHP nicht gibt.
Hab mich lange und breit damit auseinander gesetzt und weis genau wo es Probleme gibt. Einmal macht man Updates bei Bedarf und ein ander Mal müssen sie pünktlich und nur einmal passieren. Das alte UGamela hatte bei längerem und zu schnellem (Spielgeschwindigkeitsfaktor) Spiel immer wieder Flottenverdoppelungen. Ein Daemon lässt sich in PHP nicht in seiner Standardausführung schreiben, nein, aber man kann etwas ähnliches schreiben.
Und dies macht den Ansatz ineffizient. Zugriff auf den Hauptspeicher eines System ist mindestens eine Größenordnung schneller und wäre daher eine Alternative.
Schön. Das benötige ich dann für ein Spiel einer anderen Größenordnung. Momentan geht es darum aus einem Webspace so viel rauszuholen wie möglich. Ein vServer soll später für ein solches Spiel vollkommen ausreichen. Da arbeite ich mit dem was mir zur Verfügung steht: PHP+Datenbank.
Ich habe mich ja gerade erst dazu entscheiden einen Schritt weiter zu gehen und Python dazu heran zu ziehen, weil es weit besser als PHP geeignet ist und etliche weitere Vorteile bietet. Ich weiß jetzt nicht wie weit ich mit einem einfachen Python Webserver auf den Hauptspeicher zugreifen kann, aber das wäre natürlich in Erwägung zu ziehen. Andererseits finde ich es unnötig Flotten die erst in zwei Tagen ankommen permanent im Hauptspeicher zu lassen.
Bündnisse im Kampf sind aufwendig.
Ja, so wie du sie beschreibst... So schwer ist das aber eig. gar nicht:
Flotten können mit Erlaubnis auf einem Planeten halten. Wenn der Planet angegriffen wird kämpfen sie mit, auf der Seite des Planeten. Zum Angriff kann man sich auch zusammenschließen.
Fragwürdig finde ich, dass du (so habe ich das verstanden) sagt, dass du bei Dingen, die sich wahrscheinlich nicht zum selben Zeitpunkt ändern, keine Transaktionen brauchst. Es ist IMHO nicht maßgeblich, ob sich etwas selten oder häufig ändert. Wenn auch nur die kleinste Chance für einen Konflikt existiert, muss man ACI-Transaktionen benutzen. Angenommen, ein Spieler kennt die Zahl der Rohstoffe, die er verbauen kann. Dieses Attribut ist zwar privat für jeden Spieler, aber dieser eine Spieler kann ja (mit mehreren Browsern oder Programmen) mehrere Befehle quasi parallel abschicken und somit auszunutzen versuchen, dass es hier Racing-Conditions geben könnte, je nachdem wie das genau implementiert ist.
Wie bereits gesagt, ich habe das im Blick. Dein Beispiel funktioniert zum Beispiel nicht, weil die Gebäude automatisch in eine Warteliste gelangen bevor sie dann wirklich gebaut werden und natürlich braucht man dabei Transaktionen. Ich rede von Nachrichtensystem oder persöhnlichen Einstellungen oder angebundenen Foren, die recht unabhängig vom eigentlichen Spielgeschehen sind. Bei dieser "Userverwaltung" brauche ich keine Transaktionen und werde auf ein normales ORM zurückgreifen.
[url]http://ugamela-blog.pheelgood.net[/url]
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Okay, mein Beispiel mit den 5000 Spielern ist in der Tat unrealistisch. Dennoch bleibt bei einer strikten Einteilung des Spiels in sehr kurze Runde das Problem, dass man nur wenig Zeit hat und somit zusehen muss, dass nicht zu viele Aktionen in einer Runde stattfinden. Du schreibst ja selbst, es ich wichtig, dass alles pünktlich stattfindet.
ch weiß jetzt nicht wie weit ich mit einem einfachen Python Webserver auf den Hauptspeicher zugreifen kann, aber das wäre natürlich in Erwägung zu ziehen. Andererseits finde ich es unnötig Flotten die erst in zwei Tagen ankommen permanent im Hauptspeicher zu lassen.
"Auf den Hauptspeicher zugreifen" führt in die Irre. Es geht darum, ihn zu nutzen. Der fundamentale Unterschied ist, wie das Programm aufgerufen wird bzw. wie es abläuft. Für einem 2,50€-Mietserver spielen diese Überlegungen eh keine Rolle, aber wenn du einen eigenen dedizierten Server hättest, in dem einige GB RAM stecken, dann kannst du ganz anders vorgehen. Das Stichwort im Java-Umfeld heißt hier Application Server, aber ich denke, wird sind hier in unterschiedlichen Welten zuhause.
Ja, so wie du sie beschreibst... So schwer ist das aber eig. gar nicht:
Natürlich kannst du einen Kompromiss mit den Spielregeln machen. Ich hätte schon gerne die Möglichkeit, dass ein Spieler ein unabhängiger Beobachter auf einem Planeten sein kann oder aber das ein Verbündeter plötzlich die Seiten wechselt. Vielleicht bin ich dabei aber immer noch zu sehr in der Welt der Brett- oder Postspiele verwurzelt, wo es mehr um Diplomatie denn um tatsächliches Kräftemessen gehen sollte.

Noch was zu deinem Blog-Artikel: Python gibt es seit 20 Jahren und deutlich länger als PHP. Selbst Ruby ist älter und bei Java würde ich's auch noch sagen, wenn PHP 3.0 (1997) als die Version, die wir heute noch kennen, zugrunde legt (Java erschien 1995). Ich würde Python daher schon zu den alteingesessenen Sprachen zählen. Allgemein leidet die Glaubwürdigkeit eines Artikels, wenn einfach überprüfbare Fakten am Anfang eines Artikel schon fargwürdig sind.

Ob ein Browsergame wirklich mit nichts im Web vergleichbar ist, ist für mich noch nicht bewiesen. Ich halte es nicht für so anders. Anfragen werden verarbeitet, Webseiten dargestellt. Das man diese Dinger nicht häufiger sieht, liegt IMHO eher daran, dass es schwer ist, sich entsprechende Regeln auszudenken. Außerdem scheint es eine Subkultur zu sein, die ich zum Teil irritierend primitiv finde (wenn ich einmal von der Sprache und Art der die Beiträge in deinem Forum urteilen darf). Eigentlich schade.

Ich würde übrigens nicht mit der Performance (so weit sie die Ausführung der Programme angeht) argumentieren. Diese ist egal. Das führt nur zu unschönen Streitereien um Nichtigkeiten. Dich wird die Datenbank und die Auslieferung der Webseiten über das Netz begrenzen, nicht wie schnell jetzt Python oder PHP rechnen können.

Ich finde übrigens interessant, wie konservativ und wenig dem neuen aufgeschlossen die Teilnehmer im Forum sind. Da weht ein kalter Wind, was Python angeht ;) Ich hoffe, du bleibst trotzdem am Ball.

Stefan
Benutzeravatar
Phlegma
User
Beiträge: 20
Registriert: Samstag 24. Januar 2009, 12:05

Mh, ich hätte auch sehr gerne ein komplexes Kampf-/Bündnissystem, aber das kann ich mir momentan nicht leisten. Zur Zeit versuche ich einen guten Grundaufbau hinzubekommen, die Feinheiten kommen später. Ich hoffe auch später auf andere Entwickler, die mit meinem Grundgerüst ein paar Ideen umsetzten wollen. Mal sehen wie sich das entwickeln wird...

Die Fehler über Python sind natürlich reine Dummheit. Ich hätte das umbedingt nachsehen müssen. Vielen Dank für den Hinweis!

Aber wie kommt es dann, dass PHP soviel verbreiteter ist?
[url]http://ugamela-blog.pheelgood.net[/url]
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Mh, ich hätte auch sehr gerne ein komplexes Kampf-/Bündnissystem, aber das kann ich mir momentan nicht leisten
Warum kannst du dir das nicht leisten? Mache einfach die Runden länger. Kämpfe finden dann nur alle 15 Minuten statt. Oder mache das Spiel kleiner. Wenn du nur 100 Spieler hast (was ich ja auch schon viel finde) die z.B. 1.000 Planeten verwalten und insgesamt 10.000 Raumschiffe haben, wird's doch schon viel entspannter.

Meine Vorstellung (vom dem Brettspiel Twilight Imperium kommend) wäre, Raumsektoren zu haben, um deren Vormachtstellung man kämpfen kann. Ein Raumsektor kann mehrere Planeten enthalten, Ich würde dabei versuchen, so viele Spieler wie möglich interagieren zu lassen, d.h. mehrere Spieler pro Planet und Raumsektor zu erlauben. Denn meist ist eine Kooperation schwieriger und interessanter als einfach nur ein Vernichtungskampf.

Pro Sektor gibt es dann Flottenbefehle, z.B. Neuankömmlinge anzugreifen. Ausnahmen müssten möglich sein, um etwa einem eigentlich verfeindeten Spieler den Durchflug zu ermöglichen. Angenommen, ich habe im Schnitt 4 Planeten pro Sektor, dann habe ich 250 Sektoren und somit 250 mögliche Kämpfe pro Runde.

Eine andere Alternative wäre, einfach nur 3 aktive Flotten pro Spieler zu erlauben. Dann kann es maximal zu 300 Kämpfen pro Runde kommen. Da man sich aber wahrscheinlich nicht nur gegenseitig überfallen will, sondern gegeneinander kämpft, werden sich die Flotten ballen und es sind noch weniger.
Aber wie kommt es dann, dass PHP soviel verbreiteter ist?
Das ist denke ich der Eigenschaft von PHP zu verdanken, relativ einfach und unkompliziert als Apache-Modul in einem Sharedhosting-Umfeld einsetzbar zu sein. Außerdem hat die Sprache den Ruf, recht einfach zu sein und so wie JavaScript schafft sich da jeder so ein bisschen Knowhow drauf.

Stefan
Benutzeravatar
Phlegma
User
Beiträge: 20
Registriert: Samstag 24. Januar 2009, 12:05

sma, sorry, bin jetzt nicht weiter auf dich eingegangen, weil ich das Gefühl hatte, dass wir fertig waren und sowieso etwas aneinander vorbei reden, weil wir versch. Ideen von Browsergames haben.

Ich komm hier nochmal zum Anfangspost zurück, weil ich eben einen Eintrag zu Applicationservern in einem Browsergamesforum gelesen habe. Dort wird C# und Java angepriesen, aber mit Zope gibt es ja auch einen in Python. Wie gut eignet dieser sich für
1. Ajaxtortur von vielen kleinen Anfragen
2. einen Daemon, der ständig eine Datenbank nach eintretenden Events fragt

?
[url]http://ugamela-blog.pheelgood.net[/url]
Antworten