In der Commodore Plus/4 Ungarn Facebook-Gruppe habe ich bereits kurz erwähnt, dass ich an einem Port von The Pit für den Plus/4 zu arbeiten begonnen habe.
Als Einleitung zitiere ich das dort Geschriebene:
Wofür brauche ich die Töne, die ich im früheren Beitrag erwähnt habe? Für einen meiner großen Favoriten, der meine erste Begegnung mit Videospielen war, wenn man den Videoton Fernseh-Tennis nicht mitzählt.
Mitte der achtziger Jahre gab es im Offiziersklub der Militärsiedlung (!!!) aus irgendeinem Grund einen Münz-Arcade-Automaten, auf dem The Pit lief. Wir warfen unzählige Kossuth-Fünf-Fillér-Stücke hinein, bis wir herausfanden, dass der Schlüssel zum "Saal", den man extra anfordern musste, wenn man spielen wollte, auch die Kasse des Automaten öffnete.
Natürlich war es größtenteils nur so lange interessant, bis man keinen eigenen Computer zu Hause hatte, denn das sich ständig wiederholende, wenn auch mit der Zeit schneller werdende Spielgeschehen war bei weitem nicht so spannend wie das Warten vor dem Kassettenrekorder auf das Laden des aktuellen Spiels.
Jedenfalls hat es bei mir einen tiefen Eindruck hinterlassen, und ich erinnerte mich wieder daran, als ich vor kurzem entdeckte, dass Doug Turner, der Schöpfer von Icicle Works (und anderen großartigen Bergbau-Spielen) vor etwa fünf Jahren mit einem neuen Release herauskam: mit The Pit.
Was übrigens ein ganz anderes Spiel ist, mit ganz anderem technischem Know-how und Niveau, aber dennoch gibt es eine direkte Parallele. Dougs Inspiration, sein eigenes Icicle Works, ist eine frei interpretierte Boulder Dash-Klon in Weihnachts-Winter-Thematik. Die Inspiration für Boulder Dash war laut Aussage des Schöpfers Peter Liepa ein BASIC-Programm von Chris Gray, das für die heutige Zeit nicht erhalten geblieben ist. Chris' Programm war jedoch auch keine originelle Idee – es entstand in einer Spielhalle, während er an einem Arcade-Automaten spielte. Dieser Automat war The Pit.
Versteht ihr die Analogie? Wir sehen das Untergrundabenteuer im Querschnitt wie in einem Ameisenbau, Steine fallen auf unseren Kopf, und so weiter, und so fort...
Was für ein schöner Kreis, nicht wahr?
So hat mich The Pit dazu angeregt, den Plus/4-Port von The Pit zu erstellen. Keine wirklich menschen- und technikherausfordernde Aufgabe, aber angesichts der Zeit, die ich für so etwas habe, und wie sehr ich mich wieder ins Codieren einarbeiten muss, ist es für mich die perfekte Aufgabe.
Ich habe auch drei Videos angehängt, falls jemand das Spiel nicht kennt. Das erste ist die originale Arcade-Version, das zweite der C64-Port, und das dritte der zukünftige Plus/4-Port. Letzteres ist nur ein Vorgeschmack, denn die Fortsetzung ist noch sehr holprig.
Es veranschaulicht jedoch gut, dass das Einfügen von Digitaltönen eine starke Übertreibung wäre (es sei denn, wir digitalisieren eine Rechteckwelle, aber wozu, nicht wahr), und auch Soundeffekte brauchen nicht zu viele, deshalb zerbreche ich mir noch den Kopf darüber (im kurzen Ausschnitt spielt TEDZakker).
Noch ein Grund, warum ich nach einer effizienten Lösung suche: Ich möchte bei 16K bleiben. Die originale C64-Version war auf Cartridge, die geknackte Version läuft auch an der Stelle der Cartridge, passt bequem in 16K, mit viel freiem Platz.
Oh, und wie wird der Titel lauten? Natürlich The Pit, denn das ist auch der Originaltitel, aber ich werde mir etwas einfallen lassen, um es zu unterscheiden. Zum Beispiel The Pit Arcade oder ähnliches.
Obwohl ich relativ wenig Zeit dafür habe (wie es bei Erwachsenen üblich ist), schreitet das Projekt dennoch gut voran und wird voraussichtlich in absehbarer Zeit fertig sein.
Der Grund, warum daraus ein Blogbeitrag geworden ist, ist, dass aufgrund der relativen Einfachheit relativ viele spezielle, zu lösende Probleme aufgetaucht sind, auch wenn ich einen Teil davon selbst verursacht habe.
Erstens: Das originale C64-Programm (zumindest das, was zu mir gekommen ist) wurde von einer Cartridge geknackt und passt in 16K, wobei noch reichlich Platz übrig ist. Daher wurde eines der Ziele, dass die Plus/4-Version auch in 16K passt und sogar auf dem C16 läuft (die beiden sind nicht dasselbe!).
Zweitens: Im Original gibt es eine Menge Sprites (vom Hintergrund unabhängige, hardwarebasiert laufende Elemente wie der Spieler, die Feinde usw...), diese können auf dem Plus/4 nur softwaremäßig gelöst werden, was sehr ressourcenintensiv ist. Das charakteristische Merkmal des Spiels ist jedoch, dass die meisten davon klein sind (1x1 Zeichen) und relativ selten auf den Hintergrund oder aufeinander treffen, so dass das Sprite-Masking (das "Kämmen" von Sprite und Hintergrund) fast vollständig weggelassen werden kann.
Daher stand von Anfang an fest, dass die Sprites wie folgt funktionieren werden:
1. Spieler: 1x1 Zeichen Figur, die theoretisch auf einer 2x2 Zeichen großen Sprite-Maske erscheinen könnte. Wie könnten wir das vereinfachen?
- Die pixelweise Bewegung bleibt, aber anhalten kann er nur innerhalb der Zeichengrenzen. Das erleichtert das Spiel ein wenig, im Original war es nämlich besonders fies, die Pixelgrenzen zu treffen.
- Wenn der Spieler sich im Sand bewegt, gräbt er sich immer ein zeichengroßes Gebiet vor sich frei – daher bewegt er sich immer auf leerem, bereits ausgegrabenem Boden. Daher trifft er nicht auf den Hintergrund, es muss nicht maskiert werden.
- Wenn er einen Schatz aufhebt, ist wieder keine Maskierung nötig – denn er hebt ihn auf, womit auch hier nur leerer Platz zurückbleibt.
- Wenn er mit einem Feind kollidiert, muss nicht maskiert werden, denn TOD! TOD! TOD!, was im Original-Spiel eine seltsame, verhedderte Animation hat. Dies kann aus festen Phasen erzeugt werden, und zwar innerhalb der Zeichengrenzen.
- Mit dem Projektil muss er nicht maskieren, denn er schießt es vor sich, und es entfernt sich von ihm.
- Wenn der Felsen herunterfällt, ist die Situation dieselbe wie mit dem Feind, es gibt nichts Extra zu tun.
- Unser Spieler bewegt sich außerdem nicht diagonal, sondern nur vertikal ODER horizontal, gleichzeitig beides ist nicht möglich.
Aufgrund des Obigen vereinfacht sich die Bewegung und Darstellung des Spielers erheblich. Praktisch muss er sich vor leerem Raum bewegen, er könnte sogar zeichenweise erscheinen, aber dann wäre seine Bewegung sehr ruckelig. Für die pixelweise Bewegung entstand folgende Lösung:
- Wenn der Spieler innerhalb der Zeichengrenzen ist, setzen wir ihn einfach als ein Zeichen aus, in das wir die aktuelle Animationsphase kopieren.
- Wenn er sich seitwärts bewegt, erhält er von der aktuellen Position aus LINKS nein, RECHTS ein zusätzliches Zeichen, in diesen beiden schieben wir ihn seitwärts um 1-7 Pixel, der 8. erfolgt bereits ein Zeichen weiter.
- Bei Auf-Ab-Bewegung geschieht dasselbe, aber von der aktuellen Position aus eine Zeile tiefer erscheint das zweite Zeichen.
- Den Hintergrund überschreiben wir damit nicht, denn vor der Bewegung prüfen wir, was in den vier möglichen Richtungen zu finden ist, und lassen nur weiter, wenn leerer Platz da ist. Wenn in einer Richtung Sand das Hindernis ist, aber der Spieler sich bewegen würde, graben wir einmal – danach wird auch dort leerer Platz sein, er kann weitergehen.
- Da das Spielfeld außer dem Eingang von unpassierbaren Hindernissen umgeben ist, ist aufgrund des Vorherigen keine Überprüfung der minimalen und maximalen begehbaren Position nötig, denn die Hindernisse halten den Spieler auf, bevor er den begehbaren Bereich verlässt. Der Eingang (und der Ausgang neben dem Panzer) wird übrigens von $00-Zeichen umgeben, die genauso leer sind wie die begehbaren $20-Zeichen, blockieren aber die Weiterbewegung des Spielers.
Ein besonderer Bonus ist die Gestaltung des Spielfelds, weshalb die rechte Seite des Bildschirms für den Spieler nicht begehbar ist. Eine kleine Erklärung dazu:
Der Bildschirm des Commodore Plus/4 ist 25 Zeilen mal 40 Zeichen groß, in Pixeln 320x200. Die vertikale Position (0-199, oder hexadezimal $00-$C7) kann in einem Byte beschrieben werden, die horizontale jedoch nicht, ihr Wert (wenn der gesamte Bildschirm begehbar wäre) könnte $0000-$013F sein, was bereits nur in zwei Bytes gespeichert werden kann. Selbst wenn die Sprite-Position sowieso nicht $013F / $C7 sein kann, denn dann wäre nur noch ein Pixel in der unteren linken Ecke sichtbar.
Nun, bei The Pit gibt es dieses Problem nicht, unter Verwendung des originalen Levels kann der Spieler (und somit natürlich auch die Feinde), einschließlich seiner Größe, maximal bis zur Position $D0 / $B8 gehen. Das kann bereits in einem Byte gespeichert werden. Dieser Unterschied scheint nicht signifikant zu sein, aber so sparen wir mit dem kürzeren Programm auch Speicher und Prozessorzeit durch das unnötige Rechnen mit +1 Byte.
2. Feinde: Fast alles, was für den Spieler gilt, trifft auch auf sie zu. Plus Bonus, dass sie sich sehr selten treffen, damit muss man sich nicht näher befassen. Wenn sie aufeinander treffen, überschreiben sie sich einfach, was im Spiel-Eifer nicht auffallen und somit nicht störend sein wird.
3. Projektile: Es gibt zwei Arten von Geschossen, die des Spielers und die des Panzers. Letztere werden einfache zeichenbasierte Darstellungen sein, brauchen nicht mehr. Die des Spielers werden auch nicht komplizierter, denn sie bewegen sich vor leerem Hintergrund, bei Kollision mit einem Hindernis verschwinden sie (= verschwinden einfach), bei Kollision mit einem Feind verschwinden sie zusammen mit diesem.
4. Bomben im unteren Höhlenbereich: Ihre Darstellung ähnelt der der Geschosse, außerdem bewegen sie sich nur in eine Richtung, sind also noch einfacher zu handhaben.
5. Monster im Säurebecken, Panzer, UFO: haben keine wirkliche Rolle im Spiel. Alle drei können mit einfacher zeichenbasierter Geschichte auf minimaler Fläche sich bewegend dargestellt werden. Einzig der Panzer bekommt eine halb phasenverschobene zeichenbasierte Animation aufgrund der relativ langen, geraden zurückgelegten Strecke.
Um in 16K zu passen, musste ich keine allzu großen Anstrengungen unternehmen, da das Spiel selbst nicht allzu kompliziert ist.

Der Zeichensatz von The Pit im aktuellen Stand. Dies ist nicht der endgültige, die Animationsphasen werden noch entfernt.
(Für die Grafik habe ich im Grunde die C-64-Version als Basis genommen, aber einige Details aus der originalen Arcade-Version übernommen)

Der Sound des UFOs, 45 Byte
Der Großteil des Obigen spart natürlich nur minimal Platz, aber um zu verstehen, warum auch diese Krümel wichtig sind, blättern wir jetzt zurück zum oben scheinbar grundlos grün geschriebenen Text – dessen Größe beträgt etwa 4500 Zeichen, also etwa 4.4kB.
Dieser kleine grüne Textteil passt viermal hintereinander schon nicht mehr in 16K!
Noch eine Kleinigkeit zum Schluss: Während der Entwicklung verwende ich oft so eine Art Bauklotz-Debug-Methoden, die dann aus der endgültigen Version leicht-schnell entfernt werden können. Dabei ist der Bildschirm passiv, auf für den Programmablauf unwichtigen Bereichen können hervorragend Informationen angezeigt werden, die die Fehlersuche oder sogar den Entwicklungsprozess selbst unterstützen. Solche sind auch auf diesem Screenshot zu sehen:

"Debug-Modus" unter The Pit
Man sieht gut einerseits die klassische "Rasterzeit-Messung", die zu Beginn des Interrupts gestoppte und am Ende zurückgesetzte Rahmfarbe, andererseits unten auf dem Bildschirm in einer Reihe die pixelweisen X- und Y-Koordinaten des Spielers, die pixelweisen X- und Y-Koordinaten innerhalb des Zeichens, die zeichenweisen X- und Y-Koordinaten, den Grabezähler (0-7, bzw. entsprechend @-G), sowie die aktuelle Bewegungsrichtung (horizontal, vertikal oder – im vorliegenden Fall – keine).
In der High-Score-Liste stehen oben anstelle der Namen die Hindernisse in den vier Richtungen um den Spieler, darunter die aktuelle Bewegungsrichtung.
Außerdem ist hier im Debug-Modus das oben erwähnte leere, aber vom freien Bereich abweichende $00, also @-Zeichen, nicht leer, enthält ein einzelnes Pixel, um es vom wirklich leeren, begehbaren $20 (Leerzeichen)-Zeichen unterscheiden zu können. Deshalb sieht man zum Beispiel auch, dass vom Ausgang neben dem UFO der Spieler nur nach unten abfahren kann.
Darüber hinaus kann im Debug-Modus die Bewegung der Feinde, das Fallen der Felsen, das Schießen des Panzers usw. ausgeschaltet werden (und hier ist es ausgeschaltet). Das kann viel helfen, wenn man einen Fehler zurückverfolgen muss, dessen Quelle noch völlig im Dunkeln liegt.
Dieser ganze Debug-Modus kann vor dem Speichern der fertigen Version mit einigen ; auskommentiert werden, beim Speichern dann übersprungen werden. In unserem Fall – gerade wegen des 16K-Ziels liegt er ohnehin über $4000, stört also auch im verfügbaren Speicher nicht.
Nun, das war's erstmal, nächstes Mal – hoffe ich – melde ich mich mit dem fertigen The Pit.