Rückblick auf die Crash Bandicoot-Entwicklung oder wie Entwickler ganze Spiele in 2 MB RAM packen

Ursprünglicher Autor: Dave Baggett
Hier ist ein Witz aus den späten 90ern. Ich (Dave Baggett) war einer von zwei Programmierern (zusammen mit Andy Gavin), die Crash Bandicoot für die PlayStation 1 entwickelten.



RAM war selbst damals ein großes Problem. PS1 hatte nur 2 MB RAM, und wir mussten verrückte Dinge tun, um das Spiel zu passen. Wir hatten Ebenen, die mehr als 10 MB reine Daten enthielten, und diese 10 Megabyte mussten pro Seite geladen und dynamisch ohne sichtbare Verzögerungen für den Player mit einer Bildrate von 30 Bildern pro Sekunde in den Speicher geladen werden.

Dies funktionierte im Grunde, weil Andy ein großartiges Auslagerungssystem geschrieben hat, das Seiten in 64-KB-Speicher laden und entladen sollte, als Crash das Level überstieg. Dieses System war ein echtes Kunstwerk und umfasste die gesamte Palette der verfügbaren Tools, von der Speicherverwaltung auf hoher Ebene bis zur direkten Arbeit mit dem Speicher und der Programmierung in Opcodes. Andy musste auch die Position der Bytes auf der CD-ROM kontrollieren, damit die PS1 selbst bei einer Geschwindigkeit von 300 KB / s das Laden von Daten für alle Ebenendetails bis zum Eintreffen von Crash schaffen konnte.

Ich habe einen Packer geschrieben, der Spielressourcen in Anspruch genommen hat - Sounds, Kunst, Lisp-Code zum Verwalten von Kreaturen usw. und packte sie in 64K-Seiten für das von Andy geschriebene Swap-System. (Übrigens ist die Aufgabe, einen Satz beliebiger Datengrößen in Seiten fester Größe zu packen, NP-vollständig und im Polynom, dh zu jeder akzeptablen Zeit, fast unmöglich zu lösen. Das Rucksackproblem. )

Einige der Ebenen passen kaum, und mein Packer verwendete eine ganze Reihe von Algorithmen (First-Fit, Best-Fit usw.), um zu versuchen, die beste Verpackungsoption einschließlich der stochastischen Suche zu erhalten, ähnlich dem Gradientenabstiegsprozess, der im Simulationsalgorithmus verwendet wird Glühen.Im Grunde hatte ich eine ganze Reihe verschiedener Verpackungsstrategien und habe sie alle ausprobiert und das beste Ergebnis erzielt.

Das Problem bei der Verwendung von zufälligen Richtungssuchen bestand darin, dass Sie nie sicher sein konnten, dass Sie wieder genau dasselbe Ergebnis erzielen konnten. Einige Stufen von Crash Bandicoot passen in die maximale Anzahl von Seiten (21, wenn ich mich nicht irre), nur weil der Packer Glück hatte und diese Option gefunden hat. Dies bedeutete auch, dass Sie, sobald Sie die Paketversion erhalten hatten, den Code für einen Fehler ändern und niemals das Paket erhalten konnten, das in 21 Seiten passt. Es gab Fälle, in denen der Designer etwas ändern wollte und dies die Anzahl der Seiten erhöhte und wir an anderen, fast zufälligen Stellen etwas ändern mussten, bis der Packer wieder eine funktionierende Option fand. Erkläre es den gereizten Designern um 3 Uhr morgens :)

Die beste Folge dieser Retrospektive und der schlimmste Zeitraum war dann das Packen des Kernel-Codes in C und Assembler. Wir hatten nur ein paar Tage Zeit, um die „Gold Master“ -Version herauszubringen - unsere letzte Chance, pünktlich zur Weihnachtszeit zu sein, bevor wir ein weiteres Jahr verlieren. Und wir saßen da und ordneten C-Code in semantisch identische, aber syntaktisch unterschiedliche Konstrukte um, um den Compiler-Issue-Code so zu gestalten, dass er 200, 125, 50 und dann 8 Byte kleiner war. Neu geordnet, zum Beispiel: "für (i = 0; i <x; i ++)" - und versuchen wir, dies in einer while-Schleife umzuschreiben und die Variable zu verwenden, die bereits irgendwo zuvor für die Iteration verwendet wurde? Dies geschah alles, nachdem wir Standardtricks ausprobiert hatten, z. B. das Einfügen von Daten in die letzten beiden Bits des Zeigers (und dies funktionierte nur, weil die R3000-Adressen mit 4 Bytes ausgerichtet waren).

Letztendlich passte Crash in den Speicher der PS1 und es blieben sogar 4 Bytes übrig! Ja, 4 Bytes von 2097152. Viel Glück.

Jetzt auch beliebt: