Nov 19 2008

ORM (object relational mapping – objektrelationale Abbildung)

Tag: Allgemein,EntwicklungPhoscur @ 12:00

ORM wird größtenteils den Kern meines Frameworks darstellen.

Nur, was ist ORM? [Ich meine hier übrigens nicht Objekt Role Modeling, das auch ORM abgekürzt wird]

Ich muss vorwarnen, das wird jetzt wahrscheinlich für den Großteil der Blogleser unverständlich. Es gehört wohl zu den Tiefen des Programmierens, neben den Entwurfsmuster. Oft wird hier mit Fremdwörtern nur so um sich geschmissen. Ich habe immernoch so meine Probleme, so lange mache ich das ja noch nicht. Ich werde mich trotzdem bemühen es einfach auszudrücken.

Relationale Datenbanken, wie MySQL, legen Daten in Tabellen ab. OOP arbeitet aber mit Objektinstanzen. ORM soll nun das Zwischenstück bilden, das die Objekte in der Datenbank abbildet. Ich möchte mittlerweile nurnoch mit Objekten arbeiten, es vereinfacht das Programmieren ungemein. Ich möchte vor allem Spielelemente wie Flotten als Objekte verwalten, um besser Interaktionen zu überblicken. Doch bevor man sich bei jedem Objekt mit dem Speichern in der Datenbank herumschlagen muss, möchte ich das lieber in verschiedenen (Abstraktions-)Schichten verstecken. Für die „Community-Entwickler“, die hoffentlich nach Fertigstellung des Frameworks tatkräftig mithelfen ein Spiel zustande zu bringen, bedeutet dies, dass ein Haufen Arbeit wegfällt. Dafür müssen sie sich halt mit (relativ einfachen) Klassen herumschlagen, was sie vielleicht von PHP noch nicht gewöhnt sind.

Ganz nebenbei wird dann übrigens gecacht und Race Conditions umschifft, ohne dass man etwas davon mitbekommt. OOP hat den großen Vorteil, dass man anderen Code nicht kennen muss, man muss nur wissen was er tut, und dafür gibt es die Dokumentation.


Okt 11 2008

Phlame Engine: Weitere Überarbeitungen, Module

Tag: EntwicklungPhoscur @ 19:01

Die Phlame Engine wird natürlich weiterentwickelt, auch wenn ich dieser Tage besonders wenig Zeit habe, diese Woche schreibe ich zB zwei Arbeiten und zwei Tests in der Schule, da bleibt nicht viel Zeit für Programmieren.

Ich muss das Schema, das ich aufgestellt hatte, revidieren. Das Datahandler verliert eine seiner Rollen, das Erstellen der Models. Diese werden direkt in den Requestern gebildet um ein paar Schleifen zu sparen, und haben dadurch auch eine Bindung zu diesen, die ich nicht Cachen möchte, da die Requester eigentlich eine Erweiterung der Datenbankverwaltung darstellen, welche eine Resource ist (Resourcen kann man nicht serialisieren/cachen).

Ich habe kürzlich ein neues Forum entdeckt, das mir gefällt: http://www.galaxy-news.de

Dort habe ich ein paar ähnlich gesinnte Entwickler gefunden. Hier die erste teils „geklaute“ Idee:

Die Models erhalten Module, die entweder selbst Models (zB im Falle einer Flotte Schiffe) oder eben bestimmte Module, mehr dazu gleich.

Ich habe überlegt den Techtree in Models abzubilden, dadurch hätte man optimale Möglichkeiten an den einzelnen Einheiten herumzubasteln. Für Basisfähigkeiten oder oft Genutztes kann man in Module, wie oben beschrieben verpacken. Für die Basisfähigkeiten gibt es zudem noch eine (abstrakte) Basisklasse (zB Ship) die bestimmte Fähigkeiten bereits vorgibt oder vorraussetzt. Der Vorteil an den Modulen wäre allerdings auch noch, dass man sie vllt sogar über ein grafisches Interface im Adminbereich in bestimmte Einheiten einbauen könnte. Diese Module wären tatsächlich auch von außen modular, das heißt man könnte die Dateien einfach auch (de)installieren.

Die Idee ist gerade im Anfangsstadium, kann gut sein, dass ich dies die Tage nochmal umdenke und editiere.


Sep 26 2008

Phlame Engine: Der Entwurf (Nr.2)

Tag: EntwicklungPhoscur @ 18:48

Der DataHandler

Mich hatte schon vor dem Sommer der Gedanke interessiert die Daten innerhalb von Models(Dartstellung realer Objekte) zu verwalten. Eine Flotte oder ein Planet würde als ein entsprechendes Objekt dargestellt werden. PHP ist keine reine OOP Sprache und ich habe OOP selbst erst seit April/Mai gelernt, daher fiel mir das nicht besonders leicht.

Ich habe versucht den Artikel verständlich zu halten, setze aber ab jetzt einige Kenntnisse für das Verständnis voraus (PHP, OOP und BG Projekte). Wen das trotzdem interessiert, der muss Wissenslücken schließen. Ich kann Google empfehlen ;D

Im Mittelpunkt stand meikels Idee des Cores der alles wichtige erledigt, doch das erweist sich für mich als nicht die richtige Lösung, da man nicht immer DB, Sessions, Authentification braucht. Genau genommen braucht man Auth nur einmal, beim Login. Auth basiert auf den Sessions, aber die Sessions sind unabhängig von der Datenbank. Daher ist eine Vererbung unsinnig, selbst wenn alle einen Singleton verwenden. Core (die letzte der 4 Klassen) hatte ich dazu missbraucht irgendwelche Funktionen zu lagern, die eigentlich komplett unabhängig wären (zB die Umformatierung von Arrays in einem bestimmten Stil).

Dazu kamen Models, die jeweils selbst ihre Datenbankeinträge kontrollierten, indem sie alle von einer bestimmten Klasse abgeleitet wurden. Das Problem war die Ineffizienz. Teils wollte ich einfach mehrere Flotten mit einem Query aus der Datenbank holen.

Überblick DataHandler

Daher habe ich etwas neues mit einem zentralen DataHandler entworfen, der es erlaubt mehrere Flotten (oder ähnliches) gleichzeitig zu laden. Ich habe das Prinzip nirgendwo aus dem Internet abgeschrieben, aber natürlich kann es sein, dass das schonmal jemand erfunden hat…

Ich hoffe nun, dass sich keine weiteren Probleme auftun und arbeite daran das Konzept umzusetzten. Einiger Code des vorigen Konzepts lässt sich zum Glück wiederverwerten [Ich hatte das recht weit entwickelt..]!

Momentan hänge ich an einer kleinen Entscheidung: Der Datahandler verwaltet die DatenArrays und erstellt Zugriffsobjekte (Flotten, Schiffe, Planeten, etc.). Sollten die Zugriffsobjekte (aka Models) mit Referenzen auf die Arrays im DataHandler enthalten oder lieber Kopien und diese bei Zerstörung (spät. bei Scriptende) zurückgeben?

Ich mag Referenzen nicht, aber ich denke ich werde sie verwenden um zu verhindern, dass es Überschreibungen gibt, wenn man zweimal das selbe Objekt aus dem Datahandler holt, sonst müsste dieser die ausgegeben Objekte speichern… Nein das wird mir zu komplex und sonst nur fehleranfällig.

Meinungen?


Sep 21 2008

Browsergame Eventhandler

Tag: Allgemein,EntwicklungPhoscur @ 22:22

Das Thema ist wohl bekannt und wurde, wie man über Google merkt, oft diskutiert. Ich berufe mich deshalb nicht nur auf meine Erfahrung, sondern möchte auch darauf hinweisen, dass man bei Google Ähnliches findet.

Das große Problem:

Bei einem Browsergame wie UGamela läuft die Zeit weiter, wenn der User sich abmeldet. Dem Server ist es sowieso egal, ob der User gerade eine Page liest, es kommt immer nur auf die Momente an, zu denen jemand klickt und Daten nachgeladen werden.

Annäherung:
Das Naheliegendste ist es zu denken, dass die Daten immer aktuell gehalten werden, dann wäre ja alles klar. Aber das ist mit einfachen PHP Scripten nicht möglich und wäre auch arg ressourcenverschwenderisch.

Lösungsvorschläge:
Die Erste und wohl beste Methode wäre es, aus komplexeren Problemen, wie den Flotten, Events, kleine Jobs für einen Daemon, zu machen. Daemon bedeutet ein Script, fast eigenständiges Programm, das permanent läuft und Ereignisse dann abarbeitet wenn sie Geschehen. Diese Möglichkeit wäre eindeutig einfacher, wobei man nurnoch auf sehr seltene Überscheidungen achten müsste (zwei Events zum gleichen Zeitpunkt mit überschneidenden betroffenen Objekten), aber selbst das wäre kein Problem, das es ja nur eine Daemon Instanz gibt, also keine Race Conditions.

Ein solcher Daemon müsste tiefer im System sitzen als ein kleiner PHP Script im Apache Server und sollte nach Möglichkeit in einer schnelleren Programmiersprache als PHP geschrieben sein ( C(/#/++), Java ). Daher ist dafür in jedem Fall mehr als ein einfacher Webspace nötig. [OGame hat nach eigenen Angaben ein C oder C++ basiertes Script und extra Server nur für die Kampfberechnung.]

Damit möchte ich mich nicht zufrieden geben. Früher habe ich UGamela gerne mit phpBB verglichen, aber so einfach ist das dann doch nicht. In einem Forum passiert nichts wenn es nicht ein User direkt tut… Trotzdem will ich den Spagat schaffen, dass das Spiel auch auf einem einfachen Webspace läuft.

Hier mein Ansatz:
Eine Berechnung wird erst dann nötig, wenn die Daten benötigt werden, aber dann muss gründlich berechnet werden. Um die Rohstoffe korrekt zu berechnen habe ich MySQL Prozeduren geschrieben, die das erledigen bevor der Apache überhaupt was von den Daten zu Gesicht bekommt. Bei den Flotten will ich auch nur die berechnen, die gerade relevant sind. Aber ich will keinem user Wartezeiten zur Kampfberechnung aufbürden. Der Einzige, der nicht meckert – außer möglicherweise dem Apachen selber – wenn der Script zu lange braucht und selbst auf einem Webspace zur Verfügung steht, ist der Cronjob. Allerdings höchstens alle zwei Minuten. Nun können wir uns ärgern, dass wir dann die Kämpfe nicht zum richtigen Zeitpunkt berechnen lassen können oder wir schieben die Kämpfe in dieses zwei Minuten Raster. Dann findet der Kampf halt nicht sofort statt wenn die Flotte ankommt, sondern „läuft“ während einer gewissen Zeit, zum Beispiel könnte man eine Runde alle zwei Minuten ausrechnen, der User könnte dies „live“ mitverfolgen und sogar seine Flotte während des Kampfes zurückziehen. Auf jeden Fall ist dies um einiges realistischer als der 10-Sekunden Kampf…

Die meisten anderen Events werden ähnlich wie die Rohstoffberechnung von MySQL Prozeduren abgearbeitet. Nun sorge ich mich langsam nicht mehr um meinen Apachen sondern um meinen MySQL Server… Überlast? .. Ich bin mir da noch nicht sicher, aber ich werde auf jeden Fall mit einem Sessionmanagement aushelfen, teils werden wir gar keine Queries oder Prozeduraufrufe brauchen, hoffe ich.

Ich bitte hier nur die Leute, die wirklich etwas davon verstehen zu posten, ansonsten garantiere ich nicht dafür, dass ich die Kommentare stehen lasse.


Sep 17 2008

OOP (Objekt orientierte Programmierung) PHP

Tag: EntwicklungPhoscur @ 14:03

Seit PHP4 ist es möglich PHP OO zu programmieren. Mit PHP5 wurde das stark ausgebaut, aber bisher habe ich noch kein OS (Open Source) Projekt gesehn, in dem das wirklich verwendet wird, dabei ist das doch nun schon älter… PHP geht schon in Richtung PHP6…

Ich habe mich sofort für OOP begeistern können, als ich es kennenlernte, auch wenn mir das nicht leichter fällt als prozedural (das ist der andere PHP Stil den quasi alle praktizieren) zu programmieren.

Yeah, PHP OOP ist supertoll, das muss ich ab jetzt umbedingt immer verwenden!
→ Nein! Man muss eindeutig abwiegen, ob man etwas OO programmiert, den bei PHP geht dabei Performance verloren, denn das kompliieren dauert länger.

Zum Preis von einem bischen Performance bekommt man dafür:

  • Übersichtlichkeit / Lesbarkeit
  • Darstellung von abstrakten und realen Dingen
  • Erweiterbarkeit
  • Wiederverwendbarkeit
  • Kapselung
  • und somit Effizienz

Und diese Liste ist noch lang nicht vollständig.

Das hat mich letztlich überzeugt. Ich bin dabei das Herzstück („Phlame Engine“) für UGamela in OOP zu schreiben. Dabei werde ich zum Beispiel Planeten und Flotten in Models abbilden. Das Ergebnis gibt den Moddern, die hoffentlich angespornt sind und viele Ideen haben, einfache Möglichkeiten mit den Daten umzugehen, wahrscheinlich ohne selbst Ahnung von MySQL oder Sessions zu haben.

Ihr könnt ich somit schon auf die PHP OOP Pfeilchen „->“ freuen xD


Sep 15 2008

Race Conditions, ein BG Problem (Flottenverdoppelung)

Tag: EntwicklungPhoscur @ 18:43

Ich werde nun nicht nochmal selbst Race Conditions erklären, wenn das schon sehr gut auf Wikipedia beschrieben ist. Link

Bei einem PHP Apache Server agieren ständig mehrere Threads, Scripte oder System (wie auch immer man sie nennen will) gleichzeitig. Jedes Mal wenn ein User einen Script aufruft (quasi immer wenn er irgendwo draufdrückt), wird ein neuer Thread für ihn gebildet, dieser läuft parallel zu den anderen.

Ein BG (Browsergame) wie UGamela hat – wie Viele gar nicht wissen – eine komplexe Spiellogik im Inneren, welche bei bisherigen Versionen nur hingemurkst wurde. Beispiel siehe Fusionskraftwerkbug.

Ein weiteres Problem stellt die insgesamt schlechte Programmierung und somit unnötig und zu lange Berechnungszeit der Scripte dar, je länger der zeitliche Abstand zwischen dem SQL Select Befehl und dem SQL Update Befehl, desto höher die Wahrscheinlichkeit, dass es zu einem Race Condition bedingten Fehler kommt.

Häufigster bekannter Fehler dieser Art ist das Problem der Flottenverdoppelung!

Problemlösung ist in diesem Fall wirklich nicht so einfach, vor allem wenn man nicht noch längere Berechnungszeiten und somit irgendwann Wartezeiten für die User riskieren will.

MySQL stellt dafür einen Befehl bereit, der eine ganze Tabelle sperrt („LOCK TABLE `xx`“) – anstehende Queries warten. Für die ganze Tabelle!! Dh letztendlich für alle Threads, dabei ist gar nicht klar, ob sich die Queries überhaupt überschneiden. Bei größeren Userzahlen gleichzeitig wird das dann wirklich spaßig, wenn die Wartezeiten immer länger werden.

Interessanter wäre es doch die einzelnen Einträge zu Sperren. Doch dies ist mit einigem Aufwand verbunden, weil ich aus Performancegründen benötigte Daten in einem Rutsch laden will (zB die Planeten des Spielers gleichzeitig). Dennoch soll es tief im Grundgerüst verankert werden, sodass letztlich der Modder keine Ahnung davon haben muss. Er schreibt höchstens sein spezielles „WHERE“ im SQL Select Befehl.

Hier ein kleiner Einblick: Weiterlesen „Race Conditions, ein BG Problem (Flottenverdoppelung)“


Sep 07 2008

Spiellogik: Koordinatensystem (Update)

Tag: Allgemein,EntwicklungPhoscur @ 18:23

Linear sollte es nicht sein (OGame)..

Zuerst wollte ich ein dreidimensionales System aufbauen, welches von der Berechnung nicht ultimativ schwerer gewesen wäre, aber eindeutig unübersichtlicher und unhandlicher bzw schwierig darzustellen wäre.

Die Wahl fällt so auf ein zweidimensionales System, welches man auch in einem Bild darstellen könnte.

Weiterlesen „Spiellogik: Koordinatensystem (Update)“


Sep 02 2008

Phlame Engine: Flottengeschwindigkeit, Treibstoff, Bauteile

Tag: EntwicklungPhoscur @ 14:47

Sehn wir uns das mal bei OGame an:
Jedes Schiff hat eine bestimmte Geschwindigkeit, die je nach verwendeter Antriebstechnologie noch verbessert werden kann. Um das Problem der Unrealistik mit einem Verbrennungstriebwerk von einer Galaxie zur anderen zu fliegen kümmere ich mich noch. Doch, dass der Treibstoff bei Flottenstart einfach komplett verpufft finde ich doch sehr seltsam.

Auch wenn dies einige Rechenarbeit ersparen würde, möchte ich das ändern. Zudem finde ich man sollte Geschwindigkeiten etwas variabler machen. Weiterlesen „Phlame Engine: Flottengeschwindigkeit, Treibstoff, Bauteile“


Aug 30 2008

Phlame Engine: Ressourcenberechnung (Fusionskraftwerkproblem/Endliche Rohstoffe) & Bauliste mit Wartefunktion

Tag: EntwicklungPhoscur @ 15:36

Ich arbeite schon den ganzen Sommer an der Ressourcenberechnung und gerade zur Zeit an einer Bauliste und dem Eventhandler (Das sind die drei Ebenen der Planetenaktualisierung, die bei jedem Klick geschehen. Daher müssen sie auch besonders performant sein).

Mich wundert das noch niemand den Fusionskraftwerkbug bemerkt und ernst genommen hat. Er bedingt einige Funktionalitäten auf die ich nicht verzichten möchte:

Gebäude mit starkem „Resourcendrain“ (hoher Verbrauch, höher als die Produktion ist) oder eine sehr knappe Ressource die von bestimmten Gebäuden verbraucht wird. Weiterlesen „Phlame Engine: Ressourcenberechnung (Fusionskraftwerkproblem/Endliche Rohstoffe) & Bauliste mit Wartefunktion“


Aug 26 2008

Phlame Engine: UGamela Tabellenumstrukturierung & KS

Tag: EntwicklungPhoscur @ 17:51

Da bei OGame und somit UGamela jedes Schiff eines bestimmten Typs die selbe Angriffskraft hat, reichte es Flotten und Planeten mit Gebäuden in einzelnen Zeilen darzustellen, in denen jeder Typ ein Feld besitzt. Da dies unpraktikabel für Erweiterungen und vor allem für besondere Schiffe ist, werden Flotten und Planeten nun als Blöcke (mehrzeilige Tabelleneinträge) dargestellt. Dies hat zum Vorteil, dass beim hinzufügen eines neuen Schiffes kein ALTER TABLE mehr ausgeführt werden muss. Zudem bekommt jedes Schiff in der Flotte spezielle Angriffs-, Verteidigungs- und Lebenswerte. Für mein Kampfsystem kommt noch ein spezieller Kampftyp dazu, der die Berechnung der Kämpfe zuerst zwischen kleinen und großen Schiffen unterteilt (Die Jäger tragen untereinander erstmal ihre eigene Schlacht aus). Zudem basiert der Kampf auf der Summenbildung des Schadens, welche einfach per MySQL SUM(`damage`*`count`)  erledigt werden kann. Im Kampf werden erst die größten Schiffe zerballert, da sie das größte Ziel bieten.

Resultierend aus dieser Umstrukturierung wird es auch möglich sein dem Spieler eine individuelle Schiffgestaltung zu überlassen. Dh. man könnte es beispielsweise ermöglichen bestimmte Waffen einzubauen. Dies ist vorerst allerdings nur Zukunftsmusik, ich kümmere mich vorerst nur um serverinterne Angelegenheiten und um Performance & Erweiterbarkeit. Das Interface könnten danach auch ein paar Helferlein schreiben können, die nichtmal so viel davon verstehen müssten.

Leider ist mir heute bei einem Windoof Absturz mein SQL Ressourcen- und Eventhandlerscript abhanden gekommen, einen Großteil hatte ich mir zum Glück ausgedruckt, aber die Bauliste muss ich wohl neuschreiben, zudem muss ich einiges abtippen. Das kostet mich Zeit und regt mich auf, aber das wird schon.

PS: Morgen werde ich 18 😀


« Vorige Seite