<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Zeitalter3 - Browsergames Entwicklerblog &#187; Patterns</title>
	<atom:link href="http://blog.zeitalter3.de/tag/patterns/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.zeitalter3.de</link>
	<description>Ein Blog über persistente Browsergames und deren Entstehung</description>
	<lastBuildDate>Fri, 20 Jan 2012 12:23:56 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Mehr Entitysysteme</title>
		<link>http://blog.zeitalter3.de/2010/05/10/mehr-entitysysteme/</link>
		<comments>http://blog.zeitalter3.de/2010/05/10/mehr-entitysysteme/#comments</comments>
		<pubDate>Mon, 10 May 2010 05:08:32 +0000</pubDate>
		<dc:creator>Dirk</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Entity Systeme]]></category>
		<category><![CDATA[Patterns]]></category>

		<guid isPermaLink="false">http://blog.zeitalter3.de/?p=816</guid>
		<description><![CDATA[Adam hat in seinem Blog eine Implementation eines kompletten Entitysystems in Java vorgestellt. Genug gesagt.]]></description>
			<content:encoded><![CDATA[<p><a href="http://t-machine.org" target="_blank">Adam</a> hat in seinem Blog eine Implementation eines <a href="http://t-machine.org/index.php/2010/05/09/entity-system-1-javaandroid/" target="_blank">kompletten Entitysystems</a> in Java vorgestellt. Genug gesagt.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zeitalter3.de/2010/05/10/mehr-entitysysteme/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Mehr komponentenbasierte Systeme</title>
		<link>http://blog.zeitalter3.de/2010/04/26/mehr-komponentenbasierte-systeme/</link>
		<comments>http://blog.zeitalter3.de/2010/04/26/mehr-komponentenbasierte-systeme/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 21:42:06 +0000</pubDate>
		<dc:creator>Dirk</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Entity Systeme]]></category>
		<category><![CDATA[Literatur]]></category>
		<category><![CDATA[Patterns]]></category>

		<guid isPermaLink="false">http://blog.zeitalter3.de/?p=808</guid>
		<description><![CDATA[In der aktuellen Printausgabe des Making Games Magazin ist ein Artikel von Thorsten Lange (seinerseits Technischer Leiter bei Deck13) über komponentenbasierte Systeme (bzw. Entity-Systeme). Da meine Artikel zu dem Thema bei euch gut ankamen könnte dieser für euch ebenfalls interessant sein. Der Artikel geht über vier Seiten und beginnt mit den Problemen einer klassenbasierten Hierarchie bei [...]]]></description>
			<content:encoded><![CDATA[<p>In der aktuellen Printausgabe des <a href="http://www.makinggames.de/index.php/magazin" target="_blank">Making Games Magazin</a> ist ein Artikel von <a href="https://www.xing.com/profile/Thorsten_Lange11" target="_blank">Thorsten Lange</a> (seinerseits Technischer Leiter bei <a href="http://deck13.com/" target="_blank">Deck13</a>) über komponentenbasierte Systeme (bzw. Entity-Systeme). Da <a href="http://blog.zeitalter3.de/2010/02/13/das-gamesystem-modul/" target="_self">meine</a> <a href="http://blog.zeitalter3.de/2010/02/16/datenhaltung-mit-gamedata-class-php/" target="_self">Artikel</a> zu dem Thema bei euch gut ankamen könnte dieser für euch ebenfalls interessant sein.</p>
<p>Der Artikel geht über vier Seiten und beginnt mit den Problemen einer klassenbasierten Hierarchie bei Objekten mit komplexen Eigenschaften. Als Lösung beschreibt er ein Komponentensystem, welches die Eigenschaften eines Objekts definiert. Das System setzt die Objekte aus den Komponenten zusammen, die Logik steckt dabei allerdings, im Gegensatz zu meiner Implementation, in den Komponenten selbst. Es gibt einige Beispiele in Pseudo-Code (welche die Objekt-Initialisierung zeigen) und er spricht kurz über einen Property-Editor und dessen Anbindung.</p>
<p>Alles in allem kein sehr tiefgehender Artikel, aber mehr über andere Ansätze und Implementationen zu lesen ist immer gut. Kurz: Lese-Empfehlung.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zeitalter3.de/2010/04/26/mehr-komponentenbasierte-systeme/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Datenhaltung mit gamedata.class.php</title>
		<link>http://blog.zeitalter3.de/2010/02/16/datenhaltung-mit-gamedata-class-php/</link>
		<comments>http://blog.zeitalter3.de/2010/02/16/datenhaltung-mit-gamedata-class-php/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 17:49:34 +0000</pubDate>
		<dc:creator>Dirk</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Zeitgeist-Framework]]></category>
		<category><![CDATA[Entity Systeme]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Zeitgeist]]></category>

		<guid isPermaLink="false">http://blog.zeitalter3.de/?p=740</guid>
		<description><![CDATA[In meinem Artikel über das Zeitgeist Gamesystem-Modul habe ich etwas mehr über die Klasse zur Datenhaltung (gamedata.class.php) geschrieben. Diese ist in Zeitgeist angelehnt an die Datenhaltung eines Entity-Systems. In den Kommentaren wurde mir von Gameplorer folgende Frage zu dem Prinzip gestellt: Wie gut eignet sich das tatsächlich für Browsergames? Durch die component_data_N – Tabellen ist es ja [...]]]></description>
			<content:encoded><![CDATA[<p>In meinem Artikel über das <a href="http://blog.zeitalter3.de/2010/02/13/das-gamesystem-modul" target="_blank">Zeitgeist Gamesystem-Modul</a> habe ich etwas mehr über die Klasse zur Datenhaltung (<a href="http://code.google.com/p/zeitgeist-framework/source/browse/framework/trunk/modules/gamesystem/gamedata.class.php" target="_blank">gamedata.class.php</a>) geschrieben. Diese ist in Zeitgeist angelehnt an die <a href="http://t-machine.org/index.php/2009/10/26/entity-systems-are-the-future-of-mmos-part-5/" target="_blank">Datenhaltung eines Entity-Systems</a>. In den Kommentaren wurde mir von <a href="http://www.gameplorer.de/" target="_blank">Gameplorer</a> folgende Frage zu dem Prinzip gestellt:</p>
<blockquote><p><em>Wie gut eignet sich das tatsächlich für Browsergames? Durch die component_data_N – Tabellen ist es ja nicht mehr möglich, effektiv mit Joins zu arbeiten. Dadurch muss ich aber pro Entity zig Queries absetzen (jede component_data – Tabelle) was auf die Performance schlägt. Für z.B. einen Kampf müssten dann auch noch mehrere Entities geladen werden. Das klingt für mich nach einem absoluten NoGo in einem Browsergame.<br />
Mir kam die Artikelreihe daher eher vor, als wäre ES für Clientbasierte-Spiele ausgelegt.</em></p></blockquote>
<p>Das ist eine gute Frage, da sie auf einem verbreiten Mißverständnis beruht wie Entity Systeme funktionieren. Es werden (wenn richtig implementiert) kaum Joins benötigt, da keine Notwendigkeit besteht die kompletten Entites zu laden (geschweige denn mehrere). Das Missverständnis beruht wohl auf dem Versuch sich Entity Systeme wie klassisch objektorientierte Systeme vorzustellen, in denen das System über die Objektklassen immer (mehr oder weniger direkten) Zugriff auf alle Daten des Objekts hat. Mir ging es nicht anders und ich brauchte einige Anläufe, um mich davon zu lösen.</p>
<p>Hier also mein Versuch zu erklären, wie ich Entity Systeme verstehe und wie sie in Zeitgeist implementiert wurden.</p>
<p><span id="more-740"></span></p>
<p><strong>Ein simples Weltraum-Spiel</strong></p>
<p>Da man anhand von Beispielen immer besser erklären kann, nehmen wir einmal ein einfaches Weltraum-Spiel mit folgenden Eigenschaften:</p>
<ul>
<li>Ein Spieler hat ein oder mehrere Raumschiffe</li>
<li>Es gibt 3 Raumschifftypen: leicht, mittel, schwer</li>
<li>Ein Raumschiff hat eine gewisse Panzerung, entsprechend den Typen: leicht, mittel und schwer (vergleichbar mit Lebenspunkten: wenig, mittel und viel)</li>
<li>Ein Raumschiff hat eine festgelegte Waffe, entsprechend den Typen: leicht, mittel und schwer (vergleichbar Angriffskraft: wenig, mittel und viel)</li>
<li>Ein Raumschiff fliegt durch das Universum</li>
<li>Ein Raumschiff kann gegen ein anderes Raumschiff kämpfen</li>
<li>Ein Raumschiff kann in Raumstationen fliegen, in denen es sich reparieren lassen kann</li>
<li>Angedockte Raumschiffe können nicht angegriffen werden</li>
</ul>
<p>Was würde für so ein Spiel also an Daten benötigt? Zunächst einmal die Raumschiff-Daten: Welcher Spieler besitzt welches Raumschiff? An welcher Position befindet sich das Raumschiff? Wie viel Waffenschaden und Panzerung hat es noch und so weiter. Dazu kommen noch die Daten für die Objekte im Raum: Raumstationen und deren Position.</p>
<p>Um die Unterschiede klar zu machen folgt nun eine beispielhafte objektorientierte und komponentenbasierte Umsetzung. Beide Varianten kann (und sollte) man sicherlich auch anders implementieren, aber dies soll nur als Veranschaulichung dienen.</p>
<p><strong>Objektorientierter Ansatz</strong></p>
<p>Der objektorientierte Ansatz sieht die Welt durch eine Ansammlung von Objektklassen, welche jeweils einen Typ von Gegenstand in der Welt repräsentieren. Deren Methoden sind die Aktionen, welche dieser Typ Gegenstand durchführen kann.</p>
<p>In unserem Beispiel gäbe es üblicherweise eine Objektklasse für Raumschiffe. Wie definiert hat ein Raumschiff einen Besitzer, eine Panzerung und Waffe, sowie eine Position im Raum. Außerdem kann es gerade fliegen oder an einer Raumstation angedockt sein. Daneben gäbe es wahrscheinlich eine Klasse für Raumstationen, die jedoch nichts weiter tun, als auf einer Position zu verharren.</p>
<p>Die Daten werden in Tabellen gespeichert, welche mehr oder minder den Objektstrukturen ähneln. In der Realität mag es mehr Streuung durch <a href="http://de.wikipedia.org/wiki/Normalisierung_(Datenbank)" target="_blank">Normalisierung</a> geben, aber im Großen und Ganzen sähen die Tabellen für unser Beispiel so aus:</p>
<ul>
<li>Tabelle 1: Raumschiff (Besitzer, Panzerung, Waffenschaden, Position, Angedockt)</li>
<li>Tabelle 2: Raumstationen (Position)</li>
</ul>
<p>Spieler sind im Besitz eines Raumschiffs, sobald dieses in der Tabelle Raumschiff eingetragen ist.</p>
<p>Die eigentlichen Raumschiffe der Spieler und Raumstationen in der Spielwelt wären Instanzen ihrer entsprechenden Objektklassen. Das System initialisiert die Instanz eines spezifischen Raumschiffs mit den entsprechenden Daten aus der Tabelle.</p>
<p>Neben den Daten verfügt eine Objektklasse über Methoden, welche die Daten der jeweiligen Instanz (und damit des Raumschiffs bzw. der Raumstation) verändern. Als Beispiel für die Raumschiffklasse:</p>
<ul>
<li>Raumschiff.bewegen(x,y,z): verändert die Position des Raumschiffs</li>
<li>Raumschiff.angreifen(RaumschiffID): greift das Raumschiff mit der gegebenen ID an</li>
<li>Raumschiff.andocken(RaumstationID): dockt das Raumschiff an die Raumstation mit der gegebenen ID an</li>
<li>..</li>
</ul>
<p>So weit die kleine Wiederholung von <a href="http://de.wikipedia.org/wiki/Objektorientierte_Programmierung" target="_blank">objektorientierter Programmierung</a>.</p>
<p><strong>Komponentenbasierte Datenhaltung</strong></p>
<p>Der komponentenbasierte Ansatz sieht die Welt durch eine Sammlung von <em>Komponenten</em> und <em>Entitäten</em>. Zunächst einmal die Erklärung, was diese eigentlich sind:</p>
<ul>
<li>Eine Komponente beschreibt eine Eigenschaft, die ein Gegenstand haben kann</li>
<li>Eine Entität repräsentiert einen dedizierten Gegenstand in der Welt</li>
<li>Eine Entität besteht aus einer oder mehreren Komponenten</li>
</ul>
<p>An dem Beispiel können diese Definitionen vielleicht besser veranschaulicht werden. Mit folgenden Komponenten (Eigenschaften) können alle Gegenstände unserer fiktiven Spielwelt abgebildet werden (in Klammern steht jeweils der Wert, mit dem eine Eigenschaft bemessen werden kann):</p>
<ul>
<li>Komponente 1: Ein Gegenstand kann eine Waffe haben (Angriffsschaden)</li>
<li>Komponente 2: Ein Gegenstand kann gepanzert sein (Panzerungswert)</li>
<li>Komponente 3: Ein Gegenstand kann eine Position haben (x/y/z)</li>
<li>Komponente 4: Ein Gegenstand kann einen Besitzer haben (SpielerID)</li>
<li>Komponente 5: Ein Gegenstand kann beweglich sein (j/n)</li>
<li>Komponente 6: Ein Gegenstand kann angreifbar sein (j/n)</li>
<li>Komponente 7: Ein Gegenstand kann andere Gegenstände reparieren (j/n)</li>
</ul>
<p>Nehmen wir nun einmal irgendein Raumschiff. Dieses hätte folgende Komponenten: Waffe, Panzerung, Position, Besitzer, istBeweglich, istAngreifbar. Eine Raumstation hingegen hätte nur folgende Komponenten: Position, kannReparieren. Diese Typen von Entities sind <em>Assemblages </em>- eigentlich nur Sammlungen von Komponenten, die einen bestimmten Typ von Gegenstand ausmachen.</p>
<p>Der nächste Schritt ist leicht &#8211; jede Komponente bekommt eine Tabelle in der Datenbank. Dazu noch eine für die Entities, sowie eine Tabelle, um die Verbindung zwischen einer Entity und ihren Komponenten herzustellen:</p>
<ul>
<li>Tabelle 1: Entities(ID)</li>
<li>Tabelle 2: Entities_zu_Komponenten(Entity, Komponente)</li>
<li>Tabelle 3: Komponente 1 &#8211; Waffe (Angriffsschaden)</li>
<li>Tabelle 4: Komponente 2 &#8211; Panzerung (Panzerungswert)</li>
<li>Tabelle 5: Komponente 3 &#8211; Position (x/y/z)</li>
<li>Tabelle 6: Komponente 4 &#8211; Besitzer (Spieler_ID)</li>
<li>Tabelle 7: Komponente 5 &#8211; istBeweglich (j/n)</li>
<li>Tabelle 8: Komponente 6 &#8211; istAngreifbar (j/n)</li>
<li>Tabelle 8: Komponente 7 &#8211; kannReparieren (j/n)</li>
</ul>
<p>Die Assemblages würden so aussehen:</p>
<ul>
<li>Assemblage 1: Raumschiff (Waffe, Panzerung, Position, Besitzer, istBeweglich, istAngreifbar)</li>
<li>Assemblage 2: Raumstation (Position, kannReparieren)</li>
</ul>
<p>Damit wurden nur Daten beschrieben &#8211; nirgendwo steckt ein Stück Interaktion. Im Gegensatz zum objektorientierten Ansatz, bei dem die Interaktion in den Methoden der Gegenstände selbst steckt, ist eine Entität oder eine Komponente völlig losgelöst von Methoden oder überhaupt Code. Wo also kommt die Interaktivität her?</p>
<p><strong>Entity Systeme</strong></p>
<p>Die Interaktivität kommt von den sogenannten Systemen. Objektorientierung geht davon aus, dass eine Methode für eine Objektklasse sich von den Methoden anderer Objektklassen unterscheidet. Das Komponentenmodell geht im Gegensatz dazu davon aus, dass die Interaktion die auf eine Komponente einwirkt unabhängig vom Gegenstands immer gleich ist. Ein Beispiel wäre die Komponente &#8220;Position&#8221;. Es ist unerheblich welcher Gegenstand eine Position hat, das Prinzip &#8220;Bewegung&#8221; ist für alle Gegenstände gleich: die Position ändert sich. Damit hat sich der Gegenstand bewegt. Dies gilt für Raumschiffe ebenso wie für Rennautos, Flugzeuge oder Fußbälle.</p>
<p>Die Interaktion für Komponenten wird also in einzelnen, in sich abgeschlossenen Systemen gekapselt, die nur ihre jeweils relevante Komponente(n) bearbeiten. Alles andere interessiert sie nicht. Um einen Gegenstand zu bewegen ist es unerheblich wem er gehört oder wie er bewaffnet oder gepanzert ist. Das heißt nicht, dass diese Informationen in diesem Moment gänzlich unwichtig sind, aber dafür ist ein anderes System zuständig. Und deshalb laufen alle Systeme möglichst parallel.</p>
<p><strong>Auswirkung 1: Komponentensicht = Flexibilität</strong></p>
<p>In jedem Browsergame findet der Großteil der Entwicklung nach dem Launch statt. Bugfixing macht davon nur einen kleinen Teil aus. Früher oder später muss man am Balancing nachdrehen und in mehr oder weniger regelmäßigen Abständen wird es Erweiterungen geben: neue Einheiten, neue Regeln, neue Features, neue Dinge zu entdecken.</p>
<p>Nehmen wir unser Beispiel. Angenommen Spieler sollen auch Raumstationen besitzen können. Andere Spieler können diese natürlich zerstören. In einem objektorientierten Umfeld würde ich jetzt anfangen die Klasse der Raumstation zu erweitern. Bei einem Komponentensystem würde ich die Komponente &#8220;Besitzer&#8221; und &#8220;istAngreifbar&#8221; der Assemblage der Raumstation hinzufügen. Done. Keine Codeänderung nötig.</p>
<p>Oder fügen wir die Raumschiffklasse &#8220;Trägerschiff&#8221; hinzu. Es soll eine Art großes Raumschiff sein, das wie eine bewegliche Raumstation agiert und andere Raumschiffe daran andocken können. Also, ich erstelle eine neue Klasse dafür und fange an zu programmieren. Oder aber ich erstelle eine neue Assemblage und füge die entsprechenden Komponenten hinzu (was Datenbankeinträge sind!).</p>
<p>Und jetzt stellen wir uns einen einfachen Einheiten-Editor vor, der einfach nur Assemblages erstellen und mit Komponenten verknüpfen kann.</p>
<p>Wenn ich denn tatsächlich mal eine neue Eigenschaft brauche, muss ich natürlich das entsprechende System entwickeln. Allerdings steht die Eigenschaft damit automatisch auch allen anderen Assemblages zur Verfügung.</p>
<p>Zugegeben, mit Mehrfachvererbung oder Interfaces kann man auch in klassisch objektorientierten Umgebungen so eine Flexibilität versuchen, aber ich würde es nicht empfehlen. Früher oder später läuft alles auf massive Superklassen hinaus, die nicht mehr pflegbar sind.</p>
<p><strong>Auswirkung 2: Kleine Systeme = Wartbarkeit</strong></p>
<p>Wenn jedes System nur eine (oder wenige) Komponente(n) bearbeitet, sind diese per Definition relativ überschaubar. Anstatt über die Klassen verteilt habe ich auch nur an einem dedizierten Punkt meine Logik: in den Systeme selbst. Ich muss auch nicht in jeder Klasse immer wieder die gleiche oder ähnliche Logik unterbringen oder mich mit Vererbung und Interfaces herumschlagen, um den Code aus den Klassen herauszuhalten. Ich habe einen zentralen Punkt, an dem ein abgegrenztes Set von Daten geändert wird.</p>
<p>Durch diese Abgrenzung sind die Systeme außerdem großartig testbar.</p>
<p><strong>Auswirkung 3: Spezialisierte Systeme = Performance</strong></p>
<p>Nehmen wir als Beispiel an in der Queue des Eventhandlers liegen Events zur Bewegung von Schiffen. Es existiert ein System für &#8220;Bewegung&#8221;, dessen Aufgabe die Bearbeitung dieser Events ist. Es schaut also in der Event-Tabelle nach: was muss bewegt werden und wohin?</p>
<p>Klassisch objektorientiert wäre das &#8220;was&#8221; die ID eines Raumschiffs, aus dem dann die Raumschiff-Instanz erzeugt wird. Instinktiv mag man dem &#8220;was&#8221; in einem Entity System die ID der Entity zuweisen. In diesem Fall müsste das System jedoch erst einmal die Entity-ID finden, dann die Zwischentabelle befragen wo in der Komponententabelle &#8220;Position&#8221; denn der dazugehörige Eintrag liegt. Und da sind wir wieder bei der eigentlichen Frage von Gameplorer: &#8220;Sind diese Joins nicht unperformant?&#8221; Antwort: ja, aber warum sollte ich sie überhaupt machen? Wieso wird nicht einfach die ID des Komponenteneintrags als &#8220;was&#8221; genutzt? Sobald das passiert ist reduziert sich die Aufgabe des Systems auf einfache Updates.</p>
<p>Und noch besser: wer sagt, dass ein System in meiner Applikation leben muss? Letztendlich fragt es die Datenbank ab (Event-Tabelle), um mit den Ergebnissen eine andere Tabelle zu aktualisieren (Conponent_Data_Position). Das alles kann man bequem in einer Stored Procedure erledigen.</p>
<p><strong>Auswirkung 4: Parallele Systeme = Skalierung</strong></p>
<p>Angenommen ich habe alle Systeme ausgelagert. Weiter angenommen ich merke, dass ein System viele Ressourcen frisst, wohingegen andere recht genügsam sind. Was hintert mich daran das anspruchsvolle System einfach auf einen eigenen Server zu verlegen? Solange es Zugang zur Datenbank hat ist alles fein.</p>
<p><strong>Was jetzt noch bleibt</strong></p>
<p>Neben den Systemen bleibt noch der Logik-Server. Dies ist der Haupt-Gameserver, den die Clients ansprechen. Etwas muss ja auch dafür sorgen, dass sich Nutzer anmelden können, die Spielregeln implementiert sind und der Eventhandler befüllt wird. Dadurch dass aber alle Vorgänge innerhalb der Spielwelt nun losgelöst sind beschränkt sich dieser aber auch auf diese Aufgaben, wird deutlich schlanker und dadurch auch performanter.</p>
<p>So, der Artikel is jetzt lang genug. Ich hoffe ich habe euch meine Vorstellung von Entity Systemen etwas näher erklären können. Wie <a href="http://t-machine.org/index.php/2009/10/26/entity-systems-are-the-future-of-mmos-part-5/" target="_blank">schon erwähnt</a> gibt es viele Arten von Entity Systemen. Es würde mich freuen von euch zu hören, falls ihr eine Meinung zu dem Modell habt.</p>
 <p><a href="http://blog.zeitalter3.de/?flattrss_redirect&amp;id=740&amp;md5=d138e5e54669f723a5b7a63b113e11ff" title="Flattr" target="_blank"><img src="http://blog.zeitalter3.de/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.zeitalter3.de/2010/02/16/datenhaltung-mit-gamedata-class-php/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Game Design Patterns: PvP Herausforderungen</title>
		<link>http://blog.zeitalter3.de/2009/04/09/game-design-patterns-pvp-herausforderungen/</link>
		<comments>http://blog.zeitalter3.de/2009/04/09/game-design-patterns-pvp-herausforderungen/#comments</comments>
		<pubDate>Thu, 09 Apr 2009 05:22:16 +0000</pubDate>
		<dc:creator>Dirk</dc:creator>
				<category><![CDATA[Spieldesign]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Spielmechanik]]></category>

		<guid isPermaLink="false">http://blog.zeitalter3.de/?p=562</guid>
		<description><![CDATA[Ich habe mir in letzter Zeit Gedanken darüber gemacht, wie Spieler in unserem Browserspiel gegeneinander antreten können. Hintergrund: es soll möglich sein, dass zwei bis vier Spieler in einzelnen &#8220;Auseinandersetzungen&#8221; gegeneinander antreten können. Die Frage ist nun: wie kann man organisieren, dass eine solche Auseinandersetzung stattfindet? Ein Beispiel, um das Thema zu verdeutlichen: nehmen wir [...]]]></description>
			<content:encoded><![CDATA[<p>Ich habe mir in letzter Zeit Gedanken darüber gemacht, wie Spieler in unserem Browserspiel gegeneinander antreten können. Hintergrund: es soll möglich sein, dass zwei bis vier Spieler in einzelnen &#8220;Auseinandersetzungen&#8221; gegeneinander antreten können. Die Frage ist nun: wie kann man organisieren, dass eine solche Auseinandersetzung stattfindet?</p>
<p>Ein Beispiel, um das Thema zu verdeutlichen: nehmen wir an, jeder Spieler repräsentiert einen Piloten eines Jets (Raumschiffs, Rennwagens). Als reguläre Spieloberfläche hat jeder Spieler eine Auflistung seiner Möglichkeiten auf dem Flughafen (Flugzeugträger, Raumschiff, Fahrerlager, ..), unter anderem sich mit anderen Piloten zu Übungszwecken zu duellieren. Bis zu insgesamt 4 Spieler können in &#8220;Dogfights&#8221; (Wettrennen) gegeneinander antreten. Nachdem sich 2-4 Spieler gefunden und geeinigt haben, starten sie. Die Oberfläche wechselt zu einem Cockpit, in dem nun jeder Spieler sein Jet (Raumschiff, Rennwagen) steuert (Wechsel von &#8220;Nicht Auseinandersetzung&#8221; zu &#8220;Auseinandersetzung&#8221;).</p>
<p>Gemäß des <a href="http://www.gamasutra.com/features/20020313/kreimeier_01.htm" target="_blank">Aufrufs von Bernd Kreimeier</a> in <a href="http://www.gamasutra.com/" target="_blank">Gamasutra</a> beschreibe ich kurz mal das Problem und skizziere die Lösungen, auf die ich gekommen bin. Die Problemstellung ist bei allen gleich:</p>
<p>Problem:<em> &#8220;2-4 Spieler sollen in Auseinandersetzungen gegeneinander antreten können. Es steht während der Auswahl keine grafische Repräsentation der Spielwelt zur Verfügung. Die Auseinandersetzungen selbst finden in einer grafischen Repräsentation statt und sind so &#8220;losgelöst&#8221; von der sonstigen Oberfläche. Wie können sich Spieler finden, die gegeneinander antreten wollen? Wie können Spieler gezielt gegen spezifische Spieler antreten? Wie können die Spieler kontrolliert von der Oberfläche der &#8220;Nicht-Auseinandersetzung&#8221; in die der &#8220;Auseinandersetzung&#8221; wechseln?&#8221;</em></p>
<p><strong>Skirmish</strong></p>
<p><em>Lösung</em>: Der Spieler gibt die Anzahl seiner gewünschten Mitspieler ein und bestätigt seine Wahl. Er wird in eine Warteschlage aufgenommen, die alle Spieler enthält, welche die gleiche Anzahl an Mitspieler wünschen. Er wartet so lange, bis diese Anzahl erreicht ist. Anschließend wechselt der Kontext für alle Spieler in der Warteschlage und sie treten in der Auseinandersetzung gegeneinander an.</p>
<p><em>Konsequenz</em>: Das Finden der Mitspieler wird vom System automatisch übernommen. Ein Spieler kann nicht gezielt gegen spezifische Spieler antreten. Der Spieler hat keinen direkten Einfluss wann das Spiel stattfinden wird, sondern wird gezwungen passiv zu sein.</p>
<p><em>Beispiel</em>: Battlegrounds in World of Warcraft. Skirmisch-Modus in Echtzeit-Strategiespielen.</p>
<p><strong>Lobby</strong></p>
<p><em>Lösung</em>: Der Spieler gibt die Anzahl seiner gewünschten Mitspieler ein und bestätigt seine Wahl. Dies eröffnet einen neuen Raum mit der Anzahl an Mitspielern als offene Slots. Andere Spieler sehen diesen Raum und können diesen betreten. Wenn alle Slots von Spielern gefüllt sind, beginnt das Spiel.</p>
<p><em>Konsequenz</em>: Das Finden anderer Mitspieler ist für den Ersteller des Spielraums nicht möglich, nur für die teilnehmenden Mitspieler. Der Spieler kann durch eigene Absprachen gegen spezifische Mitspieler antreten. Abhängig von der Implementation haben die Spieler Kontrolle über den Übergang auf die Oberfläche der Auseinandersetzung.</p>
<p><em>Beispiele</em>: Viele Rennspiele implementieren eine vom Ersteller des Raums gesteuerte Variante: der Ersteller muss, nachdem andere Spieler seinen Spielraum betreten haben, manuell die Auseinandersetzung bestätigen bzw. beginnen. Er hat also Kontrolle über den Übergang. Echtzeit-Strategiespiele implementieren meistens eine Variante, in der jeder teilnehmende Spieler die Spielrunde bestätigen muss = alle Spieler haben Kontrolle über den Übergang.</p>
<p><strong>Direkte Herausforderung</strong></p>
<p><em>Lösung</em>: Ein Spieler wählt aus einer Liste der existierenden und verfügbaren Mitspieler 1-3 weitere aus und bestätigt seine Wahl. Der Spieler wechselt direkt in den Kontext der Auseinandersetzung, die allerdings noch nicht beginnt. Es wird eine Benachrichtigung mit einer Herausforderung an die gewählten Mitspieler versendet, die einen Link enthält. Der Link führt die Spieler direkt in die Auseinandersetzung. Die Auseinandersetzung beginnt, sobald alle Mitspieler im Kontext der Auseinandersetzung sind.</p>
<p><em>Konsequenz</em>: Die Spieler können gezielt gegen spezifische Mitspieler antreten. Sie haben allerdings kaum Kontrolle über den Wechsel &#8211; sie müssen warten, bis alle anderen Mitspieler der Herausforderung gefolgt sind. Die Zeitspanne dafür ist nicht absehbar und die Herausforderer müssen unter Umständen lange auf eine Reaktion warten. Spieler können sich gegenseitig über eine Liste der verfügbaren Mitspieler finden.</p>
<p><em>Beispiel</em>: Einige Browsergames arbeiten mit dieser Art von Herausforderung. Bei einer Herausforderung ist es dabei üblich eine Mail zu versenden bzw. zusätzlich auf der Oberfläche des Browsergames die Herausforderung kenntlich zu machen. Seltener sind Benachrichtigungen per IM und SMS (eigentlich nur bei mobilen Spielen üblich).</p>
<p>Fällt euch noch ein Pattern ein? Falls ja, beschreibt es bitte als Kommentar. Und was mich noch interessieren würde: welches der drei vorgestellten Patterns sagt euch mehr zu? Ja, ich weiß, das ist abhängig vom Spielprinzip und der Implementation, aber wenn ihr einfach aus dem Bauch heraus antwortet: welches wäre das dann?</p>
<p>Oh, und den oben erwähnten <a href="http://www.gamasutra.com/features/20020313/kreimeier_01.htm" target="_blank">Gamasutra-Artikel</a> kann ich wirklich empfehlen <img src='http://blog.zeitalter3.de/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zeitalter3.de/2009/04/09/game-design-patterns-pvp-herausforderungen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Das Zeitgeist Nachrichtensystem</title>
		<link>http://blog.zeitalter3.de/2008/11/23/das-zeitgeist-nachrichtensystem/</link>
		<comments>http://blog.zeitalter3.de/2008/11/23/das-zeitgeist-nachrichtensystem/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 14:11:54 +0000</pubDate>
		<dc:creator>Dirk</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Zeitgeist-Framework]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Refactoring]]></category>
		<category><![CDATA[Zeitgeist]]></category>

		<guid isPermaLink="false">http://blog.zeitalter3.de/?p=435</guid>
		<description><![CDATA[Jetzt mal ernsthaft &#8211; ihr könnt euch ruhig trauen hier im Blog mit Hilfe der Kommentare zu fragen, anstatt mir umständlich eine Mail zu schreiben. Die Frage war: Was ist dieses angesprochene Message-System? Nun, einfach gesagt: Die Message-Klasse stellt Funktionalitäten bereit, um systemweite Textnachrichten zu verwalten. Das Prinzip der systemweiten Nachrichten sollte vielen bekannt sein, [...]]]></description>
			<content:encoded><![CDATA[<p>Jetzt mal ernsthaft &#8211; ihr könnt euch ruhig trauen hier im Blog mit Hilfe der Kommentare zu fragen, anstatt mir umständlich eine Mail zu schreiben.</p>
<p>Die Frage war:</p>
<p><strong>Was ist dieses angesprochene Message-System?</strong></p>
<p>Nun, einfach gesagt: <em>Die Message-Klasse stellt Funktionalitäten bereit, um systemweite Textnachrichten zu verwalten.</em></p>
<p>Das Prinzip der systemweiten Nachrichten sollte vielen bekannt sein, die schon einmal etwas tiefer in die  Dektop-Programmierung eingestiegen sind. Man kann es sich als eine Art Modul vorstellen, das von überall her angesprochen werden kann. An dieses Modul können Nachrichten übergeben und umgekehrt wieder angefordert werden. Auf diese Weise können alle Module eines Projekts miteinander kommunizieren.</p>
<p><span id="more-435"></span></p>
<p><strong>Ein Beispiel</strong></p>
<p>Nehmen wir einmal einen typischen Fall in einer Webapplikation: ein Benutzer kauft in einem B2B-Webshop den Inhalt seines Warenkorbs. Dieser einfache Klick setzt einige Abläufe in Gang &#8211; gehen wir der Einfachheit mal von folgenden Prozessen und Fragen aus, die das System nun anstößt:</p>
<ul>
<li>Ist der Benutzer eingeloggt?</li>
<li>Kenne ich alle nötigen Angaben des Benutzers?</li>
<li>Was ist denn der Inhalt des Warenkorbs</li>
<li>Sind die Waren überhaupt noch verfügbar?</li>
<li>Erstelle eine Rechnung</li>
<li>Informiere das Warenwirtschaftssystem</li>
</ul>
<p>Diese können leicht durch Klassen und deren Methoden beantwortet werden. Allerdings werden dabei viele, viele Zwischenfragen gestellt und lauter Klassen müssen ineinander greifen: Benutzerverwaltung, Warenkorb, Waren, Rechnungsstellung, Schnittstelle zum Warenwirtschaftssystem und so weiter. Der ganze Ablauf wird wahrscheinlich verwaltet durch eine Art Controller (in MVC), mit dem jede Klasse für sich sprechen kann. Doch wie können diese individuellen Klassen miteinander sprechen?</p>
<p><strong>Falsch!</strong></p>
<p>Einfache Antwort: in sauberem OOP <em>sollen</em> Arbeiterklassen auch gar nicht untereinander Daten austauschen. Gut, zugegeben. Aber abgesehen von Daten: wie wäre es, wenn sie Informationen über ihren Zustand austauschen? Oder sie alle wollen möglicherweise mit dem Controller oder gar dem Benutzer reden. Und dieses Mitteilungsbedürfnis kann eben über den einfachen Rückgabewert hinaus gehen. Wenn mir eine Methode einer Arbeiterklasse ein <em>false </em>zurückliefert, was ist denn eigentlich genau schief gelaufen? In welchem Zustand befindet sich dann die Arbeiterklasse? (An dieser Stelle würde ich ja gerne mit Exception Handling anfangen, aber die Implementation in PHP5 ist so mangelhaft, dass das leider nicht geht).</p>
<p>Also &#8211; gehen wir von einer Art Verbose-Modus innerhalb der Applikation aus, in dem jede Klasse ihre Schritte dokumentieren kann und alle anderen wissen, in welchem State sich die Applikation gerade befindet.</p>
<p><strong>Die Umsetzung<br />
</strong></p>
<p>Gundsätzlich könnte man jetzt das Problem mit globalen Variablen lösen. Mal abgesehen von dem &#8220;globale Variablen sind die Wurzel allen Übels&#8221;-Stigma sind sie wirklich nicht besonders sinnvoll. Es ist schwer im Blick zu halten, welche Funktion gerade was in welche Globale geschrieben hat, was Debugging und vor allem Testing zu einem Horrortrip macht.</p>
<p>Alternativ würden sich Session-Variablen anbieten, aber wenn man es genau betrachtet sind diese in dem Zusammenhang auch nichts anderes als Globale in Grün.</p>
<p><strong>Was ist daran schlecht?</strong></p>
<p>Das da:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="src" value="http://www.youtube.com/v/-FRm3VPhseI&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en&amp;fs=1" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/-FRm3VPhseI&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en&amp;fs=1" allowfullscreen="true"></embed></object></p>
<p><strong>Warum machst du es dann doch, obwohl sogar Google sagt, dass es schlecht ist?</strong></p>
<p>Wer aufgepasst hat, der hat sich gemerkt, dass Singletons (über die wir hier reden) nicht per se schlecht sind. Man muss sie nur entsprechend designen. Denn grundsätzlich haben Singletons einige entscheidende Vorteile gegenüber einer Anzahl von &#8220;dummen&#8221; Globalen.</p>
<p>Zunächst einmal wäre da die <em>Nachvollziehbarkeit</em>. Die Klasse selbst kann nachvollziehen welche Methode oder Funktion gerade auf sie zugegreift und was diese verändert. Voraussetzung ist, diese Informationen fließen alle in eine Art Tracing-Mechanismus, was dem Entwickler zu jeder Zeit des Programms transparent macht, was an welcher Stelle passiert ist. In der Kombination mit dem Tracer bleibt dann nachvollziehbar, was genau mit dem Global State passiert (siehe Video).</p>
<p>Ich erwähnte bereits, dass das Nachrichtensystem die Informationen nicht nur speichert, sondern auch verwaltet. Eine Methode kann eine Nachricht mit einem <em>expliziten Empfänger</em> versehen. Somit erhält eine Methode an anderer Stelle bei einer Anfrage nach für sie relevanten Nachrichten auch nur die für sie gespeicherten Informationen.</p>
<p>Möglich ist auch eine effektive <em>Rechteverwaltung</em>, welche Module auf welche gespeicherten Informationen zugreifen bzw. diese verändern können.</p>
<p>Und schließlich: Nachrichten können über Aufrufe hinweg <em>gespeichert </em>werden. Ein Beispiel: wenn bei einem Aufruf einige Funktionen einen Fehler melden, der Benutzer daraufhin per Redirect auf eine andere Seite geleitet wird, kann das System immer noch nachvollziehen, welche Fehler eigentlich gemeldet wurden und dem Benutzer entsprechende Ausgaben präsentieren. Das ist eigentlich die Hölle für einen Global State, aber noch einmal: wir können leicht nachvollziehen wer den State wann gesetzt hat. Und umgekehrt können wir diesen auch leicht definieren, um ihn so testen zu können.</p>
<p><strong>Fazit</strong></p>
<p>Ja, das ist Overhead. Aber nicht so viel, wie man denkt. Macht es das Debuggen und Warten des Codes problematischer? Ja, ein bischen. Oder vielmehr: man sollte sich über ein paar Dinge im Klaren sein. Dann aber ist es immer nett, wenn man mehr Informationen zur Verfügung hat, was genau in der Applikation vorgeht &#8211; auch innerhalb der Applikation selbst.</p>
<p>Aber um eine Sache klarzustellen: wir reden hier von Nachrichten, Kommunikation und Übersicht. Die eigentilchen Arbeiterklassen sollten entsprechend korrektem OOP-Design erstellt werden (siehe oben, siehe Vortrag). Was nicht Sinn der Sache ist, dass (wie in unserem B2B-Shop-Beispiel) der Warenkorb plötzlich über das Nachrichtensystem von einer Arbeiterklasse zur nächsten gereicht wird. Dann sind wir in der Tat bei &#8220;Bad Global State&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zeitalter3.de/2008/11/23/das-zeitgeist-nachrichtensystem/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Der Motor: Zeitgeist</title>
		<link>http://blog.zeitalter3.de/2008/07/29/der-motor-zeitgeist/</link>
		<comments>http://blog.zeitalter3.de/2008/07/29/der-motor-zeitgeist/#comments</comments>
		<pubDate>Tue, 29 Jul 2008 17:42:36 +0000</pubDate>
		<dc:creator>Dirk</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Zeitgeist-Framework]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Zeitgeist]]></category>

		<guid isPermaLink="false">http://blog.zeitalter3.de/?p=282</guid>
		<description><![CDATA[Wir haben an dieser Stelle bereits einiges zu unserem Framework fallen gelassen. Hier nun die im letzten Post versprochene Überraschung: es ist an der Zeit nähere Details über den Motor unserer Projekte zu veröffentlichen: Zeitgeist. Ursprünglich wurde Zeitgeist geplant und entwickelt für unser erstes Browserspiel-Konzept: Zeitalter3. Und daher auch der Name: es ist der gute [...]]]></description>
			<content:encoded><![CDATA[<p>Wir haben an dieser Stelle bereits einiges zu unserem Framework fallen gelassen. Hier nun die im <a href="http://blog.zeitalter3.de/2008/07/27/quick-links-update/" target="_blank">letzten Post</a> versprochene Überraschung: es ist an der Zeit nähere Details über den Motor unserer Projekte zu veröffentlichen: <em>Zeitgeist</em>.</p>
<p>Ursprünglich wurde Zeitgeist geplant und entwickelt für unser erstes Browserspiel-Konzept: Zeitalter3. Und daher auch der Name: es ist der gute Geist, welcher Zeitalter3 antreibt. Jedoch wurde das Framework frühzeitig mit dem Fokus entwickelt ein generischer Unterbau für alle Arten von webbasierten Mehrbenutzersystemen zu sein. In so fern ist das Framework weder auf ein einziges Spiel spezialisiert, noch ist es nur auf Spiele festgelegt. Ob Browserspiel, Webapplikation oder Community – alle Webanwendungen können theoretisch auf der Basis von Zeitgeist entwickelt werden.</p>
<p>Technisch basiert Zeitgeist auf PHP5 mit einer Datenbank im Hintergrund. Es ist voll objektorientiert und stellt Klassen für viele Bereiche der Webentwicklung zur Verfügung. Features sind zum Beispiel:</p>
<ul>
<li>Debugging der gesamten Anwendung, inklusive Tracing</li>
<li>Einfache Konfiguration der Applikation</li>
<li>Datenbankanbindung, inklusive rudimentäres SQL-Profiling</li>
<li>Transparente Session- und Benutzerverwaltung</li>
<li>Transparente Validierung aller eingehenden Parameter</li>
<li>Automatische Formularvalidierung und -Handhabung</li>
<li>AJAX-Datenserver</li>
<li>Lokalisierung</li>
<li>Templatesystem, basierend auf Dreamweaver-Templates</li>
</ul>
<p>Zeitgeist bietet also Hilfen und fertige Klassen für einen großen Teil der üblichen Aufgaben von Webprojekten. Aber wie ist nun eine Implementation eines Zeitgeist-Projekts aufgebaut?</p>
<p><span id="more-282"></span></p>
<p><strong>Die Struktur von Zeitgeist</strong></p>
<p>Gleich vorweg: Zeitgeist basiert nicht auf MVC. Der Model-View-Controler Ansatz mag für schnelle Prototypen gut geeignet sein, jedoch eignet er sich unserer Meinung nach nur bedingt für komplexere Projekte (das ist aber eine Diskussion für sich). Statt dessen verwendet Zeitgeist einen eher an klassische Event-basierte Systeme angelehnten Ansatz.</p>
<p>Die Basis von Zeitgeist bildet ein Set von grundsätzlichen Klassen, die in jedem Projekt verwendet werden und zum Betrieb des Frameworks notwendig sind. Dieser Kern trägt bezeichnenderweise den Namen <em>Core</em>. Alle weiteren Schichten des Projekts basiert auf diesem Unterbau.</p>
<p>Auf diesen Kern setzen die <em>Framework-Module </em>von Zeitgeit auf. Diese stellen weitere optionale Funktionalitäten zur Verfügung, die per Konfiguration aktiviert und deaktiviert werden können. Somit kann jedes Projekt nur die Module nutzen, die es wirklich braucht und kann auf unnötigen Overhead verzichten.</p>
<p>Der erste Applikationsschicht besteht aus einem Set von <em>Worker-Klassen</em>, welche die Anwendungslogik bereit stellen. Darüber hinaus sollten in dieser Schicht sinnvollerweise die Klassen des Kerns oder der Framework-Module erweitert werden, um sie für spezielle, projektspezifische Anforderungen zu erweitern.</p>
<p>Auf die Anwendungslogik setzen die <em>Anwendungsmodule </em>auf. Anwendungsmodule sind jeweils logische Teile der Applikation, bestehend aus mehreren <em>Aktionen</em>, welche zusammengenommen die einzelnen Schritte der Ablauflogik bilden. Ein Beispiel wäre in einer typischen Community-Plattform alle Aktionen eines Benutzers sich selbst betreffend im Anwendungsmodul <em>User</em> zusammenzufassen, bestehend aus den Aktionen: <em>Passwort ändern</em>, <em>Benutzerdaten ändern</em>, <em>Passwort vergessen</em>, usw.</p>
<p>Schließlich bedienen sich die einzelnen Aktionen üblicherweise dem Templatesystem als <em>Präsentationsschicht</em>. Grundsätzlich kann aber eine beliebige Technologie als Benutzerinterface verwendet werden: Flash, Silverlight, etc.</p>
<p><img class="aligncenter size-full wp-image-290" title="zeitgeist_schichten2" src="http://blog.zeitalter3.de/wp-content/uploads/2008/07/zeitgeist_schichten2.png" border="0" alt="" width="380" height="266" /></p>
<p><strong>Die Funktionsweise von Zeitgeist</strong></p>
<p>Wie bereits in einem <a href="http://blog.zeitalter3.de/2007/11/22/aktionsverwaltung/">vorhergehenden Artikel</a> beschrieben ist Zeitgeist aktionsbasiert. Das bedeutet, dass bei jedem Seitenaufruf das Framework mit jeweils einer Angabe des gewünschten  Anwendungsmoduls und dessen Aktion aufgerufen wird. Zeitgeist verarbeitet diese Angaben mit seiner Aktionsverwaltung, die Teil des Kerns ist.</p>
<p>Die Aktionsverwaltung ist relativ umfangreich: sie kümmert sich um die Initialisierung der Anwendung und des jeweiligen Moduls, um Sicherheitsmechanismen, das Session-Handling inklusive Benutzer- und Rechteverwaltung und schließlich sorgt die Aktionsverwaltung, dass der Aufruf an das entsprechende Modul weitergegeben wird.</p>
<p>Ein Problem bei einer solchen Architektur ist die Kommunikation der einzelnen Schichten untereinander. Da alle Komponenten in allen Schichten (ausgenommen natürlich der Präsentationsschicht) als Klassen ausgelegt sind, können Informationen nicht einfach während des Ablaufs hin- und hergereicht werden. Der Einsatz von globalen Variablen ist in PHP zwar möglich, aber unserer Meinung nach sehr unsauber. Spätestens bei umfangreichen Webprojekten kann man sich nie sicher sein, ob eine Variable bereits existiert, wo sie herkommt, für wen sie bestimmt ist oder ob sie noch gebraucht wird. Ganz abgesehen davon, dass solche globalen Container, in die alles unstrukturiert hineingeworfen wird, irgendwann rießig werden und nicht mehr zu debuggen sind.</p>
<p>Um dieses Problem auch ohne Einsatz globaler Variablen zu lösen bietet Zeitgeist ein Nachrichten- und Objektsystem. Das Objektsystem ist als eine Art Manager zu sehen, mit dessen Hilfe die Komponenten Objekte, also Variablen oder Instanzen, untereinander austauschen können.</p>
<p>Das Nachrichtensystem dient zum Austausch von Meldungen zwischen den einzelnen Komponenten der Anwendung. Dabei können Nachrichten an bestimmte Komponenten (Empfänger) gesendet werden oder eine Komponente kann sich die Nachrichten aller oder nur bestimmter Absender abholen.</p>
<p>Durch das Objekt- und Nachrichtensystem können Zustände und Meldungen vom Framework über alle Schichten hinweg transportiert werden und beispielsweise von der Präsentationsschicht angezeigt werden.</p>
<p>Ebenfalls schichtübergreifend ist die Debugging-Komponente von Zeitgeist, die neben der üblichen Ausgabe von Debug-Nachrichten auch über <a href="http://blog.zeitalter3.de/2008/04/16/function-guarding/" target="_blank">Function Guarding</a> (Tracing), sowie rudimentäres Anwendungs- und <a href="http://blog.zeitalter3.de/2008/04/06/mysql-performance/" target="_blank">SQL Profiling</a> für das gesamte Projekt verfügt.</p>
<p><strong>Zeitgeist im Einsatz</strong></p>
<p>Zeitgeist wird von uns zur Zeit in zwei Projekten aktiv eingesetzt.</p>
<p>Zum einen bei Taskkun, der vor kurzem angekündigten webbasierten Projektmanagement-Lösung. Taskkun basiert auf <a href="http://blog.zeitalter3.de/2008/06/22/instanzierung/" target="_blank">instanzierten Benutzergruppen</a> (mehrere Gruppen von Anwendern können abgeschottet von einander Taskkun nutzen) und ist sehr flexibel (jede der einzelnen Gruppen kann den Arbeitsablauf von Taskkun selbst konfigurieren). Die Darstellung erfolgt mit XHTML. Das Projekt ist in der Closed Beta.</p>
<p>Zum Anderen nutzen wir Zeitgeist als Basis für unser erstes Spiel. Dieses ist ein schnelles, rundenbasiertes Action-Strategiespiel, in dem mehrere Spieler gegeneinander spielen. Die Darstellung erfolgt sowohl in XHTML (Seite), als auch in Flash (eigentlicher Spielclient). Es existiert ein lauffähiger Prototyp des Clients.</p>
<p>Und dann wäre da noch der Auslöser des Ganzen: Zeitalter3. Dabei handelt es sich um ein browserbasiertes Weltraum-Handelspiel, bei dem die Spieler in einem umfangreichen Universum gegeneinander antreten, um sich in regelmäßigen Spielrunden in verschiedenen Kategorien mit ihren Mitspielern zu messen. Kurz: ein browserbasiertes MMORPG. Zeitalter3 <a href="http://blog.zeitalter3.de/2008/01/16/die-grenze-des-moglichen/" target="_blank">ruht zur Zeit</a> in der Konzeptphase in unserer Schublade.</p>
<p>Trotz dieser 3 doch sehr verschiedenen Anwendungen hat sich Zeitgeist als enorm vielseitig herausgestellt. Es hat sich ausgezahlt viel Zeit in die Konzeption, aber auch die dauernde Refakturisierung der Komponenten zu investieren. Bei der Entwicklung steht der agile Ansatz &#8220;Fail early, Fail often&#8221; im Vordergund. Wenn eine Komponente nicht funktioniert, oder sich als zu unflexibel herausstellt, wird sie entfernt und durch eine komplett neu geschriebene ersetzt, ganz egal wie viele Module bereits darauf aufbauen. Dies mutet zunächst wie ein in der Praxis untragbarer Luxus an, erhöht aber die Qualität der Lösungen enorm und spart auf lange Sicht viel Zeit, die sonst in die Anpassung unflexiblen Codes fließen würde.</p>
<p><strong>Vorläufiges Fazit</strong></p>
<p>Bisher sind wir sehr zufrieden mit der Entwicklung von Zeitgeist. Der generische Ansatz erlaubt es unterschiedliche Anwendungen schnell und nachvollziehbar auf das Framework zu setzen. Die Struktur eines Projekts ist übersichtlich und alle Schichten sind logisch und von der Entwicklung her voneinander getrennt:</p>
<ul>
<li>Kein projektspezifischer Code im Framework</li>
<li>Keine Anwendungslogik in der Ablauflogik</li>
<li>Saubere Präsentationsschicht  ohne Logik- oder Ablauf-Code</li>
<li>Beliebige Technologie für Benutzeroberflächen (XHTML, Flash, Silverlight, ..)</li>
</ul>
<p>Über die Zeit werden wir mehr Informationen zu dem Framework hier posten. Was jedoch zur Zeit nicht passieren wird ist, dass wir Versionen unseres Frameworks veröffentlichen. Dies ist für einen späteren Zeitpunkt geplant, jedoch steht noch nicht fest unter welchen Bedingungen.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zeitalter3.de/2008/07/29/der-motor-zeitgeist/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

