Devlog #01 - Ruhe nach dem Sturm

Die letzten Wochen hat sich an der RawSalmonEngine viel getan. Nachdem sich der Arbeitsaufwand fürs Sommersemester einigermaßen eingependelt hat, konnte ich jetzt endlich wieder Zeit finden dem Projekt etwas Leben einzuhauchen.

Terra Australis Alpha #1 Bandicoot

"Terra Australis" ist das Demo-Spiel welches wir als Erprobungsfeld für die Engine ersonnen haben. Für die erste Alpha haben wir jetzt endlich alle nötigen Features festgelegt welche implementiert werden müssen damit endlich ein richtiges kleines Spiel draus werden kann.
  1. Mapwechsel generell
  2. Tod des Spielers inklusive Zurücksetzen zum Anfang
  3. Checkpoints
  4. Einsammelbare Gegenstände (Münzen bspw.)
  5. Benutzer-Interface mit Lebenspunkten usw.
  6. Menü
Derzeit arbeiten wir daran alle Punkte zu verwirklichen, nur musste ich feststellen dass sich so einige problematische Abschnitte im Code aufgestaut haben und förmlich darum bettelten umstrukturiert zu werden. Der Umfang war alles andere als klein aber jetzt bin ich deutlich zufriedener, denn das Arbeiten mit der Codebasis ist nun viel komfortabler für mich als Entwickler geworden.

Event System Refactoring aka. C++ Template Hell

Über die Events läuft die Logik des kompletten Spielablaufs und deswegen sind sie integral für die Engine. Sie werden eingelesen über XML Dateien (derzeit in der Tiled Map integriert), können Daten halten und modifizieren ein Objekt über seine öffentlichen Schnittstellen. Das heißt, wenn ein Charakter über die Map laufen soll, dann schickt man per Tastendruck ein oder mehrere Events die den Charakter animieren, bewegen und dabei auf Kollision prüfen.

Der alte Ansatz hatte zwei Hauptprobleme;
  • Das Speichermanagement der Events lief über eine "zwischengeschaltete" Klasse in der Vererbungshierarchie (Irgendwo wollte ich mir beweisen dass ich sowas verrücktes wie das CRTP in diesem Kontext zum laufen bekomme 😀).
  • Und der Typ der Objekte auf denen die Events operieren war fest, was viel doppelten Code zufolge hatte.
Jetzt ist die Mutterklasse nicht mehr "ActorEvent" sondern template-isiert "Event<Scope>", was erlaubt Events zu implementieren welche auf beliebigen Objekten operieren können. Außerdem gibt es jetzt die Template Klasse "SmartEvent<Scope>" die sich um das Speichermanagement der bösen Event Pointer kümmert. Zudem wurde das "registrieren" der Events bei der Mutterklasse automatisiert, jetzt kann niemand mehr diesen Schritt vergessen und sich wundern dass der Parser beim Einlesen meckert dass das Event unbekannt ist.

Das Sahnehäubchen obendrauf; Ich hab mich mal endlich drum gekümmert ein kleines Python Script zu basteln was neue Event Klassen generiert. Man muss also nur noch Attribute hinzufügen, dem Parser(auch neu) diese mitteilen und schon kann man sich um den "richtigen" Code den das Event ausführen soll kümmern.

Abspeckkur für MapData

Die Klasse "MapData" war lang genug das Mädchen für alles und wurde nun auf seinen Platz zurechtgewiesen. Ein Großteil der Funktionalität welcher sie den Tilesets und Map-Layers abgeluchst hat, stecken jetzt in der "TilesetCollection" und der "MapCollection" die jene deutlich besser beherbergen.

Was auch neu ist, jetzt gibt es nicht mehr nur "eine" Map, sondern Maps werden auf einem Stack angelegt um einfach so etwas wie Menüs, Pause Bildschirme, usw. zu realisieren. Dazu passend gibt es natürlich auch endlich ein "LoadMapEvent", was durch all die vorherigen Verbesserungen viel leichter zu implementieren war.

Weiterer Ausblick

Es wurde viel Strecke gemacht, Feature 1 steht und für 2, 3 und 6 wurde ein solider Grundstein gelegt. Mein nächstes Ziel ist es die Kollision neu zu strukturieren und zu vereinheitlichen, primär für Feature 4. Derzeit ist der Ablauf von Kollision mehr oder weniger Kraut und Rüben.
  • Erst sollen die Standard-Hitboxen der Actors mit den Standard-Hitboxen der Tiles auf Kollision geprüft werden (was automatisiert bei der bewegung der Actors passiert). 
  • Dann wird auf Kollision aller Hitboxen der Actors mit allen Hitboxen der Tiles, außer der Standard-Hitbox geprüft.
  • Und dann wird auf Kollision aller Hitboxen der Actors untereinander geprüft.
Ist das Prüfen der Kollision positiv, wird bei Actors das Callback "onCollision" ausgelöst (was als Event implementiert ist), das zusätzlich Information über den Kollisionspartner und die Namen der Hitboxen trägt.

Zusätzlich soll die aktive Frame der Animation ebenso Hitboxen tragen, dem Actor temporär hinzufügen und sogar gegebenenfalls gleichnamige Hitboxen zeitweise überschreiben. Gerade für Kampfspiele ala "Street Fighter" mit verschiedenen Treffer- und Angriffszonen sollte das äußerst nützlich sein.

"Nice to have" wären natürlich auch die Render-Ausrichtungen "Isometrisch" und "Hexagonal" sowie alle vier möglichen Render-Reihenfolgen. Da ich ohnehin an den MapLayers für die Kollision rumschrauben muss, könnte ich das wenn ich schon dabei bin ohnehin einfach mal "einbauen".

Kommentare