Weltenraum

Ein zugbasiertes 2D-Strategie-Spiel

- Konzept -
paperless RFC paper, 28./29.Feb 2002.
License: GPL.
Autor: tk@taponet.de

Worum geht's?
Erinnerst Du dich an VGAPlanets von Tim Wissemann, oder Tradewars damals auf dem Amiga? Das waren Spiele, bei denen die Begeisterung auch nach Tagen und Wochen nicht nachgelassen hat. Diese recht frühen Multiplayer-Spiele funktionierten nach dem Prinzip, dass jeder Spieler basierend auf seiner aktuellen Sicht der Welt seinen nächsten Schritt spielte, um dann sein "Turn-File" zum Server zu schicken. Dort wurde dann alle Turn-Files ausgewertet, und jeder Spieler erhielt ein File mit Updates über die aktuelle Situation seiner Planeten, Raumschiffe usw.

Diese Spieleart kommt vor allem denjenigen Spielern entgegen, die nicht fünf Stunden am Stück im Netz zocken wollen -- oder können. Denn irgendwoher muss ja das Geld kommen, und nach sechs bis acht Stunden am PC ist man so platt, dass eine Online-Multiplayer-Session nach der Arbeit kaum noch in Frage kommt. So hat man bei einem zugbasierten Spiel ein paar Tage Zeit für seinem Zug, kann sich in Ruhe eine Strategie ausdenken, und dann in einem entspannten Moment handeln.

Angesichts der positiven Erinnerungen jedes ehemaligen Spielers dieses Genres habe ich mich gewundert, warum es unter dem hippen Betriebssystem Gnu/Linux noch kein entsprechendes Spiel gibt, zumindest keines, das man irgendwie als "etabliert" bezeichnen könnte. Es gibt u.a. auf Sourceforge ein paar Projekte in die Richtung -- ein richtiger Fortschritt bei den Projekten ist jedoch nicht auszumachen...

Nun, das fand' ich so schade, dass ich mir in den Kopf gesetzt habe, selbst ein allerdings plattfomübergreifendes Spiel für dieses Genre zu entwerfen. Eines mit offenen Protokollen und Datenformaten, so dass es recht einfach sein sollte, Clients für verschiedenste Systeme zu programmieren.
 

Warum 2D?
Vor kurzem probierte ich ein in Java geschriebenes Projekt dieses Genres aus, "Universe!", das ein 3D Weltraum-Modell benutzt. Man kann dabei sogar mit Sternen unserer Milchstraße spielen -- eine nette Idee... Auch macht es viel Spaß, die Sternenkarte in alle möglichen Richtungen zu rotieren. Nur wenn ich mir dabei vorstelle, ich wollte ein Route planen, die mein Schiff über drei Sterne zum Ziel führt, dann bekomme ich schnell Probleme: Irgendwie ist zumindest mein Gehirn zu sehr auf Flächenvorstellungen getrimmt, als dass ich auf Anhieb sagen könnte, bei welcher Route ich am effizientesten bei meinen Planeten vorbeischauen könnte.
Ich denke, irgendwie könnte das damit zusammenhängen, dass wir in einer 2D-Welt leben. Sicher, es gibt Bäume und Wolken usw, jedoch bewegen wir uns immer nur auf einer Fläche. Berge sind Ausbeulungen der Ebene, wobei wir uns weiterhin nur auf der Oberfläche bewegen. Stockwerke in Häusern sind ein Trick, bei dem Ebenenteile übereinander gestapelt werden -- auch dort bewegen wir uns aber immer auf einer einzelnen Ebene, und nicht etwa frei Raum.
Wer jetzt einwenden mag, dass ein 2D-Weltraum unrealistisch sei, der erkläre mir bitte, wie ein Warpantrieb funktioniert, oder wie 500 Planeten ohne eine einzige Sonne existieren können... :-)

Von dem Universe!-Projekt kann man übrigens auch lernen, wie wichtig eine umfassende Dokumentation des Programms ist -- ohne selbige ist es für Quereinsteiger heftig schwer, einen Einstieg zu finden...
 

Der Kern: der Server
Das zentrale Element des Spiels ist der Server, also der Ort, wo die Turnfiles verarbeitet werden, und wo die Eigenschaften und Naturgesetze der simulierten Spielwiese verwaltet werden. Mir kommt dabei gerade die Idee, dass die Spielwiese ja auch wörtlich genommen werden könnte: eine Wiese, auf der Ameisenvölker verschiedener Arten um Nahrungsbrocken, Siedlungsmöglichkeiten usw. kämpfen... :-)
Der Server steht bestenfalls irgendwo im Internet, so dass er jederzeit Turnfiles von Spielern entgegen nehmen kann, und von wo aus er entweder das Abholen der neuen Gamefiles durch Clients ermöglicht, oder selbst aktiv per Email die neuen Gamefiles an die Clients senden kann.
Allein aus der Tatsache, dass die meisten Internetserver mit Linux, Unix oder einem dickeren Windoze betrieben werden (letztere z.B. an einer Flatrate) folgt eine relativ enge Auswahl für die Programmiersprache, in der man den Serverprozess realisiert. Da gerade eine objektorientierte Programmierung Modularisierung unterstützt (die brauchen wir, wenn mehrere Leute am Projekt arbeiten), schrumpft die Gruppe der passenden Sprachen zusammen auf Python, Java und C++.
Dabei wären nur C++ und eventuell noch Python geeignet, durch das Erstellen von Compilaten zumindest einfachen Manipulationsversuchen entgegen zu wirken (Ein Javakompilat ist zu schnell dekompiliert und manipuliert).
Die letzte Entscheidung ist hier allerdings noch nicht gefallen.

Die Spielbedingungen müssen in einem weiten Rahmen modifzier- und erweiterbar sein. Man könnte dabei überlegen, z.B. die Rassen und ihre speziellen Eigenschaften in einem XML-File unterzubringen, oder einer vergleichbaren Sache (YAML?), die zur Not auch mit einem normalen Editor korrigierbar ist.
Alle Einstellungsmöglichkeiten müssen gut dokumentiert werden -- und es sollte wohl am besten von Anfang an ein Konfigurations-Tool existieren, das GUI-basiert eine bequeme Einstellung der Parameter ermöglicht.
Jede Änderung/Erweiterung des Servers um Parameter MUSS dann gleichzeitig auch im Konfig-Tool vorgenommen werden, damit niemals Expertenwissen notwendig ist, um den Server nutzen zu können.
Für die Programmierung eines solchen Tools würde sich Java anbieten -- denn nur für Java existiert unter Linux neben der Sprache auch eine umfassende professionelle Dokumentation.

Der Server sollte übrigens autark funktionieren, also ohne einen Benutzer, der erst die Turnfiles aus Emails zusammenklauben muss, um dann HOST.EXE zu starten, und danach neue Emails zu schreiben.
Da man eigentlich immer gerne Möglichkeiten nutzt, um anderen Spielern in die Karten zu spieken, muss es möglich sein, die Turn-/Gamefiles verschlüsselt zwischen Server und Clients auszutauschen.

Achja, es ist nicht so gedacht, dass ein einzelner erdweit zentraler Server servt, vielmehr soll jeder einen Server aufsetzen können, wobei dann zB in den Gamefiles die Information an den Client gesendet wird, wohin dieser seine Turnfiles schicken muss -- und wie.
Jeder Server sollte in der Lage sein, mehrere Spiele zu verwalten.

Man muss noch eine sinnvolle Process-Order für die Tasks auf dem Server definieren. Was ist zum Beispiel, wenn ein Schiff Cargo ablädt und dann ein feindliches Schiff angreift, während der Gegner seinem Schiff nur das ATTACK-Kommando gegeben hat? Wird dann erst die Fracht abgeladen, und dann findet der Fight statt, oder beeinflusst der Angriff des Gegners das Abladen der eigenen Fracht?
 

Die Clients
Sie bilden die sichtbare Schnittstelle zum Spieler. Eine grafische Oberfläche ist das mindeste (eine Starmap in ASCII dürfte nicht wirklich überzeugend wirken), und sie sollte an persönliche Wünsche anpassbar sein (Skins? Grafiken für Objekte wie Schiffe, Planeten, Basen bzw. Ameisentransporter, Abfallkörbe, magische Technikzentren). Nur wenn ein Spieler sich in seinem Client wohl fühlt, wird er mit Spaß beim Spiel sein -- und bleiben :-).
Der Ur-Client wird vorerst mit einem ASCII-Interface ausgestattet sein, da die vorerst wichtigste Arbeit ein gutes Serverdesign ist. Diesen ersten Client werde ich in Python implementieren.
 

Das Turnfile-Protokoll -- oder wie sage ich's dem Server
Ich habe mich eine Zeit lang mit dem Versuch beschäftigt, einen Linuxclone von VGAPlanets (Tim Wissemann) zu programmieren. Bei jenem Spiel gibt es ein Hackerfile, in dem die Formate aller involvierten Dateien beschrieben wird. Alle wichtigen Daten sind wohl in Records (TurboPascal?) gespeichert, und nicht offiziell dokumentiert. So gesehen ist es nicht leicht, Zusatzsoftware oder alternative Clients zu erstellen (ok, VGAPlanets ist/war kommerzielle Software).
Mir schwebt für dieses Projekt zumindest für die Turnfiles ein Format vor, dass sich in einem gewissen Rahmen selbst erklährt. Für den nicht verschlüsselten Zustand schwebt mir da etwas vor in der Art eines Logfiles oder Protokolls. Wenn man im Client beispielsweise einem Schiff 1 befiehlt, Fracht auf den Planeten 123 abzuladen, und dann Kurs auf Planet 54 zu setzen mit 90% Speed (des installierten Antriebs), dann könnte das im Turnfile zum Bleistift wie folgt aussehen:

1 TRANS_CARGO_SHIP_PLANET 1 123 1 400
2 SHIP_NEW_PLANET_TARGET 1 54 90
3 ...

Vorne habe ich mal eine laufende Nummer gedacht. Die Einträge erfolgen zeilenweise -- das vereinfacht die Verarbeitung der Einträge. Das Schlüsselwort gibt die Aktion an, also das Abladen von Ladung von einem Schiff auf einen Planeten, gefolgt von den IDs des Schiffs, des Planeten, der Frachtart (welches Erz oder Clans oder so), und der Menge in kilo-Tonnen.
Die IDs der Arten an Fracht und eventl auch die Information, welcher Schiffstyp einzelne Frachtarten (verstrahlten Müll?) transportieren kann, wird beim Einrichten des Spiels auf dem Server festgelegt.
Diese Daten werden dann entweder nur mit dem ersten Gamefile, oder auch auf Anfrage an den Client gesendet. Hier eine ID zu nehmen kann Vorteile haben (so ist es einfach, eine Zahl an den Client zu senden und wieder via Gamefile im Server zu erhalten, bei einem Erz "Schlöfahn" ist das nicht so leicht (Umlaute, Sonderzeichen) ...

Die zu implementierenden Kommandos müssen noch definiert werden, darunter z.B.:
- Transfer von Cargo von (Schiff|Planet) zu (Schiff|Planet|Space).
- Kommandos vom Schiff an die Werkstatt einer Raumstation.
- Baukommandos für Fabriken, Minen usw auf einem Planeten.
- Besteuerung von Eingeborenen
- Bauaufträge für Schiffe, Waffen, Munition, Antriebsysteme (Raumbasis)
- Investitionen in Forschungseinrichtungen (zur "Erfindung" neuerer Antriebe/Waffen)
- Minen legen
- Schiffe bewegen (Ziele setzen, stoppen), Auch Raumkoordinaten als Ziel. ggf. auch eine Richtung?
- Angreifen von Feinden
- Allianzen festlegen
- Schiffe/Planeten/Raumstationen an anderen Spieler abgeben
usw...

Alle diese Kommandos MÜSSEN in einer Art API dokumentiert sein.

Eventuell wäre es sinnvoll, den Text, der im Client einen Planeten beschreibt, serverseitig festzulegen. Damit es auch ein Mülleimer in einem Park sein kann. Ein Mülleimer mit vielen leckeren Sachen für die Ameisen-Kolonie...
 

Vom Server zum Client: das Gamefile
Wenn der Server alle Turnfiles erhalten hat, wertet er diese aus, und erzeugt einen neuen internen Zustand der gesamten Welt. Dann muss er jedem Spieler/Client dessen spezifische aktuelle Sicht der Welt mitteilen. Ich denke, dass hier XML oder YAML das passende Format ist --  ein strukturiertes Datenformat, dass sich recht einfach verarbeiten lässt. Dabei kann man auf Clientseite entweder direkt mit dem DOM-Objekt arbeiten, oder man übersetzt einzelne Teile des XML-Baums in z.B. Schiff-Klassen, Planeten-Klassen, usw., die man in einem geeigneten Container speichert. Der Weg über XML dürfte die Implementierung von Clients erheblich weniger behindern als etwa Dateien mit Records drin, die eine wilde Mischung an Words, Bytes, vorzeichenbehaftete Zahlen, Characters usw enthalten.

Das Worldfile
Diese Datei, auch wohl ein XML-Dokument, gibt dem Client vielfältige Informationen darüber auf den Weg, mit welchen Spielregeln, Naturgesetzen, usw. gespielt wird. Es sollte dem Client auch Auskunft darüber geben, welche Schifftypen er bauen kann, was das bauen kostet usw., welche Waffensysteme er bauen kann, wie teuer die sind, wie effizient seine Rasse beim Fördern von Erzen ist, usw.
Sprich: alles was für das Spiel konfiguriert wurde, und von dem der Spieler Kenntnis haben darf, muss hier rein.
Eventuell soll das Worldfile auch Informationen darüber enthalten, wie ein Ding mit Ressourcen drauf zu nennen ist (Planet, Mülleimer, Sonne), wie Transporter heißen (Schiff, Ship, Raumschiff, Muli), usw. Dazu muss auf Serverseite für jeden Spieler neben Spieldaten wie Rasse, Anfangsausstattung usw auch die Sprache des Spielers (Deutsch, Esperanto, Englisch) eingestellt werden, so dass der Spieler ein an ihn angepasstes Worldfile erhalten kann.
Die zentrale Verwaltung von Sprachspezifika hat den dicken Vorteil, dass dieser Kram nur einmal programmiert werden muss. Denkbar ist da eine serverseitige Struktur, bei der die sprachspezifischen Daten in XML-Files untergebracht sind -- entweder ein File pro Sprache, oder ein Zweig pro Sprache.
Ersteres hat den Vorteil, dass das Erweitern um eine Sprache simpler wäre. Wichtig auch hier: es braucht ein GUI-Tool, das jemanden bei der Erstellung eines Language-Files unterstützt, damit die Files auch wirklich die korrekte Struktur haben. Außerdem vermindert es die Frustgefahr auf Seiten des freiwilligen Helfers immens.
 

Weitere Gedanken/Ideen:

Die Konfiguration eines Servers sowie zB die Erstellung von Sprach-Files durch Mitcoder setzt jeweils ein GUI-Tool für die Eingabe der strukturierten Daten voraus. Dabei wäre noch zu klären, ob der Anwender die Struktur überhaupt sehen muss (XML-Treeview) -- jedenfalls braucht es eine Art wiederverwendbares Tool für die Pflege von XML-Dateien. Ein Tool, dass auf Windows und Linux laufen sollte. In Java geschrieben? Dann müsste man nicht mehrere Programme parallel pflegen...
Oder man baut ein Windows-Programm (Delphi?) und eins für Unix (Python+GTK oder AnyGui), und denkt sich einen coolen Mechanismus aus, bei dem man dem Programm mit einem Steuerfile sagt, welche Einstellungen möglich sein sollen. Das ist dann schon ein eigenes Projekt... :-)

Eine Sache, die mir bei VGAPlanets nicht gefällt, ist die Tatsache, dass man in seinem Client die Positionen aller Planeten des ganzen Clusters sieht, obwohl man ja nicht überall gewesen ist. Eigentlich sollte ein Spieler nur die Sterne sehen, von denen er durch Erkundung oder Austausch mit Allierten Kenntnis hat. Damit die flachen Raumkoordinaten der Planeten und Schiffe dem Spieler nichts verraten, braucht jeder Spieler ein eigenes Koordinatensystem -- das könnte sein Heimatplanet sein, oder in einem anderen Szenario auch die erste Position seines Schiffes mit den Kolonisten. Dieser persönliche Koordinaten-Ursprung muss auf der Serverseite gespeichert werden.

Eigentlich müsste ja auch jeder Spieler die von ihm "entdeckten", bislang unbekannten, Planeten selbst benamen. Wenn ein Spieler dann eine Allianz eingeht, importiert er den Planeten-Namensraum eines anderen Spielers. Da dieser mit einem Scanner vielleicht einen Planeten auch schon gesehen (und benamt) hat, der "mir" gehört, kann ein Planet so auch mehrere Namen haben. Da muss man sich dann etwas einfallen lassen, wie man die Namen händelt (A.BigPlanet / B.Vulcan). Planeten, die man entdeckt, werden vom Server spielerspezifisch durchlaufend nummeriert. Dass ein Spieler den Namen eines entdeckten Planeten ändern kann ist dann eine Art extra-Service -- der Planet wird weiterhin über seine eindeutige ID angesprochen (und das ist die ID aus Sicht des Spielers).
Wenn 11 Planeten habe, und dann durch eine Allianz Informationen über 20 weitere Planeten erhalte, dann muss der Server sich für diese 20 weiteren Planeten merken, dass sie für Spieler 1 diese Nummern, für Spieler 2 aber jene Nummern tragen. Und ggf. verschiedene Namen.
Lustig wird es dann, wenn ich einen ganzen Planeten an einen Allierten übergeben will.

Für das Setzen eines Namens gibt es dann genau wie auch bei Schiffen ein entsprechendes Kommando (z.B. PLANET_SET_NAME  ID Name_als_Unicode).

En weiteres Thema ist das möglicher Start-Szenarien.
- Start mit Planet und 2 Schiffen
- Start mit Planet mit besteuerungfähigen Eingeborenen plus 2 Schiffe.
- kleine Flotte mit Kolonie-Schiff, das sich auf einem Planeten auf Kommando zerlegt, und Minen und Fabriken anlegt.
- Wrapping Space Borders (Kugelfläche): Der Weltenraum hat keine Grenzen, wenn man weit genug nach links fliegt kommt man von rechts wieder zum Startpukt zurück. Frage: Wie siehts in den Ecken aus? :-) Es wird dann sicher auch Spaß machen, im Client die Starmap so zu programmieren, dass sie die Gitterlinien auf einer Kugel immer richtig zeichnet :-)
 

Welche Projektteile sind wichtiger als andere
Es braucht von Anfang an ein Konzept für die entwicklungsnahe Dokumentation der Zusammenhänge der einzelnen Module, der Hostorder, der Befehle im Turnfile, und des Formats der Gamefiles.
 

----------------- wird fortgesetzt. ---------------