Tagebuch: Game Jams

Hab heute 3 Kommentare gelesen. Die Bomben tot zu bekommen ist für viele schwieriger als erwartet. Kann mir aber nur vorstellen, dass der eigenen Schuss zu wenig aufgeladen wird. Auch wenn er recht klein ist. Bleibt man kurz stehen, dann laufen die Bomben in einer geraden Linie auf einen drauf zu.

Irgendwie hab ich das Gefühl das Spiel macht ist sehr ambitioniert darin, die Leute unter Stress zu setzen. Man hat nämlich gerade am Anfang eigentlich noch genug Zeit zu Chargen und ein paar Bomben der mit einem Schuss zu erledigen. Dann hat man auch eine Lücke durch die man durch kommt und „etwas Zeit gewonnen“ sich um die restlichen zu kümmern.

Die Buttons haben einen Hover. Aber der ist einfach nur verdammt schlecht zu sehen ^^. Generell hatte ich mit der Farbpalette sehr viele Schwierigkeiten, einfach weil sie überwiegend Dunkel ist und die wenigen hellen Farben nicht alle gut gepasst haben. Letztendlich verwende ich glaub auch nur die hälfte der Farbpalette im Spiel - der Rest wollte irgendwie nicht harmonieren. Ka - vllt einfach meine Unfähigkeit.

Danke. Bin auch mega stolz auf das Ergebnis. Ich hab wieder extrem viel gelernt und gerade gestern war extrem frustrierend. Vor allem das Intro hätte ich fast wieder komplett verworfen, weil ich mich selber die Physik über 3 ecken zerhauen hab und ich lange nicht verstanden hab, wieso.

Ich bin aktuell gerade sehr beschäftigt mit machine learning. Unity bietet da eine nette Lib an die ich zufällig vor kurzem durch ein YouTube-Video entdeckt hab. Mein Ursprünglicher Plan war es, einen KI zu entwickeln, die Keep Your Memory besser spielt als ich.

Leider hab ich das nicht hinbekommen und mein Projekt war jetzt auch nicht gerade für KI-Training designed. Das macht es für einen Anfänger natürlich umso schwerer.

Also dachte ich: beginne ein neues Projekt, welches eine einfachere KI voraus setzt. Erstmal laaangsam anfangen.

Ich dachte auch, dass ich ein ganz gutes Anfangsprojekt habe, was ich auch für ein Spiel zu einem Game-Jam ausbauen könnte. Spielprinzip ist einfach: Straße muss überquert werden, ohne das man vom Auto getroffen wird.

Sollte recht einfach sein für den Anfang. Die KI muss wenig wissen und noch weniger Aktionen ausführen. Vergleichen wir mal die Aktionen.

Keep Your Memory

  • Drehen
  • Bewegen
  • Schuss chargen
  • Schießen

Neues Spiel

  • Bewegen

Ich wollte nicht mehr als 2 Aktionen und bin sogar nur bei 1er. Gut was :slight_smile:. Während ich viele Stunden schon KIs trainiert hab, haben die umgekehrt auch mich trainiert.

Im wesentlichen funktioniert es so. Die KI trifft in Abständen immer wieder eine Entscheidung. Ich kann jetzt mittels Rewards sagen ob die gut oder schlecht war.

  • Positive Zahl = gut
  • Negative Zahl = schlecht

Damit kann ich also belohnen und bestrafen. Im wesentlichen schaut mein Model derzeit so aus:

  • Ziel erreichen: 1.0 (fix)
  • Vom Auto getroffen werden: -1.0 (fix)
  • Am leben sein: -0.001
  • Nach vorne Bewegen: 0.002
  • Zurück bewegen: -0.2

Kurz noch eine Erklärung was ich mit fix meine. Ein Agent (also das Teil was lernt) lernt in Episoden. Eine Episode ist vorbei wenn das Ziel erreicht wurde oder er von einem Auto getroffen wurde. Danach setzte ich den Agent auf seine Startposition zurück und beginne eine neue Episode. In dieser Zeit bekommt er von seinem Reward je nach Aktion positive oder negative Punkte. Es kann also sein, dass der Agent mit einem derzeitigen Reward von -0.5 beim Ziel ankommt. Dann addiere ich aber keine 1 sondern setze den Wert auf. Ich möchte, dass der Wert am Ende immer positiv ist - weil er könnte da auch durchaus mit -60 ankommen. Und dann ist -59 nicht so gut wie eine 1 ;-).

An der Stelle merke ich übrigens, dass ich das nur machen sollte, wenn der Wert unter 0 ist um schnelles erreichen des Ziels zu belohnen!

So. Die Zahlen die ich habe sind meine aktuellen. Die waren nicht immer so. Ich hab da ziemlich viel mit rumgespielt über die Zeit!

Generell hab ich zu Anfang haufenweise dummer Fehler gemacht. Ob ich es jetzt richtig hab, weiß ich btw nicht. Aktuell trainiere ich gerade eine (hoffentlich) vielversprechende KI.

Einer meiner ersten Fehler war das Leveldesign. Ich dachte mir: lass die KI durch ein Level rennen, wie es später auch sein könnte. Ergo: die ersten Straßen sind leichter als die am Ende. Hat nur ein paar Nachtteile:

  • Warum sollte die KI erst lernen mit den einfachen Sachen klar zu kommen, wenn ich sie auch gleich gegen den härtesten Schwierigkeitsgrad trainieren lassen kann? Ich starte mit mehreren Agents parallel (50 Stück - gleiches Level). Davon kamen 1-3 bei den letzten Levels an. Somit können auch nur 3/50 meiner Agents die schweren Passagen trainieren.
  • Warum überhaupt ein komplettes Level? Diese sollten sich später eh in der Anzahl der Straßen unterscheiden können. Also reicht es doch aus eine Straße auf höchster Schwierigkeit zu haben.
  • Nur eine Straße haben ist dumm - zum Schluss funktioniert die KI nur wenn Autos von rechts kommen. Also hab ich eine gespiegelte Variante direkt daneben gepackt. Sodass beides trainiert wird.

Für den zweiten Punkt hab ich mehrere Tage gebraucht. Der dritte Punkt kam mir dann relativ schnell.

Ein weitere Fehler (den ich immerhin nach glaub einem Tag mit dem neuen Spiel bemerkt hatte): Meine KI weiß zu wenig! Meine KI hatte ein paar Raycasts und das wars. Irgendwann kam mir: vllt sollte sie wissen WO sie sich befindet!

Irgendwann hab ich mich gewundert, warum die KIs den Autos nicht wirklich ausweichen. Anfänglich dachte ich: die Strafe ist zu niedrig. Doch ich hab was entscheidendes gelernt: Überprüfe was deine KI sieht! Denn sie sahen die Autos nicht. Ich hatte das Auto-Gameobjekt falsch eingestellt. Die KI konnte es nicht sehen.
Als ich noch das große Level hatte, hatte ich nach jeder Straße einen Trigger aufgestellt, der die KIs belohnen soll beim durchlaufen. Negativ war: die Trigger haben wie eine Wand für die Trigger funktioniert. Meine KIs konnten schon wieder die Autos nicht erkennen.
Dann hatten meine Agents sich immer mal wieder gedreht (Phsyikalisch bedingt). Ich sende aber nur Rays nach vorne und zur Seite. D.h. nach hinten sind meine Agents Blind (aber gewollt). Was nicht gewollt ist: wenn meine KIs gedreht sind, dann schauen die nicht mehr nach vorne - sondern zur Seite oder sonst wo hin. Ergo: Sie konnten die Autos schon wieder nicht sehen (Das hatte ich aber zum Glück ziemlich Zeitgleich mit der Trigger-Wand entdeckt).

Und zu guter letzt (heute morgen rausgefunden). Nachdem ich gestern Stunden lang meine KI trainiert hatte, hatte die ein ganz seltsames Verhalten angenommen. Alle kuschelten unten rechts auf einem Fleck und ich wusste nicht warum. Ich dachte über eine erhöhte Strafe nach um Sie nach vorne zu bewegen.

Das Problem ist nur allzu menschlich! Ich würde mal sagen: die KI hatte schlicht Angst! Warum kann ich seit heute morgen kann ich es zu 100% nachvollziehen und würde mich absolut genauso verhalten. Es war nämlich folgendes:
Meine Agents kollidieren nicht miteinander. D.h. Sie verhalten sich zueinander mehr wie Geister die durch den anderen durch gehen können (sie sollen sich ja nicht gegenseitig beeinflussen). Was ich aber ich nicht eingestellt hatte, war das sie auch durcheinander durchschauen können. Somit können die nicht aneinander vorbei schauen.
Dementsprechend können die mitunter ankommende Autos nicht sehen. Die die vorbei gelaufen sind wurden also mit hoher Wahrscheinlichkeit direkt überfahren. Ich würde da auch lieber warten, bis der vor mir über die Straße gegangen ist, sodass ich sehe, was ankommt. Dummerweise hatten die dann alle noch ganz an der Seite geparkt und die Autos kommen durch eine Wand. Vllt hätte ich die Agents auch dadurch schauen lassen sollen. Aber ich wollte auch, dass sie wissen wo level-ende ist. Da wüsste ich derzeit auch nichtmal wie ich das Problem sinnvoll löse. Wobei - hab ich mehr oder weniger.

Denn dadurch, dass ich mein Trainings-level angepasst habe, gehen die Agents alle in die Mitte. Sie sehen ankommende Autos und können eine gute Möglichkeit abschätzen.

Und so schaut das level derzeit aus:

Das Thema an sich ist unglaublich spannend. Aber auch unglaublich komplex. Ihr habt jetzt nur eine sehr grobe Zusammenfassung bekommen. Denn da gibt es bei weitem noch sehr viel mehr zu beachten.

Also. Mein erstes Model was ich da raus bekommen hab sah tatsächlich sehr gut aus. Erfolgsrate 93% (Soviele wurden zumindest laut meinen Metriken nicht von einem Auto getroffen). Sobald aber die zweite Straße ins Spiel kommt, schaut es wieder ganz anders aus. Da haut es mir 80% der Agents weg.

Deshalb habe ich jetzt eine weitere Scene gebaut - bei dem es zwei Straßen gibt:

Und hier sieht man auch schön die Metric:

Orange zeigt das Modell an, welches mit nur einer Straße trainiert hatte. Rot zeigt das Modell an, welches mit zwei Straßen trainiert basierend auf dem orangen Modell! Also ich hab kein neues Training angefangen. Das einzige was sich verändert hat ist die Map.

Ich hoffe, dass danach die KI mit allen Richtungswechseln klar kommt.

Also das ist das beste was ich hinbekommen hab:

Und ich glaub besser wird es erstmal nicht. Deswegen lasse ich das ganze ruhen und werde einen anderen Kurs einschlagen.
So interessant das Thema auch ist. Im moment lenkt es mich zu Stark von meinem eigentlichen Vorhaben ab: Game Jams. Deswegen werde ich das ganze nur noch time-based verfolgen.

Ich stells mir so vor. Nachdem ich ein Spiel fertig hab, werde ich versuchen eine KI dafür zu entwickeln. Aber ich hab dafür nur einen Tag Zeit. Oder ich Sollte ich früher mit einem Spiel fertig sein, dass die restliche Zeit vom Game-Jam dafür nutze. Oder eben: ein Jam startet in ein zwei Tagen: Zur Überbrückung steht dann KI-Entwicklung an.

Hab es jetzt endlich geschafft einen Generator für komplexe Levels zu schreiben. Nachdem ich am Anfang versucht hab die Pfade komplett selber zu generieren bin ich über zu einer Semi-Prozeduralen-Lösung.

Heißt: ich hab ein paar vordefinierte Module und die werden aneinander gesteckt bis ein Level fertig ist. Das ganze schaut dann so aus:

Von der Logik her ist es auch tatsächlich recht simpel. Die einzelnen Module haben so genannte „ExtensionPoints“. Das sind praktisch leere Container in die ich ein Modul reinstecken kann. Vorteil: Das Modul befindet sich am richtigen Platz mit der richtigen Rotation. Das ganze könnt Ihr hier sehen:

Das komplett grüne sind ExtensionPoints. Die Linie über der grünen Platform zeigt an, in welche Richtung weiter gebaut wird.

Zu erkennen sind auch blaue rechteecke:

image

Alle außer die ExtensionPoints haben solche „Rechteecke“. Diese definieren einen Bereich, wo kein weiterer „Boden“ platziert werden darf. Somit verhindere ich Überschneidungen.

Das System funktioniert auch soweit echt verdammt gut und wie Ihr im Video seht: auch große Level sind absolut kein Problem :slight_smile:.

Hab jetzt Gegenstände drin, die man aufsammeln kann:

Zum einen welche die Punkte geben (sind immer 10 Punkte - aber damit es schöner ausschaut sind es verschiedene 3D-Modelle). Und zum anderen welche die die Zeit auffüllen.

Ich hab noch relativ viel vor mir. Bin echt gespannt wie weit ich das Spiel bis zur Deadline bekommen werde. Ich hab afair noch 6 Tage Zeit. Sollten die mir nicht reichen, werde ich es glaub nach dem Game-Jam trotzdem noch weiter entwickeln.

Hab hier schon länger nicht mehr geschrieben. Das was jetzt kommt wird euch schockieren (macht clickbait innerhalb eines Themas überhaupt Sinn? Die Antwort wird euch auch schockieren!)

Zuerst. Das Projekt über das ich hier geschrieben hab ist tot. Warum? Ich hab meine Motivation verloren und das aus den Gründen:

  • Das Projekt geht zu lange
    Die eigentliche Deadline konnte ich nicht halten, bin auf einen anderen Jam umgeschwungen, zu dem das Spiel auch passen könnte um mehr Zeit zu haben. Aber ich hab gemerkt das ich da schon mehr Zeit verbraten hab als ich möchte und es noch eine ganze Menge mehr Zeit brauchen würde

  • Ich hab kein gutes Konzept
    Ob meine Ursprüngliche Idee funktioniert hätte bezweifle ich irgendwie. Ich glaub das Spiel wäre von der ersten Sekunde an langweilig gewesen. Das auszubauen hätte den Zeitlichen Rahmen weiter gesprengt.

  • Mir hat es visuell nicht zugesagt
    Das Level wirkte TOTLANGWEILIG. D.h. ich hätte nochmal an die Assets ran gemusst. Das wäre aber wieder Zeit die drauf gegangen wäre

  • Es fühlte sich an Industry City
    Und wer meinen Tagebüchern folgt der weiß was ich damit mein. Bei Industry City hab ich unglaublich viel Zeit verbraten. Das Spiel hat es nie wirklich weit gepackt. Zudem hat es mehrere Versuche gebraucht.

Auf jeden Fall hab ich mich irgendwann gefragt: warum zieh ich das durch? Ich wollte mich wirklich auf kleine Spiele konzentrieren. Zudem hat das Projekt seine Deadline ja auch verpasst und ist in keinem spielbaren Zustand. Dafür fehlt noch viel zu viel.

Also kam ich zu dem Entschluss: Bei Game-Jams werden es nicht alle Spiele packen. Manche werden halt einfach „failen“. Was aber ja auch gut ist. So kann man ich immer mal wieder neue Sachen ausprobieren und wenn etwas kacke ist - dann bin ich es wenigstens auf absehbare Zeit los.

Letztendlich hab ich in bei dem Spiel auch wieder einiges gelernt. Allen voran das Nutzen von BlendTrees war sehr interessant. Zudem hab ich eine gute Lösung für Zukünftige prozedural generierte Level was auch nicht verkehrt ist.

Zu guter Letzt hab ich in dem Projekt auch mal den CharacterController verwendet um meinen Spieler zu steuern (was eigentlich ganz Nett war).

Da das Projekt tot ist brauche ich ein neues Projekt. Ich hab einen Game-Jam gefunden der das Thema „One-Button“ hat. Man darf als nur eine Input-Methode habe (eigentlich zwei: Mausbewegung dürfte man auch dazu nehmen). Ich ging aber für die „Hardcore“-Variante. Ich dachte mir, ich versuche was zu basteln, was man wirklich nur durch klicken einer Taste (sei es Maus oder Tastatur) spielen kann. Das war ganz witzig und ich hab auch etwas hinbekommen. Vorab: Ja, die Idee ist inspiriert von Flappy Bird. Aber es ist kein Flappy Bird.

Als ich begonnen hab dachte ich mir: Ein Button bietet mehrere Input-Möglichkeiten. Am einfachsten sind zwei Events: Click/LongClick. Man kann 4 draus machen, wenn man Begin/End berücksichtigt. Habe letztendlich aber nur 3 gebraucht.

  • Einfacher Klick: Spiel start (Menu) / Richtungsänderung (Ingame)
  • Lange halten: Spiel beenden (Menu) / Nichts tun, da ein Schuss folgen wird (Ingame)
  • Loslassen nach langem halten: Schießen (Ingame)

Ihr seht, ich hab das Konzept auch auf das Hauptmenü übertragen (weswegen es diesmal sehr einfach ausgefallen ist). Wobei ich auch für ein richtiges Menü nicht unbedingt die Zeit gehabt hätte. Denn für das ganze Spiel hab ich 3 Tage gebraucht. Ich hab am Donnerstag gestartet und gestern abend hab ichs veröffentlicht.

Also ja - es ist fertig.

Das Spiel heißt Gravity Run und ihr spielt eine Kugel die entweder nach unten fällt - oder nach oben. Ziel ist es möglichst Möglichst viel Meter zu machen. Entgegenkommende Hindernisse versuchen das zu verhindern.
Im Gegensatz zu Flappy Bird sterbt Ihr aber nicht, wenn ihr Wand oder Hindernis berührt. Ihr dopst einfach von ab und werdet mit unter nach hinten gedrückt. Aber solange der Ball im Level ist, ist es nicht verloren.

Ein weiterer Unterschied ist, dass Ihr die Wände zerschießen könnt. Dazu müsst Ihr aber erst Kugeln aufsammeln die zufällig spawnen. Sobald die Kugel die Wand trifft - verschwindet diese mit einer Animation. Der Spieler muss aber nicht auf das Ende der Animation warten sondern kann direkt durch.

In diesem Spiel hab ich ein neues Asset verwendet. Ich hab nämlich Bolt durch Flow- und NodeCanvas ersetzt. Das scheint mir zwar Unity etwas instabiler zu machen - aber alles in allem sind die Tools deutlich besser als Bolt.

Zudem hab ich auch das erste mal das Problem gehabt, dass ich ein Spiel in einem bestimmten Format vorgeben möchte. In dem Fall: 16:9. Ich glaub fürs Web funktioniert das nicht so gut - aber die App-Varianten setzten das durch (Für Desktop bietet mir Unity das in den Export-Einstellungen an. Leider ist das für andere Plattformen nicht der Fall -.-).
Ich hätte es zwar auch via Code lösen können - das hat mir aber nicht so gut gefallen.

So - genug geredet. Das Spiel findet Ihr hier:

Ich wünsche viel Spaß beim spielen :wink:

(nein ich glaub clickbait ist innerhalb eines Themas unnötig)

So. Mit meinem neuen Projekt möchte ich gerne mal gerne eine höhere Polygonzahl testen. Meine Modelle sind jetzt deutlich komplexer. Meine Szene hat in Blender über 11K Polygone.

Während ich keine Bedenken hab, dass es aufm PC gut laufen wird - so bin ich gespannt auf die Webversion.

Hier könnt ihr sehen, was ich bisher gebastelt hab:

Derzeit bin ich daran allem ein Rig zu verpassen. Der Fisch ist fertig - bei den Pinguinen bin ich noch voll dabei. Hab eben erst das Rig soweit erstellt - aber noch nicht angewandt (das wird noch etwas Arbeit bedeuten!).



Alles in allem bin ich auf jeden Fall sehr stolz auf die 3D-Modelle. Denn die waren nicht gerade einfach für mich und gerade beim Seelöwen dachte ich mir vor beginn „Will ich das wirklich?!“. Und jetzt bin ich froh, dass ich mich der Herausforderung gestellt hab :slight_smile:

So. Der Pinguin ist fertig geriggt. Und das war ne ganz schöne Arbeit im Vergleich zu meinen sonstigen Modellen. Der Grund ist relativ simpel: Man muss Knochen die einzelnen Vertecies zuordnen mit einer Gewichtung (ein Vertex kann zu mehreren Knochen zugeordnet werden). Meine bisherigen Modelle hatten so wenig Polygone (und somit auch viel weniger Vertecies), dass ich jeden Vertex einzeln einstellen konnte.
Das geht hier nicht. Der Pinguin hat so viele, dass ich die Gewichtung aufmalen muss.

Glücklicherweise musste ich das nur einmal machen. Denn er Baby-Pinguin ist eine Kopie vom großen Pinguin und hat die exakt selbe Vertex-anzahl. Ich hab nur Farben und ein paar Vertex-Positionen geändert. Aber ansonsten sind die Meshs absolut gleich. Aus dem Grund konnte ich das selbe Skelett nutzen + die Vertex-Gruppen mit der Gewichtung von Mama-Pinguin auf Baby-Pinguin kopieren.

Als ich dann endlich fertig war und einen Pinguin neben den anderen stellen wollte hab ich gesehen: ich hab ein paar Vertecies vergessen. Und das schaut dann so aus:

image

Nachdem ich das und noch ein paar weitere Kleinigkeiten gefixt hatte, war ich dann auch fertig. Und so schaut das finale Ergebnis aus:

So langsam nimmt das Spiel seine Züge an. Diesmal hab ich auch meinen ersten eigenen Wasser-Shader entwickelt und bin sogar ganz glücklich damit.

Zudem hab ich jetzt auch ein paar Animationen erstellt und Wasser = Tötliche Zone. Es gibt auch einen entsprechenden Visuellen Effekt für den Spieler :slight_smile:

Ich glaube diesmal mit deutlich mehr Fokus zu arbeiten, als es bei meinen bisherigen Spielen der Fall ist. Man neigt doch gerne dazu viel auf Vermutung zu entwickeln um sich Arbeit abzunehmen. Tatsächlich war das aber eher kontraproduktiv weil ich damit schon Entscheidungen für die Architektur treffe obwohl ich diese noch gar nicht brauche. Das ist vor allem dann echt toll, wenn man etwas vorbereitet was man später gar nicht umsetzt, weil man es nicht möchte.

Auch wenn das Spiel aktuell nach noch nicht viel ausschaut, ich hab schon viele Ideen verworfen. Z.B. hatte ich einen Doppelsprung drin und Wasser war generell als Todeszone gedacht. Und nun wurde durchs Wasser laufen ein wichtiges Spiel-element.

Zudem kann der Spieler sein Baby aufheben und woanders platzieren (aber nur auf einer Eisscholle).

So - genug geschrieben (vor allem weil ich glaub, dass es bald essen gibt). Ich hab natürlich auch ein Video.

https://youtu.be/5Y-OlCkYBwk

Heute hab ich viel gepackt. Meine Fische bewegen sich nun intelligenter durchs Wasser. Sie weichen sich gegenseitig aus und versuchen nicht in den anderen rein zu schwimmen. Das war gar nicht mal so schwer zu implementieren.

Die Fische senden alle einen kurzen Raycast nach vorne aus. Erkennen Sie einen anderen Fisch, dann berechne ich das Dot-Product beider Schwimmrichtungen. Beim Dot-Product bekomme ich einen Wert zwischen -1 und 1. Wenn kleiner 0 dann schauen beide in unterschiedliche Richtungen (da sie sich sehen, gucken sie sich an). Wenn größer als 0.7 dann sollten beide in die gleiche Richtung (wichtig wegen Kreuzungen). (wenn 1 dann schauen beide in die gleiche Richtung).

Ansonsten hab ich jetzt wohl so ziemlich das komplette HUD eingebaut. Der Spieler bekommt alle nötigen Informationen und es gibt nun ein Game-Over. Bevor ich das alles erkäre, schauts euch einfach hier an:

Bisher hab ich den Seelöwen noch nicht rein bekommen. Und ich weiß auch noch nicht, ob ich den einbauen werde. Um das Spiel-Element „Heb dein Baby auf“ irgendwie sinnvoll zu gestalten werde ich wohl einbauen, dass das Baby kontinuierlich nach vorne läuft. Fällt es ins Wasser => GameOver.

Wenn du schwarmartiges Verhalten haben willst, kannst du Boids oder allgemeiner „Flocking Algorithmen“ benutzen, z.B. http://www.red3d.com/cwr/boids/

Interessant - aber nein. Tatsächlich möchte ich genau das Gegenteil. Die Fische sollen nicht im Schwarm agieren sondern individuell. Ich möchte, dass jeder seinen eigenen Weg geht.

Sie sollen sich schön verteilen und das bekommt man mit Random eigentlich schon ganz nett hin. Das einzige was ich halt einbauen musste, war das sie Kollisionen miteinander vermeiden. Was wie gesagt sehr einfach war (wenn jeder in die selbe Richtung ausweicht, dann ist das sehr einfach zu lösen).


Btw wird der Seehund wohl wirklich nicht zum Einsatz kommen. Ich hab jetzt eingebaut, dass der Baby-Pinguin konstant nach vorne läuft (außer der Spieler ist in unmittelbarer nähe). Das erzeugt mehr als genug Druck auf den Spieler. Selbst mit Minimap (die ich mittlerweile auch eingebaut hab :slight_smile:):

Meine wichtigsten offenen Punkte sind dann noch: Sounds und Hauptmenü. Letzteres hab ich zwar schon angefangen - aber bis auf den „New Game“-Button funktioniert da noch nichts.

Penguin Effect ist fertig und steht hier zum Download bereit: Penguin Effect by Tomate Salat

natürlich auch wieder mit den Assets: Penguin Effect - Assets by Tomate Salat

War auf jeden Fall ein interessantes Projekt bei dem ich wieder viel gelernt hab. Und das wichtigste vorab: mit den Modellen kann ich Web vergessen!
Deshalb gibt es diesmal auch keine Web-Version. Sie läuft zwar, aber nicht flüssig. Das ist gut und schlecht.

Gut: Ich hab frühzeitig die Grenze gefunden. Und das Spiel ist jetzt nicht soooo toll, dass ich einer Web-Version nachtrauern würde

Schlecht: Ich hätte trotzdem gerne die Möglichkeit gehabt komplexere Modelle zu nutzen. Das Level war schon nett.


Aber ich hab einen Plan B der viel mehr eine Idee ist. Und zwar beschäftige mich schon seit einigen Tagen mit der Unreal Engine. Die bietet zwar wohl auch die Möglichkeit an für Web ein Spiel zu exportieren - aber da hab ich keine Ahnung wie und ob ich das hinbekomme.

Gehe ich einfach mal von aus, dass das nicht möglich ist. Dann entwickle ich Spiele für Jams weiterhin in Unity und Unreal für „Abends auf der Couch“.

Warum so rum? Ganz einfach. Ich will möglichst viel Feedback für meine Spiele. Und die Leute spielen wohl eher ein Spiel im Browser als es herunter zu laden. Deswegen möchte ich die Hürde für meine Spiele da möglichst gering halten. Und das Feedback was ich bekomme dreht sich ja hauptsächlich um Gamedesign. Das lässt sich auf Unreal übertragen. Spiele die ich in der UE entwickle können dann Desktops und Handies als ziel haben. Dann könnte ich auch mit detailreicheren Modellen arbeiten.

Aber auf jeden Fall bleibt Unity meine führende Engine

Diesmal geht es mit einem 1st-Person-shooter weiter. Die erste Schwierigkeit die sich mir stellte war eher überraschend - aber einfach zu verstehen. Meine Waffen konnten durch Wände verschwinden. Die Waffe soll aber natürlich immer sichtbar sein!

Die Lösung war dann aber doch relativ einfach. Meine Main-Camera rendert alles - außer die Waffe. Und eine zweite Camera rendered nur die Waffe. Bis vor wenigen Minuten hat sie das ganze auf eine eigene Textur gerendert, welche ich dann über ein HUD angezeigt hab.

Jetzt hab ich herausgefunden, dass ich Kameras auch stacken kann. Somit rendern beide direkt auf den Bildschirm :slight_smile:.

Ursprünglich hatte ich noch den Fehler gemacht und die Waffen einfach irgendwo in der Scene platziert. Was ich dann direkt gemerkt hab: Die Beleuchtung passt nicht mehr. Und eigentlich macht es keinen Sinn, die Waffen irgendwo zu platzieren. Ich kann die Kamera ja sehr einfach folgen lassen.

Jetzt bin ich sehr zufrieden mit dem Ergebnis :slight_smile:

Die nächste Aufgabe ist das Spawnen von Projektilen. Das funktioniert aber auch recht einfach. Dafür mach ich mir den Viewport zu nutzen. Egal wie groß die Anzeige ist. Unten links sind die Koordinaten (0|0) und oben rechts (1|1). D.h. die Mitte vom Bildschirm ist immer (0.5|0.5). Das kann ich mir von der Camera in World-Koordinaten übersetzen lassen. Und schon weiß ich, wo ich mein Objekt spawnen muss. Die Rotation übernehme ich einfach vom „Kopf“ des Spielers und dann passt alles.

Das ganze könnt ihr hier sehen:

Die Gegner hab ich auch schon etwas vorbereitet. Ich werde hier eine Technik übernehmen, die in Spielen glaub sehr beliebt ist (bei Nahkampf). Bei meinem ersten Spiel Rawbot hatte ich Probleme mit dem Nahkampf, weil ich wirklich mit Kollisionen gearbeitet hab. Was man stattdessen aber machen kann ist folgendes:

Ich kann mich vom Animations-System benachrichten lassen, wenn ich in der Animation an einem bestimmten Punkt bin. Z.B. bei einer Laufanimation. Immer dann wenn der Fuß den Boden berührt setze ich ein Event und kann dann im Code daraufhin einen Footstep-Sound spielen. Bei einer Attacke gehe ich dann eben her und setze mir das Event dort, wo der Gegner getroffen werden würde. Im Code prüfe ich dann einfach ab, ob der Spieler in Reichweite ist. Ist das so, dann mache ich schaden.

Ein Beispiel dafür seht ihr hier:

Zwar mit bedeutend weniger Logik dahinter - aber vom Prinzip her genau das was ich meine :slight_smile:

Musste meine Waffenpositionen dann doch nochmal etwas umstellen, weil beim Schuss es nicht so aussah, als ob die Kugel aus der Waffe kommt.

Ich glaube aber, dass hab ich jetzt besser hinbekommen. Zudem hab ich auch den Hammer schonmal soweit implementiert, dass er theoretisch Schaden machen könnte.

Das nette: beide Waffen nutzen das AnimationsSystem als StateMachine. D.h. ich trigger dadurch wann der Spieler seine nächste Attacke ausführen und beim Hammer: wann Schaden angerechnet werden soll.

Und so schaut es aus:

Lang ists her, das ich hier was geschrieben hab. Das letzte Spiel hab ich eingereicht und hab den Jam sogar damit gewonnen. Wobei es auch nur 2 Spiele gab und ich mit 2 Bewertungen doppelt so viel hatte wie das andere. Auch wenn ich das andere Spiel nicht gespielt hab: ob meins wirklich besser war - wage ich zu bezweifeln.

Aber nach diesem Spiel hab ich einen anderen Jam gesucht und das war gar nicht so einfach. Die Auswahl war … naja. Hängen geblieben bin ich bei einem RPG-Jam, welcher knapp 2 Monate geht. Das hat mich dann auch vor allem deswegen interessiert, weil ich vorher ein Video über Leveldesign gesehen hab. Das war sehr ausführlich und sehr interessant.
Das wollte ich mal ausprobieren. Alles umgesetzt bekomme ich sicher nicht - aber wer weiß.

Derzeit schaut mein Level so aus (noch alles in Blender):

Das ganze hat bisher noch unter 14K Polyogonen, was mich echt überrascht. Aber hier zahlt sich aus, dass ich auf Low-Poly gesetzt hab. Was nicht von Anfang an der Fall war, weswegen ich diesen Charakter wieder aus dem Spiel gestrichen hab:

Hat mich ja nur einen kompletten Tag gekostet den zu erstellen. Aber genau hier lag meine Hauptmotivation für den Wechsel. Wenn ich für jedes Modell einen Tag brauche, dann dauern meine Assets einfach viel zu lange.

Wohingegen mich diese:

Nur wenige Stunden kosten.

Ich bin echt gespannt, ob ich das Spiel so hinbekomme, wie ich es mir vorstelle. Falls nicht, auch egal. Bei dem Projekt gibt es viel was ich lernen kann.

Btw, hab ich jetzt auch mittlerweile meine Arbeitsecke ein wenig aufgewertet. Und zwar hängt hinter mir nun endlich ein schönes großes Whiteboard :slight_smile:

(Könnte schon länger hängen, aber da nachdem ich bei unserer Küche ein paar Löcher schief gebohrt hatte, hat mir meine Verlobte verboten zu Lebzeiten jemals wieder einen Bohrer in die Hand zu nehmen. Würde da gerne widersprechen, aber die Löcher waren trotz Bemühung so schief - sie hat halt leider recht ^^. Das + die Tatsache wir nichtmal einen besitzen hat dazu geführt, das ich warten musste bis jemand zufällig mit Bohrmaschine uns mal besuchen kommt.)

Wie muss ich mir das vorstellen?
"He danke für die Einladung. Ach übrigens ich hab mal meine Bohrmaschine mitgenommen, einfach so weil ich sie mag :slight_smile: "?^^

In etwa. Sie amüsieren sich schon etwas länger über die Tatsache, dass ich das Board nicht aufhängen kann+darf+will. Von daher hätten Sie die Bohrmaschine vermutlich so oder so mitgenommen. Aber ich hab da auch nachgeholfen.

Sobald auch nur der Hauch einer Chance bestand, dass jemand der eine Bohrmaschine besitzt uns besuchen kommen könnte, hab ich ganz diskret das Gespräch immer darauf gelenkt. Manchmal hab ich das auch, wenn es nichtmal den Hauch einer Chance gab :slight_smile:

Ich bastle gerade an einem Quest- und Dialog-System. Einen „alten“ Stand könnt ihr hier sehen:

Heute hab ich da aber ganz schön umgebaut. Meine Quests kannten z.B. sowas wie:

  • Npc bei dem man die Quest abgibt
  • Npc von dem man die Quest bekommt
  • Diverse Texte

Hab ich alles rausgeworfen. Warum? Ganz einfach.

  • NPC-Infos
    Die Quest braucht das gar nicht zu wissen. Immerhin sollte der NPC wissen, welche Quests für Ihn erledigt worden sind. Die Quest braucht gar nicht zu wissen - von wem das war.
  • Texte
    Egal was ich als Text angebe, es wird immer eine billigere Lösung sein als das, was mir der Dialogue-Tree anbietet! Also warum doppelt pflegen?

Das was die Quest braucht sind auf jeden Fall mal die 3 Dinge:

  • Title zum Anzeigen im HUD
  • Ist aktiv? die StateMachine vom NPC kann dieses Flag prüfen und entsprechend reagieren
  • Ist erledigt? auch hier: eine StateMachine kann darauf reagieren

Was ich derzeit noch drin hab und vermutlich auch brauche sind Questbedingungen. Angenommen ich muss x mal Y töten/sammeln.

Aber ansonsten brauch ich tatsächlich nicht viel mehr. Das System ist bereits jetzt schon gut genug dafür, dass ich zwei NPCs hab. Und einer redet erst mit mir wenn ich vorher mit dem anderen geredet hab :slight_smile:.

Und die StateMachine dafür ist auch sehr übersichtlich:

image