Schlagwort-Archive: Remake

Exemplarisch wie ich mein SPACOLA-Remake entwickle, eine kleine Anekdote aus meinem Leben als Softwareentwickler: Bei meinen ziellosen Recherchen zur Historie des Atari ST und seiner erstaunlichen, reichhaltigen Public-Domain-Welt stolperte ich über eine kurze Spezifikation des Dateiformats für Bilddateien aus dem sehr beliebten Zeichenprogramm STAD. Der Name ist ein Akronym und steht für ST-aided Design. Das Programm wurde 1986 von Peter Melzer bei den Application Systems Heidelberg veröffentlicht und eröffnete den Nutzern ungeahnte Möglichkeiten – selbst 3D-Modellierung war damit machbar, wenn auch äußerst sperrig und unbequem. Auch meine Wenigkeit verbrachte in den 80ern und 90ern sehr viele Kindheitstage mit dem Malen von lustigen Bildern und Animationen in STAD. Achja, bevor ich darauf angesprochen werde: Ja, rein theoretisch war STAD keine PD-Software, aber wir wissen doch alle wie das damals so lief. Wer kennt nicht die berüchtigte Diskettenwanderung.

Die Bilder konnten in mehreren verschiedenen Formaten abgespeichert werden, darunter unkomprimiert als Doodle, gepackt, oder als DEGAS-Bild (ein weiteres zeitgenössisches und sehr bekanntes ST-Zeichenprogramm). Dabei entwickelte Melzer mit den gepackten .PAC-Bilddateien sein eigenes Bildformat, das die Bildinformationen relativ unspektakulär mittels RLE kodiert und so platzsparend auf der Diskette ablegen kann. Nun, meine Programmierkenntnisse in GFA-BASIC in den 90ern waren leider sehr begrenzt, und so konnte ich seinerzeit nur unkomprimierte Bilder in meine Progrämmchen einlesen, da ich dafür Codebeispiele in meinen Programmierbüchern fand. Im Traum hätte ich nicht daran gedacht, gepackte STAD-Bilder zu laden oder noch verrücktere Bildformate. Ich hatte schlicht keinen Code dafür, und wie andere Entwickler solche Formate in ihren Quellcode einbinden, das war für mich eher schwarze Magie.

Bekanntes Beispielbild „KRUSCH.PAC“ aus STAD. Die einzelnen Fortschritte während der Entwicklung des STAD-PAC-Konverters von oben nach unten. (Rote Bereiche sind nur Hintergrund, wo noch nichts gezeichnet wurde.)

Doch kein Problem ist für einen Haudegen wie mich alt genug um es nicht doch noch zu lösen: Kaum 30 Jahre später will ich es mir beweisen. Ich kann einen STAD-PAC-Konverter entwickeln. Vielleicht nicht mehr unbedingt in GFA-BASIC, aber zumindest in Java, und diesen damit theoretisch für mein Remake-Projekt nutzbar machen. Wofür genau? Das ist mir noch vollkommen unklar, aber wen kümmert es schon. Um eins klarzustellen: Es gibt funktionierenden Cross-Platform-Code in der Wildnis um STAD-Dateien zu laden. Unter anderem der beliebte Bildbetrachter “XnView MP” lädt alle STAD-PAC-Dateien erfolgreich, was mich anfangs extrem überrascht hat, da es doch heutzutage ein mindestens äußerst exotisches und rares Dateiformat ist. Scheint so als wolle der Entwickler dem Anspruch gerecht werden, möglichst viele Dateiformate zu beherrschen. Leider ist ausgerechnet die Software dieses Entwicklers natürlich nicht quelloffen, und daher für Studien nicht verfügbar, doch mit Hilfe der im Internet frei verfügbaren Spezifikationen wollte ich es auf jeden Fall selbst versuchen.

Und so setzte ich mich daran und begann die Spezifikation zu implementieren. Aus meiner Kindheit besitze ich unzählige eigene PAC-Dateien mit Bildchen, ich konnte aber zusätzlich sehr viele Beispieldateien im Netz finden und bei der Entwicklung zum Testen nutzen. Wie die Spezifikation beschreibt, gibt es zwei Sorten von STAD-PAC-Dateien: Die vertikal gepackten, und die horizontal gepackten. Die Implementierung der RLE-Dekodierung war dann auch tatsächlich nicht so schwer, vieles an Vorarbeit zum Bytestream-Handling hatte ich bereits früher erledigt bei der Entwicklung an meinem Shapelist- und Dongleware-PAC-Konverter. Schwierig wird es, wenn man zusätzlich Quellen im Internet findet, die zwar ebenfalls das Bildformat beschreiben, aber leider Fehler enthalten, wie einen falschen Runcount zu verwenden. Merke: Man sollte nicht alles glauben, was im Netz steht.

Schon relativ schnell erkannte ich die erste größere Schwierigkeit: Alle Internetquellen haben die Tatsache gemeinsam, dass sie die RLE-Dekodierung genau dokumentieren, aber bei den unkomprimierten Bilddaten nur noch ganz abstrakt von “use bytes” die Rede ist. Es wird tatsächlich nirgends beschrieben, wie das Bild damit genau gezeichnet werden soll. Der Teil fehlt einfach, so als wäre er entweder unnötig oder komplett trivial. Und selbst wenn die Bezeichnung “vertically packed” es so darstellt, die Pixel fortlaufend von oben nach unten zu zeichnen, ist leider nicht des Rätsels Lösung. Und so verbrachte ich noch eine Handvoll weiterer Stunden damit, die Zeichenroutinen zu debuggen, zu reverse engineeren und inkrementelle Fortschritte zu feiern, bis ich endlich eine fehlerfreie Implementierung in den Händen hielt. Gerne möchte ich das Internet mit meinen mühsam selbst gesammelten Erkenntnissen bereichern und die Spezifikationen um die überall fehlenden Informationen ergänzen:

Die vertikal gepackten Bilder (mit dem Header “pM86”) werden in Blöcken von je 8×8 Pixeln gezeichnet, wobei die Pixel innerhalb des Blocks zuerst von links nach rechts und von oben nach unten gezeichnet werden, während die Blöcke zuerst von oben nach unten und von links nach rechts gezeichnet werden. Am Ende erhält man ein binäres Vollbild mit (mehr oder weniger) 640×400 Bildpunkten. Die horizontal gepackten Bilder (mit dem Header “pM85”) werden als fortlaufende Pixelsequenz von links nach rechts und von oben nach unten gezeichnet. Vertikal gepackte Bilder sind dabei in einer erstaunlichen Mehrheit vorzufinden, während das horizontal gepackte Format vermutlich älter ist und seltener vorkommt. Immerhin ist das STAD-PAC-Format um mehrere Größenordnungen weniger komplex als das Dongleware-PAC-Format, aber selbst hier musste ich ein wenig experimentieren und basteln.

Das ebenfalls bekannte STAD-Beispielbild „ESCHER1.SEQ“, dargestellt im STAD-PAC-Konverter

Aufgefallen ist mir außerdem, dass viele STAD-PAC-Dateien mehr Zeichenanweisungen im Bytestream enthalten als es zu zeichnende Pixel auf dem Bildschirm gibt. Aus diesem Grund muss meine Implementierung überzählige Runcounts und überflüssige Bytes am Ende der Datei verwerfen, wenn das Bild vorzeitig fertig ist. Das fand ich durchaus ein wenig seltsam und unnötig. Ebenfalls bemerkenswert, dass besagter Bildbetrachter XnView MP die wenigen horizontal gepackten STAD-Dateien zwar korrekt entpackt, aber aus irgendeinem Grund falsch darstellt: Es wird ein Bild erzeugt, das 640×400 Pixel enthält, doch es wird vertikal gestreckt auf 440 Pixel. Und selbst wenn man dieses Bild direkt nach PNG konvertiert, wird es mit diesem seltsamen Streckfaktor (DPI bzw. Pixels per Unit unterschiedlich in Y-Richtung) in den Metadaten der PNG-Datei gespeichert.

Da kann ich doch glatt stolz darauf sein, dass meine Implementierung einen Fehler weniger hat als einer der bekanntesten Bildbetrachter überhaupt. Alles in allem wieder einmal ein schönes, erfolgreiches, produktives Wochenende, an dem ich eine kleine historische Software-Knobelaufgabe lösen konnte. Das SPACOLA-Remake kann nun gepackte STAD-Bilder laden, falls es mal nötig wäre. Zusätzlich habe ich auch wieder die Arbeit an einigen kleineren Aspekten an dem Spiel aufgenommen. Wie das eben so ist, ich muss mich mal wieder in das Thema reinfinden, und dafür eignen sich am besten die einfacheren Aufwärm-Themen.

Hallo? Hallooo?? Liest das hier noch irgendjemand? Schreibt hier überhaupt noch wer? Naja, zumindest die Zugriffszahlen deuten daraufhin, dass es noch vereinzelt Leser gibt, und alle paar Monate kommt doch wirklich mal ein Beitrag von mir. Also wenn euch das nicht reicht, dann müsst ihr an der Kasse euer Eintrittsgeld zurückverlangen.

Besagte Leser werden sicherlich gemerkt haben, dass ich im Prinzip aufgegeben habe – und gleichzeitig NICHT aufgegeben habe. In den letzten Monaten habe ich mich um einen neuen Job kümmern müssen, und auch sonst musste ich mir privat wieder mal über einige Dinge klarwerden. Aber das nun als den einen Grund anzuführen, wieso Success Denied vergammelt, wäre ganz einfach gelogen. Ich habe nur festgestellt, dass es mich kaum noch reizt, die Welt mit meinen kruden Ansichten zu nerven. Gleichzeitig packt mich aber dann doch selten die Schreibwut und so werde ich nun eben in wesentlich größeren zeitlichen Abständen meine wirren Beiträge in den Äther kotzen.

Das Wichtigste: Niemand hat die Absicht, Success Denied abzuschalten. Die Seite bleibt natürlich online. Das Dongleware-Museum wäre offline auch ziemlich nutzlos.

Der Grund, warum ich 2010 die Seite überhaupt ins Leben gerufen habe, war mein SPACOLA-Remake, über das ich regelmäßig schreiben wollte. Auch heute macht mir die (On-Off-)Entwicklung an dem Projekt immer noch Spaß, und meine letzten Beiträge sollten demonstriert haben, wie investiert ich in das Thema weiterhin bin: Mehr als je zuvor. Auch in Zukunft werde ich daher über die Fortschritte informieren, sofern es sie denn in nennenswerter Menge gibt.

Aber natürlich habe ich gerade in der Anfangszeit auch einige Beiträge über Politik, die Gesellschaft, Technik, und beliebige Aufregerthemen aus dem Tagesgeschehen geschrieben, von denen manche mir heute eher peinlich erscheinen. Solche Beiträge schreibe ich praktisch nicht mehr. Also kann man sagen, ich habe es aufgegeben, mir selbst Druck zu machen, wie oft ich nun in welchen Abständen Beiträge zu einem breiten Themenspektrum auf meinem Blog veröffentlichen muss. Das hat ohnehin noch nie funktioniert und wird es auch nie. Aber ich habe es nicht aufgegeben, diese Webseite zu betreiben und manchmal, oder eben manchmal auch nicht, mit neuen Informationen zu füllen.

Ich hoffe, das ergibt irgendwie Sinn. Stay tuned!

Ich will jetzt nicht unbedingt behaupten, dass ich fleißig bin, aber wenn ich mal ausnahmsweise nicht faul bin, dann bin ich so richtig nicht faul. Nach einer längeren Abwesenheit und gleichzeitigen Arbeitspause an meinem Spiele-Remake, bin ich nun endlich wieder dran. Mich hat aus irgendeinem mysteriösen Grund plötzlich wieder die Motivation eingeholt, und sofort konnte ich zumindest wieder etliche Kleinigkeiten angehen und Fehler korrigieren. Allerdings habe ich durch Zufall ganz unerwartet einen weiteren Meilenstein bei der Entwicklung erreicht; einen Punkt auf meiner To-Do-Liste, den ich definitiv irgendwann umsetzen wollte, selbst wenn dies einen Nutzen nur theoretischer Natur auf dem Papier bringt.

Was bisher geschah: Einem unfassbar mäßig begabten Entwickler eines Spiele-Remakes, der zwar nicht vom Erfolg seines Projektes überzeugt, aber dafür wenigstens nicht von seinem Ziel abzubringen ist, war es gelungen, die Original-Dateien des Atari ST-Spiels SPACOLA mit Hilfe eines Debuggers zu entpacken und anschließend sogar das undokumentierte Format der Sprite-Dateien zu dechiffrieren und einen eigenen Konverter zu schreiben. Dies sollte ihm endlich einen wichtigen Einblick in die Hintergründe der Unterhaltungssoftware einer längst vergessenen Zivilisation geben. Wie hatten unsere Vorfahren einst Spiele entwickelt? Wurden die Quellcodes damals noch in Keilschrift verfasst? Mussten Benutzer an einer Kurbel drehen, wenn sie ihren Heimcomputer starten wollten? Waren antike Computerprogramme auch nur in schwarzweiß? (In diesem Fall, ja!). Unermüdlich arbeitete der selbsternannte Software-Archäologe weiter an den historischen Dokumenten, um vielleicht irgendwann einmal das perfekte Remake zu erschaffen.

Teil 3 meines fortlaufenden Hintergrundberichts: Es war eigentlich reiner Zufall als ich im Internet auf die Reverse-Engineering-Erkenntnisse von Jeremy Sawicki aus dem Jahr 2003 stieß. Der hatte diverse OXYD-Spiele in ihren Farbversionen für den IBM-PC erfolgreich analysiert und deren Formatspezifikationen offengelegt, darunter das Levelformat, die Grafik- und Sounddateien. Seine Dokumentation war unter anderem nützlich bei der Entwicklung des freien OXYD-Klons Enigma. Als ich mir die Angaben zum Grafikformat genauer ansah, erkannte ich plötzlich viele Gemeinsamkeiten zu den PAC-Dateien, die in den alten Monochromversionen der frühen Dongleware-Klassiker Verwendung fanden. Diese Dateien enthielten binäre Vollbildgrafiken für die Spiele seit Esprit (1989) und bis mindestens OXYD2 (1991).

Ich hatte mich natürlich längst selbst mehrfach daran versucht, das seltsame Dateiformat zu dekodieren, zuletzt auf Grund meiner Erfolge beim Konvertieren der Sprite-Dateien, doch das PAC-Format widersetzte sich meinen Annäherungsversuchen konsequent. Bis auf einige sehr offensichtliche Headerinformationen konnte ich kaum sinnvolle Werte herauslesen, und meine einzigen Erkenntnisse über das Kompressionsverfahren bestanden darin, dass das Bild in Blöcke unterteilt wird, und die Pixelinformationen grundsätzlich durch ein XOR-Verfahren invertiert von oben nach unten beschrieben werden. Durch Manipulieren der Dateien im Hexeditor und anschließendem Beobachten der Auswirkungen in OXYD, stellte ich erstaunt fest, dass die Dateistruktur eine sehr eigenwillige sein musste, weil oft komplett unvorhersehbare und unintuitive Artefakte im Bild dadurch enstanden. Als ich keinerlei Gesetzmäßigkeiten ausmachen konnte, gab ich mein Vorhaben desillusioniert auf.

Seit heute weiß ich endlich sehr genau, was das große Problem war. Von Sawickis Arbeit angespornt, begann ich endlich an der Entwicklung eines eigenen Konverters, den ich letztlich in mein Remake einbauen wollte, so wie bereits getan beim Konverter für Sprite-Dateien. Ich studierte die Formatspezifikationen und implementierte die Dekompressions- und Zeichenroutinen. Ohne nun zu sehr ins Detail zu gehen (wer alles wissen möchte, kann die Originalseite lesen), besteht jede Packed-Bitplane-Datei aus einem Header, einem Bitstream und einem Bytestream. Der Bitstream beschreibt dabei die gesamte Struktur des Bildes, sowie Angaben über die Kompressionsmethodik, und der Bytestream enthält die tatsächlichen Pixeldaten, die entsprechend gezeichnet werden müssen.

Jedes Bild hat die Auflösung von 640×400 Bildpunkten und ist in Blöcken von je 16×16 Pixeln aufgeteilt. Der Bitstream beschreibt dabei, wie das Bild nacheinander in Reihen von Blöcken, Blöcken, Blockquadranten und Reihen von Pixeln in immer kleinere Häppchen aufgespalten wird, wobei jedes Element entweder übersprungen oder gezeichnet werden kann. Müssen Pixel gezeichnet werden, so wird ein Byte aus dem Bytestream gelesen und dessen Bits als Pixel interpretiert, abhängig von einer der Pixelreihen darüber, die miteinander XOR-verknüpft werden, also je nachdem ob ein Bit gekippt wird oder nicht. Die Formatspezifikation von Sawicki ist dabei technisch betrachtet soweit korrekt, aber leider an mehreren Stellen etwas unpräzise formuliert, so dass ich mehrere Fehler machte, deren Behebung mich viel Zeit gekostet hat.

Das Titelbild „TITLE.PAC“: Die einzelnen Fortschritte während der Entwicklung des PAC-Konverters von oben nach unten. (Rote Bereiche sind nur Hintergrund, wo noch nichts gezeichnet wurde.)

Während der Entwicklung fiel mir jedoch auf, dass Sawicki eines der Features des proprietären Dongleware-Formats definitiv nicht kannte: Neben dem Invert-Flag, das festlegt, ob das fertige Bild noch invertiert werden muss, gab es in meinem Archiv eine einzelne Datei, die ein undokumentiertes Flag setzt. Zum Glück konnte ich am Output des Konverters bereits erkennen, was dem Bild fehlte: Es musste ein Dithered Pattern („Schachbrettmuster“) mittels XOR über das gesamte fertige Bild gezeichnet werden, um die ursprüngliche Grafik wiederherzustellen. Dieser Modus wird wohl zwar nur sehr selten angewandt, aber mein Konverter unterstützt dieses Feature nun ebenfalls. Im Endeffekt war es mir in geschätzt sechs bis sieben Stunden gelungen, eine Implementierung abzuliefern, die sämtliche 16 PAC-Dateien, die ich aus vier Spielen gesammelt hatte, fehlerfrei einzulesen und anzuzeigen vermochte.

Ohne das hilfreiche Dokument wäre ich immer noch nicht schlauer, und sonst einen Konverter zu schreiben, hätte ich wahrscheinlich nur geschafft wenn ich viele Wochen und Monate in mühsames Debugging der Spiele investiert hätte. Ob ich mir diese Zeit jemals hätte nehmen wollen, sei mal dahingestellt. Nun bin ich umso glücklicher über diese angenehme Abkürzung, die ich nehmen konnte. Der Konverter ist fertig und bereits ins Remake eingebaut. Dadurch bin ich jetzt endlich in der Lage, auch die originalen Grafikdateien in unveränderter Form im Remake einzulesen und zu verwenden. Das macht – wie eingangs im Absatz beschrieben – für den Spieler absolut keinen Unterschied, für mich als Entwickler mit Perfektionsdrang aber einen gewaltigen.

Mein SPACOLA-Remake kann nun die ursprünglichen Sounddateien, die Sprites und die Grafikdateien korrekt lesen. An der Interpretation der originalen Leveldaten arbeite ich mich weiterhin Schritt für Schritt voran, sie werden aber immerhin schon komplett eingelesen. Alles was jetzt noch vollständig fehlt: Die Musikdaten im SMS Synthesizer-Format von Jürgen Piscol. Ob ich dieses Kapitel jemals abschließen werde, lässt sich im Moment noch nicht einmal sagen. Andererseits, wer weiß schon, ob sich nicht doch wieder jemand findet, der zufällig eine detaillierte Analyse des Formats in Schriftform für mich zur Einsicht hat. Dann könnte nämlich alles ganz schnell gehen.

Das „Boss Is Coming“-Bild aus OXYD2, dargestellt im PAC-Konverter, zeigt den Datenbank-Manager „Phoenix“ von den Application Systems Heidelberg

Und falls sich nun jemand fragt, wieviele PAC-Dateien in SPACOLA Eclipse denn nun eingelesen und angezeigt werden können: Es sind ganze vier Dateien! Erstens, das Titelbild beim Laden des Spiels. Zweitens, das typische HUD mit dem Radar auf der rechten Seite. Drittens, der Rentenbescheid zum Ausdrucken nach Abschluss des letzten Levels. Die vierte und letzte PAC-Datei ist tatsächlich ein ungenutztes Bild, das die Kontaktadresse des Dongleware-Verlages enthält. Vermutlich wurde es in einer früheren Version des Spiels verwendet, und dann durch ganz normalen Text in der Dongleware-Schriftart ersetzt. Alle diese vier Originaldateien werde ich nun ins Remake einbauen und in irgendeiner Weise nutzen, damit sich der ganze Entwicklungsaufwand auch gelohnt hat.

Wieder ist beinahe ein Jahr vergangen, seit ich den letzten Statusbericht zum SPACOLA-Remake abgeliefert habe, daher ist es nun ganz dringend an der Zeit, ein bisschen über die aktuellen Neuerungen seitdem zu plaudern. Bekanntlich habe ich eine ausgedehnte Winterpause eingelegt, so dass die Änderungen sich insgesamt in Grenzen halten, aber ein paar Fortschritte gab es durchaus. Die Entwicklung an dem Spiel verhält sich ein wenig wie ein Gletscher: Egal ob man sich heute, morgen, nächsten Monat oder nächstes Jahr danach erkundigt, wie weit das Spiel fortgeschritten ist, wird es immer so aussehen, als habe sich nichts bewegt – aber es bewegt sich doch! Und jede Änderung wird sogar schriftlich in meinem Devlog dokumentiert.

Smart-Aim

Die neueste Work-In-Progress-Version 0.92 bringt einige nette, aber hauptsächlich experimentelle Spielereien mit, die ich unbedingt ausprobieren wollte. Letztmalig kündigte ich die Möglichkeit eines Aimbots (Smart-Aim) für den Spieler an. Diesen habe ich nun tatsächlich eingebaut. Mit per Menü aktiviertem Smart-Aim muss der Spieler nur noch grob in die Richtung eines Gegners zielen und die automatische Zielhilfe passt den Schusswinkel bis zu einem gewissen Grad so an, dass ein Treffer garantiert ist. Wenn kein Treffer garantiert werden kann, greift die Zielhilfe dagegen nicht ein. Die Arbeit am im letzten Update-Artikel erwähnten Weapon-Interface ist vollständig abgeschlossen. Zusätzlich lassen sich nun ganz einfach per Mausrad die verschiedenen Waffen des Spielers durchschalten und im Spiel verwenden. Das muss nicht bedeuten, dass der Spieler im Endeffekt mehrere Waffen besitzt, aber er könnte theoretisch.

Eingabequellen

Nach dieser kleinen großen Baustelle eröffnete ich dann gleich die nächste, und so überarbeitete ich skrupellos die komplette Spielsteuerung. Meine Idee war die Entwicklung eines flexiblen InputReceiver-Interfaces, das es ermöglichen sollte, verschiedene Eingabequellen für Spieler-Inputs an die Spielerschiffe anzuschließen. Dies wird spätestens im Multiplayer-Modus ein sehr wichtiges Thema. Die konkreten InputReceiver-Implementierungen erzeugen getaktet (pro Update) einzelne „ControlActions“, also gekapselte Eingabedaten, die auf eine abstrahierte Maus und Tastatur anwendbar sind, um ein Spielerschiff und somit die Spielwelt zu beeinflussen. Genauer gesagt habe ich nun einen MouseInputReceiver, der (wie der Name schon sagt) direkt die Maus (und Tastatur) anzapft. Aber zusätzlich habe ich auch einen RemoteInputReceiver, der Benutzereingaben von anderen Mitspielern aus dem Netzwerk empfängt, einen ReplayInputReceiver, der Benutzereingaben aus einer persistierten Datenquelle einlesen und ausführen kann, und zuletzt einen BotInputReceiver, der in Echtzeit künstliche Benutzereingaben anhand eines vorgegebenen Regelwerks erzeugen kann. Moment … Replays? Bots?

Bots

Als ich über die technischen Möglichkeiten meiner dynamischen Gegner-KI, des fertigen Aimbots und der InputReceiver-Logik sinnierte, ist mir plötzlich aufgefallen, dass ich im Grunde schon die halbe Arbeit erledigt hatte, die nötig wäre, um einen kompletten Spieler-Bot zu entwickeln. Diese Idee hatte ich eigentlich schon zu Beginn des Projektes für Skirmish-Multiplayer-Spiele, wenn mal nicht genügend menschliche Mitspieler zur Verfügung stünden. Außerdem würde ein funktionaler Spieler-Bot mir die Arbeit beim Testen erleichtern, da ich nicht mehr gleichzeitig spielen und debuggen müsste, sondern mich auf das Wesentliche konzentrieren könnte. Allerdings fiel mir beim Implementieren auf, dass es wohl doch nicht so ein Spaziergang werden würde, wie ich zunächst dachte. Im Gegensatz zur Gegner-KI, die die Raumschiffe immer direkt steuern kann (drehen, beschleunigen, bremsen, schießen…), darf ein Spieler-Bot im Grunde nur Maus und Tastatur übernehmen, das Spieler-Raumschiff also indirekt mit simulierten Mausbewegungen und Mausklicks steuern. Mit Hilfe der InputReceiver war dies nun zumindest technisch kein Problem mehr. Aber natürlich musste die Logik dafür trotzdem erstmal geschrieben werden.

Nach einigen Tagen des Grübelns, Ausprobierens und auch Scheiterns hatte ich einen halbwegs glaubhaften Bot entwickelt, der in jedem Level losfliegen, bei Bedarf nützliche Powerups einsammeln, Gegner und Asteroiden beschießen und auch ins Ziel fliegen kann. Um das zu bewerkstelligen darf er im Grunde nur die Maus im Kreis bewegen, sowie die linke und die rechte Maustaste drücken. Er kann leider noch nicht ausweichen und ist auch sonst relativ blind und stur, aber er zielt immerhin ganz gut und gewinnt daher auch fast immer. Das Potenzial für Verbesserungen ist dafür enorm, z.B. müsste er verlorene Waren wieder einsammeln. Meine finalen Bemühungen, die Bewegungen des Bots realistischer zu machen, waren begrenzt erfolgreich. Dennoch ist das Ergebnis aus meiner Sicht schon beachtlich. Nebenbei fand ich eine deutlich bessere Methode, einen Abfangvektor zu einem beweglichen Zielobjekt im Level zu berechnen. Diese Methode habe ich mir sogar vorgemerkt, um sie bei der Gegner-KI einzubauen, als ich feststellte, dass das Ergebnis exakt genauso aussieht wie bei etlichen Gegnern im Originalspiel. Endlich war ich auf der richtigen Fährte, nachdem ich jahrelang keine Ahnung hatte, wieso meine KI sich immer irgendwie anders bewegt als im Original.

Replays

Gleich der nächste Knüller: Mit der Idee der InputReceiver konnte ich endlich Benutzereingaben im Spiel aufzeichnen und theoretisch jederzeit erneut ausführen. Fürs Aufzeichnen gibt es im Spiel nun einen ReplayRecorder, der die ControlActions pro Update ableitet und in einem Replay-Objekt speichert. Am Ende wird das Replay-„Tape“ finalisiert und kann im Speicher gehalten oder komprimiert in eine Datei gespeichert werden. Ein ReplayInputReceiver kann dieses Objekt wieder als Eingabequelle für den Spieler wählen. Vereinfacht gesagt, das komplette Gameplay eines Levels lässt sich aufnehmen und anschließend nochmal exakt identisch als Replay abspielen. Da die Aufzeichnung natürlich kein Film ist, sondern nur ein Protokoll aller Benutzereingaben auf einer Zeitachse, ist der Speicherbedarf geringer, aber das Replay anfällig für Veränderungen. Was ich damit meine, wird jetzt deutlich, wenn ich die nächste kleine große Baustelle erwähne, an der ich seit einigen Tagen arbeite.

Die Replays lassen sich zwar endlich perfekt aufnehmen und auch wieder abspielen, aber sie ergeben danach keinen Sinn mehr: Der Replay-Spieler macht zwar alles exakt so, wie das Tape es vorgibt, aber die Spielwelt eben nicht. Das Level sieht anders aus, die Gegner verhalten sich anders, nichts ist da wo es sein sollte. Folglich kracht der Spieler plötzlich wie ein Betrunkener überall dagegen, schießt meilenweit an den Gegnern vorbei, fliegt in die völlig falsche Richtung, und ist quasi nach wenigen Sekunden Gameover. Das Gameplay verlässt sich an sehr vielen Stellen auf Zufallszahlen, und auch die Levelgenerierung ist zufällig. Daran ist im Grunde gar nichts auszusetzen, da Spielentwicklung ganz ohne Zufallsgeneratoren kaum möglich wäre. Was mir nur noch fehlte, war der programmweite Einsatz von reproduzierbaren Zufallszahlen, die auf Basis eines gespeicherten Seeds funktionierten. Gleicher Seed bedeutete dann: Gleiches Level, gleiche Gegner, gleiches Verhalten, alles exakt gleich. Die Spielwelt musste vollständig deterministisch zufällig werden, und die Replays müssten den Seed speichern, der dann die Grundlage für das Replay bildet. Diese Umstellung ist leider sehr aufwändig und umfasst das Umschreiben vieler Bausteine der Levelgenerierung.

Spielereien

Nach diesem schwergewichtigen Problem möchte ich zum Schluss noch kleinere Physikspielereien erwähnen, die ich ins Remake eingebaut habe. Als kleine Option im Enhanced-Modus lassen sich die Stationen der Piraten quasi kugelsicher schalten, so dass die Geschosse des Spielers daran mit passendem Soundeffekt abprallen. Hierzu musste ich meinen Bounce-Code umschreiben, denn der sah bisher nur Kollisionen zwischen zwei beweglichen Objekten vor. Im Spezialfall einer Kollision zwischen einem unbeweglichen und einem beweglichen Objekt durfte eine Reaktion logischerweise nur auf das bewegliche Objekt erfolgen. Das Feuern auf die kugelsichere Station sieht schon recht witzig aus und die abgelenkten Kugeln fliegen einem um die Ohren. Ob das im fertigen Spiel Verwendung findet, steht natürlich auf einem anderen Blatt, aber es schadet nicht, wenn die Funktion schonmal eingebaut ist. Achja, eine weitere Option erlaubt jetzt das Zerstören der Stationen. Ich wollte einmal testen wie es aussehen könnte, wenn im Spiel ein großes Objekt gesprengt wird, und dabei kam diese kleine Funktion heraus. Es werden Unmengen an Explosionspartikeln erzeugt und die Station verabschiedet sich mit einem lauten Knall. Wie gesagt, natürlich nur eine Spielerei. Ergibt auch keinen Sinn, besonders dann nicht, wenn es die Zielstation war.

Eine letzte neue Option im Optionsmenü ist die Wahl der Spielgeschwindigkeit. Hierdurch lässt sich das Spiel mittlerweile erheblich verlangsamen. Für den Anfang kann man die Updaterate daher auf 1/2, 1/4, 1/8 oder 1/24 stellen. Dies ist allerdings nicht nur sinnlose Spielerei, sondern die erste Vorbereitung auf einen Rewrite der Spielengine, der früher oder später dringend nötig sein wird: Das völlige Entkoppeln von Update- und Drawrates, und die stufenlose Wahl der Spielgeschwindigkeit. Es muss also möglich sein, die Spielgeschwindigkeit z.B. drastisch zu reduzieren, aber trotzdem alle Spielobjekte weiter mit bis zu 72 fps flüssig zu bewegen. Denn aktuell bedeutet eine reduzierte Geschwindigkeit nur, dass die Spielwelt weniger oft aktualisiert wird, und dann spielt die Framerate eben keine Rolle. Das Spiel sieht dann leider nicht nach Zeitlupe aus, sondern nach Diashow.

Meilenstein

Es gibt da zwar noch so ein Thema, einen wichtigen Meilenstein, den ich unbedingt erläutern möchte, aber das werde ich demnächst in einem separaten Artikel abhandeln, da es sehr umfangreich wird.

Ein Besucher meines Blogs hat mir vor einigen Wochen die absolut berechtigte Frage gestellt, ob die Entwicklung an meinem kleinen SPACOLA-Remake-Projekt denn inzwischen eingestellt wurde. Ich möchte diese Gelegenheit für ein ehrlich gemeintes Lebenszeichen und wieder einmal ein wenig Selbstkritik nutzen. Ich bin zudem dankbar für jedes bisschen Aufmerksamkeit, das mir immer wieder einzelne Leser des Blogs schenken, die sich für das Projekt interessieren. Das zeigt mir zumindest, dass ich die Arbeit nicht alleine für mich mache (obwohl das natürlich nach wie vor der Hauptgrund ist).

Die gute Nachricht: Nein, die Entwicklung an dem Spiel ist definitiv NICHT eingestellt. Ja, ich arbeite Monat für Monat daran weiter. The show must go on.
Die schlechte Nachricht: Ich arbeite sehr langsam, und meine Motivation schwankt leider von Woche zu Woche. Es tut mir leid, so ist es eben. Manchmal hänge ich mich so richtig rein und kann mich kaum bremsen. Manchmal kriege ich aber auch wochenlang mal so überhaupt nichts gebacken. Das ärgert mich dann meist selbst, so dass ich versuche, Strategien zu entwickeln, um wieder in das Thema hineinzufinden.

Ein Release von SPACOLA ECLIPSE liegt also eher in ferner als in naher Zukunft. Das mag enttäuschend sein, aber das heißt nicht, dass ich aufhöre. Und es heißt vor allem nicht, dass ich zwischenzeitlich nichts gemacht habe, denn kleine Fortschritte gibt es ständig. Das möchte ich heute mit diesem Beitrag zeigen. Vor allem die Farbversion des Remakes hat in den letzten Wochen erneut Fahrt aufgenommen. Und da Bilder bekanntlich mehr sagen als 1000 Worte, möchte ich einfach mal drei aktuelle Impressionen der neuesten Work-In-Progress-Version 0.85 zeigen.

Work-In-Progress-Version 0.85 im verbesserten „SPACOLOR“-Spielmodus

Ich habe versucht, einen Screenshot zu erstellen von einer möglichst hektischen und actionhaltigen Szene, auf der viele Elemente gleichzeitig zu sehen sind. Das komplette HUD ist quasi fertig. Wie zu erkennen ist, sind die Stationsgeschütze noch nicht koloriert, aber vieles andere schon. Außerdem sorgen die vielen Explosions- und Antriebs-Partikel schon für eine Menge Bewegung und Gewusel auf dem Bildschirm. Um meinen neuen Lenkraketen-Code zu testen, habe ich die Stationsgeschütze so eingestellt, dass sie eine größere Anzahl Lenkraketen auf den Spieler abfeuern, anstelle kleinerer Geschosse. Die gefährlichen Stationsgeschütze eingeschlossen, sind hier immerhin drei Gegnertypen zu sehen, die allesamt Jagd auf den Spieler machen. Der kann in der Szene allerdings mit seinem Schutzschild (noch) dagegen halten kann. Mehrere Lenkraketen werden demnächst von allen Seiten einschlagen, was die Situation sicherlich nicht verbessert.

Level-Auswahl-Bildschirm vor jeder Runde

Am Anfang des Spiels kann man stets nur ein einziges Level auswählen. Die schwierigeren Sonnensysteme werden dann nach und nach zugänglich, sobald man in der Galaxie ein wenig Geld verdient hat. Das gesamte Spiel mit allen Menüs ist inzwischen in Farbe verfügbar, darunter natürlich auch die Schriftarten, die Mauszeiger, das Level-Auswahl-Panel, und alle Schaltflächen. Am unteren Rand analog zur TOS-Demo des Ur-SPACOLA prangt ein kleiner Hinweis bezüglich der Unfertigkeit des Remakes. Authentizität und Originaltreue ist bei der Entwicklung immer ein entscheidendes Grundprinzip. Jeder einzelne Pixel muss immer genau dort sitzen, wo er im Original auch platziert worden wäre. Hierzu nehme ich mir viel Zeit, um Screenshots zu vergleichen und Abstände zu messen.

Künstlerische Freiheiten nehme ich mir ausschließlich dort, wo sie absolut sinnvoll und vor allem nötig sind. So ist zum Beispiel der gesamte Metallic-Look der Farboberfläche eine alte Idee von mir, die ich schließlich möglichst perfekt mit dem Original-Design in Einklang bringen wollte. Selbst den Farbverlauf des Remake-Schriftzugs habe ich nicht einfach irgendwie aus dem Ärmel geschüttelt, sondern es basiert auf einem Design von der alten Dongleware-Webseite, wo es bereits eine frühe eingefärbte Fassung zu bewundern gab.

Der gute alte „SPACoLASSIC“-Spielmodus mit handgepixelter Monochromgrafik

Selbstverständlich lässt sich das Spiel auch komplett in der Originalgrafik spielen, bei der alles soweit unangetastet bleibt (verständlicherweise bis auf Details im Intro). Für Fans und Puristen gibt es dann „nur“ Monochrom-Sprites bei limitierten 36 Bildern pro Sekunde, und keinerlei Partikeleffekte oder sonstige neue Spielereien. Das Gameplay bleibt allerdings identisch.

Wer wissen möchte, an welchen Details ich mich da eigentlich so aufhalte, der möge gerne weiterlesen: Im Remake gibt es inzwischen ein Weapon-Interface, das es allen Schiffen im Spiel (Spieler, Mitspieler und Feinde) dynamisch ermöglicht, quasi auf Befehl eine andere Waffe zu aktivieren, seien es die Spieler-Standardwaffe, Lenkraketen, Laserwaffen, zwei Arten von Turret-Waffen, Minen, oder beispielsweise schlagkräftige Kanonenkugeln. Darüber hinaus habe ich eine AimHelper-Klasse geschrieben, die alle im Spiel bekannten Arten von Anvisier-Techniken der Gegner wiederverwendbar implementiert und mühelos auf alle möglichen Spielobjekte anwenden lässt. Wie präzise oder wie schlecht ein feindliches Schiff zielt, kann ich so dynamisch ohne Quellcode-Änderungen bestimmen. Damit kann sogar der Spieler eine Art „Aimbot“ bekommen, wenn man denn möchte. Das wäre jedenfalls eine Idee für ein zusätzliches Powerup.

Im Dezember habe ich übrigens das SPACOLA-Codebuch abgetippt. Nein, nicht die Koordinaten. Die gibt es schon in digitaler Form und sind im Remake auch zu 100% enthalten. Die Rede ist von den Powerups, also die Extras, die als kleine Symbole neben den Koordinaten im Buch abgedruckt sind. Mein innerer Perfektionist wollte partout nicht damit leben, dass dieser Teil des „Sternenatlas“ nicht im Remake nutzbar sein wird. Also habe ich angefangen, die Extras mühsam abzutippen, wo sich allerdings nach zwei Buchseiten bereits zeigte, dass ich so niemals fertig werden würde. Also habe ich mir ein kleines Progrämmchen geschrieben, das mir die Eingabe der Zeichen erleichtert: Ich musste quasi nur noch das jeweils passende Symbol anklicken und das Ergebnis wird direkt in eine CSV-Datei geschrieben.

Aber im Endeffekt bleibt alles Handarbeit. Es geht hier schließlich um 154 Buchseiten á 3 Blöcke pro Seite á 64 Symbole. Summa summarum sind das 29568 Symbole. Also 29568 Netto-Mausklicks. Und dann ist da noch gar nicht eingerechnet, dass ich mich recht oft verklickt oder verlesen habe, und einige Seiten im Buch von so schlechter Druckqualität sind, dass man praktisch nur noch raten kann, was da steht. Zum Glück gibt es eine Methode um zu validieren, ob die Eingabe stimmt, sonst wär die Fehlerquote einfach zu hoch. Und ja, es hat einige Tage gedauert, aber am Ende war ich mit allem fertig. Somit kann ich nun stolz behaupten, dass das Remake nicht nur sämtliche Koordinatenangaben akkurat wiederverwendet, die im Sternenatlas abgedruckt sind, sondern auch alle Powerups in die Levelkarten einbindet, so wie es im Originalspiel war.

Und wann wird SPACOLA ECLIPSE endlich fertig … oder wenigstens mal spielbar? Tja, keine Ahnung. „When it’s done“ ist ja mittlerweile ein geflügeltes Wort in der Spielebranche, das immer wieder gerne gewählt wird und auch sehr gut passt. Ich weiß nicht wann es fertig wird. Aber ich weiß, dass ich weitermache. Und so langsam fügen sich die vielen kleinen Puzzleteile immerhin zu einem erkennbaren Bild zusammen. Vielleicht dauert es gar nicht mehr so lange, bis das erste komplett spielbare Level veröffentlicht wird.