Tagebuch: Feature Runner

So. Bisher hab ich noch 2 Probleme gefunden:

  • Beim Block “Dirt” hat die Spielfigur sowas wie einen Vorsprung wo er drauf stehen kann. Das dürfte wohl den Collidern geschuldet sein. Einen hab ich heute morgen schon entfernt, hab aber vergessen den anderen anzupassen, damit er die volle höhe des Blocks ein nimmt. Dann sollte das Problem gefixt sein.
  • Die Geschwindigkeit der Säge. Sie ändert sich auch mit der Levelgeschwindigkeit und ich hab das Gefühl, dass daher ein “Stocken” sichtbar ist was als Lag wahr genommen werden könnte. Es gibt eigentlich keinen Grund die Endgeschwindigkeit der Säge weiter anzupassen. Deswegen werde ich dieses Verhalten anpassen müssen.

Ansonsten ist mir nichts weiter aufgefallen. Mal schauen ob ich heute Abend ein Update rausgeben kann.

Ok, ich glaube es liegt doch nicht an der Säge. Ich hab mich jetzt mal mit dem Profiler beschäftigt und der hat mir etwas interessantes aufgezeigt.

Objekte dich ich entfernen lasse haben selbst geprüft, wo sie sich befinden + ggf aufgeräumt. Das war wohl sehr teuer. Ich hab es jetzt auf ein Collision-model umgestellt (wie ich es auch meine mal in einem offiziellen Video gesehen zu haben).

Nach einem kurzen Test scheint es auch sehr erfolgsversprechend zu sein. Und da ich gerne mal wieder etwas veröffentlichen möchte, riskier ichs glaub einfach mal und hoffe, dass sonst alles passt :slight_smile:

So: neue Apk im playstore eingereicht und die win-version wurde geupdated :slight_smile:

Viel Spaß :slight_smile:

Ok. Nächster Meilenstein erreicht - die App zwingt mich mittlerweile immer mehr so zu arbeiten, wie ich es aus dem professionellen Umfeld gewohnt bin. Neben dem fahren von analysen hab ich mich jetzt etwas mehr mit dem Profiler auseinander gesetzt und eine weitere Optimierungsmöglichkeit gefunden.

Erstmal im groben, wie ich den Profiler verstehe und nutze:

  1. Panel anzeigen lassen und eine Runde spielen. Pause
  2. Zum Segment Update.ScriptRunBehaviourUpdate gehen (ich gehe davon aus, dass [nur?] hier die Klassen aus meinem Code zu finden sind). Danach schaue ich mir an, was davon am meisten Resourcen braucht.

In meinem letzten Schritt war das der ObjectRemover. Ich hatte erkannt, dass der viele GameObjects prüft und das auf Dauer teuer wurde. Wie schon erwähnt, hatte hier der Wechsel durch Kollisionserkennung geholfen. Leider kann ich euch dazu nix mehr zeigen, da ich die Änderungen schon vorgenommen hab.

Glücklicherweise(?) hab ich aber ein zweites Problem gefunden:

Hier gut zu sehen: mein MoveController ist an Stelle 1 was Resourcenhunger angeht. Also lag es nahe, sich das mal genauer anzusehen. In der zweiten Liste (rechts daneben) seht ihr einen Ausschnitt aller Elemente, welche diesen Controller verwenden. Ziemlich viel was? Aber glücklicherweise sehr einfach zu optimieren [bilde ich mir zumindest mal ein].

Und zwar sind viele der Objekte Kindelemente vom FloorSpawnerV2:

image

Gut zu erkennen auf der linken hälfte des Bildes. Und auf der rechten könnt ihr sehen: der Spawner besitzt selber auch Koordination in der Scene. Mein Plan schaut also wie folgt aus:
Anstatt jedes Element innerhalb des Spawners durch den MoveController bewegen zu lassen, bewege ich den Spawner nach links. Und alle Kindelemente werden folgen.

Und hier sieht man auch das “schöne” am profilen: Anwendungen die man noch nie durch einen Profiler gejagt hat lassen sich i.d.R. sehr leicht optimieren. Da man gerade solche Sachen wie oben hat, die einen förmlich anspringen und danach schreien optimiert zu werden. Der eigentliche “Spaß” fängt dann an, wenn man optimierte Software profilen darf.

Mit über 550 Runden, die ich gespielt habe, kann ich hoffentlich wertvolles Feedback geben.
Ich möchte dabei auf zwei Entwicklungsstände eingehen. Den vor dem letzten Update gestern und den nach diesem Update.
Zunächst vor dem Update:
Das Spiel hat mMn eine gravierende Schwäche. Um die Highscores zu überbieten spielt Glück eine zu große Rolle. Vor Wassergräben muss man quasi vorhersehen, wann wohl die Säge kommt, um zu entscheiden mache ich einen kleinen flachen Sprung um vor der Säge wieder hüpfen zu können oder brauche ich einen langen hohen Sprung um Wassergraben und Säge in einem zu überspringen. Gerade bis zu einer Distanz bis ca. 200 landet man mMn zu oft in der Säge ohne was falsch gemacht zu haben. Gerne auch mal auf den ersten 50m. Deshalb war auch schnell meine Motivation bezüglich Highscores weg. Die ergeben sich eher zufällig. Mehr Motivation habe ich aus den Durchschnittswerten gezogen. Ärgerlich dabei aber: Die haben sich nach einem Update, was schon länger zurückliegt, nicht mehr nach jedem Lauf aktualisiert. Man muss das Spiel beenden und neustarten um sie zu aktualisieren.
Ohne die Schwäche mit dem frühen Scheitern wäre für mich auf jeden Fall aber genug Motivation da gewesen, um es regelmäßig in der Bahn oder so zu spielen.

Und jetzt das aktuelle Update. Ärgerlich schon mal, dass die Highscores weg waren und auch der Shop. Da ich im Besitz von über 10000 Münzen bin, kein Problem. Alles neugekauft. Nur um festzustellen, dass nach dem erneuten Starten alle gekauften Items und damit auch die Highscores wieder weg waren. Dazu kommt jetzt eine Steuerung, die überhaupt nicht mehr so leicht und locker ist wie vorher. Auch funktioniert das doppelte Hüpfen um höhere Bereiche zu erreichen bei mir nicht richtig. Wenn ich weiter als über die erste Säge komme ist das super. Meine Stats zieht das natürlich extrem runter. Insgesamt momentan leider eine App, die für mich keinen Sinn macht

1 „Gefällt mir“

Ist mir gar nicht aufgefallen. Muss ich mal drauf achten was da schief gelaufen ist.

Oh, das sollte eigentlich nicht so sein oO. Da ist dann was mit dem wechsel auf das neue System falsch gelaufen. Eigentlich sollten die alten Features übernommen werden (was der einzige Grund ist, warum ich jetzt schon legacy-code hab …). Das Items/Highscore dann nochmal verschwinden klingt ganz böse. Landet zusammen mit dem oben erwähnten Statistiken auf meiner Prio-Liste ganz oben.

Hmm interessant. Ich hab die Logik vom alten Spawner noch (glaub das ich dafür nichtmal auf die Historie vom Repo zurückgreifen muss). Mal schauen wie aufwändig es wäre das als ersten zusätzlichen Modus anzubieten. Wem das neue Level-design nicht gefällt könnte dann den alten Modi spielen.

Das hab ich auch schon festgestellt. Die Level-Teile sind aber auch erstmal der erste Wurf. Da werde ich noch einiges verbessern dürfen.

Hab ich absolutes Verständnis für! Vielen dank, dass du das mitgeteilt hast anstatt die App einfach zu deinstallieren. So hab ich die Chance das Spiel für dich wieder attraktiv zu machen :slight_smile:

Hab’s gerade eben getestet. Das mit den Stats kann ich reproduzieren. Desweiteren fängt das Spiel nach einer Runde böse mit lags an. Das hätte mir gestern eigentlich auffallen müssen - das Update kam viel zu früh :/.

Ich werde ein performance-update gleich hochladen. Leider ist in dem Update bei weitem nicht soviel drin wie geplant - aber er dürfte hoffentlich das Spiel länger “Spielbar” halten. Es wird das Problem also nicht beheben - da ich es noch nicht gefunden hab. Mir fehlt aber auch die Zeit das heute zu finden und zu fixen. Deswegen möchte ich wenigstens die Lags etwas reduzieren. Morgen werde ich auch nix tun können - da ich im Freizeitpark bin. Aber am Freitag werde ich mich dann weiter auf die Fehlersuche machen.

So. Ich will mal ein Update geben zum aktuellen Stand. Also es schaut so aus: ich habe noch einiges an der Performance verbessern können. Durch das viele Profilen und Googlen hab ich auch auf jeden Fall viel gelernt. Leider hat das Spiel noch immer lags - sie kommen jetzt aber deutlich später als am Anfang (da war ja nach der ersten Runde direkt Schluss!). Leider kann ich nicht mit Sicherheit das Problem benennen, da es auch mit Profiler nur sehr schwer zu deuten ist. Deswegen hoffe ich es mit meinen final geplanten Änderungen erschlagen zu können. Kacke wirds nur, wenn darunter nicht die Problemlösung ist - denn dann werden die Lags wieder kommen. Einziger Wermutstropfen: man wird dafür sehr viele Runden am Stück spielen müssen!

Meine geplanten Änderungen mit denen ich das Problem HOFFENTLICH erschlage, da ich mir viel von erhoffe:

  1. Levelobjekte recyclen.
    In seinen Anfängen auch schon implementiert und ich spiels gerade auf mein Smartphone.

  2. Vorgladen der Levels auf ein Minimum reduzieren
    Es werden viele Dinge vorgeladen die so schnell noch gar nicht benötigt werden:
    image
    Alles was Rot schraffiert ist, könnte eigentlich noch einige Frames warten! Diese schon jetzt zu haben kostet mich gleich nämlich Speicher, Animation und Physik (letzteres ist teuer!).

  3. Leveldaten vereinfachen (Bereits umgesetzt)
    Wie oben schon beschrieben generiere ich die Levels anhand eines Bildes. Die meisten Pixel davon sind aber transparent. Somit ist da haufenweise toter Information drin. Diese Bilder lese ich nun nur noch einmal ein und speichere sie mir in einem effizienteren Model.

  4. Entspannung in den Levels
    Es sollen keine Levelteile direkt hintereinander geklatscht werden. Zwischendurch sollte es einfach mal „entspanntere“ Laufpassagen geben. Das macht das Spiel etwas „einfacher“ und insgesamt sollte es dann auch weniger Objekte geben, deren Physik berechnet werden muss.

Damit sollte dann hoffentlich das Performance Problem ein Ende haben! Wird aber etwas dauern bis ich das alles drin hab.

Eine gute Nachricht hab ich aber noch:

Den Bug hab ich mir angeschaut und auch bereits behoben. Der Fix kommt dann zusammen mit den Performance-Verbesserungen :slight_smile:

Ich glaub ich hab gerade sowas wie einen Durchbruch geschafft. So im durchschnitt hatte ich im Profiler gestern abend bei physikalischen Berechnung folgende Anzahl an Calls für die 2 Methoden:

Physics2D.DestroyShapes: 80 - 120
Physics2D.CreateShapes: 80-120

Dadurch, dass ich dem GameObjekt welches das Level hält einen Collider gegeben hab, der alle Child-Collier (vermutlich) zu einem zusammenfasst hab ich jetzt bei beiden so ziemlich konstante 7! SIEBEN!!!

Die Physik läuft jetzt also Stellenweise um den Faktor 17(!!!) schneller als vorher!

Habs noch nicht aufm Smartphone getestet. Aber ich bin sehr zuversichtlich :slight_smile:

Hä?..

So ein Grasblock hat einen Collider. Der wird getriggert wenn der Spieler damit in Berührung kommt (Kollisionserkennung). Diese Collider gibt es in Unterschiedlichen Varianten. Ich verwende z.B. sehr viele Box-Collider (d.h. ich definiere ein Viereck, welches auf Kollisionen reagiert). Vor meiner Änderung wurden alle einzeln behandelt. Nach meiner Änderung wurden diese zusammengefasst und es wird als einzelnes behandelt.

Nach welchem Prinzip werden die zusammengefasst? Sie müssen ja immernoch einzeln behandelt werden, auch können Physics Engines nur Convex Shapes verarbeiten.

Gerade mal wieder ausprobiert, ist es normal das man bei jedem Neustart alles neu kaufen muss?

Das Männchen bleibt zudem immer an Vorsprüngen hängen wenn man nicht rechtzeitig springt.

Ich tipp mal drauf, dass es wie eine Fläche behandelt wird und nicht 30 einzelne.

Nein. Eigentlich nicht. Mal ne Frage: ist das für dich Reproduzierbar? Weil ich konnte das jetzt noch nicht beobachten. Gut möglich, dass es durch die neuen Features gekommen ist. Dementsprechend glaub ich, dass es sich von alleine wieder fängt und nur bei EA-Testern auftritt.
Ich hoffe zumindest mal, dass es so ist. Weil dann löst sich das Problem von alleine und ich kann mich auf die anderen Sachen konzentrieren.

Ja, reproduzierbar. Die Münzen werden korrekt gespeichert, aber der Power Up Store ist bei jedem Neustart weg.
Würde das gerne ausführlicher testen aber ich hab keine Lust jedesmal 50 Münzen zu erspielen :stuck_out_tongue:

Ok. Ich konnte es nachstellen. Ich hab den Shop als Feature entfernt - und den kann er jetzt dem alten Legacy-Model nicht mehr zuordnen. An der Stelle stirbt die Zuordnung dann und es verschwindet bei jedem Neustart.

Den Bug hab ich behoben und der Fix wird im nächsten Update drin sein.


So dann mal noch etwas Tagebuchmäßiges:

Wir waren ja (wie im Freu-Thread erwähnt) in Tripsdril. Meine Freundin sammelt Notizbücher und ich hatte so ein richtig cooles gefunden - mit Wolf vorn drauf. Allerdings mit 3D-Effekt. Voller Stolz hab ichs Ihr gezeigt und war mir sicher es wird Ihr gefallen (zumal sie glaub keins hat mit 3D-Effekt). Wir habens also gekauft. Nicht für Sie, sie fands kacke, aber für mich. Dachte mir, es wäre gut die ganzen Ideen mal aufzuschreiben. Denn bis dato waren die Ideen:

  • Auf Post-Its
  • Hier im Thread
  • In meinem Kopf (der praktisch nur aus Memory-leaks besteht).

Und ich muss sagen: ich konnte EINIGES nieder schreiben.




Ich denk, meine Schrift ist einigermaßen leserlich. Damit habt Ihr dann auch mal meine aktuelle Roadmap. Ich hoffe, ich hab nix vergessen. Da der Thread aber mittlerweile schon verflucht lang ist - will ich nicht auschließen, dass etwas in Untergegangen ist.

Aber es ist auch schön zu sehen, dass mir nicht so schnell die Arbeit ausgehen wird ^^. Bin am überlegen, ob ich mir Youtrack aufsetze für ein Kanban-Board. Momentan hab ich noch einen recht guten Überblick über mein Backlog (dank des Notizbuches). Nur, sollte das noch mehr wachsen - würde es vllt doch Sinn machen.

3 „Gefällt mir“

Das gibt mal auf jeden Fall ein like von mir für die Tastatur!

So. vorab mal vielen Dank für die vielen Likes zu meiner Tastatur :smile:.

Ansonsten hab ich heute morgen noch ein bisschen an der App gearbeitet und eine neu Version eben im Store eingereicht. Zufrieden mit der Performance bin ich nach wie vor nicht - aber es sollte das Spielerlebnis trotzdem (hoffentlich deutlich) angenehmer machen als die letzte Version. Ansonsten fixe ich damit ja zumindest 2 nervige Bugs.

Die Windows-Version hat auch Ihr Update erhalten. Hier nochmal der Link: https://1drv.ms/u/s!Av4-trM0Vnk9tybTQfqeveVSdVrr

Das Update 1.9 in Stichpunkten:

  • Bugfix: Statistiken werden nun nach jedem Lauf wieder aktualisiert
  • Bugfix: Power Up Store & Items verschwinden nun nicht mehr nach einem Neustart
  • Performance Optimierungen
  • Überarbeitung an den Level-Generatoren

Eben kam mir noch eine Idee, womit die Performance-Probleme zusammen hängen könnten. Schuld daran könnte die neue Architektur sein!

Viele Änderungen während des Spiels werden durch Events verteilt, in Echtzeit. Und genau da vermute ich das Problem - die Echtzeit. Denn dadurch wird Code außerhalb der Vorgehen Callbacks ausgeführt. Updates für das Spiel sollte ich in der Update() oder FixedUpdate() machen (erstere rennt jede Frame, letztere wie sie will. Im durchschnitt alle 2 Frames. Würde die Performance absacken, dann würde FixedFrame() häufiger rennen. Wird hauptsächlich für Physik-Zeug verwendet um Ruckler zu vermeiden).

Also meine Idee: Weg mit den Listenern auf den Models (zumindest den meisten) und dann auf Änderungen innerhalb der vorgesehenen Lifecycle-Callbacks reagieren.