Seite 1 von 3

Verfasst: Montag 26. Januar 2009, 21:05
von veers
Phlegma hat geschrieben:Mir missfällt an den ORM-Frameworks, das was eigentlich gefallen sollte. Ich gebe die Macht über die Datenbank an ein bestimmtes Konstrukt, das mir aus Einträgen Objekte mit Beziehungen erstellt. Entweder ich habe es einfach noch nicht verstanden, oder ich möchte meine Queries einfach spezieller formulieren. Dann erscheint mir das ORM allerdings als Bremse.
Seh dir SQLAlchemy an ;)

Verfasst: Montag 26. Januar 2009, 22:14
von Phlegma
Hab jetzt nicht die besonderen Unterschiede zu anderen ORM Mappern finden können. Ich habe weiterhin das Gefühl, dass diese ORM Frameworks einen Overhead prodizieren, den ich gar nicht brauche. Ich werde mich natürlich weiterhin mit dem Thema beschäftigen und rausfinden was das Beste für mein Spiel (übrigens dann AGPL) und mich ist.

Ich hoffe immer noch auf ein paar Meinungen welches Framework (wenn überhaupt) passen würde. Es darf auch gerne kompliziert sein wenn es performant ist.

Verfasst: Dienstag 27. Januar 2009, 09:42
von Leonidas
Phlegma hat geschrieben:Hab jetzt nicht die besonderen Unterschiede zu anderen ORM Mappern finden können.
DataMapper statt ActiveRecord und wie gesagt, das ORM ist optional. Man kann den ORM-Layer weglassen und ich kenne durchaus jemanden der das auch so macht.

Ich habe hier eine Erklärung, warum SQLAlchemy auch ohne das ORM sinnvoll ist.

Verfasst: Dienstag 27. Januar 2009, 11:20
von veers
Leonidas hat geschrieben:
Phlegma hat geschrieben:Hab jetzt nicht die besonderen Unterschiede zu anderen ORM Mappern finden können.
DataMapper statt ActiveRecord und wie gesagt, das ORM ist optional. Man kann den ORM-Layer weglassen und ich kenne durchaus jemanden der das auch so macht.

Ich habe hier eine Erklärung, warum SQLAlchemy auch ohne das ORM sinnvoll ist.
Als ich die URL gesehen habe war mir sofort klar das es sich um einem Vortrag von __doc__ handeln muss *g*

Verfasst: Dienstag 27. Januar 2009, 14:06
von Phlegma
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.

Verfasst: Dienstag 27. Januar 2009, 15:39
von veers
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

Verfasst: Mittwoch 28. Januar 2009, 11:23
von sma
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

Verfasst: Mittwoch 28. Januar 2009, 13:15
von gerold
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
:-)

Verfasst: Mittwoch 28. Januar 2009, 13:59
von Phlegma
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.

Verfasst: Mittwoch 28. Januar 2009, 18:13
von veers
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

Verfasst: Mittwoch 28. Januar 2009, 18:20
von Phlegma
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...

Verfasst: Mittwoch 28. Januar 2009, 19:47
von veers
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:

Verfasst: Sonntag 1. Februar 2009, 18:58
von sma
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

Verfasst: Sonntag 1. Februar 2009, 20:17
von Phlegma
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.

Verfasst: Freitag 6. Februar 2009, 11:56
von Phlegma
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?

Verfasst: Freitag 6. Februar 2009, 13:33
von veers
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

Verfasst: Freitag 6. Februar 2009, 13:36
von Phlegma
Gut.

Vielen Dank an alle!!

Ihr hört von mir sobald ich wirklich was rausbringe, kann aber in Python noch gut ein Jahr dauern.

Verfasst: Samstag 7. Februar 2009, 13:01
von sma
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

Verfasst: Samstag 7. Februar 2009, 13:36
von Phlegma
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.

Verfasst: Sonntag 8. Februar 2009, 12:00
von sma
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