Wie wurden Cartridge-basierte Spiele programmiert? [geschlossen]

44

Ich denke an wie das SNES, N64, Atari ... sogar das DS heute, nehme ich an.

SNES-Spiele nahmen normalerweise nicht mehr als 4 MB Speicherplatz ein, und N64-Spiele waren normalerweise 32 bis 64 MB Daten wert.

Heutzutage kann man kaum noch eine "Hallo Welt" zusammenstellen! Programm ohne die resultierende Zusammenstellung, die 1.21 Gigabyte erzeugt !! von Dateien. (Abgesehen von Scherzen nehmen Dateien heutzutage im Vergleich zu einigen Technologien Tonnen und Tonnen an Speicherplatz ein.)

Also ... wie haben sie es gemacht?

  • In was haben sie diese Spiele programmiert? ASM? Das Ganze in ASM ?!
  • Wie wurden Grafiken erstellt? Mit welcher Technologie mussten sie Sprite-Sheets und in einigen Fällen (wie beim N64) 3D-Modelle erstellen?
  • Wie haben sie so viele Level, Charaktere, Quests und Gegenstände auf diese Patronen gepasst? Ich meine, Super Mario World auf der SNES-Uhr ist ungefähr 1 MB groß und hat 96 Ausgänge! Ocarina of Time, Banjo-Kazooie, DK64 und einige andere Spiele belegen weniger als 64 MB und hatten riesige Welten, jede Menge Inhalte und 3D-Modelle!

Tut mir leid, wenn meine Fragen ein wenig anders aussehen, ich bin nur erstaunt, dass viele großartige Titel es geschafft haben, in einen so kleinen Speicherplatz zu passen.

Es ist faszinierend für mich, weil selbst kleinste und trivialste Dateien und Spiele mindestens ein paar MB belegen. Die Vorstellung, dass große Ebenen wie die in GoldenEye 007 so gut wie keine Daten aufnehmen, ist umwerfend.

Corey
quelle
1
Auch in Bezug auf das Duplikat, das ich kenne, werden die Leute darauf hinweisen: Ich bin hauptsächlich daran interessiert, wie die tatsächlichen Daten in die Spiele geschrieben wurden und wie große Ebenen erstellt wurden, während eine kleine Dateigröße beibehalten wurde - nicht so sehr der Entwicklungsprozess und die verwendeten Tools.
Corey
1
NES (siehe Metroid Source bei MDB) und SNES (der Quellcode einiger Spiele von Drittanbietern ist im Web verfügbar) verwendeten ASM, N64 (Zelda: MMs Debug-Bildschirm zeigt den Dateinamen in den Absturzinformationen an) verwendeten C.
Ivo Wetzel
Das Programmieren von Spielen war in den 8-Bit-Tagen sehr umfangreich. Zum Beispiel kostet es ein Vermögen, Pacman zu machen, wenn es heute recht billig gemacht werden kann. Die Gründe dafür sind, dass die Einschränkungen der Hardware tausendmal (oder mehr) einschränkender waren als heute. Das bedeutete, dass Sie sich für diese 8-Bit-Spiele auf Assembler-Code verlassen mussten. Der Grund, warum Spiele heute so groß sind, ist nicht, dass sie es sein müssen. Es ist vor allem, dass sie sein können. Sie könnten über Wirths Gesetz lesen.
Wolfdawn
Ja, in Assembly wurden oft 8-Bit-Spiele geschrieben. Die SMS-Spiele wurden mit einem Z80 gemacht, das ist allgemein bekannt. Wenn Sie in Assembly schreiben, können Sie weiterhin nützliche Bibliotheken erstellen. Ich verstehe nicht, wie wichtig es heutzutage für die Spieleentwicklung ist, den Code kompakt zu halten. Es klingt wie eine Frage, wie man Pferde in einem modernen Autoforum füttert und pflegt. Wenn Sie native Binärbefehle schreiben, können Sie den Code natürlich in einer Maschine mit einem bestimmten Zweck kompakt halten. Wie aufgebläht kann es sein, wenn Sie Ihren Code benötigen, um mit ein paar Megahertz ausgeführt zu werden. :)
Wolfdawn

Antworten:

25

Es sind die Grafik- und Audio-Ressourcen, die Platz beanspruchen. Bei der Auswahl der Programmiersprache ging es mehr darum, das Beste aus der Hardware herauszuholen.

Am Beispiel von N64 waren die meisten Spiele von Drittanbietern 8, 12 oder 16 MB groß. Die 32- und 64-MB-Spiele stammten größtenteils von Nintendo, da es so teuer war, sie auf so großen Karren für alle anderen zu versenden. Das klingt winzig, aber das Kunstvermögen und die endgültige visuelle Ausgabe waren es auch. Sie müssen sich daran erinnern, dass die meisten N64-Spiele mit 320 x 240 Pixel nicht mit 1280 x 760 Pixel oder mehr von heute gerendert wurden. Bei einer so geringen Ausgabeauflösung waren Texturen und Sprites viel kleiner als heute.

Aufgrund des winzigen Textur-Cache auf dem N64 waren die meisten Texturen 32 x 64 Pixel mit einer 4/8-Bit-Palette (auch bekannt als 16/256-Farben). Zusätzliche Farbdetails wurden häufig durch Mischen von Texturen und Scheitelpunktfarben erzielt. Die Banjo-Spiele sind ein gutes Beispiel dafür.

Heutzutage hat ein einzelner Stein in einem Spiel mit unwirklicher Engine mehrere 512x512x24bpp oder sogar 32bpp. Anstatt nur einer einzigen diffusen Textur stehen jetzt normale Karten, Spiegelmasken, Reflexionsmasken, Reflexionswürfelkarten und mehr zur Verfügung. Ein Objekt, das früher 4 KB Texturen enthielt, ist jetzt in mehreren MB Daten enthalten.

Alte Spiele haben auch eine enorme Wiederverwendung von Kunst. Die Büsche in Super Mario Bros. sind die gleichen Sprites wie die Wolken, die Hügel die gleichen wie die Pilze. Verschiedene Charaktere sind nur farbverschobene Versionen der gleichen Kunstressourcen. All dies brachte mehr Nutzen für jede Textur oder jedes Sprite, das sich auf dem Wagen befand.

Audio ist ein weiterer großer Unterschied für moderne Spiele. Fast alles in den alten Tagen wurde mit sequenzierten Tracks gemacht. Jetzt werden sowohl Musiktitel als auch Sprach- und Soundeffekte in verschiedenen komprimierten Audioformaten gespeichert. Sie sind zwar sicherlich kleiner als unkomprimierte Daten, aber immer noch erheblich größer als ihre sequenzierten Äquivalente.

wkerslake
quelle
8
Ah, die Mario Sträucher / Bäume Inzest mit einer logischen Erklärung! Ausgezeichnet.
Kzqai
10
Es ist erwähnenswert, dass die Wagen oft in mega Größe wurden Bits , nicht mega Bytes . Diese 64-MB-Carts waren nur 8 MB groß.
Dash-Tom-Bang
3
Die Ausgabe in N64 war nicht 320 x 240. Die Angaben sind falsch. Die meisten Spiele benutzten wahrscheinlich 256 × 224. siehe hier
Wolfdawn
13

Im Folgenden finden Sie eine grundlegende Übersicht über das NES (und meistens auch das SNES). Ich habe keine NES-Spiele geschrieben, aber einen NES-Emulator (Graybox) geschrieben und einiges an Rev-Engineering für alte Karren durchgeführt.

Was die Programmiersprache angeht: Ja, es war alles Assembler. Das Programmieren des NES bedeutete, direkt mit Hardware-Interrupts, DMA-Ports, Bank-Switching usw. zu arbeiten. Glücklicherweise ist das Programmieren des 6502 (oder besser gesagt des 2A03) recht einfach [1]:

  • Es gibt nur wenige Register: A, X und Y, wobei die beiden letzteren nur zum Indizieren und Iterieren verwendet werden können
  • Der Befehlssatz ist klein und meist unkompliziert
  • Nicht viel Speicher: Der Hauptspeicher ist 2 KB groß, mit einer optionalen batteriegepufferten 8-KB-Erweiterung. Von diesen 2 KB sind 256 Byte für den Stack reserviert und Seite 0 (die ersten 256 Byte) war der Ort, an dem Sie Ihre am häufigsten verwendeten Zeiger und Werte aufgrund einiger spezieller Adressierungsmodi speichern möchten

Diese drei Dinge zusammen ergeben eine Umgebung, die leicht zu merken ist, während man damit arbeitet. Ja, Sie verwalten den gesamten Speicher selbst, aber das bedeutete im Wesentlichen, dass Sie eine vollständige Karte erstellen, auf der alles vor sich geht, und diese Karte nicht sehr groß ist, da Sie sich nur um 2 KB kümmern müssen, sodass Sie dies auf einem Stück auszeichnen können Millimeterpapier. Sie mussten etwas mehr planen und Variablen und Konstanten statisch RAM- und ROM-Positionen (auf Kassetten) zuweisen.

Sobald Ihre Cartridge-Daten die adressierbaren Grenzen der CPU überschreiten, wird es etwas schwieriger. Das sind 64 KB, von denen die unteren 32 KB in Stein gemeißelt und auf alle Arten von Hardware-Ports und RAM abgebildet sind. Hier kommt das Bank-Switching ins Spiel, dh das Zuordnen eines Abschnitts des ROM zum (Teil des) höheren 32-KB-Adressraums.

Dies kann nach Belieben des Programmierers verwendet werden. Als Beispiel kann jedoch ein Spiel mit 3 Ebenen verwendet werden, bei dem alle Ebenendaten, Metadaten und der Code für jede Ebene in separaten 8-KB-Speicherbereichen auf der Kassette gespeichert sind. Die Ebene könnte Rückrufe für z. B. Initialisierung, Aktualisierung pro Frame usw. enthalten. "Laden" der Ebene würde bedeuten, dass 8 KB Speicherblock auf z. B. 0xC000 abgebildet werden. Sie können dann festlegen, dass die Init-Routine immer bei 0xC000 ist, die Frame-Update-Routine bei 0xC200 ist und die Level-Daten bei 0xC800 beginnen. Der Hauptcode des Spiels, der sich in einem anderen Speicherblock befindet, steuert dann Pegeländerungen, indem er einfach den rechten Block eintauscht und zu den entsprechenden Zeiten zu den absoluten Adressen 0xC000 und 0xC200 springt.

Für grafische Daten: Die Kacheldaten des NES sind 2-Bit-Karten mit 8 x 8 Pixeln. Für den Hintergrund werden sie mit einer 2-Bit-Ebene mit einer Auflösung von 1/4 kombiniert. Diese 4-Bit-Werte wurden dann in einer Palette mit 16 Einträgen indiziert, wobei meines Erachtens 53 effektive, eindeutige Farben zur Verfügung stehen. Sprites verwendeten auch die 2-Bit-Pixeldaten und jedes Sprite spezifizierte seinen eigenen 2-Bit-Gruppenindex, der wiederum einen 4-Bit-Pal-Index bildete. Das Hintergrundbild auf dem Bildschirm ist ein 32x30-Array von Kachelindexnummern.

Im Wesentlichen können Sie durch eine Menge Wiederholungen und Indizes in Indizes Daten sehr klein halten. Level-Daten wurden häufig als vertikale Balken in Kachelindizes gespeichert. Da diese vertikalen Balken auch wiederverwendet wurden, wurden diese ebenfalls indiziert und nur einmal auf der Kassette gespeichert. Einfache Datenkomprimierungstechniken funktionieren ähnlich. Dies ermöglichte es Mario 1, 32 KB Daten (mit genügend Platz) und 8 KB Bitmap-Daten zu speichern.

In Bezug auf Entwicklungsumgebungen habe ich einige Fotos gesehen, auf denen Menschen an einigen nachweislich alten Computern arbeiteten, die für ihre Arbeit an EEPROM-Brenner angeschlossen waren. Das toolgestützte Debuggen war erst nach dem SNES-Alter möglich [2]. Dies ist der Hauptgrund, warum so viele alte Spiele "offensichtliche" Fehler aufweisen und warum Dinge wie Gameshark tun können, was sie tun. Die Gesundheit des Spielers befindet sich immer an Speicherort X, sodass Sie jederzeit 100 erzwingen können.

Wenn Sie diese Dinge interessant finden, empfehle ich Ihnen, zB http://wiki.nesdev.com/w/index.php/Nesdev_Wiki zu besuchen. Es gibt einige Programmierkurse für NES, die auch online verfügbar sind.

Ich hoffe, dieser vereinfachte Überblick gab einen Einblick in die Spieleentwicklung der 80er Jahre.

[1] Relativ gesehen. Außerdem bin ich voreingenommen, da ich Graybox selbst in einer 85% PowerPC-Assembly geschrieben habe. [2] Siehe den Making-of-FF6-Artikel: http://www.edge-online.com/features/the-making-of-final-fantasy-vi/

Zenmumbler
quelle
3

Es gibt viele Unterthemen in fast allen Fragen, die Sie stellen. Optimierung ist ein riesiges Feld für sich und es gibt eine Menge zu erforschen.

Wenn Sie an dieser Art von Optimierung interessiert sind, können Sie unter anderem die Demoszene erkunden . Die Demoszene und einige ihrer verwandten Kunstkulturen haben seit langem ein Gefühl des Staunens darüber bewahrt, komplizierte Kunst für Computer zu schaffen, die so wenig Platz wie möglich einnimmt. Viele von ihnen werden Informationen darüber haben, wie sie einige oder alle ihrer "Tricks" gemacht haben.

Oft gibt es eine kunstvolle Mischung aus gesundem Menschenverstand, obwohl es "Tricks" und "Hacks" gibt, die für ein Spiel oder Genre spezifisch sind. Oft geht es um ein bisschen "Glück" und ein Team, das die Grenzen kennt, an denen es arbeitet (vielleicht stößt es während des gesamten Prozesses ständig an diese Grenzen), die verfügbaren Kompromisse kennt und bereit ist, einige der notwendigen Kompromisse einzugehen -offs und Opfer, um ihre Grenzen zu erreichen.

Hier sind einige der Dinge, die ich mir vorstellen kann, um einem Team zu helfen, ein Spiel auf eine kleinere Größe zu bringen:

  • Wiederverwenden, was Sie können: Wenn Sie dieselben Sprites wiederverwenden und die Variationen, die Sie auf einfache Weise aus einem einzelnen Sprite-Bild erstellen können (z. B. Reflexionen, Rotationen, Palettenverschiebungen), sparen Sie Platz. Das Gleiche gilt für Code, Musik und fast alles andere in einem Spiel.
  • Komprimieren Sie, was Sie können: Es gibt eine Reihe von Komprimierungsschemata, und wenn Sie wissen, welche Sie verwenden müssen, können Sie viel Speicherplatz sparen. Selbst einfache Komprimierungsschemata wie die Lauflängencodierung können manchmal einen überraschenden Unterschied bewirken. Darüber hinaus gibt es Komprimierungsschemata (und alternative Formate, die nicht exakt komprimiert sind) für einzelne Dateitypen, häufig mit Qualitätskompromissen. Beispielsweise können Wave- / CD-Audiodateien mit geringfügigem Informationsverlust in MP3-Dateien komprimiert werden. Auch Dateiformate wie MIDI und Sampler-basiertes MOD sind alternative Formate, die viel weniger Platz beanspruchen, aber Musik ganz anders codieren und unterschiedliche Fähigkeiten erfordern, damit sie gut klingen.
  • Verlieren Sie, was Sie nicht brauchen: können Sie es billiger machen? Können Sie beispielsweise die "Persönlichkeit" eines Zeichens in weniger Pixeln (oder Polygonen) wiedergeben? Muss die Platzierung von Kacheln von einem Designer genau definiert werden oder können sie in Ihrem Programmcode zufällig generiert werden?
  • Code ist oft billiger: Obwohl Sie sich darüber lustig gemacht haben, wie viel Speicherplatz ein Code-Kompiliervorgang normalerweise in Anspruch nimmt (und es gibt Gründe, warum diese "Plattform" im Laufe der Jahre zugenommen hat und wie Sie sie bei Bedarf verkleinern können), Wenn Sie jedoch etwas algorithmisch / prozedural / in-Code leicht ausführen können, ist dieser Ansatz auch einfacher zu optimieren und für andere ähnliche, aber unterschiedlich aussehende Assets wiederzuverwenden. Ein besonders anschauliches Beispiel sind Fraktale: Sie könnten ein Bild eines komplizierten Fraktals haben, das im Vergleich zu der mathematischen Formel, die es generiert, viel Platz einnimmt. Die mathematische Formel kann zusätzlich Parameter enthalten, die ähnliche, aber manchmal überraschend anders aussehende Bilder erzeugen können.

Für so viele Fragen sind einige der oben genannten Themen hoffentlich ein guter Ausgangspunkt, um mehr zu erfahren.

WorldMaker
quelle
Verwenden Sie außerdem Technologien, die weniger Platz beanspruchen.
Speeder
3
(Entschuldigung, Problem erneut eingeben ... es gibt eine Möglichkeit, es zu deaktivieren? Ich hasse es, dass jedes Mal, wenn ich drücke, der Kommentar eingibt).
Speeder
Ein anderer Ansatz: / Verwenden Sie Technologien, die weniger Platz beanspruchen, wie z. B. prozedurale Karten (Noctis verfügt über eine ganze Galaxie mit mehreren Millionen Sonnensystemen, auf denen Sie Planeten landen und Leben, Bäume, Ruinen, Gebäude ... in weniger als 3 MB sehen können ), Modulmusik (Musik in Formaten wie .mod, .xm, .it ...), prozedurale Texturen (siehe werkkzeug, mapzone und einige andere Software), prozedurale Klangeffekte (fast jeder Klangeffekt ist aus Mathe möglich) Gleichungen oder Manipulation von Grundschallwellen) und so weiter.
Speeder
@ Speeder Es ist einfach, auf "Bearbeiten" oder "Löschen" bei versehentlichen Kommentaren zu klicken ...
Dash-Tom-Bang
Betreff: "Komprimieren Sie, was Sie können", auf der alten Hardware, die Sie normalerweise auf alles komprimieren würden, was die Hardware handhaben könnte. Sie würden Audio niemals in MP3 komprimieren, da die Audio-Hardware dies nicht nativ handhabt und Sie keine Zeit damit verschwenden möchten, es auf der CPU zu dekomprimieren, wenn Sie es einfach direkt vom Medium in die Audio-Hardware streamen könnten. MIDI war großartig, weil jeder einen Wavetable-Synth an Bord hatte (und hat); Laden Sie einfach Ihre Proben und los geht's.
Dash-Tom-Bang
0

Eine Sache ist, ich bin nicht sicher, ob es noch in der Ära nach N64 steht, aber die SNES und N64 verwendeten häufig Texturen auf anderen 3D-Objekten wieder, was oft viel Platz spart und vorgerenderte Kunst, deren Hintergründe oft gefälscht sind. Ein weiterer Trick bestand darin, einen Rand zu erzeugen, der als Hintergrundnebel verwendet wurde.

San Francisco Rush N64 hatte immer etwas Nebel, obwohl Einstellungen die Dichte ändern konnten, in der die San Francisco Rush-Spielhalle keine hatte, und Sie die Golden Gate Bridge auf Gleis 1 im Vergleich zur N64-Version sehen konnten.

Spiele verwenden oft Musik wie Zelda Ocarina of Time wieder, was ich ärgerlich finde, denn es hätte eine bessere Arbeit leisten können, als wenn Banjo Kazooie / DK64 oft Themen innerhalb von Themen gehabt hätte!

Zelda Ocarina von damals hätte die Hyrule Overworld und dann eine Unterwasserversion des Themas haben können, wenn Sie unter Wasser gegangen wären oder die Instrumente im Shop-Thema den Außenbereich widerspiegeln würden, in dem Flöten und Geigen für den Kokiri Forest-Shop und die Hörner und verwendet würden Trompeten für den Hyrule Castle Town Laden und Trommeln im Goronendorf

In PCs werden 3D-Module in Bibliotheken kompiliert, um mit einem Programm zum Entpacken schnell darauf zuzugreifen. Ich bin mir jedoch nicht sicher, ob dies bei Nintendo der Fall ist, das auf ROM basiert. PCs sind RAMs, als würden sie in einen unordentlichen Raum gehen, in dem Dinge nicht immer dort bleiben, wo sie hingehören, und Informationen können so weit überschrieben werden, dass der Computer nicht einmal mehr startet!

Spielekonsolen sind ROMs, in denen alles in einem zugewiesenen Speicherplatz gespeichert ist, sodass jedes Mal, wenn Sie das Spiel einschalten, nach den Dateien in diesem zugewiesenen Speicherplatz gesucht wird, mit der Garantie, dass sie dort bleiben.

Der Grosse
quelle