+4 Daumen
81 Aufrufe

lua1.png

1. EinfĂŒhrung

Das erste Spiel eines Gamers nimmt eine besondere Rolle in seinem Herzen ein. Bei mir war es damals Super Mario World fĂŒr das SNES-System. Heutzutage bietet es die Videospielfirma Nintendo innerhalb der Virtual Console, die das Spielen von Retro-Klassikern auf Vertretern der neueren Konsolengeneration (Wii U, Switch, Nintendo 3DS) ermöglicht, zum Download an. Dass dieses Spiel eines Tages eine EinfĂŒhrung in die Programmiersprache Lua ermöglichen wĂŒrde, haben die Entwickler um 1990 vermutlich nicht kommen sehen. In diesem Artikel geht es genau darum: GrundzĂŒge der Programmiersprache Lua anhand von Super Mario World zu erlernen. Doch wie soll dieses hehre Ziel umgesetzt werden? \(\Longrightarrow\) Durch ROM-Hacking.

Nun, genauer gesagt ist es kein ROM-Hacking im klassischen Sinne, das man heutzutage in zahlreichen YouTube-Videos prĂ€sentiert bekommt. Dort wird hĂ€ufig nur ein WYSIWYG-Editor verwendet, in den die ROM geladen und per Drag-and-Drop die Spielelemente auf dem Bildschirm verschoben werden. Das kann mittlerweile auch der Mario Maker (und zwar in weitaus besserer QualitĂ€t). Wir gehen anders vor: Wir laden die ROM des Spiels in einen Emulator und nehmen ĂŒber eine Lua-Schnittstelle Manipulationen an der emulierten Hardware bzw. den Speicheradressen (und den dort befindlichen Werten) vor. Du fragst Dich vielleicht, was ein Emulator ist. Wikipedia definiert treffend:

Als Emulator (von lateinisch aemulari, „nachahmen“) wird in der Computertechnik ein System bezeichnet, das ein anderes in bestimmten Teilaspekten nachbildet.

Der Emulator, den wir verwenden (BizHawk) emuliert das SNES-System derart, dass ROMs (Read-Only-Memory, Festwertspeicher) des jeweiligen Spiels darauf verwendet werden können. In der Speedrun-Szene werden insbesondere bei sogenannten Tool-Assisted Speedruns (TAS) Emulatoren eingesetzt, um entweder bestimmte Glitches (Spielfehler) frame-perfect (auf den Frame genau) auszufĂŒhren oder einfach auf Fehlersuche zu gehen.

2. Download des BizHawk-Emulators und Aufbau des Setups

ZunĂ€chst einmal benötigst Du den BizHawk-Emulator. Diesen kannst Du Dir unter der folgenden Adresse herunterladen: https://github.com/TASVideos/BizHawk/releases/ 

WĂ€hle die aktuellste Version (zum Zeitpunkt dieses Tutorials ist dies die Version 2.2.1)

1.png

Nach der erfolgreichen Installation solltest Du mit dem Doppelklick auf EmuHawk.exe folgendes Bild zu Gesicht bekommen:

2.png

Zudem sollte auf Deinem System Lua installiert sein: https://www.lua.org/download.html

Zuletzt ist eine ROM des Spiels "Super Mario World" vonnöten. 

---------------

Disclaimer

Bevor Du weiterliest, möchte ich darauf hinweisen, dass es von Nintendo nicht gerne gesehen wird, alte Nintendo-Klassiker auf Smartphones, Tablet oder PCs zu emulieren. Auch ich vertrete die Auffassung, dass Du mindestens eine Kopie des Spiels kĂ€uflich erworben haben solltest (entweder ĂŒber den Virtual Console Store oder als SNES-Modul), bevor Du das Spiel emulierst. Solltest Du eine Kopie besitzen, wĂŒnsche ich Dir viel Spaß beim Rest des Tutorials.

---------------

Wichtig: Lade Dir die US-Version herunter. Ziehe das .sfc-File per Drag-and-Drop in das Emulator-Fenster. Wenn alles richtig funktioniert, solltest Du Folgendes sehen können:

3.png 

WÀhrend das Spiel innerhalb des BizHawk-Emulators lÀuft, kannst Du in Lua geschriebene Skripts mit der Dateiendung ".lua" ebenfalls in den Emulator ziehen, der dann im Optimalfall das programmierte Verhalten auslöst. Doch wie was kann man eigentlich alles programmieren?

3. MarI/O - Ein neuronales Netz lernt Level 1 auf Yoshi's Island

Wer sich mit automatischer Gesichtserkennung oder dem AufspĂŒren von Tumorerkrankungen in Zellgewebe beschĂ€ftigt, wird frĂŒher oder spĂ€ter mit Machine Learning in BerĂŒhrung kommen. Hierbei lernt die Maschine (der Computer) selbst, welche Eigenschaften in den auftretenden Daten (Gesichter oder Gewebsaufnahmen) zu welchem Ergebnis (die Zuordnung von Gesichtern zu Menschen oder die Detektion von mutiertem Gewebe) passen. Dieses Wissen generiert der Computer aus Daten, die vom Menschen bereitgestellt und in Trainingssessions "gelernt" werden. Anschließend ist der Computer zur selbsstĂ€ndigen Zuordnung in der Lage. Auch dieser sehr spannende Zweig der Informatik fußt auf mathematischen Modellen. Ein oft in der Bildverarbeitung eingesetzter Ansatz ist das "neuronale Netz", das wiederum auf Matrizenrechnung (Lineare Algebra) beruht.

Doch nicht nur in der Bildverarbeitung, sondern auch im Bereich der Programmierung von "intelligenten" NPCs kommen neuronale Netze zum Einsatz. Ein tolles Beispiel, das man theoretisch gegen Ende des Studiums selbst entwickeln kann, wenn man die entsprechenden Vorlesungen und VertiefungsfĂ€cher gewĂ€hlt hat, ist eine kĂŒnstliche Intelligenz zum Lösen von 2D-Sidescroller-Spielen ganz nach dem Vorbild von MarI/O:


All das ist ĂŒber die Lua-Schnittstelle des BizHawk-Emulators implementierbar. Wir werden innerhalb dieser Tutorial-Reihe zwar kein neuronales Netzwerk programmieren, das ein Level zu lernen imstande ist (dafĂŒr ist einfach zu viel Expertenwissen im Bereich "neuronale Netze" nötig). Vielmehr werden wir kleine Skripte schreiben, die z. B. 

- Mario ungebremst in eine bestimmte Richtung laufen lassen

- Den Powerup-Zustand modifizieren

- Unverwundbar machen

- Den Ingame-Level-Timer verlangsamen/schneller machen

- 99 Extraleben spendieren

4. Hello World

Um eine Manipulation der dafĂŒr nötigen Speicheradressen durchzufĂŒhren, benötigen wir eine sogenannte RAM-Map (also eine Übersicht, in der die Speicheradressen samt Bedeutung aufgelistet und die ĂŒber unser Lua-Skript angesprochen werden können).

Eine solche RAM-Map findest Du hier: https://www.smwcentral.net/?p=map&type=ram

Die einzelnen BizHawk-spezifischen Funktionen, die innerhalb von Lua aufgerufen werden können, sind in einer API ĂŒbersichtlich dokumentiert: http://tasvideos.org/Bizhawk/LuaFunctions.html 

Wir werden als erstes Mini-Skript ein Hello-World-Programm schreiben, das ein 200x200 Pixel großes Fenster im Emulator erzeugt, das wiederum den Text "Hello World!" enthĂ€lt (also noch keine Manipulation der Speicheradressen; diesen Spaß heben wir uns fĂŒr spĂ€ter auf). DafĂŒr erzeugen wir zunĂ€chst eine Canvas ĂŒber die Funktion createcanvas, die als Argumente die LĂ€nge und Breite des Canvas (in Pixeln) erhĂ€lt:

local canvas = gui.createcanvas(200, 200);
Je nach gewĂŒnschter FunktionalitĂ€t, sucht man die Funktionen in dem API-Reiter.

5.png

Hier wĂ€hlt man z. B. gui aus und erhĂ€lt alle Möglichkeiten angezeigt, mit der eine GUI erzeugt und gestaltet werden kann. Das Keyword local zeigt an, das wir eine lokale Variable erzeugen. Dieser weisen wir den RĂŒckgabewert von createcanvas (unser Canvas) zu. Durch

canvas.Clear(0xFF000000);

schwÀrzen wir den Bildschirm. Durch VerÀnderung des Arguments 0xFF000000 kannst Du andere Hintergrundfarben auswÀhlen.

canvas.DrawText(0, 0, "Hello World!");

erzeugen wir an der Pixelposition \((0,0)\) den Text "Hello World!"

Das fertige Lua-Skript besteht also aus nur \(3\) Codezeilen:

local canvas = gui.createcanvas(200, 200);
canvas.Clear(0xFF000000);
canvas.DrawText(0, 0, "Hello World!");

Ziehst Du das Skript nun in den laufenden Emulator, erhÀltst Du folgende Ansicht:

4.png 

Die Lua-Console interessiert uns zunÀchst einmal noch nicht. Diese wird erst in den weiteren Tutorials relevant.

Das Mitglied hat durch den Artikel 50 Bonuspunkte erhalten. Schreib auch du einen Artikel.
geschlossen: Stack-Artikel
von 8,3 k

Ein anderes Problem?

Stell deine Frage

Willkommen bei der Stacklounge! Stell deine Frage sofort und kostenfrei

x
Made by a lovely community
...