<?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; Gamestates</title>
	<atom:link href="http://blog.zeitalter3.de/tag/gamestates/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.zeitalter3.de</link>
	<description>Ein Blog über persistente Browsergames und deren Entstehung</description>
	<lastBuildDate>Sat, 07 Aug 2010 06:22:27 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Das Gamesystem-Modul</title>
		<link>http://blog.zeitalter3.de/2010/02/13/das-gamesystem-modul/</link>
		<comments>http://blog.zeitalter3.de/2010/02/13/das-gamesystem-modul/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 10:22:46 +0000</pubDate>
		<dc:creator>Dirk</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Zeitgeist-Framework]]></category>
		<category><![CDATA[Entity Systeme]]></category>
		<category><![CDATA[Gamestates]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Zeitgeist]]></category>

		<guid isPermaLink="false">http://blog.zeitalter3.de/?p=712</guid>
		<description><![CDATA[Zeitgeist hatte, obwohl als Framework für Spiele konzipiert, lange Zeit keine eigenen Funktionalitäten die speziell für Spiele ausgelegt sind. Wenn man genauer nachdenkt sind viele Anforderungen an ein PBBG genau die Selben wie für alle anderen Webanwendungen: Verwaltung der Nutzer und deren Daten Ein Eventhandler zur Ablaufsteuerung Konfigurationsmanagement für die Applikation, Sprachen usw. Sicherheit und [...]]]></description>
			<content:encoded><![CDATA[<p>Zeitgeist hatte, obwohl als Framework für Spiele konzipiert, lange Zeit keine eigenen Funktionalitäten die speziell für Spiele ausgelegt sind. Wenn man genauer nachdenkt sind viele Anforderungen an ein PBBG genau die Selben wie für alle anderen Webanwendungen:</p>
<ul>
<li>Verwaltung der Nutzer und deren Daten</li>
<li>Ein Eventhandler zur Ablaufsteuerung</li>
<li>Konfigurationsmanagement für die Applikation, Sprachen usw.</li>
<li>Sicherheit und Fehlerbehandlung</li>
</ul>
<p>Doch welche Eigenschaften und Funktionalitäten brauchen Spiele, die sich nicht aus einem allgemeinen Framework für Webapplikationen ergeben?</p>
<p><span id="more-712"></span></p>
<p><strong>Auf der Suche</strong></p>
<p>Am Anfang stand die Idee, dass Zeitgeist ein Framework speziell für Spiele sein sollte. Mit der Zeit wandelte es sich zu einem allgemeinen Framework für Webanwendungen und alle Abläufe für Spiele musste das Spiel selbst liefern. Nach 3 Spiele-Prototypen stellte ich jedoch fest, dass es Elemente gab, die in jedem Spiel vorkommen und somit genauso gut in ein generisches Modul für Spiele ausgelagert werden könnten.</p>
<p>Um zu bestimmen, was ein solches Spielsystem eigentlich können soll, muss man sich darüber im Klaren sein, was ein Spiel aus Sicht einer Applikation eigentlich ist. Ich habe lange hin und her gestrichen und kam schließlich auf folgende Definitionen:</p>
<ul>
<li>Jeder Benutzer mit einer Session ist ein potentieller Spieler</li>
<li>Jede Instanz der Applikation ist ein potentielles Spiel (<a href="http://www.raphkoster.com/2009/01/08/database-sharding-came-from-uo/" target="_blank">Sharding</a>)</li>
<li>Jedes Spiel hat Spieler</li>
<li>Jeder Spieler hat Metadaten, die seinen Zustand im Spiel beschreiben</li>
<li>Das Spiel an sich hat ebenfalls Metadaten, welche die Spielwelt definieren</li>
<li>Spieler agieren mit anderen Spielern und der Spielwelt durch das Spiel</li>
<li>Jede Interaktion mit dem Spiel wird durch eine Aktion abgebildet</li>
<li>Aktionen verändern die Metadaten der Spieler und der Spielwelt</li>
<li>Aktionen können sich unmittelbar oder zukünftig auswirken</li>
</ul>
<p>Das ergibt folgende Komponenten:</p>
<ul>
<li><strong>Aktionsverwaltung</strong>: Ein Eventhandler, der alle Aktionen verwaltet, die ein Spieler (oder Spiel) ausführen kann</li>
<li><strong>Datenhaltung</strong>: Ein System, welches alle Daten verwaltet, die einen Spieler oder die Spielwelt betreffen können</li>
</ul>
<p>Nun, auf den ersten Blick deckt sich die Aktionsverwaltung des Spiels mit der Ablaufsteuerung einer Webapplikation und die Datenhaltung ebenfalls. Brauchen wir wirklich alles nochmal, obwohl das Framework alles schon mitbringt?</p>
<p>Kurze Antwort: ja.</p>
<p><strong>Der Gamehandler</strong></p>
<p>Der Gamehandler besteht im Wesentlichen aus 2 Komponenten: einem Eventhandler, der hereinlaufende Aktionen verwaltet und einem Gamehandler, der die Aktionen auf die Logik mappt.</p>
<p>Eine Aktion des Eventhandlers hat folgende Parameter:</p>
<ul>
<li>Aktion: Eine ID für eine Aktion, die auf ein Stück Code gemapped werden kann</li>
<li>Parameter: Ein Parameter-Objekt, welches dem Aktionscode mitgegeben wird</li>
<li>Ausführungszeit: Der Zeitpunkt im Spiel, an dem die Aktion relevant wird</li>
<li>Spieler: Der Spieler, der die Aktion ausgeführt hat</li>
<li>Shard: Die ID des Shards, auf dem die Aktion ausgeführt wird</li>
<li>Zeitpunkt: Der Zeitpunkt, an dem die Aktion ausgeführt wurde</li>
</ul>
<p>Durch die Angabe des Shards wird ermöglicht, dass mehrere Spiele in einer Datenbank abgelegt werden können. Dies ist unabhängig davon, ob die Spiele selbst auf einem oder mehreren Servern laufen. In einem typischen Aufbau-Strategie-PBBG ist es meistens so, dass viele Mitspieler in einem Spiel (bzw. einer Spielwelt) agieren. Bei Spielen mit einer kleinen, abgegrenzten Anzahl von Spielern pro Spiel (Bsp. Tic Tac Toe) laufen viele Spiele gleichzeitig nebeneinander. Solange für jeden Spieler die ID seines eigenen Spiels mitgegeben wird, lassen sich die Daten sauber trennen.</p>
<p>Der Gamehandler mappt die vom Eventhandler aufgenommenen Aktionen auf Klassenobjekte. Jede Aktion steht also für eine externe Klasse, welche für die eigentliche Logik hinter der Aktion sorgt. Was dort dann genau passiert ist nicht mehr Sache des Gamehandlers. Er reicht nur alle relevanten Aktionen für einen gegebenen Zeitpunkt, einen gegebenen Spieler und ein gegebenen Shard weiter.</p>
<p>Alternativ zu dem Gamehandler kann natürlich auch ein permanent laufender Application Server eingesetzt werden, der andauernd die Eventliste abarbeitet.</p>
<p><strong>Datenhaltung</strong></p>
<p>Die Datenhaltung muss für alle Spiele und alle Spieltypen passen. In der Theorie müsste sie also die Daten eines typischen Aufbau-Strategie-PBBG genauso gut verwalten können, wie die einer Tic Tac Toe Plattform.</p>
<p>Das ist natürlich Unsinn. Eine spezialisierte Datenhaltung, die genau auf das Projekt zugeschnitten ist wird immer performanter, aber vor allem auch lesbarer sein, als eine generische. Aber: eine solche spezialisierte Datenhaltung zu entwickeln kostet Zeit. Bei einem Tic Tac Toe mag der Zeitaufwand sehr gering sein, aber man wird schnell an die Grenze stoßen, wo man überlegen muss, ob es sich tatsächlich lohnt sofort auf eine performante Datenhaltung zu optimieren, oder ob nicht erst einmal eine generische genügt.</p>
<p>Aber gibt es Datenstrukturen bzw. Ansätze, mit denen man so unterschiedliche Anforderungen abdecken kann? Antwort: ja, gibt es. Es ist nicht so, als hätte die Spieleindustrie nicht schon lange an dem Problem zu knabbern. Deren Antwort lautet: <a href="http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/" target="_blank">Entity Systeme</a>.</p>
<p>Die Gamedata-Klasse nimmt sich 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> zum Vorbild und implementiert diese in PHP. Für Details und Erklärungen der Funktionsweise verweise ich auf den <a href="http://t-machine.org/index.php/2009/10/26/entity-systems-are-the-future-of-mmos-part-5/" target="_blank">Artikel</a>, der das so wie so viel besser erklärt, als ich hier in Kürze könnte.</p>
<p>Im Einzelfall muss aber jeder selbst entscheiden, ob er diese nutzt, oder ob es sinnvoller ist die Datenhaltung speziell für das Spiel zu entwickeln.</p>
<p><strong>In Aktion</strong></p>
<p>Die letzten beiden Versionen der Spiele-Prototypen wurden mit dem <a href="http://code.google.com/p/zeitgeist-framework/source/browse/#svn/framework/trunk/modules/gamesystem" target="_blank">neuen System</a> umgesetzt und ich bin ziemlich zufrieden. Ich werde mich bemühen in den kommenden Wochen ein kleines Spielchen damit (möglichst sauber) zu entwickeln und als Beispiel ins SVN aufzunehmen.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zeitalter3.de/2010/02/13/das-gamesystem-modul/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Spielzustände</title>
		<link>http://blog.zeitalter3.de/2009/02/15/spielzustande/</link>
		<comments>http://blog.zeitalter3.de/2009/02/15/spielzustande/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 13:12:02 +0000</pubDate>
		<dc:creator>Dirk</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Gamestates]]></category>
		<category><![CDATA[Pipeline]]></category>

		<guid isPermaLink="false">http://blog.zeitalter3.de/?p=542</guid>
		<description><![CDATA[Das Projekt hat gerade eine lange Refakturierungs-Phase hinter sich. Ziel war es, die eigentliche Spiel-Pipeline zu überarbeiten. Kurz zur Problematik: ein Spieler führt eine Aktion aus, beispielsweise will er sich nach Punkt D bewegen. Daraus ergeben sich einige Fragen. Darf er das in diesem Moment? Wie lange braucht er dazu? Wo befindet er sich überhaupt [...]]]></description>
			<content:encoded><![CDATA[<p>Das Projekt hat gerade eine lange Refakturierungs-Phase hinter sich. Ziel war es, die eigentliche Spiel-Pipeline zu überarbeiten.</p>
<p>Kurz zur Problematik: ein Spieler führt eine Aktion aus, beispielsweise will er sich nach Punkt D bewegen. Daraus ergeben sich einige Fragen. Darf er das in diesem Moment? Wie lange braucht er dazu? Wo befindet er sich überhaupt in diesem Moment gerade? Um eine Aktion auszuführen muss das System also in dem meisten Fällen erst einmal wissen, in welchem Zustand sich der Spieler befindet (im Sinne von Ort, Zeit etc.).</p>
<p>Die Reihenfolge sieht also in etwa so aus:</p>
<ul>
<li>Ein Spieler führt eine Aktion aus</li>
<li>Das System schaut, in welchem Zustand sich der Spieler befindet</li>
<li>Es prüft, ob diese Aktion dem Spieler im Moment gestattet ist</li>
<li>Falls ja führt es sie aus und stößt eventuelle Konsequenzen (für den Spieler selbst und für andere Spieler) an</li>
</ul>
<p>Das klingt so weit ganz einfach, doch spannend wird es, diesen Ablauf in einen sauber verständliches und vor allem performantes Konstrukt zu bringen. Je nach Spiel kann der aktuelle Status des Spielers recht kompliziert werden. Insbesondere, wenn er noch mit anderen Spielern interagiert.</p>
<p>Das aktuelle Konstrukt sieht in etwa so aus:</p>
<p><img class="aligncenter size-full wp-image-543" title="lineracer_spielverwaltung" src="http://blog.zeitalter3.de/wp-content/uploads/2009/02/lineracer_spielverwaltung.jpg" alt="lineracer_spielverwaltung" width="450" height="162" /></p>
<p>Zur Erklärung:</p>
<ul>
<li>Die Präsentationsschicht nimmt die Eingaben der Spieler auf</li>
<li>Die Aktionsverwaltung stößt die entsprechenden Prozesse an, die zu einer Aktion gehören</li>
<li>Der aktuelle Spielzustand, der den Benutzer betrifft, wird generiert. Er setzt sich zusammen aus den relevanten vergangenen Aktionen des Benutzers und aus den Events, die ihn in diesem Moment betreffen</li>
<li>Diese ganzen Daten werden zu einen aktuellen Snapshot der Situation für den Spieler verarbeitet und in einer Struktur gespeichert</li>
<li>Die Aktionen der Aktionsverwaltung greifen auf diese Struktur zu und führen die vom Spieler durchgeführten Aktionen aus</li>
<li>Zukünftig wirkende Aktionen werden als Events gespeichert</li>
<li>Die gerade durchgeführte Aktion des Spielers wird gespeichert, um später den Spielzustand wieder zu rekonstuieren</li>
</ul>
<p>Durch die selektive Betrachtung des für den Spieler relevanten Spielzustands werden unter Umständen eine ganze Menge Ressourcen gespart. Darüber hinaus gibt es durch die gespeicherten Aktionen ein definitives Backlog, was jeder Spieler wann gemacht hat. Ein schöner Nebeneffekt ist damit die komplette Nachvollziehbarkeit, um Fehler im Ablauf zu finden, aber auch um Cheater aufzuspüren. Um die Größe der Daten mache ich mir in diesem Fall keine Sorgen: die Tabelle enthält nur die ID des Spielers, die ID der Aktion, die Parameter und einen Zeitstempel. Entsprechend alte Einträge werden in eine Archiv-Tabelle verschoben.</p>
<p>Alles in allem hat mich das jetzt lockere 2 Wochen gekostet bis alles Hand in Hand griff und ich mit dem Design zufrieden war (zumindest bis zur nächsten Refakturierungs-Runde). Als weiteren Nebeneffekt habe ich die Unit-Tests der Pipeline überarbeitet: sie benutzen nun zufällige IDs zum Erstellen von Objekten. Vorher kam es vor, dass ich im Code Primärschlüssel vertauscht hatte und die Tests nicht Alarm schlugen, weil beide im Test den Wert 1 haben sollten. Es knallte erst im eigentlichen Spiel an der entsprechenden Stelle. Faulheit verfolgt einen bei Unit Tests eben immer.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zeitalter3.de/2009/02/15/spielzustande/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
