89 - DROVA: Jetzt wird's Technisch! - podcast episode cover

89 - DROVA: Jetzt wird's Technisch!

Apr 02, 20253 hr 44 minEp. 89
--:--
--:--
Download Metacast podcast app
Listen to this episode in Metacast mobile app
Don't just listen to podcasts. Learn from them with transcripts, summaries, and chapters for every episode. Skim, search, and bookmark insights. Learn more

Episode description

Heute geht es mit Kai tief in die Technik von Drova. Wir reden über Textur Atlanten, Sprites Meshes, Schatten, Wasser Stencil Buffer, Outlines, Kampferkennung durch Musik und vieles mehr. Aber verzagt nicht! Man muss der Programmierung nicht fähig sein, um dem Podcast zu folgen. Zumindest nicht bei allen Themen.

Transcript

Simon

Hallo kleine vorwarnung diese folge wird ein bisschen technischer zumindest teilweise und ich wollte nur noch mal darauf hinweisen dass es gibt kapitelmarken und ihr könnt gerne wenn ein thema irgendwie euch nicht ganz interessiert oder es irgendwie zu schwierig nachzuvollziehen ist weil gerade nicht auf ein bild gucken könnte was hier eingeblendet ist dann könnte auch das käme gerne überspringen also es wechselt immer mal so zwischen auch teilweise sehr technische sachen

und dann kommen wieder so sachen die einfach super interessant zum zuhören sind und nicht so super technisch deep. Und genau, also nur falls ihr in der ersten Stunde schon irgendwas hört und dann sagt, okay, das ist mir zu krass und dann hört ihr auf. Das lohnt sich auf jeden Fall weiterzuhören, würde ich jetzt schon manchmal sagen. Und bezüglich Bilder übrigens, das hat alleine zwei Stunden gedauert, diese ganzen Bilder zusammenzutragen.

Deswegen guckt die Bilder bitte an und erlaubt euch an ihn, damit sich das auch gelohnt hat, diese investierte Zeit. Und insgesamt hat die Folge zwölf Stunden, zwölfeinhalb Stunden Produktion gekostet. Aber das ist noch relativ wenig, weil nämlich da die ganze Research-Sache gar nicht mit reingezählt ist, denn das war ja in der letzten Folge. Also ich habe die ganze Research gemacht und es hat sich jetzt gelohnt, dass ich daraus zwei Folgen machen konnte sozusagen, weil wir ja nicht alle Fragen.

Abgehandelt hatten. Allerdings muss ich sagen, habe ich jetzt, ihr werdet auch sehen, es gibt glaube ich vier noch extra Einsprecher. Ich habe nämlich noch ein bisschen extra Research gemacht mit ein paar Themen, die noch so on the fly aufgekommen sind. So, jetzt geht's aber los. Hallo und herzlich willkommen beim GameDiff-Podcast. Heute mit Kai. Hallo Kai.

Kai

Hallo Simon, willkommen.

Simon

Ja, du, nee, aber herzlich willkommen. Schön, wir sind hier bei, genau, wir kommen hier beide zusammen. Wir heißen uns beide willkommen. Und du bist nämlich da für, also Drova 2. Das ist mein Clickbait-Titel übrigens, Drova 2. Weil das ist die zweite Episode, wo wir über Drova reden. Aber ich habe echt überlegt, ob ich in dem YouTube-Thumbnail dann irgendwie so Drova 2.0 hinschreibe, um da noch ein paar Klicks abzugrasen.

Kai

Wenn das jetzt irgendwelche Köder sind, dazu kann ich bisher aber selber noch nichts sagen.

Simon

Achso, nee, du, keine Köder. Es ist einfach so, dass ich, ach, Marketing ist wirklich immer so ein schwieriges Thema. Und wenn ich diese YouTube-Thumbnails mache, dann auf der einen Seite bin ich immer so ein Fan von, ich möchte die Informationen, die im Podcast besprochen werden, zum Beispiel jetzt Pathfinding, Tools und Grafik, so auf der Thumbnail packen als Wörter, damit man einfach weiß, was man kriegt. so, ja.

Aber gleichzeitig langweile ich mich selbst schon, weil das irgendwie so, weißt du, das ist nicht catchy, das macht keinen nicht irgendwie so richtig Lust auf mehr. Aber wenn da jetzt so was steht wie Drowa 2, dann denken alle, wow, Drowa 2, und dann klicken die drauf und dann.

Kai

Ja, ich drücke die Daumen, dass es funktioniert auf jeden Fall. Du hast dir Gedanken gemacht.

Simon

Ja, mal gucken, mal gucken. Du, genau, also du, okay, das würde es nicht überraschend sein, du hast auch an Drohwe mitgearbeitet und dein Name ist schon sehr, sehr oft gefallen in der letzten Episode, wo ich mit Chris schon sprechen konnte, aber irgendwann ist die Zeit ausgegangen und außerdem hast du ja ganz, ganz viel auch in Bereichen gearbeitet, wo er nicht gearbeitet hat.

Und deswegen dachten wir, hey, es sind noch so viele Fragen übrig geblieben, da wollen wir noch mal einen Blick reinmachen.

Kai

Ich bin sehr gespannt, ich freue mich auf jeden Fall, dass wir noch mal so ein bisschen die technische Seite dann auch noch mal erleuchten können.

Simon

Genau, genau, genau. Es ist so spannend, was da noch alles kommt. Mal gucken, was wir alles heute abarbeiten können. Wir können aber noch ein, zwei Worte zu dir sagen. Dein Lebenslauf ist überraschend kurz auf LinkedIn. Also du hast studiert, ne? Dann Scientific Assistant und dann Prova.

Kai

Ja, genau so war es.

Simon

Genau, aber was ich gefunden habe, ist eine Website. Das fand ich nochmal interessant. Warte. Hä, wo ist es denn jetzt? Ah, genau, weiter unten. Und zwar …, gibt es eine Seite von, genau, eine Virtual and Augmented Reality Group. Und da taucht dein Name auf. Und da gibt es verschiedene Scientific Publications. Und da steht überall dein Nachname da. Und ich frage mich, ist das alles, hast du da überall mitgemacht?

Also, weil das, das sind so ganz viele medizinische Applikationen mit Augmented Reality und Virtual Reality und sowas.

Kai

Nee, da habe ich tatsächlich überall mitgemacht. Meine Bachelorarbeit, Ich glaube, das ist das dritte von unten, die Konzepte zur Diefendarstellung, bla bla, das war im Endeffekt meine Bachelorarbeit. Das da drüber war ein Paper und das da drüber war dann, glaube ich, meine Masterarbeit.

Und über diese ganze VR, AR-Geschichte und über die Uni bin ich im Endeffekt nicht zur Spielentwicklung, aber zu Shadern und grafischen Effekten und so weiter gekommen, weil ich hier viel mit Shadern gearbeitet hatte. Und genau, nee, da habe ich überall mitgearbeitet, ja.

Simon

Ach, das ist ja spannend, weil die letzte Episode oder eine vorherige, die 86, die gerade rausgekommen ist, ist nämlich die Vero zu Gast gewesen und sie ist Game Designerin für ein, also nicht direkt, jetzt muss ich überlegen, das ist nichts falsch zu sagen, doch genau, an der Uniklinik in Aachen. Und da geht es nämlich auch ganz viel um so medizinische Sachen. Und das passt ja einfach sehr, sehr gut zusammen gerade.

Die haben dann dort auch mit so einem Holo-Table gearbeitet und damit wird auch rumprobiert, dann irgendwelche Visualisierungen zu machen und sowas. Aber es war halt einfach super spannend auch zu erfahren, dass es an einem Uniklinikum halt eine Game-Designerin gibt. Also die kümmern sich dann so um Applikationen eben auch so oder um Spiele, um Wissen zu vermitteln.

Kai

Naja, Fenster, ja.

Simon

Und was war denn dann deine Shader-Arbeit da?

Kai

Also es hat relativ simpel angefangen mit der Bachelorarbeit, da war es einfach nur was quasi, also ich abstrahiere jetzt mal von der Medizin weg, du hast quasi einen Punkt im Raum gegeben, wo du dich sozusagen befindest und basierend auf diesem Punkt im Raum hat man dann bestimmte 3D-Modelle ein- oder ausgeblendet, ein- oder ausgefadet oder distanzcode-technisch verwendet. Wie nah bist du an dieser Struktur dran von diesem Punkt aus.

So hatte das damals angefangen und später dann mit dem AR-VR war es auch viel, ich hatte viel später mit 3D-Volumendatensätzen gearbeitet und hatte dafür einen Shader programmiert, um den halt zu visualisieren. Und dieser Volumendatensatz wurde dann verzerrt und verschoben, um aus der Position deines Kopfes seinen Visualisierung so anzupassen, dass es tatsächlich so wirkt, als ob du um eine Projektion in 3D herumgehen kannst.

Hat nur für eine Person leider funktioniert. Aber genau, und da habe ich viel dann mitgemacht. Und dann auch in dem Shader zum Beispiel Clipping Planes eingefügt oder verschiedene Sachen auf jeden Fall. Aber alles so grob dieselbe Richtung.

Simon

Also Clipping Planes, damit man zum Beispiel so ein Gehirn in Streifen schneiden kann und dann einfach gucken kann, wie es drin aussieht oder so?

Kai

Genau, in dem Fall war es der Oberkörper, der Torso. Und wenn du einen 3D-Volumendatensatz gegeben hast, gibt es ja an jedem Voxel, sage ich mal, eine Farbe. Und deswegen kannst du zum Beispiel gar nicht reingucken, weil du siehst zum Beispiel vielleicht erst das Fleisch oder die Haut, aber du willst vielleicht dir die Knochen angucken. Und dann kannst du entweder die Transferfunktion, nennt sich das, so verändern, dass halt Strukturen mit höherer oder niedriger Intensität dargestellt werden.

Aber du könntest auch einfach von oben einfach was wegschneiden, sodass du einfach so zack, weg. Und dann kannst du einfach die Hälfte des Thorses angucken als Beispiel.

Simon

Ja, genau, so ein bisschen wie, na gut, im Bio-Unterricht haben sie immer das Plastikmodell auseinandergenommen, aber es gibt sowas in Houdini auch, wer es kennt, so eine Slice-Funktion, dass man halt in Volumen schneiden kann, um da eben so ein Volumen betrachten zu können. Aber das andere habe ich nicht verstanden. Du hast ein Volumen und abhängig von wo dein Kopf ist.

Kai

Es ist ein bisschen tricky am besten, warte, ich versuche mal, es gibt glaube ich ein Video dazu in meinem besten Englisch. Ich weiß nicht, was ich glaube, man muss es runterladen, aber ich glaube, man kann es hier runterladen auf der Website. Also im Endeffekt, wenn du sagen, gehen wir mal weg von diesem Anwendungsfall, du hast einen Projektor und der Projektor projiziert ein 3D-Modell an die Wand.

Wenn du dann drum herum gehst, um diese Projektion, dann bleibt ja der Punkt, von wo aus es projiziert wird, gleich, aber du veränderst deine Position. Das heißt, du siehst es irgendwann verschoben. Nicht so, wie wie es 3D-technisch tatsächlich wäre. Und durch die Kopfposition konnte man Visualisierung so anpassen, dass sie sich sozusagen mitbewegt hat, während du dich bewegst. Aber auf die Art und Weise, dass es eigentlich dann 3D-perspektivisch korrekt ist.

Simon

Ah, okay. Das heißt, ich stehe in einem steileren Winkel zur Wand, gucke so von der Seite auf diese Beamer-Projektion sozusagen. Und ich sehe dann aber zum Beispiel den Tor so von der Seite irgendwie.

Kai

Genau, genau.

Simon

Ah, das ist ja interessant, ja.

Kai

Funktioniert vor allem hier sehr gut im Video, wenn du das Video anguckst. Wir hatten ein paar Leute, mit denen hatten wir so Tests gemacht, die haben das irgendwie, auch als sie es verwendet haben, nicht so ganz gecheckt und waren irgendwie so, wie das soll sich mitbewegen und so. Man muss zuerst sich so ein bisschen reindenken, damit es wirklich funktioniert, aber so auf Video-Ebene klappt das tatsächlich sehr gut.

Simon

Das ist übrigens eine Sache, die auch bei dem Holotable interessant war, weil da hast du genau dasselbe Problem. Dieser Holotable, der würde ja auch ein Rendering machen von einer Perspektive und damit verschiedene Menschen das aus verschiedenen Perspektiven sehen können, hat jeder eine Brille auf und der Holotable sendet mehrere Renderings auf verschiedene Lichtwellen aus und dann kann man das so filtern und alle Brillen holen sich dann eine andere Welle rein und dann kann man das so sehen.

Kai

Das hat man tatsächlich ja auch gemacht. Wir hatten auch so eine Shutterbrille. Da hätte man es theoretisch für zwei Leute quasi darstellen können, weil halt so für linkes und rechtes Auge. Man konnte sie dann so konfigurieren, dass zum Beispiel eine Person auf beide Augen nur die linke Sicht sehen oder auf beiden Augen nur das rechte. Und dann hätte man zwei verschiedene Projektionen auch starten können. Aber das war dann nicht mehr Teil des Themas.

Simon

Okay, interessant. Ich habe wegen den Schädern übrigens gerade gefragt, weil während der Research mit der Aufnahme Vero bin ich auf dieses Video gestoßen, und zwar Realistic Tissue Rendering for VR.

Da geht es halt eben darum, dann eben Schädler zu schreiben, die möglichst realistisch sind, so wie Haut oder innere Organe aussehen, aber eben in VR, was ja nochmal eine Herausforderung ist, weil man eben nicht so viel Performance hat, aber es muss ja möglichst realistisch aussehen, damit man gut ausgebildet werden kann.

Kai

Sieht auf jeden Fall sehr, sehr cool aus. Auch ein bisschen eklig, die eine Stelle, aber schon krass, wo wir so gelandet sind heutzutage.

Simon

Ja, das stimmt, genau. Ja, cool, spannend. Und ich muss sagen, Respekt, du hast acht Publications hier. Also acht Publications. Einträge, das ist ja schon ...

Kai

Ich hatte halt, als ich an der Uni angefangen habe, war auch so ein bisschen ein Thema, ob ich einen Doktor mache oder nicht. Ich wollte eigentlich von Anfang an nicht. Der Prof hätte gern gewollt, dass ich eins gemacht hätte, sag ich mal. Ein Doktorandenstatus, wie auch immer. Aber dann kam leider Drova dazwischen und dann musste ich sagen, tut mir leid.

Simon

Diese Videospiel-Fame.

Kai

Weiß ich, ohne Drova, muss ich zugeben, hätte ich vielleicht einen Doktor gemacht, aber ...

Simon

Aber so, also, also, aber, ja, ich frag mich halt, also, war, also ... Wie kam denn so die Entscheidung dann für Drova? Weil das ist ja schon eine Unternehmung, die sehr risikobehaftet ist. Man weiß ja nie, was läuft. Es ist ein super Spiel geworden, aber auch Superspiele können leider untergehen.

Kai

Vor allem, das war ja auch unser erstes Projekt, man hatte ja gar keine Glaskugel, um irgendwie in die Zukunft zu schauen.

Simon

Genau.

Kai

Im Endeffekt hat sich das eigentlich sehr organisch entwickelt. Ich hatte halt während der Uni schon mit Chris ein paar kleinere Spiele gemacht. Und dann haben wir halt auch in Mandrova angefangen. Aber da hatten wir nur nicht das Ziel, was es jetzt im Endeffekt geworden ist. Und hatten das so auch in, wir kommen aus Magdeburg, da gab es so einen kleinen Videospielpreis. Und da hat Mandrova eingereicht und das hat sehr gut funktioniert.

Hatten dann auch ein paar Kontakte mit Leuten aus der Spieleentwicklungsszene, die dann auch sagen, hey, es hat Potenzial, ganz cool, sah bei weitem nicht so cool aus wie heute. Und dann haben wir Johannes und Julia mit ins Team bekommen und irgendwie hat sich das so organisch immer weiterentwickelt, ist immer größer geworden und dann kam ja auch Deck 13 irgendwann dazu, die dann auch Entgesser hatten.

Und dann hat sich das schon so angefühlt, wie eigentlich sind alle Schienen und alle Straßen eigentlich schon gut gelegt. Eigentlich muss man die Straße jetzt nur so ein bisschen entlang gehen. Ob es einen Erfolg hat oder nicht, ist was anderes, aber initial fühlte sich das für mich eigentlich schon, nach einem schönen Weg an, als ich mich dann dazu entschieden hatte, dort, also dann nicht weiter an der Uni zu arbeiten.

Simon

Und genau, jetzt, was sind so deine Gedanken jetzt? Bereust du es? Oder sagst du, nee, das war schon der richtige Entscheidung?

Kai

Ach nee, war schon die richtige Entscheidung. Natürlich, also ich erhabe das manchmal so, was wäre, wenn, aber eigentlich bin ich kein Mensch, der was wäre, wenn Fragen stellt, weil was wäre, wenn, kann man nie richtig beantworten, weil du kennst ja nur die Perspektive, die du hast, weil du den Weg gegangen bist, den du gegangen bist und angenommen, im Kopf stelle ich mir irgendwas schöner vor, dann gibt es aber auch negative Punkte, die es dann irgendwie vielleicht runtergezogen hätten.

Ich bin auf jeden Fall sehr froh, dass ich den Weg gegangen bin. Auch jetzt, also diese technischen Sachen an der Uni haben mir echt Spaß gemacht und auch so viel auch mit Hardware gearbeitet und dann auch zu sehen, dass es verwendet wird irgendwo. Aber so dieses ganze Paper Schreiben und wissenschaftliche Arbeiten und Zitieren und dieser ganze Schmarrn, nenne ich es mal, das war so gar nicht meins.

Simon

Ja, ja. Okay. Ja, wäre vielleicht eine Frage, die ich am Anfang hätte stellen können, aber eigentlich so, wie geht's dir denn eigentlich gerade so? In Klammern, also so gerade in dieser Post-Release-Phase, Droh war es raus, ihr habt jetzt auch die ersten Patches schon da, das heißt, jetzt sollte ja ein bisschen Ruhe eingekehrt sein, so wie geht's dir, wie fühlst du dich, wie fühlt sich das alles gerade an?

Kai

Ja, mir geht es gerade super soweit. Hatte jetzt aber, glaube ich, viel durch die Weihnachtsferien zu tun. Hättest du mich vor den Weihnachtsferien erwischt, wäre meine Antwort vielleicht anders gewesen. Aber nee, gerade bin ich tatsächlich eigentlich sehr entspannt. Es ist jetzt auch deutlich ruhiger geworden. Vor den Weihnachtsferien hatten wir nochmal einen Patch rausgehauen. Der war nochmal ein bisschen intensiver, weil wir da nur wenige Wochen Zeit

hatten, um ihn rauszuhauen. Wir wollten den so ein bisschen teilen mit dem Steam-Sale. Da war viel Inhalt drin. Das war nochmal ein bisschen stressig. Und genau, alles in einem war natürlich auch der Release irgendwo sehr stressig und dann auch die ganzen Sachen nachzupatchen und so weiter und so fort, aber allmählich und stetig, stetig, stetig, stetig, whatever, ist es dann immer entspannter geworden und gerade ist es eigentlich eine sehr, sehr schöne Phase.

Simon

Okay, warte, jetzt muss ich aber mal, ich hab's ja durchgezockt, jetzt will ich natürlich immer wissen, was war denn in dem Patch drin? Das ist das Problem, man darf Spiele nicht zu früh spielen, weil dann kommen die ganzen coolen Inhalte nicht, also zu spät, an, die hat man ja noch nicht gehabt. Mal sehen. Oh, es gibt eine neue Difficulty.

Kai

Genau.

Simon

Insane Hardcore. Wow. Ich glaube, ich habe es auf Classic gespielt und ich sehe, es gibt ein, zwei, drei, vier, fünf noch andere Schwierigkeitsstufen. Was gibt es noch? Was ist denn noch Neues, Cooles dazu?

Kai

Im Großen und Ganzen haben wir Hardcore und Insane eingebaut. Hardcore ist im Endeffekt, wenn du stirbst, Game Over. Kannst du aber auch spielen auf Klassisch, das heißt dem Bekannten Schwierigkeitsgrad oder auf Insane. Und Insane ist eigentlich, da haben wir eigentlich alles nochmal an Werten angepasst. Also die Gegner haben teilweise auch andere Graphen, also die verhalten sich auch aktiv anders.

Jeder Gegner oder fast jeder Gegner hat eine neue Attacke. Es gibt auch neue Gegnervarianten und auch einen neuen Gegner. Und insgesamt sind einfach sagen wir mal die Schadenswerte der Gegner hochgeschraubt. Es gibt auch ein paar andere Balancing-Anpassungen, wie zum Beispiel, dass Lehrer mehr Geld wollen, um dann auch da so ein bisschen nochmal nachzuprobieren. Weil manchmal war es doch sehr leicht, irgendwie an den Lehrer zu kommen.

Und im Großen und Ganzen ist es einfach nochmal ein Schwierigkeits für Leute, die einfach Bock haben. Jo, drüber habe ich durchgespielt. Jetzt hätte ich gerne mal eine neue Challenge. Möchte aber nicht nur, dass einfach Gegner stärker sind, sondern es soll sich auch noch ein bisschen anders und uniker anfühlen. Und das haben wir da vor allem eingebaut.

Und sonst sind die anderen Changes, was den klassischen Modus angeht, habe ich gerade auch nicht ganz im Kopf, aber das ist, glaube ich, eher Richtung Bugfixing und Co.

Simon

Auf jeden Fall gibt es hier eine Challenge No-Hit-Run. dass man da nicht einmal getroffen wird. Okay, ich bin raus. Okay, cool. Ja, schön. Das ist doch schön.

Kai

Ja, finde ich auch.

Simon

Gut zu hören, ja. Habt ihr jetzt mal Plan für, also ich meine, klar, ihr habt jetzt gerade Weihnachtsferien, aber Weihnachtsferien sind ja auch immer so ein bisschen hin, man fährt zur Familie und so und dann ist Silvester und so richtig ganz dolle Urlaub ist es ja dann, also zumindest bei mir dann auch nicht unbedingt, Weil eben dieses ganze Reisen und Festivities sind halt teilweise auch ein bisschen, also schön, aber auch irgendwie anstrengend.

Habt ihr denn jetzt eigentlich mal einen Plan zu sagen, okay Leute, jetzt haben wir fünf Jahre durchgeackert, wir haben jetzt geil gepatcht so und jetzt machen wir mal drei Wochen wirklich richtig Urlaub?

Kai

Also für mich hat sich das tatsächlich jetzt schon so angefühlt über die Weihnachtsfeiertage, weil es für mich jetzt mal irgendwie so zwei Wochen am Stück war, wo ich jetzt eigentlich gar nicht das Projekt geöffnet habe oder nichts wirklich dran gearbeitet habe, deswegen hat es sich für mich schon so angefühlt, entsprechend ist da zumindest jetzt erstmal demnächst nichts weiter geplant, außer halt private Urlaube, die man halt irgendwie so einpflegt ins Jahr, sage ich mal.

Simon

Okay, ja, ich finde das tatsächlich immer gar nicht mehr so einfach, weil auf der einen Seite, also man denkt ja…, Ich finde, es ist auch schön, zusammen zu feiern. Und wenn man dann released hat, dann ist, wenn man, sagen wir mal so, wir nehmen jetzt mal an, das Spiel wäre perfekt an dem Status, also wie es früher war, dass man auch auf Cartridge released, und dann muss das Spiel ja wirklich, wirklich fertig sein zu dem Punkt.

Und an diesem Punkt könnte man ja sagen, so, und jetzt alle in Urlaub. Alle gehen jetzt in Urlaub. Und das fühlt sich dann aber auch für mich so ein bisschen leer an, weil man da ja gar nicht mehr so die Zeit zusammen verbringt. Und dann noch, oh, und wir gucken jetzt gemeinsam Streams oder so was. Und jetzt ist natürlich die realistische Herangehensweise meistens, dass man dann eben nicht zu Release in Urlaub gehen könnte, wegen, weil noch Patches und Community-Management zu tun ist und sowas.

Aber irgendwann rutscht man dann auch so wieder in die nächste Projektentwicklung schon wieder rein, weil man zu lange wartet und dann ist auch wieder so der Zeitpunkt nicht da, um zu sagen, okay, jetzt machen wir mal wirklich so eine kleine Durchartenpause und kommen dann später nochmal zusammen.

Kai

Also wir hatten ja eine Release-Party, da sind wir auf jeden Fall einmal zusammengekommen und haben zumindest mal einen Abend richtig ordentlich gefeiert.

Simon

Ja.

Kai

Und jetzt, wo auch ein bisschen der Stress raus ist, wollen wir auf jeden Fall auch mehr so ein bisschen im Team wieder ein bisschen vielleicht auch mal zocken abends. Das hatten wir auch vor Weihnachten einmal gemacht. Und es steht auch im Raum, ob wir vielleicht so ein bisschen zusammen als Team wegfahren. Als Blockhütte haben wir das ein bisschen deklariert. Aber müssen wir mal gucken, da ist noch nichts Konkretes geplant.

Aber auf jeden Fall wollen wir so ein bisschen in diese Richtung auch gehen.

Simon

Ich blende zumindest gerade mal ein Bild ein von eurem Release-Kuchen. Ihr habt nämlich einen tollen Release-Kuchen. Kuchen gehabt.

Kai

Der war echt ziemlich fancy.

Simon

Mit Drova-Logo. War das von der Bäckerei nehme ich an, ne?

Kai

Ich glaube nicht. Ich glaube, es hat Chris' Freundin gemacht.

Simon

Ja, schön.

Kai

Ich war sehr beeindruckt, auf jeden Fall.

Simon

Okay. Du, es gibt eine große Kontroverse, über die wir reden müssen. Und zwar habe ich ein TikTok gefunden, wo du sagst, dass du kein C++ magst.

Kai

Oh ja, das stimmt. Kontroverse, also ich würde sagen, das ist Fakt quasi.

Simon

Ach so, okay. Na gut, also, okay. Damit du das besser verstehst, ich bin ja eigentlich 3D-Artist und habe mich dann in die VFX-Richtung entwickelt. Und so ein bisschen Programmierung mache ich auch am besten mal, aber das ist dann eher so ein bisschen Scripting. Aber ich bin jetzt nicht so ganz tief im Code. Und deswegen, aus meiner Perspektive, ist es immer so, weiß ich nicht, alle machen C++. Oder jetzt halt C-Sharp, aber C++, wenn man cool ist, macht man C++. Das ist so meine naive,

Einstellung oder Wahrnehmung. Deswegen dachte ich, das wäre eine Kontroverse, aber ...

Kai

Also ich glaube, das ist es auch, je nachdem, wen du so ein bisschen fragst. Natürlich, wenn du mich fragst, gibt es da nicht so viel Spielraum. Aber es gibt auf jeden Fall, also wir haben ja auch zum Beispiel genau in diesem TikTok-Video, wo wir das, glaube ich, auch thematisiert haben. Und wenn man mal in die Kommentare schaut, wenn ich mich recht erinnere,

ist es schon eine kleine Kontroverse auch. Aber ich glaube, es liegt daran, dass viele Menschen sich einfach sehr stark mit ihrer Programmiersprache identifizieren, die sie so am liebsten mögen. Ich dann ja natürlich auch mit C-Sharp. Und die dann entsprechend auch verteidigen, wenn andere Leute nicht der Meinung sind. Und für mich fühlt sich C++ einfach ein bisschen altbacken an.

Das hat sehr viele so, ich nenne es mal Artefakte, wo man so merkt, ja, das hat man wahrscheinlich damals so gemacht und das ist jetzt halt noch so drin, weil die Sprache ist halt noch, wie die Sprache ist. So ein bisschen technisch zum Beispiel dieses Pragma-Once oder If-and-Dev, was du mal am Anfang von diesen Dateien machst, das finde ich super nervig und warum macht er das nicht automatisch, muss man eh immer tun.

Oder auch Sachen in Header und Source-Files auslagern, gerade wenn man da mit Vererbung arbeitet, hast du plötzlich vier Dateien, die du anpassen musst, wenn du deine Methode vielleicht umnennen möchtest und das alles sind für mich so Produktivitätsstopper, die mich primär nerven, weshalb ich C-Sharp deutlich angenehmer finde, weil ich da mehr das Gefühl habe, in einen Flow zu kommen und einfach Sachen zu schaffen quasi.

Wobei natürlich, wenn man wahrscheinlich in C++ sehr, sehr gut ist, man da wahrscheinlich auch reinkommt. Da war ich dann vielleicht noch nicht auf dem Level, dass das irgendwann so zur Second Nature geworden ist. Ja, aber so ist meine Meinung dazu.

Simon

Ja, ich finde es ganz interessant, dass du sagst, dass das Ding das ja automatisch machen könnte, weil das ist das Erste, was man vor allem so, wenn man das erste Mal programmiert und diese doofe Meldung kommt, da fehlt ein Semikolon. Und das zeigt dir aber auch an wo. Dann denkt man sich ja auch, dann mach es doch hin! Das ist so der erste Gedanke, warum geht das nicht mehr automatisch?

Kai

Ja, wobei ich da wieder, weil ich bin es wahrscheinlich wieder gewohnt, Semicolons zu machen, da würde ich sagen, da mach halt eins. Das würde mich darum weniger stören, ich glaube, weil ich das schon so in meinen Workflow so integriert habe wahrscheinlich.

Simon

Aber ich kann verstehen, was du meinst mit diesen Header und Source-Files, die man dann irgendwie rumliegen hat und dann an verschiedenen Stellen was ändern muss. Weißt du, ich habe nämlich mit, also eigentlich habe ich mit QBasic angefangen, aber bin später auch in Pascal.

Und da war es dann immer so, da musste man auch immer, wenn man eine Funktion machen wollte, muss man den Header der Funktion ganz oben einmal definieren und dann unten die Funktion halt auch nochmal, also nochmal denselben Header und dann die Funktion schreiben. Da habe ich auch immer gedacht so, ey, warum? Das macht wirklich keinen Spaß.

Kai

Ja, so ist das bei C++ auch, nur dass es dann nochmal in verschiedenen Dateien liegt.

Simon

Ach, schön.

Kai

Ja, oder?

Simon

Ja, das klingt wirklich ein Traum. Ich bin ganz froh, dass ich da nicht so tief drin stecke. Aber ich dachte mal, das bringe ich hier mal an, weil es ganz, Ich finde es ein spannendes Thema, wie verschiedene Leute auf sowas blicken und vielleicht ist es ja auch eine schöne Diskussion. Wir haben ja einen Discord-Channel und für jeden Podcast gibt es auch einen eigenen kleinen Thread dort und dann könnt ihr eure Meinung zu C++ und C und C-Sharp und so weiter gerne mal reinschreiben.

Kai

Nur vielleicht nochmal als Disclaimer so hinterher, ich würde natürlich nicht sagen, dass C-Sharp objektiv die bessere Sprache ist oder C++ objektiv die schlechtere, kommt natürlich auf dem Anwendungsfall darauf an und je Hardware-H du bist Hardware näher, so rum, desto eher geht man auch in C++-Richtung und C++ hat auch schon so ein bisschen so seine Beauty irgendwie mit Pointern und so weiter rum zu hantieren, ja, aber ich brauche es halt in meinem Alltag einfach nicht.

Simon

Was ich halt, aber das ist vielleicht auch nicht nur sprachenabhängig, gehört habe, ist, auf der einen Seite hat man keine Wahl je nach Engine, die man benutzt, weil zum Beispiel Unreal ist halt C++ und wenn man da, also abgesehen von Blueprints natürlich und dann muss man das halt, da hat man keine Wahl und was ich immer mal gehört habe, das habe ich aber nie selbst am eigenen Leib, aber das wäre ja auch ein spannendes Thema vielleicht, um über Drova zu reden.

Es gibt ja die Garbage Collection, also dass man eben nicht den Speicher manuell anfordert und freigibt wie in C++, dort muss man alles manuell machen. C-Sharp ist dann so ein bisschen, ja, komm, ich handle das, aber irgendwann kommt das große Müllauto und räumt alles mal weg, was nicht mehr gebraucht wird und dann kann es aber auch zu Zuckeln kommen.

Kai

Ja, ja.

Simon

Und das war bestimmt auch ein Problem in Drohwar, oder?

Kai

Auf jeden Fall. Also man weiß das ja so ein bisschen, wenn man es viel scharf entwickelt. Hey, irgendwo ist ein Garbage-Collector, irgendwo gibt es da mal ein bisschen Zeug und irgendwann räumt er so ein bisschen auf. Ja, ja, passt schon, passt schon, passt schon. Aber unser Spiel ist dann irgendwann doch sehr groß geworden und wir simulieren sehr viel, zum Beispiel wo NPCs wann hingehen in der ganzen Welt, auch wo der Spieler nicht ist.

Und die machen da sehr viel Stuff auch offscreen. Und wenn man dann die Chunks rein- und rauslädt, kommt auch sehr viel Garbage rein und ja, irgendwann schlägt's halt zu und man weiß halt nicht wann, ist so ein bisschen unpredictable. Das mussten wir dann natürlich auch gegen Ende, haben wir sehr viel daran gearbeitet, diese Garbage, also alles, was Garbage erzeugt, zu reduzieren.

Also nicht alles in C-Sharp macht Garbage, nur bestimmte Sachen und die, die diesen Garbage erzeugen, das haben wir dann am Ende auch sehr viel profiled, optimiert, möglichst weit reduziert, dass das halt möglichst wenig ist und dann auch, man kann so Pings geben an den Garbage-Collector, zu sagen, hey, jetzt wäre ein guter Zeitpunkt, das aufzuräumen. Das heißt nicht, dass er dann aufräumt, das heißt nur, dass du jetzt sagst, dass es jetzt ganz gut wäre.

Und das nutzen wir natürlich auch in der Hoffnung, dass er das dann möglichst zeitnah tut und gerade in Dardoscreens als Beispiel. Aber so hundertprozentige Kontrolle hat man da leider nicht drüber. Das heißt leider auch so Vorteil, dann braucht man sehr wenig Zeit da natürlich auch reinstecken, das alles manuell irgendwie zu managen. In der Informatik ist leider alles immer so, hat Vor- und Nachteile. Dann kriegst du irgendwo einen Plus, dann kriegst du auch irgendwo einen Minus.

Und da muss man immer so ein bisschen so einen Pay-Off angucken, was man halt tun möchte.

Simon

Genau, und für den Kontext, was du mit Chunks meinst, ihr habt nämlich ja ein Streaming-System eingebaut in das Spiel, ne?

Kai

Genau, genau. Also man muss sich ja vorstellen, wir haben ja eine Open World, das heißt, du kannst jederzeit in jede Himmelsrichtung gehen. Und obwohl es nur 2D-Pixel-Grafiken sind, nimmt das alles schon sehr viel Arbeitsspeicher und RAM weg und auch auf der Grafikkarte und die Atletik, Texturen und Atlase, die dort dann geladen sind, die man braucht, um dieses Objekt dann zu rendern, das Spiel wäre viel zu groß, würde man alles zeitgleich quasi geladen lassen.

Und deswegen müssen wir halt zu bestimmten Zeitpunkten im Spielen neue Content reinladen und rausladen. Und das haben wir über ein Chunk-System. Das sind quasi so Quadrate in der Welt, die dann immer so geladen sind, dass man immer genau die Kamera quasi ausfüllt, bestmöglich. Und dann werden die halt rein- und rausgeladen.

Simon

Ach so, genau. Und das war noch eine Sache. Ich glaube, das hatte Chris erwähnt, dass dieses Problem vor allem mit der Switch aufgetreten ist, weil alles über zwei Gigabyte, da stürzt das Ding einfach ab. Und wahrscheinlich auf PC wäre es vielleicht noch ohne Chunk-System gegangen, oder?

Kai

Also vielleicht, aber dann würde man natürlich auch die Low-End-Geräte nicht so gut bedienen können. Also ich fand es eigentlich ganz praktisch im Nachhinein, dass wir die Switch mit im Kurs hatten, weil wir dann doch so viel optimiert haben, dass es hoffentlich auf jedem Rechner möglichst gut läuft, sofern man irgendwie ein bisschen Hardware verbaut hat.

Und deswegen bin ich eigentlich ganz froh, dass es so ist. Und andererseits gibt es auch manchmal Spiele, die sehr viel Hardware-Anforderungen haben, wo man sich so fragt, warum? Ich finde, das kommt auch nicht so gut an, so ein bisschen. Deswegen bin ich eigentlich sehr froh darum, dass wir gezwungen waren, das ein bisschen runter zu skalieren. Ich denke trotzdem nicht, dass wir die ganze Welt hätten geladen lassen können.

Aber wir hätten auf jeden Fall mehr laden können, sagen wir, das Vierfache oder sowas.

Simon

Ich finde es auch immer super spannend, wie einfach man den PC immer noch auslasten kann. Also es ist relativ einfach, einfach schlechte Performance zu erreichen. Überraschend einfach dafür, dass die Hardware ja schon extrem leistungsfähig ist eigentlich, aber es ist, Doch überraschend einfach alles. Und dann sieht es trotzdem nicht gut aus. Aber sag mal, warum, das frage ich mich jetzt, warum kostet es es denn so viel Speicher, NPC-Simulationen zu machen?

Kai

Also nicht unbedingt die spezifisch. Also an NPCs hängt bei uns sehr viel mit dran. Also theoretisch, wenn sie geladen werden würden, hätten sie ihre Kleidung. Das sind dann wiederum Texturen, die geladen sind. Die haben dann ihre Items, die sie bei sich tragen. Und die Items haben zum

Beispiel Referenzen auf eine Fähigkeit, die sie feuern. und sagen wir mal ein Feuerball oder so und dann muss ja auch die Grafik von dem Feuerball geladen sein und weil der Feuerball geladen ist, der macht ja auch einen Sound. Also im Endeffekt eine Kette und im Großen und Ganzen beginnt ein NPC bei uns diese ganze Kette an Dingen, die er benötigt, damit er für sich vernünftig funktioniert.

Gegen Ende haben wir es sehr stark noch vereinfacht, dass dann tatsächlich nicht so viel Stuff geladen werden muss, aber es hat ein bisschen gedauert, um die ganzen Sachen rauszukicken. Und ein NPC, damit er sich gut bewegen kann, braucht dann ja auch Pathfinding, Das heißt, er muss Informationen über seine Umgebung haben. Die Umgebung ist gar nicht geladen. Dazu haben wir quasi auch so einen Graph. Der war am Anfang auch noch ein bisschen anders und hatte sehr viel Speicher an sich gefressen.

Und jetzt haben wir aber das auch noch mal umgebaut gehabt, dass das eher über Polygone läuft, die dann so ein bisschen weicher, freundlicher sind. Genau. Und im Endeffekt sind das gerade, glaube ich, 150 NPCs ungefähr ohne Gegner. Das heißt, wenn man die Gegner ... Also, es ist einfach die schiere Anzahl im Großen und Ganzen.

Simon

Ah, okay, klar. Wenn man alles dazu ... Klar, da macht das Sinn, genau. Aber das finde ich interessant, weil ich hatte, ich erinnere mich bei X-Rebirth, was manchmal so, dass wenn du das Spiel gestartet hast und du hast das erste Mal zum Beispiel geschossen, dann kann es sein, dass du deine Bullet nicht gesehen hast, weil die Textur noch nicht geladen war. Und bei der zweiten kam es dann, und das hat mich sehr geärgert als WFX-Artist dann.

Und dann konnte ich sagen, ich konnte manche Texturen forcen, also erzwingen, dass die immer geladen werden. Weil alles andere war sehr dynamisch, sozusagen. Und ich finde es interessant, dass es bei eurem System, ist das normal in Unity oder ist das euer System, was gesagt hat, nö, nö, wenn wir hier irgendwie nur einen kleinen Fitzel von irgendwas laden, zum Beispiel ein NPC, dann nehmen wir aber auch bitte alles, also alle Grafiken, alle Audio und so und auch alle Effekte.

Ist das von Haus aus bei Unity so oder?

Kai

Also ich denke, wenn man von Haus aus Tutorials folgt, die man online sieht, dann ja. Ich würde aber nicht sagen, dass Unity sagt, das ist the way, der gegangen werden muss. Aber es ist entsprechend auch der, also ich hatte das ja mit Chris damals angefangen, Drovo, und es hat einfach Quellkau-technisch sehr viele Altlasten.

Heutzutage würden wir diese ganzen Systeme vermutlich auch deutlich anders und optimierter aufziehen und das dann ähnlich machen wie bei dem Beispiel, das du gebracht hattest, dass man die Textur und die Grafik nochmal explizit entkoppelt von dem Rest der Logik und dann nur on demand zum Beispiel lädt. Dann hoffentlich ein bisschen smarter, dass man die Textur dann auch sieht.

Aber nee, im Großen und Ganzen hat das einfach einen Seiteneffekt durch unsere Softwarearchitektur und wir haben tatsächlich auch recht spät angefangen. In Unity nennt sich das Addressables, dass Dinge quasi adressiert werden können und deswegen können sie dann zu einem bestimmten Zeitpunkt rein- und rausgeladen werden, streamed werden quasi. Und das System haben wir einfach sehr spät eingebaut und wir hätten diese Kette unterbrechen können, aber das hätte sehr viele Seiteneffekte gehabt.

Wir hätten sehr viel mehr noch programmieren müssen, um dann die ganzen Problemcases, die dadurch auftreten, zu verhindern. Und das haben wir einfach zu spät angefangen.

Simon

Ja gut, aber jetzt ist es ja super, denn jetzt werden ja eh nur die geladen, die in der Nähe sind.

Kai

Genau, genau.

Simon

Äh, passt das. Aber hier, Spezialfall, es gibt ab und zu mal NPCs, die laufen einen ganzen Weg. Also es gibt in dem Spiel, vielleicht sollte man auch ganz kurz mal beschreiben, worüber wir überhaupt reden. Drova ist ein 2D, äh, 2D Rollenspiel von Vogelperspektive mit einer Open World. Und in dieser Open World gibt's, ähm, zwei große Lager. Und es gibt manchmal den Fall, dass ein NPC sagt, jo, ich geh mal zu einem anderen Lager. Und dann laufen die da wirklich hin. Und jetzt wäre die Frage …

Was bedeutet das für dieses System? Weil sobald der NPC dann aus dem Bildschirm raus ist, könnte er ja eigentlich rausgeschmissen werden aus dem Speicher. Aber die Logik muss ja irgendwie weiterlaufen, dass der jetzt zu einem anderen Lager läuft und irgendwann dann auch dort ankommt.

Kai

Genau, bei uns ist das so, also es stimmt nicht ganz, dass sie 100 Prozent rausgeladen, also sie werden irgendwann bei uns rausgeladen, aber vor allem auch viel diese grafische Repräsentation.

So ein Platzhalter bleibt in der Welt quasi zurück, der dann tatsächlich auch diesen Weg entlang läuft und wenn du denen dann näher kommst, dann wird der Platzhalter wieder ausgetauscht durch den tatsächlichen NPC, aber der hat zum Beispiel weniger Informationen, der würde zum Beispiel durch Wasser gehen als Beispiel oder der geht nicht richtig durch Pathfinding oder mancher läuft da durch Wände oder so und erst wenn man denen dann näher kommt,

stellt er irgendwie fest, okay, Pathfinding wo bin ich denn? Und dann geht er wieder so back on track quasi und läuft auch viele Wegpunkte entlang, um aber auch diese Cases zu vermeiden. Und... Harte, worauf wollte ich hinaus? Aber ja, deswegen ist das, so wird das erstmal bei uns gehandhabt. Es gibt bestimmte Spezialfälle, wenn der Spieler weit genug weg ist, dass wir ihn tatsächlich zum Beispiel teleportieren.

Oder wenn zu viel Zeit vergangen ist, dass er nicht wirklich den ganzen Weg läuft, sondern was weiß ich, ich laufe als Spieler irgendwie vor und bin dann in Nemeton zum Beispiel angekommen, ist ein Lager bei uns in der Welt. Der NPC-Ast muss sein, den du am Anfang triffst. Und jetzt ist er, vielleicht wird er für einen Dialog benötigt, aber er ist einfach zu weit weg in der Welt und dann sagen wir, ja, dann porten wir einfach her. Und dann ist er dann halt auch einfach da.

Simon

Aha, interessant. Weil wir über Memory gesprochen haben. Also, ihr habt verschiedene Tools benutzt. Ich habe eine ganze Liste, zum Beispiel den Odin-Inspektor oder das A-Star Pathfinding Project und anderes davon, das passt gerade, weil wir über Speicher gesprochen haben, ist das Memory-Pack. Das gibt's auf GitHub und das ist ein Memory-Pack-Serializer. Was macht das?

Kai

Erstmal als so ein bisschen Disclaimer, es geht ein bisschen in die Johannes-Richtung. Ich weiß zumindest inhaltlich, worum es da geht, aber der könnte auf jeden Fall technisch da besser drüber erzählen. Im Großen und Ganzen, warum NPCs auch sehr teuer waren am Anfang, sind die Dialoge von denen.

Da steckt ein Dialogtree dahinter, der hat Knoten, die sind verbunden, da sind Choices drin, da sind Bedingungen drin, wann diese Knoten im Dialog gesagt werden dürfen oder wann ich mich dafür entscheiden kann und wann nicht. Und dann gibt es Subgrafen für verschiedene Kapitel oder für Quests und so. Und im Großen und Ganzen war auch ein großes Performance-Problem einfach die Größe von diesem Dialoggrafen.

Da haben wir ein Tool benutzt von Unity, also nicht von Unity selbst, sondern aus dem Asset Store. Also jemand hat das entwickelt und in Unity im Store zur Verfügung gestellt. Das haben wir für dieses Grafentool verwendet. Und das hat einfach sehr, sehr schlecht skaliert mit sehr vielen NPCs und mit sehr vielen Grafen. Und was wir dann dort umprogrammiert haben, ist quasi die Art und Weise, wie dieses Grafensystem seine Daten serialisiert und deserialisiert.

Und dafür haben wir dieses Memory Pack Tool quasi verwendet, weil das einfach deutlich performanter war als das, was dort schon quasi gegeben war. Das Serialisieren, Deserialisieren muss man sich so vorstellen, im Endeffekt liegt da, sagen wir, das ist jetzt übertrieben, es ist kein Textdokument so direkt, aber ein Textdokument auf dem PC, der sozusagen diesen Graphen mit diesen Knoten in den Verbindungen repräsentiert.

Und man muss dann ja aus diesem serialisierten Text, also serialisiert insofern, er ist einfach so Line für Line hintereinander angeordnet, dann ja irgendwie ein Objekt erzeugen, was nicht mehr so Line-by-Line ist. Und das nennt sich dann Deserialisierung.

Simon

Ja, weil man ja von der ersten Zeile zur 50. springen kann, je nachdem, was ich aussuche in dem Dialog. Baum oder ...

Kai

Nicht gar nicht. Also, wie man es sich eher vorstellen muss, stell dir vor, du hast eine Textur. Und eine Textur, sagen wir mal, ist zweidimensional. Das heißt, du hast ja pro Pixel einen Eintrag. Und du möchtest es jetzt aber auf die Festplatte ablegen. Und die Festplatte kennt nur linearen Speicher. Also du kannst nur Dinge in linear ablegen sozusagen. Das heißt, du musst ja irgendwie deine 2D-Textur nehmen und es so darstellen, dass es jetzt in eine Line passt oder in den Speicher passt.

Und dieser Vorgang vom Serialisieren, also zum in den Speicher packen oder deserialisieren, aus dem Speicher quasi ein tatsächliches Objekt erzeugen, das anders miteinander, ist recht technisch auf jeden Fall. Das meint Serialisieren, deserialisieren. Also wie kommt es auf die Festplatte und wie wird es von der Festplatte geladen sozusagen? Ich glaube, das ist einfacher.

Simon

Aber ist nicht der Speicher, also RAM oder Grafikkanspeicher oder Festplattenspeicher dieselbe Art im Sinne von, wie die Daten draufliegen, nämlich einfach linear?

Kai

Das stimmt. Die liegen dann trotzdem natürlich linear beieinander, aber ... Jetzt wird es recht technisch. Das stimmt schon, aber sie können an verschiedenen Speichern im Speicher liegen und dadurch dann zum Beispiel auch unterbrochen sein. Aber dann brauchst du ja einen bestimmten Speicher, der auch wiederum sagt, dass die beiden in Verbindung stehen.

Und das ist zum Beispiel mit diesem Knotensystem, dass man sagt, okay, dieser Knoten hat zwei Verbindungen zu zwei anderen Knoten und jeder Knoten ist ein Part im Speicher und die Verbindungen sind ein Part im Speicher. Und irgendwie muss es ja eine Verbindung geben, welche Teile des Speichers liegen beisammen und welche nicht. Und dass die jetzt nicht mehr linear beieinander liegen, das ist quasi der deserialisierte Part.

Und wenn ich das aber auf die Festplatte speichern würde, dann ist es der serialisierte Part und dann liegen alle Sachen auch nah beieinander, damit es auch als eine Datei zum Beispiel vorliegen kann.

Simon

Ja, also man kennt das ja so ein bisschen unter Fragmentierung auch. Also wenn die Daten fragmentiert sind, dann liegen halt sie überall in kleinen Fetzen verteilt im Speicher. und dann gab es früher das wunderbare bei 95D-Fragmentierungstool, was so, es hat so eine Befriedigung ausgelöst, zu sehen, wie die kleinen Blöcke zusammengerückt werden und so und Ordnung gemacht wird.

Kai

Ja, das kenne ich auch, da habe ich auch viel verwendet früher oder mein Vater wollte immer, dass wir es verwenden oder so. Weiß nicht, ob es wirklich was getan hat, aber was du schon meinst, die Visualisierung war auf jeden Fall dabei auch sehr, sehr schön.

Simon

Ja, aber was ich mich jetzt frage, also dieses, ich zitiere, das Memory-Pack-Ding, Da steht da auf der GitHub-Page Zero Encoding Extreme Performance Binary Serializer for C-Sharp und Unity. Und da steht einfach nur so eine kleine Grafik, dass das 200 mal schneller ist wie irgendwelche JSON-Response-Model, whatever. Warum ist das nicht von Haus aus dann einfach drin in Unity? Wenn das so super ist.

Kai

Also Unity, also warum es das spezifisch nicht hat, ist eine gute Frage, das kann ich nicht beantworten. Unity selbst hat natürlich auch eine Art zu serialisieren und die Art, wie Unity serialisiert ist, auch schneller als wie unser Asset-Pack, was wir verwendet hatten für die Graphen, was irgendein Grund haben die ihr eigenes Serialisierungstool, Pipeline, wie auch immer programmiert und die war vor allem nicht so gut.

Die von Unity ist auf jeden Fall besser, aber ich glaube, der Memory-Pack bla bla bla ist wahrscheinlich trotzdem deutlich besser als der von Unity. Warum der so schnell ist, ist weil der sehr viele Predictions, nicht Predictions, Vorwissen voraussetzt. Zum Beispiel markiert man bestimmte Attribute in seiner Klasse und sagt, alles klar, das liegt an der Stelle 0, das liegt an der Stelle 1. Also es gibt quasi Conditions oder Voraussetzungen, wann man es verwenden kann,

damit es so schnell ist. Und das macht es aber wiederum weniger flexibel. Das ist das, was ich auch vorhin schon mal meinte, in der Programmierung hat alles leider immer Vor- und Nachteile. Und Unity ist da, glaube ich, einfach den Weg gegangen, einfach die möglichst große Gruppe an Usern anzusprechen.

Simon

Ich habe übrigens auf diese GitHub-Page einen Satz gelesen, den möchte ich einfach gerne mal vorlesen, weil es einfach so lustig ist. Ich finde es immer lustig, ich bin jetzt irgendwie seit 15 Jahren in der Branche und wie gesagt, kein richtiger Programmierer und so, aber so ein ganz bisschen technisches Wissen habe ich ja auch. Und dann lese ich diesen Satz und ich sehe einfach nur Worte und verstehe gar nichts. Was habe ich denn lesen vor?

Mal gucken, ihr könnt euch in den Kommentaren ja melden, ob ihr jetzt versteht, was ich sage. Zero Encoding ist ähnlich wie Flatbuffer, aber es braucht einen besonderen typen. Memory Pack Serialization Target ist Poco. Okay, ich meine, das Einzige, was ich daraus mitnehme, ist, dass es anscheinend was mit einem Möbelhaus zu tun hat, weil es gibt dieses Poco-Möbelhaus. Ja, also toll, das ist doch eine tolle Erklärung, oder? Da wissen wir doch genau, was gemeint ist.

Kai

Ja, willkommen in der Welt der Informatik.

Simon

Genau, du hast verschiedene Dinge jetzt schon erwähnt eben, auf die ich jetzt Bezug nehmen könnte und ich weiß gar nicht, welches das erste ist, doch wir fangen mit etwas Kleineren an, was auch nochmal ganz humoristisch war. Ihr habt nämlich ein schönes Beispiel für alten Code bei euch auf TikTok vorgestellt. Das fand ich ganz toll. Und zwar ging es da um das Waffenziehen. Warte, jetzt muss ich noch gucken, wo ist das denn jetzt?

Also ich kann es kurz beschreiben. Ihr habt da irgendwie geguckt, welche Musik läuft und abhängig davon konnte der NPC die Waffe ziehen oder nicht. Irgendwie sowas in die Richtung war. Das war ein schönes Beispiel, wie Code natürlich wächst und irgendwann vielleicht nicht mehr ganz so optimal ist.

Kai

Also das Beispiel dort war, wir wollten einmal herausfinden, hey, befindet sich dieser oder befindet sich der Spieler gerade im Kampf oder nicht? Weil das war im Endeffekt so die programmiertechnische Abfrage, die wir dort machen wollten. Und wir hatten etwas Ähnliches programmiert, um dann halt Combat-Musik abzuspielen. Und die Abfrage ist im Endeffekt sowas gewesen wie Musik-Händler.ist-Player-in-Combat.

Und natürlich ist die Abfrage, ob der Spiel am Combat ist, nicht relevant, also relevant fürs Musiksystem. Aber das Musiksystem sollte nicht dafür verantwortlich sein, zu sagen, ob der Spiel am Combat ist oder nicht. Und das war das, was wir dann gepostet haben, was halt so historisch so ein bisschen gewachsen ist. Mittlerweile tut das übrigens nicht mehr. Und da haben sich dann die Leute auch sehr drüber amüsiert oder auch so gesagt, ey, was seid ihr denn für Leute? Problemieren wir richtig.

Simon

Genau, das Video hat 60 Kommentare. Das scheint getriggert zu haben. Ja, aber ich finde so eine Beispiele ganz toll. Und das ist auch schön bei euch, dass ihr so offen zeigt. Weil am Anfang in dem Video sagt Chris auch so, ja, man glaubt ja immer, dass die Leute, die Spiele machen, dann immer alles perfekt machen, aber nee, nee, der Code ist manchmal auch.

Kai

Da können vielleicht auch nochmal vielleicht Zuhörer googeln. Es gibt sehr schöne Kommentare im GTA 5 Quellcode, glaube ich. Das kann man einfach mal googeln. Von sehr, sehr witzigen Sachen, wo man dann auch sieht, ja, vielleicht ist da nicht alles immer so perfekt. Ich habe gerade keinen richtigen Beispiel im Kopf, aber das sind sehr, sehr witzige Kommentare, sowas wie, ja, ich mach das jetzt hier, weil ich weiß auch nicht, aber wenn ich es nicht mache, funktioniert es halt nicht.

Und dann kommt irgendein Methodenaufruf oder sowas. Und das sind schon schöne Sachen dabei, auf jeden Fall.

Simon

Aber wer ist denn da an den Quellcode von GTA gekommen?

Kai

Das ist eine gute Frage, das kann ich darum nicht beantworten.

Simon

Weil die Kommentare werden ja immer weggelöscht, wenn man dann, also selbst wenn man jetzt die Echse, disamplizieren, heißt das, glaube ich, also dekompilieren, dekompilieren würde, dann würden die Kommentare ja nicht drinnen.

Kai

Das ist eine gute Frage, da bin ich mir gerade selber nicht so sicher. Eventuell wurde es auch geleakt oder so?

Simon

Ja, kann schon sein. Oder halt einer der EntwicklerInnen hat das geteilt. Kann ja auch sein, dass es von intern kam. Nein, kam es nicht. Der Quellcode wurde geleakt. Und das ist natürlich ein bisschen unangenehm. Da kann man die ganzen schönen Kommentare nämlich lesen. Und das ist ein kleiner Rückblick auf die Jahresrückblicksfolge. Da haben wir darüber gesprochen, warum es bei Epic Richtlinien für Code gibt.

Und das ist ein wunderbares Beispiel dafür, warum man auch, wenn man glaubt, dass die Öffentlichkeit niemals lesen wird, sich vielleicht doch an so ein paar Regeln halten könnte. Denn ja, wenn man dann eben den Code geleakt bekommt, zeichnet das vielleicht ein bisschen ein blödes Bild von der Firma. Denn ich werde jetzt mal gleich ein paar Kommentare einspielen, die wirklich ganz witzig sind. Im Grunde genommen fluchen sie die ganze Zeit.

Das wirkt natürlich jetzt auch nicht so super professionell, aber werde ich jetzt nicht einspielen. aber es ist halt so, dass auch ein paar Kommentare benutzen halt das Wort retardet als Schimpfwort und das ist ja so ein bisschen verbraucht, sag ich mal, ne?

Und genau, und ich finde es aber gerade einfach ein schönes Beispiel, weil wir haben ja in der Jahresrückblicksfolge genau darüber gesprochen und uns dann gefragt, ja, ist das jetzt zu wichtig, weil das ist ja eigentlich nur für intern, bla bla bla und so. Und hier ist ein gutes Beispiel, warum Dinge von intern plötzlich zu extern wechseln können. Aber jetzt die Kommentare. Das muss man sein, das Schittes-Code in der gesamten Spiel ist. Just fucking kill me.

Hackfix, bis die Arten zuhören, um auf der fucking Luft zu legen, unter der Cut-Off-Height, die wir alle aufschlossen haben. Ich werde nicht sogar beginnen zu sagen, dass ich weiß, was da ist hier passiert. Das macht das Schiff wirklich lang. Aber ohne es, es wird Krass. Wenn das Fails, wir sind. Aber es sollte niemals verlieren, als es nur vier Shows gibt.

Aber ich wollte noch eine Frage dazu. Ach genau, weil dieses System festzustellen, ob man im Combat ist, das ist ja auch ein interessantes Thema, weil das ist ja gar nicht so einfach. Äh ... Oder?

Kai

Nee, also es kommt natürlich auch so ein bisschen, also so, wir hatten dafür, wir haben auch jetzt auch immer noch sehr viele Probleme, also das System, ob man im Combat ist oder nicht, bezieht sich momentan, so fragen wir es, glaube ich, auch wieder Johannes so ein bisschen in Richtung, ist, wenn ein Gegner den Spieler als Ziel hat, mit der Intention, ihn anzugreifen. Das ist gerade aktuell unsere Definition von, ob der Spieler im Combat ist oder

nicht. Aber wenn ich einfach durch die Spielwelt tingle und meine Waffe nicht mal gezogen habe, dann würde ich mich als Spieler nicht fühlen, als ob ich gerade im Combat bin. Und deswegen gibt es da so verschiedene Clashes, die manchmal passieren, wo das Spiel entweder denkt, du bist im Combat und du fühlst dich nicht im Combat oder manchmal bist du im Combat, aber das Spiel denkt nicht, dass du im Combat bist. Da gibt es manchmal so false positives, sage ich mal so ein bisschen.

Aber im Großen und Ganzen ist das gerade aktuell unsere Definition, ob man im Combat ist oder nicht.

Simon

Das war mir das erste Mal bewusst geworden, als ich an einer Raumschiffssimulation mitgearbeitet habe. Und da ist es so, dass die feindlichen Schiffe, die siehst du im Weltall ja schon auf krasse Distanzen. Also ist halt ein 3D-Spiel. Bei euch ist es ja so, wenn das Monster außerhalb des Bildschirms ist, ist es so gefühlt maximal 20 Meter weg oder so. Und im Weltraum kann es sein, dass du ein Schiff halt in 10 Kilometer Entfernung siehst.

Und es kann schon sein, dass das jetzt gerade umdreht und auf dich zufliegt und dich angreifen will. Aber es fühlt sich gar nicht wie Kampf an, wenn das Ding 10 Kilometer weit weg ist. Das war nochmal eine ganz besondere Herausforderung, dann so ein Gefühl dafür zu bekommen. Weil wenn diese coole Musik einsetzt und diese kleine Pixel bewegt sich so gerade auf die Zug, das fühlt sich nicht sehr episch an.

Kai

Ja, kann ich mir vorstellen.

Simon

Und teilweise ist es auch so, dass in dem Moment kannst du dich ja auch noch entscheiden, habe ich jetzt eigentlich Bock auf Kämpfen? Ach nö, weißt du, ich drehe mich einfach zur Seite und fliege zu irgendeiner Station und so. Und das fühlt sich dann auch nochmal weniger wie Kämpfen an. Deswegen finde ich das schon sehr spannend, wie man sowas... Macht aber ja, bei einem Top-Down-Spiel ist es auf jeden Fall ein bisschen einfacher, weil man diese krassen Distancen ja nicht hat.

Kai

Ich finde, man kennt das auch manchmal aus anderen Spielen, irgendwie, man läuft durch die Welt, man erkundet, plötzlich setzt die Kampfmusik ein, also du weißt gar nicht, warum und woher, aber einfach schon mal pro Format ziehst du die Waffe, machst dich bereit, da kommt bestimmt gleich irgendwas.

Simon

Obwohl das ja auch gut sein kann, um einfach vorgewarnt zu sein, nicht, dass dich da irgendwie einen Wolf von hinten einfach anspringt und denkst, hä, woher kommt der denn jetzt plötzlich? Genau, das gibt es ja tatsächlich manchmal in Trova wirklich. Also ich will jetzt nicht spoilern, aber es gibt so ein, zwei Bereiche, wo wirklich manchmal dann was aus dem Busch springt. Das war ich doch schon.

Kai

Sehr zu Horror von manchen Spielern auf jeden Fall. Also wir haben sehr viel auf jeden Fall polarisierendes Feedback bekommen, was diese Gegner angeht, von denen du sprichst.

Simon

Da muss ich mal sagen, da bin ich mal gespannt, ob jemand den No-Hit-Run schafft. Und dann will ich mal gucken, wie das dort, ja, also wie man an solchen Stellen damit klarkommt.

Kai

Ja, muss man vielleicht auch nochmal sagen, wir haben den No-Hit-Bread ins Leben gerufen, ohne zu wissen, ob es wirklich möglich ist. Aber ich denke schon, dass man das auf jeden Fall hinbekommt, wenn man das Spiel gut kennt, wenn man weiß, wo diese Gegner sind, wenn man vielleicht eine Werkenkampfhafe dabei hat, vielleicht Feuerpult oder was auch immer. Ich denke, es wird auf jeden Fall Mitteln Wege geben, dort dran vorbeizukommen. Aber ja, wir sind da auf jeden Fall auch sehr gespannt.

Simon

So, und dann hast du vorher noch was anderes erwähnt. Das ist auch ein ganz interessantes Thema. Und zwar diese Atlanten. Diese Atlanten, da hatten wir nämlich schon drüber gesprochen in der Folge mit Chris. Das sind also große Texturen, auf denen ganz viele einzelne Sprites draufliegen. Und davon gibt es welche für, ich blende jetzt auch mal ein Bild ein, davon gibt es welche für zum Beispiel Architektur.

Also sieht man jetzt auf dem Bild ganz viele Holzpalisadenwände in verschiedenen Orientierungsstufen. Und die sind halt alle auf einem großen Bild. Und dann, ich hatte hier noch ein anderes Schönes, das hatte ich auch bei Chris erwähnt, wo die ganzen Animationen drauf waren. Wo ist das denn? da waren halt alle Animationsstufen von den Charakteren, die man spielen kann und die erste Frage, die ich mir gestellt habe, wie sind diese Atlanten erstellt worden?

Weil das sieht automatisiert aus und nicht manuell zusammengeschoben. Das wäre auch, glaube ich, Horror.

Kai

Ja, genau. Also wir nutzen im Großen und Ganzen einfach Unity kommt mit Sprite-Atlas, nennt sich das dort. Und dann kann man quasi definieren, welche Ordner oder auf welche Texturen in diesen Atlas kommen sollen. Und der packt das dann für ein. Man hat nur ein paar Einstellungsmöglichkeiten, aber im Großen und Ganzen sind fast, eigentlich sind alle Atlanten quasi automatisch gepackt. Er hat auch manchmal witzige Nebeneffekte. Manchmal kann er sie besser packen,

wenn mehr Sprites drauf sind, statt weniger. Ich weiß nicht genau, man hat da leider sehr wenig Einfluss drauf. Und manchmal frickle ich einfach nur eine Option so ein bisschen um oder verschiebe irgendwo mal ein Pixel, damit es irgendwie nochmal die nächst kleinere Stufe erreicht. Aber die Sprites selbst kommen von unseren Artists quasi. Also im Großen und Ganzen, wir arbeiten ja mit A-Sprite, das ist ein Tool zur Erstellung von den Grafiken.

Wir nutzen dann ein persönliches, kustomisiertes Export-Skript, was dann bestimmte Sprites und Layer und Label nimmt aus dieser Datei und sie dann einfach horizontal in Unity, also auch in Atlanten packt, oder also in eine Textur, sagen wir mal in der Animation, wie der Spieler zuschlägt, dann ist horizontal der Schlag einfach abgebildet.

Und in Unity selbst nehmen wir dann diese Texturen und packen sie dann in diese Atlanten und sehen dann so aus wie das Beispiel, das du jetzt hier gezeigt hast.

Simon

Aber wenn auf der Textur, die aus Esprite kommt, alle Animationsstufen nebeneinander sind, dann weiß Unity ja nicht, wo hier was aufhört, oder? Also dann kann Unity doch nicht die Einzel-Sprites wieder in dem großen Atlas schön rumschieben, sondern es hätte dann eine riesige, lange, vertikale Textur, oder?

Kai

Doch, das kann Unity schon. Weil wenn wir quasi ... Also wir slicen das ja. Also wenn es dann, sagen wir, dieser Angriff, sagen wir mal, sind zehn Frames, dann sind es auch zehn Einzel-Sprites. Und was Unity sehr smart macht, ist, er findet quasi das kleinstmöglichste Mesh, was bestmöglich nur die Farbkanäle in der Textur quasi abbildet.

Das heißt, es ist nicht tatsächlich ein Rechteck von, sagen wir mal, 64x64, was als Sprite gilt, sondern ein viel, viel kleinerer Part, sagen wir mal, 12x12, was auch ein bisschen ein weirdes Shape haben kann. Was dann eigentlich tatsächlich der eigentliche Sprite ist. Und nur diese kleinere Variante nutzt er dann, um sie dann vernünftig zu packen.

Simon

Ah, genau. Also das heißt, aller Leerraum um das Sprite drumherum wird einfach weggeschnitten.

Kai

Ja, du hast es einfach ausgedrückt, äh, sich.

Simon

Genau, aber da habe ich mich auch gefragt, aber woher, also irgendwie muss ja irgendwo deine Datenbank existieren. Oder nee, warte mal, du hast gerade Polygon gesagt. Also wird irgendwie ein Polygon erstellt, was dann halt UVs hat, die genau auf diese Stelle gemappt sind?

Kai

Genau, genau.

Simon

Aber, Also, aber hä? Aber das heißt, dass ich, also, okay, ich habe mir das jetzt so vorgestellt. Ich habe meinen kleinen NPC und dieser NPC, der ist einfach auf ein Quadrat oder ein Rechteck gemappt. Aber das passt dann ja nicht. Irgendwie muss dann doch, also.

Kai

Also wie genau das jetzt Unity intern macht, weiß ich auch nicht hundertprozentig. Meine Vermutung ist, jeder Sprite hat eine eindeutige ID. Und im Editor existiert beides zeitgleich. Sowohl die Textur, die wir exportiert haben, als auch der Atlas. Und man kann auch Abfragen machen wie Textur.Atlas oder Atlas.Textur. Das heißt, es gibt in Unity zur Edit-Zeit quasi noch die Möglichkeiten, dass die beiden in Referenz zueinander stehen.

Wenn man das Spiel dann final baut, dann fliegt quasi diese Grundtextur raus und nur der Atlas bleibt übrig. Und meine Vermutung ist, dass es so eine Art Manager, wie du es auch beschrieben hast, quasi gibt, der dann einfach sagt, alles klar, hier ist ein Sprite mit dieser ID. Gib mir, wo auch immer der Herr kommt, quasi zurück. Irgendwie sowas in dieser Richtung. Aber da haben wir nichts explizit programmiert.

Simon

Das ist ja interessant. Das ist alles Unity schon direkt drin. Das ist kein crazy Plugin.

Kai

Genau, genau.

Simon

Ich habe jetzt noch mal geguckt, wie das jetzt genau funktioniert. Hatte mich noch mal interessiert. Und zwar ist es so, dass es bei Unity eben die Sprite-Atlanten gibt. Und es gibt verschiedene Optionen, die man sagen kann. Und das eine ist Tightpacking und das andere eben nicht. Und wenn man das Tightpacking nicht anwählt, dann wird jedes Sprite quasi mit einem Rechteck, also mit einem Quad dargestellt. Ein Polygon mit vier Punkten und geraden Linien eben. Also, ja, Quad.

Und dann ist es halt so, dass die Sprites auf dem Atlas so angeordnet sein müssen, dass die nicht sich sozusagen überlappen. Also wenn man jetzt um einen Sprite mit geraden Linien rechts, links, oben, unten malt, dann darf kein anderes in diesen Bereich reinragen. Ansonsten würde man das ja dann sehen, wenn das im Spiel dargestellt wird, dass da irgendwie irgendwelche Pixel an den Kanten überlappen. Von dem Sprite. Und das ist das normale Packing. Ich glaube, das kennt man auch eigentlich so.

Und es gibt aber diesen Tide-Packing-Mode. Und da ist es tatsächlich so, dass die Sprites viel näher zusammengerückt werden können, sodass sich dann Sachen so richtig nah zusammenliegen können. Und das, wenn man sich jetzt um einen Sprite wirklich so ein Viereck vorstellen würde, also wie so eine Bounding-Box quasi, dann würden halt andere Sprites da auch reinragen. Und deswegen muss man für diesen Modus auch noch anwählen. Der Modus heißt Use Sprite Mesh.

Und das ist ganz spannend, weil dann wird nämlich nicht ein Viereck benutzt, um das Sprite dann zu rendern, also ein Polygon quasi, dann später im Spiel, sondern es ist ein Mech, was viel, viel mehr Polygone hat, als zum Beispiel 5, 6 oder 7 oder 8 oder so. Und ich blende jetzt auch mal ein Bild ein, da sieht man verschiedene Positionen von einem Drover-Charakter und da könnt ihr richtig gut sehen,

wie verschieden das Mech dann aussieht, je nachdem. Also der Algorithmus versucht dann eben mit den Polygonen die Form des Sprites möglichst genau nachzuarbeiten. Und deswegen kann man die Sachen dann halt auch viel, viel mehr zusammenschieben. Und ganz witzig ist noch ein kleiner Edge Case, zumindest in 2022 war das so, ich verlinke euch da auch einen Thread vom Unity Forum. Da hat nämlich jemand im UI bemerkt, ich habe doch mein Tight Packing angewählt und auch mein Use Sprite Mesh Modus.

Warum in meinem UI habe ich genau dieses Problem, dass ich da ein Icon darstelle und dann unten rechts und links ragen da so Pixel von anderen Sprites rein, die auf dem Atlas gemalt sind und die halt schön nahe daran geschoben sind. Und stellt sich raus, dass zumindest damals das für UI hat dieses Sprite-Mesh-Ding nicht funktioniert.

Das heißt, der Atlas wurde zwar schön eng aneinandergerückt, die ganzen Sprites, aber im UI wurde dann das Icon mit einem Vieieck dargestellt, also ein Quad halt normal. Und dann war der Atlas aber zu eng gepackt und dann ragen eben die Pixel da unten noch rein. Genau, da habe ich jetzt auch mal ein Bild gezeigt. Und ja, so funktioniert das. Ja, genau.

Kai

Das ist auf jeden Fall auch sehr, sehr smart, auch dieses Texturenpacken, dass er diesen Freiraum rausnimmt, das ist wunderschön, also das ja, möchte ich auch gar nicht mehr missen. Das hat, wie gesagt, ein paar Quirks, aber so im Großen und Ganzen gefällt mir das eigentlich sehr gut.

Simon

Ja, das sieht sehr effizient aus, auf jeden Fall. War ich sehr beeindruckt, genau.

Kai

Wobei wir da noch mal ein bisschen nachgehakt hatten, was die Ektoren angeht, also unsere Menschen. Die sind an sich eigentlich auch in einem Atlas.

Simon

Ja.

Kai

Aber der Atlas war zu groß. Unity macht mehr Spielraum, als wir eigentlich brauchen. Und wir haben sehr, sehr viele Animationen von Actoren, ich glaube, über 1200 Frames für die Animation, die ein Actor durchführen kann. Und das war dann einfach von der Texturgröße zu groß. Und da haben wir noch mal sehr viel eigenen Stuff gemacht, zum Beispiel, Kann es sein, dass der erste Frame von Stehen identisch aussieht wie der zweite Frame von Ich stehe auf oder sowas.

Und dann haben wir, das habe ich dann programmiert, quasi nochmal einen kleinen Algorithmus gebastelt, der mir detektiert, ob Sprites quasi inhaltlich identisch sind. Und wenn ja, dann schmeißt er den einen raus und nutzt stattdessen den anderen. Und auch nochmal einen kleinen Algorithmus, der quasi das Padding, also der Abstand zwischen zwei Sprites auf dieser Textur auch nochmal reduziert.

Und das Ganze ist dann am Ende aber nur eine Texturen, kein Atlas, wobei aus Unity-Sicht das bei ist so ein bisschen identisch und das habe ich dann Baked Texture genannt, um da einfach noch mal ein bisschen was rauszusqueasen. Das war auch auf jeden Fall sehr spannend.

Simon

Das war eine reine Optimierung um die Atlanten kleiner zu halten.

Kai

Genau, genau, genau.

Simon

Aber warum musstest du das Padding jetzt verändern?

Kai

Auch einfach um die Größe, das wäre wie gesagt 1200 Sprites gewesen, jeder hat irgendwie einen Border von zwei Pixel, ein Pixel würde mir eigentlich ausreichen.

Simon

Ach so.

Kai

Sagen wir, auf einer Horizontal liegen 100 Sprites. Dann würde ich ja schon allein 50 Pixel sparen, auf jeder Ebene zum Beispiel. Und auch je kleiner die sind, desto anders packen würde Unity die auch noch mal. Weil da mehr Möglichkeiten hat, sie auch noch mal optimierter zu placen.

Simon

Okay, ja gut. Das ist natürlich super intern, was Unity da macht. Aber ja, spannend. Und dann ist mir aber noch eine Sache aufgefallen. Und zwar, über so eine Sache macht man sich dann ja wenig Gedanken. Und zwar, die Schatten von Objekten sind auf einem eigenen Atlas. Also zum Beispiel, wenn man jetzt einen Baum hat, dann hätte man das Baum-Sprite und dann hätte man nochmal einen Sprite für den Schatten unter dem Baum und ja, das sind zwei verschiedene Objekte.

Das fand ich jetzt spannend, weil du hast ja gesagt, dass man gibt einen Ordner an und dann packt Unity alles zusammen. Aber das bedeutet ja, dass ihr einen Ordner habt, der heißt dann Schatten. Und da sind alle Schatten drin oder so.

Kai

Das ist was auch ... Wir haben es nicht immer durchgeführt. Das war ... Also viel Unerfahrenheit steckt hier auch natürlich drin und viele verschiedene Ansätze und so weiter. Es gibt auf jeden Fall auch Atlanten, wo die Schatten mit zu dem eigentlichen Objekt kommen.

Simon

Ah, okay.

Kai

Die Idee generell ist, warum wir das hier gemacht hatten, auch in dem Bild, was du jetzt hier hast, um nicht nur ... Also es gibt verschiedene Arten zu optimieren. Du kannst einerseits entweder den Arbeitsspeicher optimieren oder auch dann GPU-RAM, aber du kannst auch optimieren, wie Objekte gezeichnet werden, also gebatcht werden. Und unsere Schatten liegen alle auf einem gemeinsamen Layer.

Und Unity kann Objekte badchen, wenn sie auf einem gemeinsamen Layer liegen und sie dieselbe Textur verwenden. Dadurch, dass Schatten eh immer auf demselben Layer sind, kann man einfach sagen, alles klar, lass uns einmal einfach den Schatten rendern. und dann kann Unity einen einzigen Dior Call draus machen, aus einem Screen, wenn alle Schatten in einer Textur sind. Ist halt deutlich effizienter fürs Rendering.

Genau, und das ist das, was wir hier versucht hatten dann zu machen, dass wir sagen, alles klar, die Schatten kommen alle in eine Textur, um einfach das Rendering selber zu begünstigen. Haben wir nicht für alle gemacht. Ich glaube, das haben wir primär für Bäume gemacht. Wir haben ja auch noch Gräser und Steine und andere Objekte. Da haben wir es nicht mit den Schatten gemacht. Wäre im Nachhinein vielleicht auch nochmal eine Möglichkeit,

Sachen zu optimieren. Aber das kommt sich dann leider in die Quere, weil zum Beispiel zwei verschiedene Bäume, verschiedene Typs vielleicht niemals zusammen auf einem Screen sind, durch diese Schattentextur aber ihre Schatten zeitgleich geladen werden. Und da muss man auch wieder das Payoff treffen, was möchte man eigentlich haben.

Simon

Ja, genau. Also hätte man eine Wüste und da steht ein Baum drin, würde man trotzdem die gesamte Schatten-Atlas-Textur laden müssen. Von allen Bäumen. Und das sind dann eben, weiß ich nicht, zehn Megabyte oder keine Ahnung wie groß oder fünf oder ... Ja, das mit dem Batching ist übrigens signifikant. Also ich habe einen kleinen Prototyp gemacht in Godot, Da habe ich einfach so, weiß ich nicht, 500 Sprites oder so. Die bewegen sich einfach vom Rand des Bildschirms auf dich zu.

Und wenn sie in der Mitte sind, sterben sie und werden neu gespawnt. Also man kann relativ viele Sprites darstellen. Und das funktioniert auch wunderbar, das läuft flüssig. Und im Rendering ist es eben so, dass die alle auf einmal gezeichnet werden. Und dann habe ich mal gemacht, dann habe ich eine Random-Farbe zuweisen lassen. Also jedem Sprite einfach eine Random-Farbe im Material zugewiesen.

Und plötzlich bricht das das Batching. Jeder Sprite wird jetzt in einem eigenen Draw-Call gerendert und plötzlich ist es irgendwie auf drei FPS runtergebrochen. Also das ist ein riesiger Unterschied, wenn man für das Rendering, wenn man da nicht aufs Batching achtet. Das kann einem richtig die Performance versauen.

Kai

Absolut. Da macht sich Unix zum Glück auch viel Haus aus und scheinbar auch Godot, ohne dass man da jetzt so viel dran macht. Aber bestimmte Sachen kann es halt leider auch breaken. Und an manchen Stellen mussten wir es sogar explizit breaken, weil sonst bestimmte grafische Effekte bei uns nicht funktioniert hätten. Weil durch das Batching auch bestimmte Informationen verloren gehen, die unter Umständen interessant sein können für bestimmte grafische Effekte.

Simon

Ja, zum Beispiel Random Farbe. Random Color.

Kai

Zum Beispiel Random Farbe. Aber da gibt es wieder auch andere Tricks, damit du trotzdem Random Farben zuweisen kannst, ohne das Batching zu zerstören. Aber da muss man wieder so ein bisschen smart und optimiert denken und arbeiten, was dann so ein bisschen, glaube ich, auch die Krux ausmacht, damit ein Spiel wie, was weiß ich, Doom oder so was flüssig läuft. Also Doom ist ja krass optimiert und läuft tatsächlich auch auf relativ alten Geräte, also jetzt auch das Aktuellste.

Oder ID.Soft generell macht sehr optimierte Spiele und da steckt viel Magic dahinter und viel Durchdachtheit.

Simon

Genau, man muss dann sehr schlau sein. Und oft ist es dann so, dass diese Workarounds oder diese Techniken, die man dann implementiert, dann den Workflow aber auch wiederum behindern können und dann ein bisschen nervig sind, diese ganzen Äste zu erstellen und zu managen und so. Aber dafür läuft es dann flüssig. Spielewicklung, wie du sagst. Es gibt halt Vor- und Nachteile.

Kai

Ja, wir haben das auf jeden Fall versucht, möglichst weit nach hinten zu schieben, dass während wir an der Welt gearbeitet haben, da sich niemand Gedanken drum gemacht hat. Und viele von den Optimierungen, die wir auch haben, passieren dann auch erst zur Bildzeit, auch teilweise automatisiert.

Zum Beispiel können wir da auch gleich zu dem Thema, ich möchte das jetzt mal vorwegnehmen, aber zum Beispiel hast du ja diese Bodentextur und hast dann dazu geschrieben, warum ist das denn eine komplette Textur? Das ist zum Beispiel auch eine unserer Optimierungsmöglichkeiten, wo sich aber Leute, die Level-Design betrieben haben, keinerlei Gedanken drüber machen mussten, weil wir es erstens spät gemacht haben und dann auch erst zur Bildzeit einsetzen quasi.

Simon

Genau, also worum es jetzt geht, das wäre nämlich auch mein nächstes Thema gewesen, ist, dass wir wissen, dass dieses Spiel 2D ist und aus verschiedenen Teilmaps besteht für den Boden, also kleinere Texturen, die einfach aneinander gekachelt werden und so. Und dann gibt es eben verschiedene für Gras und für Sand und so weiter und so weiter.

Und jetzt könnte man ja annehmen, weiß ich nicht, zum Beispiel, also wenn man jetzt zum Beispiel Minecraft sieht, könnte man ja denken, dass jeder kleine Würfel einzeln gerendert wird, weil es ein eigenes Objekt ist, mit dem man interagieren kann oder so. Und bei euch hatte ich dann gedacht, naja, wahrscheinlich wird, wenn man sich das Rendering anguckt, ja, weiß ich nicht.

Vielleicht jeder Typ von Textur, also Stein und Sand und Gras einzeln gerendert werden oder irgendwie sowas oder eine Grundbasis und darauf kommt dann alle Objekte. Aber was wir hier sehen, das blende ich jetzt auch mal ein, ist, dass wir schon, also das komplette Terrain ist eigentlich schon da, innerhalb eines Drawcords gerendert. Das bedeutet, wir sehen Erde, wir sehen Gras, wir sehen kleine, kleine gemalte Steinwege, wo Leute langlaufen können.

Und wir sehen sogar schon das Innere eines Hauses, also den Holzboden, darauf liegen Teppiche und noch ein paar Klippen. sind sogar auch schon da, von irgendeiner Steinstruktur. Also relativ viel. Und warte mal, ich sehe da glaube ich sogar, ach genau, die Wurzeln von ein paar Bäumen sind auch schon da. Also relativ viel, auf was alles in einem gerendert wird. Und das hat mich überrascht, weil ich dachte so, das ist ja ein großer Chunk, schon irgendwie zusammengefasst da.

Kai

Ja, tatsächlich repräsentiert das im Großen und Ganzen eigentlich ein Chunk. Also auch eine Chunkgröße ist genau die Größe von dem Bild, was du hier siehst. Und im Endeffekt, ich möchte nicht sagen, dass das immer besser ist oder es ist immer effizienter, es so zu machen, wie wir es tun. Aber in unserem Case hat es sich ausgezahlt. Wir hatten initial ein Shader, der den Boden, nur den Boden zeichnet.

Aber das Resultat wäre trotzdem gewesen, du würdest Steine sehen, du würdest Gras sehen, du würdest Erde sehen und so weiter. Weil der Ansatz, den wir dort haben, das nennt sich Texturesplatting. Und man kann sich quasi vorstellen, dass es eigentlich ein buntes Bild ist, wo Rot und Grün und keine Ahnung, verschiedene Farben drin sind. Und die Farben repräsentieren dann Terrain und werden dann gemischt. Dieser Shader war nicht sonderlich optimiert und war im Rendering-Prozess relativ weit oben.

Also wenn man das Rendering, sagen wir, braucht irgendwie 16 Millisekunden, dann war vom Rendering nur des Bodens, was weiß ich, acht davon oder sowas. Und das war halt sehr unoptimiert. Und dann hatten wir die erste Idee, hey, wie wäre es denn, wenn man das einfach pre-baked, also dass man sagt. Es ist nicht dieser Shader auf diesem Mesh, sondern es ist einfach nur eine Textur, ein Quad.

Ein Quad ist sehr einfach zu zeichnen, Draw Call sehr easy, der Shader ist sehr simpel und dann hatten wir das gemacht und das hat sich für uns ausgezahlt, das war einfach optimierter und der Boden ändert sich auch nicht dynamisch zur Laufzeit, wenn ich irgendwas tue. Und dann haben wir weiter optimiert, weiter gearbeitet und dann so weit irgendwann zur Switch gekommen und dann festgestellt, irgendwie läuft das da immer noch nicht.

Und dann sind wir irgendwann auf die Idee gekommen, warum, wenn wir diese ganzen Sachen eh schon pre-baken, warum pre-baken wir nicht einfach noch mehr rein von Dingen, wo wir wissen, dass sie immer unter dem Spieler liegen, weil es sonst keine Verdeckungen gibt oder sowas. Deswegen sind zum Beispiel die Wurzeln des Baumes drin, weil der Spieler nie dahinter stehen kann. Aber der Spieler kann vor und hinter dem Stamm stehen und deswegen können wir das zum Beispiel nicht rein baken.

Deswegen haben wir dann gesagt, okay, alles, was kleiner ist, ist jetzt auch intern gesehen, Ektor 0, ist sozusagen unsere Grenzwerte. Alles, was dort drunter liegt, ballern wir da einfach rein und schmeißen es dann auch zur Laufzeit wirklich raus. Also es liegt dann auch nicht mehr als Szener, als einzelnes Objekt, zum Beispiel so kleinen Steine im Wasser oder so. Also da ist noch kein Wasserwasser, kommt gleich nochmal extra.

Aber das sind zum Beispiel schon kleine Steinchen und die Steinchen gibt es auch nicht mehr als Objekt. Das reduziert die Szenengröße, die Chunkgröße, verbessert das Rendering, weil die alle in einem Drawcore gezeichnet werden. Und genau, das war dann unser Ansatz, dass wir das deutlich improved haben. Aber es hat auch nur funktioniert, weil sie in den Chunks liegen, weil die Chunks ja rein und auch wieder rausladen. Würden alle diese Texturen, die Textur ist relativ groß, ich glaube 1200.

1600, irgendwie sowas, mal 1600. Und angenommen, du hast zehn von diesen Texturen liegen, ist da schon recht viel Memory für auch wiederum die Grafikkarte. Aber das gute Ding ist, wir laden sie ja eh wieder raus. Und so sind in der Regel immer nur vier Chunks zeitgleich geladen und das können die meiste Hardtower mittlerweile ganz gut abfangen.

Simon

Okay.

Kai

Und wir haben noch mehr, fällt mir gerade ein, auch noch optimiert. Tatsächlich sind diese Sachen das Texture Splatting, der Ansatz, den ihr am Anfang meinte, der macht zwar, dass die Sachen Pixelart ähnlich aussehen, aber es mischt auch Pixel. Dadurch wirkt es ein bisschen blurry.

Simon

Ja.

Kai

Und das Schöne daran wiederum ist, dadurch, dass es ein bisschen blurry wirkte, haben wir noch eine Compression drüber gehauen. Die Compression macht auch, dass es blurry aussieht. Aber man hat es kaum noch gesehen, diese Compression, wodurch wir auch wieder RAM sparen konnten. Und dann liegt es auch auf der Festplatte als JPEG vor. JPEG macht auch ein bisschen was blurry. Also ich glaube, 99% ist relativ hoch, weil es wird dann doch recht schnell sehr hässlich.

Und das haben wir dann auch nochmal drauf gehauen. Und so sind diese Texturen im Endeffekt sehr klein geworden, auch wenn sie Texturgrößen sehr groß sind, und auch recht optimiert dann auf der Grafikkarte liegen.

Simon

Okay. Ah ja. Okay, ich habe Fragen. Also, für alle, die das jetzt Textosplating noch nie gehört haben, die Idee ist im Grunde genommen, dass ich habe eine Sandtextur und eine Grastextur und die möchte ich gerne auf dem Terrain gleichzeitig darstellen. Und da kann ich ja auf das Terrain malen mit meinem kleinen Brush in einem Tool, wie in Photoshop im Grunde genommen. Und will halt so ein bisschen das auch miteinander blenden können.

Und das funktioniert so, dass man eine Splattingtextur nimmt, Die Textur hat ja vier Kanäle, R, G, B und A. Und was ich machen kann, ist, ich sage im Shader, ich lese aus dieser Splatting-Textur den R-Kanal, also den roten Kanal aus und überall da, wo dort weiß reingezeichnet ist, Dann zeige ich zum Beispiel eine geteilte Sandtextur und überall, wo im Grünkanal weiß reingezeichnet ist, zeige ich eine Grastextur und so kann man das auch miteinander blenden.

Und daher kommt aber auch die Einschränkung, dass man bei manchen Terrain-Systemen dann zum Beispiel nur vier verschiedene Texturen miteinander blenden kann. Da wäre jetzt die Frage, ist das bei euch auch so? Habt ihr eine Vier oder habt ihr da irgendwie zwei Splatt-Texturen, damit es dann acht sind oder irgend sowas gemacht?

Kai

Also im Endeffekt ist bei uns nicht unlimitiert, klingt zu viel, aber im Großen und Ganzen rendern wir dort ein Mesh und wir nutzen dann im Endeffekt nicht von der Textur die RGBA-Kanäle, sondern von dem Mesh, von den Vertices, die RGBA-Werte. Und man kann aber auch mehr angeben, zum Beispiel haben die ja UVs, UV1, UV2, UV3, entsprechend haben wir eigentlich mehrfach davon. Momentan haben wir pro Splat Mesh quasi elf Kanäle und den Alpha-Kanal.

Der Alpha-Kanal ist nochmal extra, um tatsächlich auch wirkliches Alpha zu radieren oder rein oder rauszumalen und im Endeffekt elf Texturen, die miteinander gemerged werden können. Dadurch, dass wir aber tatsächlich einen echten Alpha-Kanal erlauben, können wir aber auch einfach mehrere Splat Planes übereinander legen und dadurch sind wir eigentlich recht unlimitiert.

Und dadurch, dass wir es im Endeffekt dann in diesem Boden baken, ist uns eigentlich völlig egal, wie viele Meshes und wie viele Layer und was auch immer, wir haben am Ende ist es eine Textur und sie wird einmal gezeichnet. That's it.

Simon

Okay, das bedeutet, ihr benutzt gar nicht die Vertex-Color-Informationen der Vertex-Color, sondern nur die UV-Color.

Kai

Auch beides. Also die RGBA benutzen wir auch. RGB sind dann schon drei Texturen, die da quasi dann drin sind. Und dann UV auch wieder XYZW quasi von den verschiedenen UVs dann auch wieder.

Simon

Das ist übrigens eine Sache, die hat eine Weile gebraucht, dass ich das so verstanden habe, Denn die UV-Kanäle, genau wie du es eben gesagt hast, die haben auch mehr Koordinaten, als man eigentlich kennt. Aber manchmal kann man sie nicht nutzen bei, jetzt muss ich überlegen, genau, bei Unreal ist es so, dass wenn du die UVs ausliest, dann kriegst du immer noch X und Y oder halt U und V und die anderen nicht.

Und wenn du aus Houdini zum Beispiel in Mech rausschreibst mit mehr, also mit Z und Y, du kriegst den halt nicht. Und was du dann machen musst zum Beispiel für Pivot Painter ist das interessant, also für einen quasi virtuellen Pivot in Mech speichern, müssen wir jetzt nicht ganz so tief eingehen, aber da brauchst du ja drei Koordinaten, X, Y und Z, um einfach eine Position im Raum zu definieren.

Und dafür musst du dann eben UV1 definieren mit XY und dann noch den anderen UV2-Kanal, um eben das Z auch irgendwie mit zu übergeben. Und den anderen musst du dann eben sagen, okay, gib mir mal UV1, gib mir jetzt UV2 und dann packe ich das in einen Vektor zusammen. Aber in Max zum Beispiel ist es so, in 3D-Studio Max, da kannst du im UV-Editor unten irgendwo umschalten, dass du auch zum Beispiel die dritte Koordinate von UV-Editor.

W, W wär's dann. Also UV, W, genau, das W. Könntest du auch, kannst du auch modifizieren ein 3D-Studio-Mex im UV-Editor. Also die zeigen dir schon an, dass da auch mehr geht eigentlich. Genau, das nochmal als, äh, okay, wo man...

Kai

Aber ich fand das grad ganz interessant eigentlich, dass du meintest, dass du Pivots, äh, Bakes quasi in einem Mesh, weil wir tatsächlich was ähnliches tun. Und zwar haben wir Wind-Effekte so auf Pflanzen. Und, äh, da haben wir quasi so eine Art Textur, die sozusagen angibt, wie sie sich bewegen. Also zum Beispiel der unterste Part bewegt sich am wenigsten, der oberste Part am häufigsten oder am meisten eher. Und das, jetzt kommen wir zu dem Thema von davor, das hat das Batching zerstört,

weil unsere Pflanzen quasi ihre Position kennen müssen. Wo bin ich in der Welt? Um dann zu sagen, wenn an diesem Punkt in der Welt Wind ist, dann bewege ich mich accordingly quasi. Und wenn man das jetzt baken würde, dann verlieren sie ihre Position, weil sie ja mit einem Draw-Coyl gezeichnet werden und alle hätten dann dieselbe Position des gemeinsamen Pivot-Punkts.

Und deswegen brauchte ich dann pro einzelne Pflanze einen Pivot-Punkt und das habe ich im Endeffekt dann auch quasi in eine Textur gebakt, die dann sozusagen in unserem Fall 2D einfach nur per XY-Offsets angeben zu ihrem Pixel, zu seinem gemeinsamen Pivot-Punkt, wodurch ich dann diesen Pivot-Punkt wieder auslesen kann pro Pixel und dann den Wind applien kann, was ich auch, ja, interessant auf jeden Fall, was hier auch eigentlich alles so ein bisschen drinsteckt.

Simon

Ach so, okay, das ist dann eine Textur pro Pflanze oder eine große, die ganz viele Pivots irgendwie beinhaltet?

Kai

Im Großen und Ganzen ist es, Dadurch, dass wir ja Sprites haben, ist es eine Textur, die sozusagen flächendeckend ist zu diesem Sprite. In dem Rotkanal steckt, glaube ich, dann drin, wie stark es sich bewegen darf. Also sprich, schwarz bedeutet, du darfst dich gar nicht bewegen, weil ich zum Beispiel ganz unten am Boden bin. Und wenn es hoch ist, eins, dann heißt es, ich darf mich viel im Wind bewegen.

Und dann habe ich quasi auf den G- und B-Kanälen dann die Pivot quasi gebakt zu einem gemeinsamen Punkt, wo er dann tatsächlich steht in der Welt, um dann, ja, seine Position wieder rauszubekommen, wenn es gebakt wird.

Simon

Okay. Ich weiß nicht, ob ich es ganz genau verstanden habe, aber zu den Pflanzen komme ich auch nochmal. Ich wollte nur ganz kurz nochmal bei dem Baking bleiben, weil eine Sache, genau, das muss ich hier noch aufschreiben. Wann genau wird das gebaked? Also, weil ich mach euer Spiel auf in Unity und dann kann ich das ja im Level-Editor noch schön modifizieren. Ich kann Objekte rumschieben, ich kann auf den Boden malen und so. Und zu diesem Zeitpunkt ist es ja nicht in Texturen gebaked. Wann?

Also, wahrscheinlich beim Building dann, wenn ihr die Version baut, oder?

Kai

Also, im Endeffekt schon ein bisschen vorher ist es gerade noch ein manueller Prozess. Es gibt so einen Button, da klickst du drauf und dann Leta, Chunk für Chunks, die Welt, bake das, dann legt das auch tatsächlich als Textur ab. Die Texturen werden nur, wenn man alle davon lädt, viel zu groß. Deswegen pushen wir es zum Beispiel nicht mit ins Git rein, weil man sie auch rekonstruieren kann.

Und der Rechner, der dann im Endeffekt baut, braucht zum Bildprozess diese Texturen bereits, um sie dann zu replacen. Das heißt, vor dem Bild irgendwann muss man mal auf dieses Knöpfchen gedrückt haben, dann hat er diese Texturen gebaked und zum Bauprozess kickt er dann die ganzen alten Objekte raus, die dann quasi gebaked sind und fügt dann stattdessen diese einzelne Textur ein.

Simon

Und jedes Objekt, was rausgeworfen wird, hat halt irgendwo einen Tag. Dadurch weiß der Bildprozess erstens, alle diese Objekte mit diesem Tag müssen in dieses Bild und dann später weiß der Bildprozess, okay, und das kann jetzt alles rausgelöscht werden.

Kai

Genau, genau, genau.

Simon

Ah, okay.

Kai

Genau, und dieses Tagging erfolgt so ein bisschen implizit. Also es hat nicht wirklich einen Tag, sondern es wird in eine Methode geworfen, hey, darf ich dich kicken? Und die gibt dann ja oder nein zurück quasi. Das heißt, zum Bauprozess wird diese Methode auch nochmal angefragt. Also wenn man, sagen wir mal, es zu früh gebaked hat und man hat irgendwas verändert, dann kann aus falsche Objekte gekekt werden. Aber in der Regel passiert das nicht und deswegen, also genau.

Simon

Aber wenn ich jetzt ein neues Objekt male, ich male jetzt ein Kissen, was auf dem Boden liegen soll. An irgendeinem Punkt muss ich ja sagen, das ist ein Objekt, das möchte ich gerne auf dem Boden haben, weil ein Charakter kann nie dahinter sein. Irgendwann muss ich das ja definieren. So hier, das ist eins von diesen Dingern, die sollen gebaked werden und können dann weg. Wie mache ich das denn?

Kai

Also momentan, also du als Artist musst ja gar keine Gedanken darüber machen, du freust dich einfach und playst deine Sachen.

Simon

Okay.

Kai

Oder als Level-Designer oder was auch immer. Entweder wissen, also im Endeffekt die Information, ob es gebaked werden soll oder nicht, fische ich mir aus dem Objekt selber. Also ich gehe zum Beispiel seinen Sprite-Renderer durch, frage ab, hey, auf welcher Ebene liegst du, auf welcher Render-Order liegst du. Und das Objekt von sich heraus weiß schon, ich bin auf Render-Order 0, auf On-Floor als Beispiel. Und dann weiß der Algorithmus, alles klar,

on Floor 0 darf gekickt werden. Und dann gibt es aber ganz viele Edge Cases. Zum Beispiel gibt es auch manchmal Orte, wo zum Beispiel Kissen dynamisch aktiviert oder deaktiviert werden. Und das dürfte ich ja nicht baken, weil dann sind die immer sichtbar, obwohl es nicht sichtbar sein soll oder so. Und die Objekte haben dann nochmal extra Abfragen. Eigentlich dürfte es gebaked werden, aber du hattest folgendes Skript dran und deswegen darf ich es doch nicht baken als Beispiel.

Simon

Ah, okay. Ja, wenn irgendeine Quest zum Beispiel sagt, dass das Bärenfell, was auf dem Boden liegt, dann geklaut wurde oder sowas.

Kai

Genau, genau, genau.

Simon

Krass, ja. Das ist ja alles sehr kompliziert. Aha.

Kai

Ja, es wäre auch echt sehr spät, dass es in der Entwicklung eingebaut hätte. Hätte man alles früher machen können, wäre es vielleicht etwas smoother geworden. Aber wir haben das ein bisschen unterschätzt, die Performance und die Switch und so und mussten am Ende einfach dann mit Kanonen um uns schießen, um möglichst viel Performance noch rauszuholen.

Simon

Und dann hast du gesagt, genau, das wird als JPEG abgespeichert, aber das ist nur dafür da, damit es auf der Festplatte relativ klein ist, ne? Weil im Grafikkartenspeicher wird es da dann eh reingeladen und da ist es ja nicht JPEG, sondern es halt, uncompressed.

Kai

Wobei, auf der Grafikkarte gibt es auch verschiedene Texturformate und manche davon haben auch, also eine Compression nicht im Sinne von, es hat weniger Festplattenspeicher, aber es benötigt weniger RAM. Inhaltlich bin ich da auch nicht zu deep drin, aber zumindest gibt es, also deswegen gibt es quasi zwei Compressions, einmal die für die Festplatte und einmal den für den RAM und wir nutzen im Endeffekt beides.

Simon

Ja, jetzt will ich das ja auch noch mal weiter ausbreiten, denn aus irgendeinem Grund, und ich weiß nicht warum, woher das kommt, habe ich immer gedacht, dass die DXT-Texturen, also die komprimierten Formate, DDS kennt man ja, das ist das File-Format und die Kompression ist dann zum Beispiel DXT 1 oder 3 oder 5, heute nennt man das BC1 bis BC7 und BC steht für Block Compression, dass die nur dafür da sind, dass die Texturen möglichst klein sind,

wenn man sie zur Grafikkarte lädt und dass sie dann dort uncompressed im Speicher rumliegen. Und das stimmt nicht. Und ich glaube, das stimmt auch schon eine ganze Weile nicht. Und irgendwie habe ich das aber im Kopf drin. Es ist so, dass ich verlinke da auch mal ein paar Links eben, YouTube-Videos und ein paar Artikel, dass die halt sagen, dass die Grafikkarten heute eben on the fly dekomprimieren. Das heißt, die Textur, die liegt einfach komprimiert, auch im Speicher, schön klein.

Und wenn die Grafikkarte da irgendwas rauslesen will, dann macht die da on the fly eine Decompression und kriegt die Pixel. Das nur nochmal zur Klarstellung. Ich weiß nicht, das ist so ein Urban Legend oder so, die ich mir irgendwie mal im Kopf gesetzt habe. Wahrscheinlich habe ich es noch nicht mal irgendwo gelesen, sondern mir einfach so vorgestellt, dass man ja, wenn man ein ZIP-File auf dem Computer hat, muss man das ja auch erst mal so entpacken, damit man es benutzen kann.

Vielleicht kommt daher meine Vorstellung, dass auch die Texturen da im Speicher entpackt werden. Aber das stimmt halt nicht. Und wenn man das nicht mehr hat, dann kann man das nicht mehr so entpacken. Mhm, okay, ja, okay, okay. Und dann, genau, und dann kommt, das fand ich ganz interessant, es gibt ja in der Welt auch Wasser und das kommt dann obendrauf.

Also erst wird das ganze Terrain gerendert mit Wiese und alles und ist ja gar nicht mal so unrealistisch eigentlich, weil unter einem See ist natürlich auch was, also Algen oder so, aber bei euch ist es dann halt zum Beispiel eine Wiese und dann wird obendrauf das Wasser gerendert. ähm, ja.

Kai

Genau, das ist vor allem deswegen da, weil das Wasser nochmal ein bisschen, eigentlich würde Wasser auch gebaked werden und es war am Anfang in dem Algorithmus auch immer unter dem Spieler und deswegen baken wir es auch. Das Problem bei Wasser ist, dass es manchmal Objekte gibt, die auf dem Wasser sein sollen, aber durchs Baking unter dem Wasser zum Beispiel liegen.

Und auch ein paar andere visuelle Effekte, zum Beispiel gibt es da so kleine Wasserwellen, die sind animiert, deswegen können wir das zum Beispiel nicht baken. Oder auch die Kanten von dem Wasser zum Land, Und es sind ja Teils, die sind auch animiert. Da gibt es so ein bisschen so Wasser. Und entsprechend, genau, haben wir das Wasser einfach nicht gebakt. Eigentlich wäre es schöner gewesen, die vermutlich auch zu baken, aber das hatte zu viele Seiteneffekte.

Simon

Das ist aber ein guter Punkt. Es gibt nämlich da so Sonderfälle. Und da bin ich mal gespannt. Also es ist nämlich so, man denkt sich ja so, oh, das ist ja alles easy und Pixelart. Das ist ja eh für Babys und das geht alles ganz einfach und so weiter. Da gibt es ja immer so Aussagen wie Pixelart ist ja nichts wert und so.

Und ein schöner Sonderfall, wo man wieder mal merkt, abgesehen von diesen ganzen Sachen, die wir jetzt schon besprochen haben, wie die ja alle super kompliziert sind, gibt es nämlich manche Objekte, die stecken im Wasser. Und das heißt, man sieht zum Beispiel einen Ast, der im Wasser steckt und dann sieht man eben einen kleinen Teil, der unter Wasser ist, der ist dann halt dunkel und blau.

Und dann, wo der Ast eben über das Wasser hinausragt, sieht er halt braun aus, wie so ein Ast, wie man sich das halt vorstellt. Und da habe ich mich gefragt, so, aha, wie ist das denn? Weil, wenn man jetzt aus 3D kommt, easy, das Wasser ist eine eigene Plane, steckt man da irgendwie ein Objekt rein, wird das mit dem Scheder eingefärbt, bla bla bla, ist ja easy. Das ist ja wie in der echten Welt sozusagen. Aber in 2D gibt es ja keine Tief- und Überlagerung in dem Sinne.

Es ist halt alles eine Fläche. Und der Ast weiß ja gar nicht, dass er jetzt unter irgendwas ist.

Kai

Ja, ja, das, ja.

Simon

Und ich habe schon, ich habe sogar schon herausgefunden, wie es bei, wie heißt es, Seegras, nee, wie heißt das, was im Wasser steckt mit diesen braunen Dingen?

Kai

Ja, ich weiß, was du meinst, Reeds, ich weiß gar nicht, wie es auf Deutsch heißt.

Simon

See, Farm, Garmen?

Kai

Warte, ich frag kurz, Reeds, Englisch? Schilf.

Simon

Schilf, Schilf, genau. Schilf heißt das. Da habe ich schon gesehen, dass der Teil unter Wasser und der Teil über Wasser ist ein getrenntes Pride. Ja, und das ist eigentlich die ganze Magie da. Also, das sind einfach zwei verschiedene Sprites. Da ist gar nichts, steckt gar nichts im Wasser. Das ist einfach, das sind einfach zwei verschiedene Sprites. Eins ist eben dann eingefärbt. Aber ist das bei dem Ast, den ich beschrieben habe, auch so?

Kai

Das ist einfach am Stück gepixelt. Also, wenn du die Ace Prater dazu aufmachst, da ist einfach Holz und dann ist da blau drin und dann ist da wieder Holz und dann ist da blau drin und so weiter. Also, es ist einfach so gezeichnet. Ähnlich wie man ein Loch pixeln würde. Da ist ja nicht ein wirkliches Loch in der Welt, sondern du zeichnest es so, dass es so wirkt, als sei es ein Loch als Beispiel. Und so ist das hier auch. Es wurde einfach so gezeichnet, dass es unter Wasser wirkt.

Deswegen dürftest du dieses Objekt zum Beispiel nicht an Land placen. Angenehm, wir würden so einen Ast auch auf Land haben wollen, bräuchte man eine zweite Variante, wo das Blau dann nicht drin ist.

Simon

Gut, das ist, das glaube ich, es macht Sinn. Das sind statische Objekte, die kann man platzieren und dann ist das alles gut. Und solange niemand böse ist und einfach Objekte woanders platziert, merkt es keiner. Aber es gibt einen Sonderfall. Es gibt Schlamm im Spiel, habe ich gesehen. Und das ist ganz spannend, weil Schlamm oder Moor, sage ich mal, da kann man durchlaufen und dann versinkt man ein bisschen in diesem Moor und die Füßchen, die sind dann plötzlich schlammig.

Und das heißt, das ist wahrscheinlich eins der wenigen Objekte, die dynamisch, also man selbst halt als Spielfigur, die dynamisch in sowas reinlaufen können und dann halt dynamisch müssen die Füßchen schlammig sein. Also beziehungsweise, ich glaube, die Darstellung ist quasi, dass die Füße unter dem Schlamm sind und dann halt ein bisschen brauner oder grüner werden. Wie ist das denn gemacht? Das ist ganz spannend. Weil, nochmal zur Wiederholung, es gibt ja keine richtige Tiefe.

Also man kann ja nicht in so ein Loch fallen, weil es gibt ja nur eine Ebene bei 2D. Das heißt, auch dieser Effekt, dass man so das Gefühl hat, dass man so einsackt, muss irgendwie gefakt sein.

Kai

Ja, alles ist gefakt. Genau. An der Stelle ist es so, tatsächlich wird der Schlamm an sich auch in den Boden gebakt. Das heißt, wenn du die ... Texture dazu angucken wirst, in diesem Chunk ist es da schon quasi fertig drin. Die Umsetzung selber ist im Endeffekt, dass an der Stelle, wo über solcher Schlamm ist, wo man einsingen kann, ist zusätzlich auch ein Physik-Collider quasi.

Und wenn der Spieler diesen Physik-Collider quasi platziert, äh, nicht platziert, berührt, kollidiert, dann setzen wir sein Visual ein paar Pixel nach unten.

Simon

Mhm.

Kai

Äh, zwei, drei, ich weiß grad nicht wie viel. Und die Füße sind im Endeffekt ein Shader. Und der Shader fragt im Endeffekt ab, hey, auf welchem oder bekommt von diesem Collider mitgeteilt, es ist Schlamm und nicht Wasser. Wir haben einen ähnlichen Effekt in Wasser. Nur dann ist dann die Fußfarbe blau und hier ist es halt eher so braun. Und dann im Shader wird dann quasi von seinem Pivotpunkt alles, was x Pixel unter dem Pivotpunkt liegt, quasi eingefärbt in Farbe des Bodens.

Genau, so haben wir das da quasi umgesetzt.

Simon

Okay, das ist, ja okay. Das heißt, der Shader hat, ja, das ist einfach ein Shader, der einen ganz speziellen Modus hat für Wasser und Schlamm. Genau.

Kai

Genau, genau.

Simon

Special Case, ja. Okay. Ja, spannend. Das sind so die kleinen Sachen, aber da hab ich dann drauf geachtet beim Spiel. Das ist sehr, sehr schön.

Kai

Da gab's auch einen witzigen Edge Case, wenn man sehr nah an der Kante des Wassers oder des Schlammes war und man geht ja rein, hab ich am Anfang den Spieler komplett nach unten verschoben. Und nicht nur sein Visual. Und dadurch hat sich aber auch sein Collider nach unten nach oben verschoben. Und nachdem, wo du standest, konntest dann mal passieren, du betrittst es, du wirst verschoben. Durch die Verschiebung betrittst du es aber nicht mehr und wirst wieder rausgeschoben.

Da gab's so ein da, da, da, da, da, da, da, da.

Simon

Ja.

Kai

Und deswegen habe ich dann irgendwann nur das Visual verschoben und nicht seine Gesamtposition quasi.

Simon

Aber das bedeutet ja jetzt mal wirklich ein Edge Case. Wenn es ein Projektil gäbe, was auf mich zufliegt und quasi die obere Hälfte meines Kopfes treffen würde, jetzt stecke ich im Schlamm, bin ein paar Pixel weiter runter. Visuell würde mich das Projektil jetzt also nicht mehr treffen, weil es fliegt gerade so über meinen Kopf hinweg. Aber mein Physikobjekt hat sich ja nicht verändert. Das ist ja immer noch an der anderen Stelle.

Ich wäre also getroffen, obwohl ich visuell, weil ich im Schlamm stecke, weil ich visuell ein bisschen weiter unten bin.

Kai

Diesen Edge-Case gäbe es und deswegen verschieben wir auch nicht mehr zwei, drei Pixel und die meisten Projektile sind schon groß genug, dass das nicht auffällt. Zumindest ist es bisher niemandem aufgefallen. Ich hoffe, wir haben jetzt hier kein Secret irgendwie preisgegeben und alle Leute beschweren sich ab sofort, wenn sie im Schlamm kämpfen.

Simon

Ja, vor allem wenn der No-Hit-Run failed.

Kai

Deswegen. Ja, genau, genau. Aber ne, das stimmt schon, das ist eigentlich ein Edge Case, der auftreten könnte, ja.

Simon

Ah, okay. Du hast eben schon Pflanzen erwähnt und bei den Pflanzen ist mir was aufgefallen, das ist jetzt ein bisschen schwierig zu beschreiben, weil wir sind halt ein Audio-Podcast, aber ich, also und selbst ein Bild einblenden ist gerade ein bisschen schwierig, mache ich trotzdem. Aber es ist so, wenn man 2D-Pflanzen hat oder wenn man überhaupt Pflanzen hat, dann kann man die ein bisschen hin und her wickeln, damit dort ein bisschen Bewegung reinkommt, als wären sie eben vom,

Vom Wind angeblasen. Und das funktioniert normalerweise über eine kleine, blurry Noise-Textur. Und dann distortet man ein bisschen die UVs und dann bewegen sich die Pixel ein bisschen hinher. Und bei euch ist mir aufgefallen, dass wenn man da mal ganz nah ran zoomt, das ist ein bisschen schwierig zu beschreiben.

Also ich kann gar nicht genau beschreiben, was da passiert. Aber da sind so Pixel, die sich bewegen, übereinander schieben und dann auch kleinere, Also, sagen wir mal, nicht pixelperfekt. Es ist wirklich schwierig zu beschreiben. Es gibt so Artefakte, dass so kleine, dünne Pixellinien entstehen, weil da irgendwas distortet wird. Und ich verstehe nicht genau, was da passiert.

Kai

Ja, das ist eine sehr gute Frage, was da eigentlich passiert. Das ist vermutlich darauf zurückzuführen, was ich vorhin meinte, dass wir diesen Pivot reinbaken. Weil diese Pflanzen werden nicht nur von Wind verschoben, sondern auch, wenn ich mich als Spieler den nähere und mit ihm kollidiere. Und dieses Artefakt ist dann aufgetrieben, als ich dieses Pivot-Baking eingebaut hatte. Bevor ich das eingebaut hatte, gab es diese Artefakte nicht.

Und meine Vermutung ist, dass das einfach Rundungsfehler im Shader sind, die dadurch zustande kommen, dass diese Pivot-Map entweder nicht akkurat ist oder vielleicht werden Werte interpoliert, wenn sie dann im Shader ausgelesen werden, irgendwie sowas. Oder vielleicht mal auch im Shader irgendwas völlig falsch. Aber das ist tatsächlich einfach ein bisschen buggy. Ja, und vermutlich einfach Float-Ungenauigkeiten. Das ist zumindest meine Interpretation bisher, warum das auftritt.

Simon

Ja, interessant. Also ich hoffe, das ist nicht zu verwirrend. Wenn ihr zuhört, ihr könnt ja, wenn ihr eine ruhige Minute habt, mal auf das Handy gucken oder bei YouTube oder so. Da kann ich ein Bild einblenden, wo man so das sieht. Ist ganz, ganz interessant. Ja, genau. Und wahrscheinlich wird es noch verwirrender, aber ich will es trotzdem nochmal nachfragen, weil ich habe das mit diesem Pflanzen-Pivotpunkt noch nicht ganz verstanden.

Also es ist so, wenn man jetzt im 3D, wenn man jetzt einen Baum hat zum Beispiel und man möchte die einzelnen Äste bewegen und um den Punkt, an dem sie an dem Stamm ansetzen, rotieren, so ein bisschen, einfach so ein bisschen hin und her wickeln lassen, dann nehme ich mir die von mir aus den UV-Kanal 1 und 2 und speichere da rein einfach die XY- und Z-Koordinaten.

Ich lade von dem Punkt, wo der Ast am Baumstamm ansetzt und im Shader lese ich das dann aus und bewege dann die Wörter von diesem Ast eben um diesen Punkt. Und das bedeutet, dass ich mehrere Pivot Points sozusagen für jeden Ast am Baum in dem Baummech an sich abspeichere. Wenn der Baum 5S hat, habe ich da eben 5 Stamm. Datenwerte reingeschrieben, schreibe ich dann in die Vertex-Daten rein.

So, aber bei euch ist das ja nicht, also es klang für mich so, als wäre das so global für alle Pflanzen irgendwo abgelegt oder so.

Kai

Nee, also jede Pflanze hat schon seine eigene Windmap, haben wir es im Endeffekt genannt.

Simon

Ja.

Kai

Und auch gleich nochmal, das ist kein schönes Bild, ich such dir gleich nochmal ein Bild raus.

Simon

Ja.

Kai

Aber ich nehme einfach das hier, ist egal. Schick dir das mal. Genau, das sind zum Beispiel jetzt Blätter eines Baumes. Und was man jetzt hier visualisiert, sieht, man kann da ja die Farben jetzt nicht interpretieren, weil ich die Farbenkanäle wieder als Daten missbrauche. Aber im Großen und Ganzen ist im Rotkanal quasi drin, wie sehr oder wie stark darf es sich bewegen im Wind, zwischen 0 und 1 sozusagen.

Und auf dem G- und B-Kanal ist quasi definiert, wo liegt sein Pivotpunkt in relativ gesehen zu seinem Pixel an dieser Stelle. Und im Großen und Ganzen zeigen alle Pivot-Punkt-Daten eines Pixels auf demselben Punkt in der Textur, sagen wir einfach unten in der Mitte.

Simon

Ja, genau, also wo die Pflanze beginnt.

Kai

Genau, und das nutzen wir aus, also wir haben zwei verschiedene Arten, Dinge im Wind zu bewegen. Das sind einmal die Bäume, die du hier siehst, und dann Objekte am Boden, weil Objekte am Boden kann der Spieler auch mit kollidieren. Und das sähe sehr merkwürdig aus, wenn wir die Pflanze oder das Blatt an einer Stelle bewegen, weil der Spieler so ein bisschen gegen nur dieses Blatt läuft, dann, Fühlt es sich nicht so an, als ob sich der Busch bewegt, sondern dieses Blatt.

Und angenommen, ich stehe in der Mitte des Busches, dann hätte ich so eine kreisförmige Distortion in jede Richtung und so verhält sich kein Busch. Und deswegen lesen wir quasi nicht jeden einzelnen Pixel aus, sondern seinen Pivot-Punkt. Und wenn der Spieler mit diesem Pivot-Punkt, ich nenne es mal kollidiert, es ist keine echte Kollision, die da stattfindet, dann bewege ich entsprechend die Blätter und so weiter.

Und dafür ist diese Pivot-Map genau da. Die Pivot-Map selbst ist reingekommen, weil wir haben einen Ort im Spiel, das ist die Heide, südlich von der Taverne. Dort gibt es sehr, sehr, sehr, sehr, sehr, sehr, sehr, sehr, sehr, sehr, ich kann jetzt noch ein bisschen so weitermachen, viele Pflanzen. Eine von diesen Szenen hat ungefähr so viele Pflanzen oder Objekte in dieser Szene wie fast alle anderen Szenen zusammen. Da sind unsere Artes Berserk gegangen quasi.

Und da wollten wir halt Batching einbauen. Aber das Batching hat dann diese Windeffekte völlig zerstört, weil dieser Pivot, sein eigentlicher Pivot, nicht ausgelesen werden kann, weil sie einen gemeinsamen Pivot bekommen. Für alles, was gebatcht wird und deswegen kam dann quasi diese Pivot-Map rein, damit wir die Objekte in der Heide wieder batchen können und damit schnell rendern. Genau.

Simon

Genau, also für alle, die die Batchen jetzt zum ersten Mal hören, das ist im Grunde genommen, wie wenn man in Blender alle Objekte selectiert und dann joint oder in, jetzt muss ich überlegen, genau, in 3ds Max wäre es attached und dann hat man ein großes Objekt, aber das hat ja nur noch einen Pivot-Point und nicht, viele, wie man sie eben haben wollen würde, wenn man die Objekte einzeln rumdrehen oder rotieren möchte oder so.

Genau, aber die Map, die du gezeigt hast, ist eben für eine Texture für einen Baum.

Kai

Genau, genau.

Simon

Aber im Batching, also und die beinhaltet sozusagen den Pivot, lokal im Local Space sozusagen zu diesem Baum. Aber wenn du die jetzt alle Bäume zusammenmergst in einen oder zusammenbatchst, dann weißt du ja nicht mehr, wo die ganzen Pivots sind, weil das war ja sozusagen nur für die lokale Szene abgespeichert. Aber wir reden ja jetzt dann plötzlich von WorldSpace.

Kai

Das Gute ist, prinzipiell erstmal ja. In unserem Fall ist so ein bisschen WorldSpace und LocalSpace, ich sag mal, identisch. Weil im Endeffekt der Sprite, den wir rennen, der hat seine Position auf der CPU sozusagen. Aber was wir nicht mehr haben auf der GPU, ist dann sozusagen, oder andersrum. Den Shader, den wir verwenden, der kennt seine World Position.

Also er weiß, in welcher World Position liegt mein Pixel. und dadurch kann ich dann in Word Position seine Local Position einfach abziehen, weil wir skalieren die Bäume nicht oder rotieren sie auch nicht oder sowas. Und deswegen kommen wir dann sozusagen von seiner Word Position des Pixels, Durch Addition, Subtraktion, was auch immer sein, ist Local Pivot Offsets trotzdem auf die Global Position in der Welt.

Aber auch nur, wie gesagt, weil wir nicht rotieren, weil wir nicht skalieren und so weiter. Weil wir skalieren und zwar auf x-Achse, entweder plus oder minus eins, das ist tatsächlich auch nochmal da reingecodet in diese Textur. Ob es geflippt ist oder nicht.

Simon

Ach so, okay, zum Flippen, ja, okay, genau.

Kai

Weil sonst bewegt sich der Wind plötzlich für diesen Baum in eine andere Richtung und für alle anderen Bäume, also unser Wind geht in der Regel von links nach rechts und hätten wir das nicht eingebaut, dann gäbe es Bäume, wenn wir sie flippen und wir flippen, um einfach Aufwand zu sparen, damit wir eine Variation mehr haben, dann würde er genau andersrum seinen Wind bewegen. Also von rechts nach links dann.

Simon

So, und ich hoffe, jetzt hören noch Leute zu. Es ist alles wahrscheinlich sehr, sehr deft, aber ich finde es total spannend. Genau. Und für alle, die auch so ein Spiel machen wollen, ist es, glaube ich, auch sehr spannend. Aber wir gehen jetzt noch mal in Pflanzen-Thema. Und das ist tatsächlich ganz spannend. Ihr habt Höhenfog eingebaut. Und das sieht man ganz besonders gut bei eben großen Bäumen.

Und da habe ich mich, also die erste Frage ist für mich, also, oder andersrum, wir reden ja über ein 2D-Spiel. Das heißt, ich kann natürlich jetzt einen halbtransparenten Layer über das gesamte Spiel legen und dann sieht das so neblig aus. Und das hätte auch total ausgereicht, glaube ich. Das hätte man so machen können, so einfach so, um eben so einen Nebeleffekt zu machen.

Aber ihr habt gesagt, nö, wir wollen mehr. Ja, und jetzt ist es so, dass so ein großer Baum, der kann tatsächlich unter, also der untere Teil des Baumes so in Nebel eingehüllt sein und der Baumwipfel guckt oben über dem Nebel raus, wie auch hier in 3D, total easy. Ja, ich meine, man hat die 3D dann so, aber wir reden ja über ein 2D-Spiel, da ist das ja noch nicht so einfach. Und das habe ich nämlich zufällig bei euch im Stream gesehen.

Ich glaube, der Johannes hatte das gezeigt und ich habe gesagt, hey, warte mal, da ist ja Höhenfunk drin, wie macht denn ihr das? Und genau, das ist total, total cool. Und du hast jetzt hier so Sachen gepostet. Kannst du mal erzählen, wie ihr das macht?

Kai

Genau, genau. Also die Inspiration war von Graveyard Keeper. Das sind jetzt hier die Bilder von Graveyard Keeper, nicht von uns. Die haben es einfach technisch ein bisschen schöner. By the way, die haben einen sehr schönen Beitrag bei damals noch Gamasutra. Ich weiß gar nicht, wie die Seite gerade heißt, aber die ist irgendwie anders. Für ein paar visuelle Effekte, die sie verwendet haben. Und da haben wir uns initial auch sehr stark inspirieren lassen.

Unter anderem an diesem Fog-Effekt. Und Chris war ein unglaublicher Fan von diesem Fog-Effekt. Für mich hätte es tatsächlich so ein bisschen gereicht, wie auch in der Vision-Demo, da hatten wir das schon, was du meinst, so ein bisschen, es wird einfach grob drübergelegt überall und dann hat man so ein bisschen, ja, Fog. Aber Chris fand diesen Effekt so geil, dass wir den halt für Drova eingebaut haben. Und ich habe mich genau dasselbe gefragt, hey, wie machen die das eigentlich?

Weil auch durch den Artikel bin ich irgendwie, irgendwie check ich es nicht. Aber was machen die? Okay. Und bin dann im Endeffekt, was du wahrscheinlich auch hier mit Drova gemacht hast, mit so einem GPU, Profiler-Tool, ich weiß gerade nicht, wie sie heißen, rangegangen und habe mir einfach mal geguckt, wie drauen die eigentlich ihre Sachen.

Simon

Ein kleiner Hinweis hier, diese Profiler-Tools, also ich kenne zum Beispiel Nvidia Insight, Intel GPA und RenderDoc ist auch sehr bekannt. Es gibt auch noch eins Pix, P-I-X, aber was wollte ich sagen? Ach ja, genau, ich wollte darauf hinweisen, dass ich einen kleinen Vortrag gemacht habe, wo es genau darum geht.

Also ich zeige in diesem Vortrag, wie man die drei Tools, Inside, RenderDoc und GPA einsetzt, um dann eben in meinem Fall Acoustic Space Survivors und Elden Ring, das sind immer zwei Spiele, die man so gleich nebeneinander nennt, auf jeden Fall habe ich die beiden tatsächlich genommen, um diese Tools zu demonstrieren und ich zeige dann wirklich Schritt für Schritt, wie das geht, weil es ist manchmal nicht so ganz klar, wie kriege ich das überhaupt zum Laufen

und so und manchmal gibt es eben auch Probleme, zum Beispiel, dass der das Kopierschutz bei Elden Ring, der mochte das gar nicht und dann zeige ich halt kurz, wie man die Detail umbenennt, damit der Kopierschutz eben da nicht dazwischen funkt und so. Und der Vortrag heißt Being a Tech Art Detective und ja, genau, da zeige ich das. Und vielleicht ist das ja hilfreich für jemanden hier, denn ja, das ist sehr praktisch damit, die Spiele zu untersuchen.

Kai

Und bin dann Step by Step durchgegangen, hab dann gesehen, wie sie es gemacht haben. Der Ansatz im Großen und Ganzen ist einfach, dass du so, ich nenne es mal Bänder in die Szene liegst, die sozusagen den Fog darstellen und zwar von unten, nee, von oben nach unten, warte, halt in die Ränder reinfolge, ich glaube von oben nach unten.

Das heißt, im Endeffekt hast du ein paar Bänder von Nebel, die sind jetzt an der Position wo auch immer, da machst du ein paar davon, dann kommt irgendwie dein nächstes Objekt, ist zum Beispiel der Baum und dann machst du die nächsten Layer vom Fog und dadurch layert sich das dann quasi so, weil einfach von einer Render-Order Teile des Fox dahinter liegen und andere Teile des Fox tatsächlich einfach davor liegen.

Einfach weil es tatsächlich Sprites sind, die in der Szene zusätzlich gerendert werden.

Simon

Ah, okay. Ja, klar. Ich meine, die Sprites können sich ja auch überlagern. Das heißt, es gibt eine Render-Reihenfolge. Also ein Haus ist irgendwo ganz hinten, dann kommt davor der Baum, dann kommt davor der Zaun und so. Und dazwischen haut man jetzt nochmal so Fogplanes, also mehrere Fogplanes. Das ist nicht nur eine Fogplane mit irgendeinem Magic Shader, der da irgendwelche Höhendaten aussieht, sondern es sind einfach verschiedene Planes dazwischen gesteckt.

Das ist im Grunde wie, wenn man so manche Scheibenkäse gibt, da hat man zwischen jeder Käsescheibe so eine kleine Plastikfolie. So ist das im Grunde genommen.

Kai

Ja, also ich wäre nie auf die Metapher gekommen, aber ja, im Großen und Ganzen ist das so.

Simon

Das ist eigentlich ziemlich exakt so und jeder Käse ist ein Sprite.

Kai

Ja, stimmt, stimmt. Und jetzt stell dir einfach vor, ein paar von diesen Käsescheiben werden weg, aber die Plastikdinger waren trotzdem da. Die sind ja auch so ein bisschen semi-transparent.

Simon

Ja, genau, genau.

Kai

Ja, das war damals auch so mein Heureka-Moment, als ich das so, wie machen die das? Magic, Tiefeninformationen, wie machen die das? Ja, und dann war es so, ich war so, okay, ist ja simpel eigentlich. Hat aber wieder Nachteile, auf der Switch haben wir es zum Beispiel gar nicht drin, den Shader für Nebel, weil dieser, nicht dieser Shader, weil diese Sprites im Endeffekt unser Batching zerstören.

Weil man kann sich vorstellen, wir haben ganz viele Gräser oder Bäume nah beieinander und zwischen diese Bäume hauen wir jetzt plötzlich Nebel und deswegen können diese Bäume zum Beispiel nicht mehr zusammengerendert werden, sondern werden durch den Nebel quasi nicht mehr batchbar gemacht. Und deswegen haben wir auf der Switch zum Beispiel diesen gesamten Effekt deaktiviert, um einfach das Rendering weiterhin aufrechtzuerhalten.

Simon

Okay, das ist eine dieser Sachen. Aber ich glaube, es gibt relativ wenige Sachen, die auf der Switch nicht so sind wie auf der PC-Version.

Kai

Genau, ich glaube, das ist eigentlich fast das hier. Und wir baken den Schatten auch in den Boden von Objekten. Das machen wir auch auf der Switch. Also wenn du jetzt eine Textur anguckst vom PC, Von diesen gebakten Sachen, die wir vorhin einmal hatten, da findest du keine Schatten drin. Aber auf der Switch-Version sind die Schatten auch einfach eingebakt.

Simon

Und warum würde man das nicht auf ... Also okay, warte mal. Meine Vermutung ist, wenn man unter einem Baum steht, will man vielleicht, dass der Schatten auf die Spielfigur auch gelayert wird, weil du ja unter dem Baum stehst. Und deswegen ist es in der PC-Version drin? Oder gibt es irgendeinen anderen Grund?

Kai

Genau, unser Schatten ist auch noch mal ein spezieller Shader. Und wenn du mehrere Schatten bei uns im Spiel überlagerst, dunkeln sie sich nicht gegenseitig ab, sondern sie bleiben gleich dunkel sozusagen. Und dieser Effekt ist dann entsprechend auf der Switch raus, weil es wird gebaked und dadurch, wenn du dich draufstellst, wird es tatsächlich dunkel, dass es sich gegenseitig ab.

Und am PC fanden wir den Effekt halt schön, dass es nicht abgedunkelt wird und deswegen haben wir es da nicht gemacht.

Simon

Also du meinst, dass der kleine Blob-Shadow unter der eigenen Figur dunkelt, die anderen Schatten. Okay, das ist natürlich ein krasses Detail schon.

Kai

Oder auch mehrere Bäume untereinander. Angenommen, du hast ganz viele große Bäume nah beieinander und ihre Schatten überlagern sich, da würden die auch schon sich gegenseitig abdunkeln, aber das tun sie in Drohwe halt aktuell auch nicht. Auf PC.

Simon

Und, Wie habt ihr das gemacht? Also was ist da die Magic dahinter?

Kai

Mit dem Stencil-Buffer quasi. Also im Großen und Ganzen, wenn wir einen Schatten reinrendern, schreiben wir in den Stencil-Buffer, da ist jetzt Schatten sozusagen. Und wenn ein anderer Schatten quasi dazukommt, der addiert sich sozusagen. Wir nehmen sozusagen das Maximum aus dem Stencil-Buffer. Das punktet sich ein bisschen anders, weil den Stencil-Buffer benutzen wir auch nur für was anderes. Aber im Großen und Ganzen kann man sich das so vorstellen.

Simon

Also die anderen Schatten ignorieren einfach die Pixel, die schon im Stencil-Buffer drin sind. Sagen aber, okay, wenn da schon mal ein Schatten ist, dann komme ich jetzt nicht auch noch dazu. Es gibt noch eine andere Sache, die ihr anders gemacht habt in der Switch-Version. Und zwar läuft die mit 30 FPS.

Kai

Ah ja.

Simon

Statt 60. Und da gibt es ein Video, da hat, glaube ich, Chris gesagt, dass ihr am Kampfsystem ein bisschen noch schrauben musste, damit sich das auch in 30 FPS flüssig anfühlt. Und ich höre mal kurz rein, da ist die, der Wortlaut ist so was wie, genau, aber wir haben schon schöne Lösungen im Kopf, sagt Chris. Hast du da irgendeine Information, was so coole Tricks da waren, damit sich Sachen flüssiger anfühlen dann in 30 FPS?

Kai

Das Ding mit der Switch-Version war quasi, du hast ja sozusagen nur halb so viele Bilder pro Sekunde als Mensch zu verarbeiten, um zum Beispiel auf einen Angriff des Gegners zu reagieren. Sagen wir, der Angriff des Gegners bei der 60 FPS-Version, weiß ich, wird sechs Frames lang abgespielt. dann sind es ja eine zehnte Sekunde. Aber eine zehnte Sekunde auf der Switch sind nicht sechs Frames, sondern nur drei Frames.

Das heißt, du hast eigentlich nur drei Frames Zeit, seine Anticipation zu lesen, um darauf zu reagieren. Und das hat sich, weil es einfach weniger FPS hatte, hat es sich so angefühlt, dass man weniger Chance oder Zeit hatte, auf einen Angriff des Gegners zu reagieren. Und deswegen haben wir einfach hart für die Switch gesagt, dass unsere ganzen Animationen, die kampfbasiert sind, die nicht vom Spieler kommen, Einfach ein paar Frames quasi länger gehen, um das so ein bisschen entgegenzusteuern.

Wir gehen dann nicht auf komplette 6 hoch, weil dann würde es ja doppelt so lange brauchen, bis dann der Angriff durchkommt, sondern, was weiß ich, immer zwei Frames mehr oder sowas. Und das war einfach eine schöne Faustregel, damit es sich ein bisschen smoother auf der Switch anfühlt, dass man die Chance hat, oh, er macht diesen Angriff, er spielt diese Animation ab, ich kann jetzt darauf reagieren.

Das ist aber, glaube ich, eher so ein Wahrnehmungsding von Menschen, warum wir das gemacht haben.

Simon

Aber in welcher Framerate sind denn die Animationen angelegt?

Kai

Also intern arbeiten wir eigentlich primär mit Zeiten. Also wir sagen, hey, diese Animation wird für 0,1 Sekunde lang abgespielt. Die Framerate selbst kommt natürlich von unseren Pixelartists, weil die pixeln das ja in irgendeiner gewissen Art und Weise mit einer gewissen Anzahl an Frames und geben dann jedem Frame an, für wie viele Millisekunden die angezeigt werden sollen.

Und dadurch ergibt sich dann sozusagen die Framerate. wir sind da aber auch ein bisschen flexibel also nicht alles im spiel hat dieselbe frame rate bestimmte angriffe sind schneller bestimmte angriffe langsamer einfach so dass es dem spielgefühl gut tut und sie nicht so weit auseinander klaffen dass man sieht das hat doppelt so viel frames und wirkt viel zu smooth oder sowas oder das hat viel zu wenig aber, wahrnehmungstechnisch nimmt man das recht selten wahr es gibt einzelne angriffe und,

Tatsächlich sogar bei dem Dokument, was du hast, wo diese Blutfliege nicht übers Wasser kommt, die greift ja an und geht beim Angriff so leicht nach oben. Und bei diesem nach oben Angriff gibt es einzelne Phasen, wo die Frames sehr langsam abgespielt werden. Das wäre zum Beispiel so ein Edge Case, wo, wenn man das nicht gut einstellt, was man häufiger sehen könnte.

Simon

Ja, also warum ich frage ist, oder noch eine kurze Seitentangente. Es gibt, ich glaube, eine Dokumentation zu dem Spider-Man-Film, Spider-Verse dem ersten. Und da haben sie, ich hoffe, ich erzähle jetzt nichts falsch, es könnte auch was anderes gewesen sein, aber es gibt auf jeden Fall Animationsfilme, wo sie normalerweise zwölf Frames pro Sekunde animiert haben. Also so typisch Cartoon oder so.

Aber bei Action-Sequenzen, wenn also zum Beispiel sich eine Figur abrollt quasi, dann auf das Doppelte gehen. Und das heißt, das ist schon ein sehr drastischer Schritt, aber dadurch hast du in ruhigeren Szenen so diesen coolen handanimierten Style. Aber wenn es dann doch mal ein bisschen actionreicher wird, dann sieht es halt nicht zu joppy aus oder man vermisst irgendwas in der Bewegung, weil man irgendwie eine Key-Pose gar nicht mehr reinbekommt oder so.

So, das finde ich schon ganz spannend, so diese Entscheidung da schon sehr drastisch plötzlich die FPS auch hochzuschrauben. Aber warum ich jetzt eigentlich gefragt habe, ist, diese Animation zum Beispiel für euer Spiel jetzt wirklich auf 60 FPS zu malen, was ja bedeutet, 60 Bilder pro Sekunde, das wäre ja viel zu viel Arbeit. Und deswegen würde es sich ja auch lohnen, zum Beispiel zu sagen, nee, also die Artists, die malen in 12 FPS, also 12 Bilder pro Sekunde zum Beispiel.

Diese Frames könnte man doch jetzt aber egal ob es 30 oder 60 FPS sind, immer gleich timen sozusagen, also ich hab jetzt noch nicht ganz verstanden, warum, ich geh jetzt mal davon aus, dass die Animationen angelegt wurden, nicht in 30 FPS und auch nicht in 60, sondern niedriger einfach um Arbeit zu sparen und ich versteh grad nicht ganz, warum, dann trotzdem da noch irgendwie extra was getweakt werden musste für die 30 FPS?

Kai

Also, wie es zustande gekommen ist, als einfach, wir haben das Spiel auf der Switch gespielt und am PC war es easy, der Ripper macht sich zum Sprung bereit, du dodged, er verfehlt dich. Und auf der Switch war es irgendwie so, wenn mich der Ripper, oh, zack, also hoch. Ich hatte irgendwie gar kein Gefühl, zu reagieren.

Und wir haben es im Endeffekt dann damit erklärt, dass einfach die, also unsere Frames sind recht wenig nicht, oder werden recht schnell abgespielt, also zum Beispiel, wenn man sich mal den Ripper anguckt, ich gucke mal kurz, um Actual-Zeiten zu nennen, der Angriff vom Ripper, wir nehmen jetzt mal einen normalen Angriff, wird angezeigt 0,16 Sekunden.

Simon

0,16, ja.

Kai

Bevor dann, okay, und da gibt es noch ein paar andere, also wir haben in unserer Animation verschiedene Phasen gezeigt und die Anticipation-Phase sind 0,16 Sekunden. Es kommen dann noch ein paar andere Phasen, bevor der eigentliche Angriff kommt, aber im Großen und Ganzen sagen wir, du hast weniger als 0,5 Sekunden Zeit, darauf zu reagieren und in diesen 0,5 Sekunden zeigen wir verschiedene Animationen ab. Er geht in die Knie, er macht seinen Maul irgendwie groß und dann kommt der Angriff.

Und wenn wir jetzt auf der Switch sind, die Animationen werden trotzdem, was du meinst, gleich verteilt abgespielt und du hast auch 0,5 Sekunden Zeit, darauf zu reagieren. Aber die einzelne Phasen, zum Beispiel die Anticipation, die 0,16 Sekunden anhält, das sind ja bei 60 FPS, wären das 10 Frames, die würde man auf der Switch nur fünf Frames lang sehen, weil du ja einfach halb so viel Frames pro Sekunde hast.

Das heißt, du hast weniger, nicht Zeit ist das Falsche, sondern du hast weniger visuelles Feedback, wie lange eine einzelne Phase der Animation angezeigt wird, um sie dann zu kognitiv zu verarbeiten, um dann darauf zu reagieren.

Und was vielleicht auch noch dazu kommt, dadurch, dass wir das Spiel nur noch 60 FPS haben, wenn ich in dem Moment, wo ich klicke, gibt es im Worst Case vielleicht auch noch mal einen kleinen Delay von 1,30 im Vergleich zu 60 FPS bis dann die Taste vielleicht auch anschlägt. Und dadurch gibt es irgendwie, es ist nicht viel, aber einen kleinen Mismatch zwischen diesen beiden Versionen einfach und wie responsive das Game ist.

Und deswegen haben wir dann quasi von den Angriffen von den Gegnern einfach gesagt, okay, wir zeigen die einfach ein, zwei Frames länger an.

Simon

Interessant, ja. Das sind so Details, da macht man sich keine Gedanken, wenn man so ein Spiel anfängt. Und dann fragt man sich auch immer so, warum dauert ein Spiel eigentlich so lange zu entwickeln? Das sind doch nur so ein paar Figuren drauf zu sehen und ein Schwert und ein Baum und dann läuft das schon.

Kai

Also dazu muss man natürlich auch nochmal sagen, es ist... Ich glaube, es macht gar nicht so einen großen Unterschied zwischen 2- und 3D-Spielen, sie, sage ich mal so, auf jeden Fall auf code-technischer Basis zu entwickeln, weil du brauchst trotzdem Pathfinding, Objekte müssen von A nach B, es muss irgendwie vernünftig laufen, du brauchst ein Inventar, nicht Simulation, Management-System und so weiter, das brauchst du ja auch alles im 3D.

Natürlich im 3D, Grafiken sind schicker, aber das kümmern sich die Artists hoffentlich drum, nicht die Programmierer. Also ich habe das Gefühl, auf Programmierebene nimmt sich 2- und 3D gar nichts und ich glaube, natürlich schon Physikkollision oder ein Parabelflug im 3D ist mathematisch ein bisschen komplizierter, aber kann man auch alles online irgendwo nachgucken.

Im Großen und Ganzen habe ich das Gefühl, die technische Grundlage ist eigentlich ähnlich kompliziert und der Rest sind so ein bisschen, ich möchte sagen, 3D ist genauso einfach, aber ja. Ja, und ja.

Simon

Was ich weiß, ist zumindest, also Rotation ist ja ein Riesending, in 2D relativ easy, irgendwie was zu rotieren, easy peasy, aber in 3D ist es dann sofort irgendwie, okay, hallo Quaternions. Ja, genau. Und das Zweite ist, wo viele strugglen in 3D, ist auch Kamera. Eine gute Kamera in 3D, die nicht durch irgendwas durchklippt.

Und, also ich meine, selbst in so Blockbustern wie irgendwie Dark Souls und Elden Ring hat man manchmal in den Kämpfen, steckt dann die Kamera, weiß ich nicht, zwischen irgendwie zwei Brückenpfeilern oder sowas und dann sieht man ganz kurz nichts und dann stirbt man und so, da bin ich selbst auch schon.

Kai

Ich würde fast sagen, es ist gar nicht so selten, wenn ich ehrlich bin. Ich habe das Gefühl, es passiert immer mal wieder bei Dark Souls Elden Ring. Auch bei großen Bossen, wenn du versuchst, die zu fokussieren, die sind einfach so groß, dass die Kamera sich irgendwie so bewegt, dass du irgendwie sehe ich gerade gar nichts mehr so in der Richtung.

Simon

Und das sind Sachen, die sind schon, da geht auch schon, also das hat man in 2D, nicht so in der...

Kai

Wobei wir aber auch sehr viel Problem mit unserer Kamera hatten. Wir haben ja mittlerweile auch durch Optionsfall verschiedene Optionsmöglichkeiten, wie die Kamera sich verhält. Und es gibt immer noch sehr viele Leute, die durch Motion Sickness bekommen, dass unsere Kamera sich so ein bisschen zu schwankend anfühlt. Wir haben auch sehr viel Zeit in die Kamera gesteckt und sind auf jeden Fall auch nicht vollends zufrieden.

Aber ja, ich gebe dir auf jeden Fall recht im 3D. Das ist nochmal ein bisschen tricky.

Simon

Was sind denn die beiden Optionen, die ihr habt?

Kai

Das eine ist, dass halt die Kamera sich automatisch... Angenommen, du stehst irgendwo rum und du bewegst, ich gehe jetzt erstmal nur vom PC aus, und du bewegst die Maus nach rechts, dann bewegt sich die Kamera auch nach rechts. Das ist der eine Modus. Also Kamera geht in die Richtung des Mauszeigers.

Die andere Option ist, die Kamera geht nicht in Richtung des Mauszeigers, sondern du stehst jetzt und du guckst mit der Maus nach rechts, dann bleibt die Kamera so, wie sie ist und sie bewegt sich erst dann, wenn sich dein Charakter quasi bewegt, in die Richtung, in die dein Charakter dann auch entsprechend guckt.

Das sind gerade die beiden Modi, die wir am PC haben. Und für Konsole, also für Joystick, ist es tatsächlich so, du bist immer hart auf der Spielfigur drauf und kannst dann die Kamera überschreiben mit dem rechten Stick und kannst dann so ein bisschen Twin-Stick-Shooter-mäßig dich umgucken.

Simon

Ah ja, genau so habe ich es nämlich auch gespielt, ja. Speaking of Controller, es gibt ein Video, wo du zu sehen bist, mit fünf verschiedenen Gamepads.

Kai

Ja.

Simon

Ich glaube, ich habe es ich muss gerade mal suchen, ich habe irgendwas mit Joystick geschrieben, aber das ist natürlich Quatsch. Joy?

Kai

Ich habe es ja auf jeden Fall gefunden in einem Dokument.

Simon

Ah, okay, genau. Und da wollte ich mal fragen, also sehr vorteilhaft oder sehr vorbildlich ist er, ihr habt euch relativ früh schon entschieden, Controller-Support anzufangen, schon in 2021. Das ist cool. Ich glaube, Chris hatte erzählt, dass das eigentlich gar nicht geplant war, weil eigentlich so, ja, wer spielt denn mit Controller? Aber dann hat es das doch ganz gut angefühlt. Und ich wollte dich halt auch noch dazu fragen, was so deine Erfahrung war mit diesem ganzen Controller.

Weil in diesem Video, da siehst du nicht sehr glücklich aus, weil so viele Controller da auf deinem Tisch liegen.

Kai

Ja, muss man auch nochmal sagen, TikTok ist ja immer so ein bisschen gestellter. So ähnlich, was du meinst, mit einem Titel. Man versucht ja schon ein bisschen … Stimmt.

Simon

Warum hast du eigentlich Joystick-Hölle? Jetzt weiß ich, wer das kommt. In diesem TikTok steht Joystick-Hölle. Aber das sind doch gar keine Joysticks.

Kai

Ich glaube, das kommt so ein bisschen bei programmiertechnisch, nennen wir viele von unseren Klassencontroller, also Objekte, die andere Klassen kontrollieren. Und damit sich das programmiertechnisch nicht in die Quere kommt, heißt es bei uns programmiertechnisch Joystick, um es einfach von den anderen Systemen so ein bisschen zu differenzieren. Deswegen sage ich, glaube ich, häufig Joystick, obwohl es kein Joystick ist. Und das war da, glaube ich, auch automatisch in meinem Kopf.

Simon

Okay.

Kai

Genau, nee, sorry, was war deine Frage?

Simon

Einfach so die Erfahrung mit Controller, war das cool zu implementieren oder gab es da Probleme? Vor allem zwischen den verschiedenen Controllern, weil du hattest da ja Playstation, Xbox. Ich weiß nicht, ob du auch den alten Steam-Controller da hattest.

Kai

Nee, nee, wir hatten da so andere No-Name-Dinger auf jeden Fall noch rumstehen, liegen wie auch immer. Ja, war auf jeden Fall spaßig. So über die ganze Entwicklungszeit. Also jetzt zu dem Zeitpunkt haben wir es, glaube ich. Der Teaser, den wir damals auf Steam hatten, hatte keinen Controller-Support. Warum wir das da eingebaut hatten, beim Großen und Ganzen, um einen Trailer aufzunehmen mit einem Kampf, der irgendwie cool aussehen soll.

Und deswegen haben wir eigentlich Controller-Support initial, also wir wollten langfristig schon Controller-Support haben, aber zu dem Zeitpunkt war es, glaube ich, so, dass wir einen Trailer aufgenommen haben, wo einer mit Maus und Tastatur am PC gegen mich mit Joystick dann quasi spielt, damit der Kampf einfach dramatisch und cool ist, damit man nicht irgendwie komische KI implementieren muss.

Und entsprechend war es dann zu der arbeitenden Zeitpunkt eigentlich relativ simpel, weil du brauchst viele Edge-Cases nicht betrachten und musst nicht Menüs damit bedienen. Über die Entwicklungszeit von Droh war es dann immer mehr Arbeit geworden, weil wir auch immer wieder Features bearbeiten mussten, weil es funktioniert am PC, aber es funktioniert mit Controller nicht, zum Beispiel UI und GUI oder sowas.

Und deswegen gab es immer wieder Features, die wir re-implementieren mussten oder verändern wollten oder auch Features, die wir teilweise so ein bisschen weggeworfen haben, weil es auf Controller schwieriger war. Der hatte auch viel weniger Tasten, das heißt, du musst dir ja dann auch zum Beispiel überlegen, am PC mit M kannst du eine Karte öffnen, kriegen wir irgendwie diesen Button auch irgendwie auf dem Controller hin, haben wir im Endeffekt nicht hinbekommen.

Und dann auch die ganze Bedienung der ganzen Menüs, also dass du sagst, alles klar, ich öffne jetzt das Inventar und ich möchte irgendwie durch die Gegend springen mit dem Joystick, Controller. Das war auch alles recht viel Arbeit und oft wurden auch einzelne GUI-Fenster vergessen und dann gab es Bug-Reports, hey, ich kann das ja gar nicht bedienen mit dem Controller und genau. Und entsprechend war es so ein bisschen nervig, aber natürlich sinnvoll ist zu tun.

Simon

Aber gab es zwischen den Controller-Probleme, also zwischen diesen No-Name-Dingern und Playstation und Xbox oder war das alles smooth?

Kai

Wir haben auch aus dem Asset-Store ein Tool benutzt oder ein Asset, das nennt sich Rewired. Das vereinheitlicht die im Großen und Ganzen alle. Das hat eigentlich sehr, sehr schön funktioniert. Es gab einzelne Controller, die Rewired noch nicht kannte und deswegen konnten wir dann auch nicht mit denen umgehen. Und dann war es aber oft so, dass wir einfach nur Rewired einmal updaten mussten, weil die dann auch aufgenommen haben oder so. Also zwischen den Controllern gab es recht wenig Probleme.

Simon

Und was waren das für Features, die rausgeflogen sind wegen Controller?

Kai

Als Beispiel ... Wir hatten, wir haben es aber auch sehr spät angefangen, die Idee, man kann ja mit, wenn man die Karte öffnet, dort Marker setzen. Und die Idee war eigentlich, dass man nicht nur Marker über die Karte setzen kann, sondern auch wenn ich in der Welt vor einer Kiste stehe und ich zum Beispiel eine bestimmte Taste drücke, dann möchte ich auch dieses Objekt bereits auf der Karte markiert haben, um nicht erst in die Karte gehen zu müssen.

Und das ist zum Beispiel eines der Feature, wir hatten einfach keinen Platz mehr auf dem Controller, um diese Taste irgendwie einzubauen. Als ein Beispiel.

Simon

Das habe ich nicht verstanden. Warum will ich eine Kiste auf der Karte markieren? Ach so, weil man, genau, man kann ja Notizen machen, genau.

Kai

Genau, genau.

Simon

Mit Tinte, muss man aber erst kaufen.

Kai

Genau, genau, genau. Und die Idee war initial, dass ich nicht nur auf der Karte direkt etwas markiere, sondern ich hier in der Welt zum Beispiel zu einer verschlossenen Tür und markiere mir aus der Sicht des Charakters quasi etwas auf der Karte und hinterher erscheint es dann tatsächlich auf der Karte, weil ich zum Beispiel E drücke oder so und E heißt, markiere mir das Objekt, das ich gerade angucke.

Als ein beispiel wir hatten auch als idee dass man wir haben ja momentan ein schnell zauber also du kannst mit coolen zauber wirken kannst ihn durchtauschen du kannst nur ein zeitgleich ausgewählt haben wir hatten überlegt eigentlich am pc was cool gewesen wenn du zwei tasten haben könntest für zwei zauber dass du schneller zaubern kannst ohne jetzt hin und her weg sind zu müssen das hat aber auch probleme der ui aber auch auf controller hat mir einfach keine taste

mehr übrig und dann ist das zum beispiel auch rausgeflogen, oder konnten es nicht implementieren so.

Simon

Okay.

Kai

Das waren jetzt keine riesigen Features, sondern eher so Sub-Features.

Simon

Ja, aber es ist ja interessant. Das sind ja, ja, doch, das sind halt so kleine, also quasi, es ist mehr so ein bisschen diese, wie heißt das, Service Features, also kleine Komfort Features sozusagen. Weil man kann ja immer noch Dinge zum Beispiel auf der Karte markieren.

Kai

Genau, genau.

Simon

Wenn man Tinte gekauft hat. Und wenn man die Karte gekauft hat.

Kai

Oder sie anderweitig besorgt hat.

Simon

Ach, das geht? Ach, interessant. Okay, wir wollen nicht spoilern, aber ich hatte am Anfang, als ich eine Person getroffen habe, die eine Karte hatte, habe ich nicht genug Geld gehabt und dann hatte ich keine Karte für eine sehr lange Zeit in meinem Spiel und habe diese Figur auch nicht mehr gefunden und dann, ja, also ja gut, aber es hat dazu beigetragen, dass ich die Welt sehr sehr gut exploriert habe.

Kai

Aber ganz interessant war eigentlich fangen wir genau diesen Edge Case ab. Du gehst zu ihm hin und willst mit ihm handeln und du kaufst die Karte nicht, dann sagt er eigentlich, bist du sicher, dass du keine Karte willst? Und wenn du dann sagst, du hast nicht genug Geld, würde er auch dir anbieten, sie dir quasi zu schenken für einen Gefallen zu einem späteren Zeitpunkt.

Simon

Es kann sein, dass ich gesagt habe, nee, sorry, ich habe genug Mafia-Filme gesehen, da lasse ich mich nicht drauf ein.

Kai

Okay, okay, fair enough.

Simon

Also, das ist mir zu gefährlich. Man weiß ja nicht, was der denn will.

Kai

Ja.

Simon

Irgendwann kommt er und sagt so, hier, da ist ein kleines Hundebaby, das musst du jetzt umbringen und wenn man das nicht macht dann ist das spiel vorbei oder so das war mit zu risiko du hast eben schon die fliege erwähnt die fliege die fliege die nicht übers wasser kommt ach die genau und und das ist vielleicht ganz interessant um über das pathfinding zu sprechen also erst mal die frage was ist denn dieses a star pathfinding project weil, Also A-Star, das ist ein Algorithmus für Path-Finding.

Und wenn man sich mit Path-Finding beschäftigt, ist das das Erste, worauf man stößt. Und alle machen das. Aber ich frage mich, was dieses Path-Finding-Project ist. Das klingt ja super fancy.

Kai

Das ist im Endeffekt auch ein Asset aus dem Asset Store, was sozusagen relativ einfach dir ermöglicht, deine Welt zu scannen und dann Pathfinding auf dieser gescannten Welt, auf diesen Knoten, entweder zum Beispiel Grid-basiert oder Polygon-basiert, dann Pathfinding-Algorithmus laufen zu lassen oder andersrum, um auf die Abfrage zu haben, hey, ich stehe hier, ich möchte nach da, gib mir einen Weg von A nach B. Und das macht das Projekt sehr, sehr gut im 2D und im 3D, hat dort verschiedene

Algorithmen und so weiter und so fort und das haben wir einfach genutzt, um uns das Leben leichter zu machen. Hatte auch viele Drawbacks gehabt, also auch viel von Performance, Floss zum Beispiel in dieses Path-Pinding-Project und ja, aber im großen Ganzen super, super Tool.

Simon

Okay, und habt ihr, ihr habt das dann irgendwie Polygon-basiert gemacht oder wie, was heißt, wenn man das scannt? Also ich meine, ihr habt ja jetzt ein paar Sprites im Level rumliegen. Irgendwie muss man dem jetzt sagen, hier, das Sprite da, da bitte nicht langlaufen. Oder irgendwie muss man das ja vorbereiten, dass das System das dann wahr ist.

Kai

Genau. Oder wie wir es gemacht haben, oder wie das Pathfinder Project das auch im Großen und Ganzen anbietet, dass du so, es gibt einen Scan-Knopf und alles, was gerade in der Welt geladen ist, im Großen und Ganzen kann man sich vorstellen, dass da ganz viele Raycasts in die Szene schießt oder Ray-Sphere-Circles, was auch immer, mit einer gewissen einen Radius mit einer gewissen Größe.

Und wenn er dann auf gewisse Physik-Layer trifft, wie zum Beispiel sind das bei uns vor allem Small Obstacles und Obstacles, und er kollidiert dann mit einem dieser Layer, weiß er, alles klar, auf diesem, ich mache jetzt einfach mal Grid-basiert, auf jedem Grid feuere ich einmal,

Ding und stellen fest, ist dort ein Obstacle, ja oder nein. Und im Großen und Ganzen kriegt man dann einen riesigen gescriptbasierten Graphen, der dann quasi kodiert, auf welchen Nodes oder kleinen Rechtecken kann ich mich bewegen und auf welchen nicht. Und das hatte initial recht viel Speicher gefressen, weil es so Welt recht groß ist und wie eine Textur kann man sich das vorstellen. Ist einfach sehr aufwendig.

Und wir haben das dann später umgemappt auf Polygone und das kann man sich wiederum vorstellen wie ein Mesh. Das heißt, ein Mesh, du hast jetzt pro Knotenpunkt auf eine Mesh quasi einfach die Information, ja oder nein. Und dazwischen wird, sag ich mal, interpoliert, ganz inhaltlich, was die da machen, weiß ich nicht, aber im Großen und Ganzen so.

Und entsprechend brauchst du einfach viel, viel weniger Knotenpunkte, wenn du es polygonbasiert machst, versus wenn man es quasi rechteckbasiert oder texturbasiert sozusagen macht.

Simon

Genau, Knotenpunkt ist ein Vertex, ne?

Kai

Genau, genau.

Simon

Okay, also man hat einfach ein riesiges Mesh und ein paar haben einfach, hier kannst du nicht lang gehen, und andere haben halt hier ganz lang gehen, okay.

Cool, ja, so das ist also das Pathfinding so und dann gibt es natürlich gewisse Bereiche, wo man nicht langen soll, und Wasser ist eins davon und es gibt zwei verschiedene Arten von Wasser es gibt nämlich das Wasser, das knöchelhoch ist da kann man auch drin rumlaufen und, alle können da drin rumlaufen, auch blöde kleine Fliegen, die einen kaputt stechen wollen, und es gibt aber auch tiefes Wasser, da kann man nicht drüber laufen jetzt ist es aber so, dass diese Fliege, die kann ja fliegen,

man würde also erwarten dass die jetzt über das Wasser drüber kann. Aber, das müssten wir jetzt einfach glauben, man kann die Fliege austricksen, indem man sich auf die andere Seite des Tümpels stellt und die versucht dann zu einem zu kommen und greift auch immer wieder an, aber scheitert daran und knallt gegen eine unsichtbare Wand, wo das tiefe Wasser ist. Und ich hab mich gefragt, was ist, also ihr habt, kann es sein, dass ihr einfach keine logisch verfliegende Wesen drin habt?

Kai

Ja, genau, genau. Also indirekt gibt es das zum Beispiel, zum Beispiel, wenn du das Ding siehst, der Spieler, der hat so kleine Wassereffekte an den Füßen und die Mücke auf der rechten Seite nicht. Und andere Gegner haben aber diese Wassereffekte, wenn sie im Wasser stehen. Also indirekt haben wir zumindest eine Abfrage, bist du ein fliegender Gegner? Aber die nutzen wir gerade nur für diesen Wassereffekt.

Und warum sie dort jetzt nicht rüberkommt, ist im Großen und Ganzen, weil wir ein sehr einheitliches System haben, was Kollision angeht. Und alle unsere Aktoren, egal ob sie fliegen oder was auch immer sie tun, sie sind einfach quasi auf Dynamic, so heißt der Layer bei uns. Und Dynamic kollidiert einfach immer mit Small Obstacles und das Wasser ist in dem Fall ein Small Obstacle.

Das heißt, man könnte immer ein Projektil drüber schießen, aber du kannst nicht drüber laufen und weil alles dasselbe System verwendet, kommt auch die Blutmücke nicht rüber.

Simon

Ihr könntet die Blutmücke, wenn die Angriffsanimation fertig ist, sie austauschen gegen ein Projektil, was aussieht wie die Blutmücke und dann, wenn sie nichts getroffen hat, wieder zurück verwandeln.

Kai

Ja, es gibt immer Tricks und Wege auf jeden Fall, aber wir haben uns ein bisschen tricky geworden für diesen einen Angriff. Das sind, glaube ich, auch die einzigen Gegner, die man zum Spiel fliegen können. Und entsprechend, ja.

Simon

Und es fällt aber auch nicht oft auf, muss ich auch sagen. Also das war so eine lustige Situation. Deswegen habe ich sie als GIF abgespeichert. Aber ansonsten war es eigentlich nie ein Problem.

Kai

Ich muss auch zugeben, als ich das GIF gerade gesehen habe, war so, bevor du die Frage gestellt hast, ob eigentlich die Frage ist, warum das Pathfinding nicht rüberfindet. Und mir ist gar nicht in den Sinn gekommen, dass sie eigentlich fliegt und einfach rüberfliegen könnte.

Simon

Ja.

Kai

Ja, weil ich glaube, ich selber schon so in diesem automatischen Modus drin bin, das so anzunehmen.

Simon

Das Pathfinding funktioniert wunderbar. Es müsste jetzt wahrscheinlich, ja, wie würde man das machen? Müsste man dann sozusagen zwei Pathfinding-Layer haben, eins für fliegende Objekte?

Kai

Und das wollten wir halt auch nicht machen, dass es da noch irgendwie für diesen einen Gegner irgendwie Zusatz Pass-Dings gibt.

Was man sonst hätte vielleicht auch machen können, dass man sagt, alles klar, du willst zwar von A nach B, aber während du im Angriff bist, deaktivieren wir zum Beispiel, das Pathfinding und wenn der Angriff dann durch ist und ich befinde mich auf dem Wasser, würde er feststellen, alles klar, ich befinde mich gerade irgendwo, wo ich nicht hin darf und dort ist mein Ziel und der kürzeste Fahrt von dorthin zu meinem Ziel wäre dann im Großen und Ganzen auch der korrekte Pfad eigentlich.

Ja, aber wie gesagt, das war einfach ein bisschen zu viel.

Simon

Ja, es ist wieder ein interessanter Edge-Kids, weil man könnte ja auch sagen, naja, fliegende Viechis, die können einfach überall hin, die brauchen gar keine Navigation, aber das wäre ja auch ein Problem, weil die sollen ja nicht durch Mauern fliegen oder sowas.

Kai

Genau, oder durch Bäume oder auf Höhen-Ebene könnte man vielleicht wieder überlegen, Aber ja, das hätte viel Probleme gehabt.

Simon

Genau, Höhenebenen sind auch eine spannende Sache, weil da habe ich mich auch gefahren, wie ihr das detektet, weil es gibt manchmal die Situation, dass man steht vor einer kleinen Mauer, einer Erhöhung, die so hüfthoch ist und da liegt oben was drauf. Da kann ich jetzt aber nicht einfach hinlaufen, weil ich kann da nicht hochklettern. Und ich glaube, wenn dort ein Objekt liegt, kann ich das auch nicht nehmen. Mein Charakter muss immer zu dem Objekt hinlaufen erst.

Ich habe hier so ein Beispiel. Ich erinnere mich jetzt gerade gar nicht mehr ganz genau, wie es im Spiel war. Aber ich glaube, ich kann, also man sieht dort den Charakter, steht vor einer kleinen Mauer oder... Eine Art Podest und auf dem Podest liegen Goldmünzen rum und die kann ich so nicht einsammeln.

Also es sieht so aus, als könnte ich jetzt die Hand einfach ausstrecken und das nehmen, aber rein von der Logik her ist es so, nee, nee, du stehst auf einem Boden und das Gold liegt auf dem kleinen Podest, was ungefähr einen halben Meter hoch ist und deswegen, wenn du da nicht hinläufst, dann kannst du das nicht nehmen. Das ist so, oder?

Kai

Das ist eine gute Frage gerade an der Stelle. Ich bin mir gerade nicht ganz sicher, wenn ich ganz ehrlich bin. Im Großen und Ganzen haben wir keine wirkliche konkrete Logik, was Höhenebenen angeht. Also weder das Objekt noch der Spieler weiß, ob ich auf Höhenebene 0 oder 1 oder 3 bin oder sonst irgendwas. Sondern da ist einfach nur ein Collider dazwischen. Und deswegen kannst du physisch steil zum Beispiel einfach nicht ran.

Simon

Ach, da ist ...

Kai

Okay. Genau, also warum du nicht näher rankommst, ist im Endeffekt diese Steintextur. Das ist quasi im Endeffekt eine Collider, ein Collision. Ein Small Obstacle, ein normales Obstacle wahrscheinlich. Bin mir gerade nicht ganz sicher. Aber auf jeden Fall kannst du halt einfach physisch irgendwann nicht mehr näher ran, weil dann der Collider von diesem Abgrund dort ist. Warum du jetzt mit dem Objekt nicht interagierst, bin ich mir gerade nicht ganz sicher.

Ich glaube eigentlich, wenn du nah genug rankommen würdest, könntest du damit interagieren, weil du auch diesen Indikator der offenen Hand hast. Das heißt, er erkennt ja, dort ist ein Objekt, das ich nehmen könnte. Ich bin nur zu weit weg. Und ich glaube, da ist einfach ein Abstandskriterium drin. und da kommt man deswegen gerade nicht dran vorbei.

Was wir aber haben, ist zum Beispiel, wenn du, wir haben ja Häuser und wenn du, und in den Häusern sind zum Beispiel auch Objekte, die du nehmen könntest. Und möchtest ja aber zum Beispiel erstens nicht, wenn du mit der Hand über ein Hausdach haverst und du nicht drin bist, dass plötzlich du schon siehst, ah, da ist irgendwas zu nehmen. Oder auch nicht, dass du durch Wände etwas nehmen können sollst.

Dort haben wir ein Extrasystem, das definiert, bist du in einem Haus oder bist du nicht in einem Haus? Und das ist ein Gegenstand, mit dem ich interagieren möchte, in einem Haus oder nicht in einem Haus oder im selben Haus. Und da haben wir auf jeden Fall Abfragen drin, dass das nicht möglich ist.

Simon

Ah, okay. Ja, ich erinnere mich, ich habe einmal was gecheased und zwar war hinter einer Ruinenmauer eine, jetzt überlege ich, war es eine Falltür oder war es irgendwie ein kleiner Schrank oder so? Auf jeden Fall konnte ich durch die Mauer damit interagieren. Und das heißt, es war nur distanzbasiert und ich habe mich nicht in einem Haus befunden, weil es halt eine Ruine ist, die gilt halt nicht als Haus. ist, ne?

Kai

Genau, genau. Und ich hab grad nebenbei mal getestet, tatsächlich ist es hier nur Distanzabfrage.

Simon

Okay.

Kai

Das heißt, wenn du näher genug rankommen würdest, wenn der Collider ein bisschen schmaler wäre, könntest du es aufsammeln.

Simon

Ah, interessant. Genau, meine eigentliche Frage war so ein bisschen, gibt's überhaupt so Höhen Ebenen? Weil man hat also nicht nur manchmal so Podeste, auf die man dann auch spielt, also wenn man irgendwie einen Weg findet, hochlaufen kann. Es gibt ja richtige, Bergpassagen, wo man halt wie in Serpentinen hochlaufen kann. Und da habe ich mich halt auch gefragt, wie funktioniert das da mit den Höhenebenen?

Also die sind halt visuell, sieht das halt so aus, als wären es Höhenebenen, aber ist ja ein 2D-Spiel, da gibt es ja keine richtigen Höhen.

Kai

Hätten wir sehr gerne gehabt, also richtige Höhenebenen, auch so ein bisschen mit Logik, zum Beispiel, dass man auch hinter eine Höhenebene laufen kann. Das geht ja momentan bei uns im Großen und Ganzen auch nicht. Das heißt, du hast da eine Collision und kommst nicht dahinter, weil sonst würdest du für denselben Pixelpunkt in der Welt einen Zustand haben für deinen Charakter, wo er auf der Höhenebene und hinter der Höhenebene liegt.

Also brauchen wir auch ein System, um zu detekten, auf welcher Höhenebene befinde ich mich eigentlich. Wenn ich zum Beispiel auf der höheren Ebene bin, ich bin auf dieser Position, möchte ich ja von oben nicht nach unten gehen können. Und wenn ich auf der unteren Höhenebene auf derselben Position bin, möchte ich ja hinter der, also man hat pro Pixel in der Welt dann mehrere Datenpunkte, sage ich mal, ob davor oder dahinter oder Höhenebene 1 oder Höhenebene 2.

Und sowas haben wir gar nicht. Also sprich, was du auch meintest, alle unsere Höhenebenen sehen nur rein optisch zufällig, in Anführungszeichen, sind natürlich so designt, so aus, als ob es Höhenebenen gibt, aber rein logisch-technisch haben wir so etwas nicht.

Simon

Und jetzt macht das auch Sinn, weil ich habe mich auch gefragt, du kannst nämlich von, natürlich von überall Pfeile abschießen und so, und du hast eben gesagt, das Projektil einfach, dass diese ganzen Collider, nee, warte mal, die können ja die Collider nicht einfach ignorieren, weil irgendwie ein Pfeil muss ja auch in der Mauer stecken bleiben oder dann geblockt werden und so.

Aber ich kann ja von, wenn ich irgendwie auf diesem Podest, was ich eben gemeint habe, schon stehe, kann ich einen Pfeil nach unten schießen. Obwohl ja das Podest auch irgendwie einen Kollider hat. Du hast eben gemeint, dass da ein Kollider ist. Wie ist das denn dann mit Pfeilen? Gibt es verschiedene Arten von Collidern bei euch?

Kai

Genau, genau. Wir haben zwei verschiedene Arten. Das sind Small Obstacles und Obstacles. Small Obstacles kann man sich vorstellen, also in der Vorstellung sind sie sozusagen hüfthoch und du kannst mit Projektilen drüber schießen. Zum Beispiel ist das Wasser ein Small Obstacle. Und dann gibt es Obstacles, da kann keine Projektile durch und das sind zum Beispiel halt Mauern, Bände, Berge und so weiter und so fort.

Und da kann dann auch ein Projektil nicht drüber fliegen. An der Stelle, wo du gerade den Screenshot da gemacht hast, bin ich mir nicht sicher, es kann sein, dass du dort nicht hoch- oder runterschießen kannst, obwohl es eigentlich logisch-technisch möglich sein können sollte, so aus der Spielweltlogik heraus.

Und da hatten wir auch einige Leute, die das ein bisschen kritisiert haben, dass sie sagen, sie finden das nicht sehr schön, dass man nicht über Höhenebenen hinweg irgendetwas schießen kann. Kommt da gleich auf die konkreten Höhenebene an. Manche gehen vielleicht, müsste ich nachgucken.

Simon

Okay, na gut, aber das, was man mitnehmen kann, dass ihr jetzt keine spezifischen, Höhenebenen irgendwie definiert habt. Das ist eigentlich eine ganz interessante Situation, weil diese Frage, finde ich, stellt sich halt so ein bisschen, wenn man das so sieht.

Kai

Wir hatten mal einen Prototyp, wo wir, weil es gibt auch coole grafische Effekte, die man mitmachen kann oder auch du kannst von oben nach unten schießen, aber nicht von unten nach oben. Aber das war sehr tricky, weil musste man, weil du musst dann ja quasi es rekursiv angenommen, du hast mehrere Höhenebenen. Erstens heißt das ja irgendwann musst du eine Transition haben von einer zur anderen.

Was macht man dann? Kann ich dann hoch oder runter schießen in dieser Transition Area, was passiert, wenn ich von unten nach oben schieße und andersrum, dann muss das der definiert werden, wir haben das über einen Collider gemacht, das heißt, es wurde ein Collider geplaced, der sagt, du bist jetzt auf Höhenebene 1. Aber wenn du auf Höhenebene 1 bist, ist der physische Collider zum Klippenrand ein anderer, als wenn du auf der Höhenebene 0 bist.

Also bist du plötzlich an einem Punkt, wo du verschiedene Kollisionsarten brauchst, je nachdem, auf welcher Höhenebene ich stehe. Und das hat alles sehr, sehr kompliziert gemacht und auch alles zu definieren wäre sehr viel Aufwand gewesen.

Simon

Ja, mir fällt es auch gerade schwer, das mir vorzustellen. Das kann ich mir sehr gut vorstellen, dass das alles...

Kai

Kann man Bildschirmübertragung machen, ja.

Simon

Aber ist okay. Wir können, weiß ich nicht, wollen wir eine kurze Pinkelpause machen?

Kai

Das können wir gerne machen.

Simon

Kurze Pause. Five minutes later.

Kai

Bei dir auch?

Simon

Ja, ja, ja, auf jeden Fall. Ich bin gespannt. Ich hoffe, dass es Feedback gibt, ob es den Leuten zu tief reingeht oder nicht. Aber ich habe schon ein paar Folgen so aufgenommen. Bisher war das Feedback eigentlich immer ganz okay. Aber vielleicht traue ich dir da auch nichts zu sagen.

Kai

Ich glaube, vieles ist auch echt schwer, sich so ein bisschen, was du auch eben meintest, mit den Höhenebenen sich vorzustellen, wenn man nur Worte verwendet. Und oft ist es einfach leichter so, ja, hier, guck mal so und dann klappt das irgendwie besser. Aber ja, und dann natürlich auch spezifisch so mit Texturen und Baking, Pivot, bla, bla, bla. Wenn man da thematisch nicht drin ist, kann es recht schnell tricky werden.

Simon

Genau, und das ist nämlich das Punkt. Ich merke das halt beim, es gibt den Gameda für die Platte Podcast und da merke ich auch, dass ich teilweise so ein bisschen abschweife, wenn ich zuhöre, wenn es mich nicht so interessiert. Aber dafür, wenn es dann halt mal ein Thema ist, wo man sich auch mal mit beschäftigt hat, ist es dann doppelt super und das wird halt nirgendwo anders besprochen und das ist dann ganz toll.

Und gerade, ich kann mir schon vorstellen, dass Leute auch Drova angucken und denken so, wir haben die das wohl gemacht so oder selbst vielleicht auch mal an sowas gearbeitet haben und dann dass das einfach schön ist, so mal so einen Einblick zu bekommen.

Kai

Das ist auch ganz cool, wir streamen ja auch oder ich ja auch viel freitags in der Wicklung von Drova, die anderen natürlich auch, aber die machen auch viel mit anderen Sachen und was ich immer cool finde, sind tatsächlich auch Leute mit konkreten Fragen, die manchmal reinkommen oder mich hinterher auf Discord irgendwie nochmal anschreiben, wie wir bestimmte Sachen gemacht haben, weil es glaube ich echt, was du auch meinst.

Ich habe das Gefühl, es gibt wenig so gute oder advanced auch Informationen, gerade was Unity angeht oder bestimmte Tricks oder wie, was ist ein guter Ansatz für irgendwas. Ja. Und das habe ich auch in Entwicklung von Drover immer wieder gemerkt. Auch zum Beispiel das Pivot-Baking habe ich mir selber ausgedacht. Und cool, so jetzt von dir zu hören, das gibt es tatsächlich so, aber ich bin selber nie darauf gestoßen bis zu dem Zeitpunkt, wo ich es dann irgendwie als Problem so hatte.

Und auch ein paar andere Sachen, die ich so, ja, es, Schade, aber so ist es halt.

Simon

Ich habe mich gerade heute, ich muss mal kurz gucken, heute mit jemandem darüber unterhalten und ich verstehe überhaupt nicht, warum das Pivot Painting heißt. Das gibt es nämlich in Unreal und das gibt es auch für Udini. Ich kann jetzt einfach mal hier so ein kleines Video, hat es keine Relevanz für unser Gespräch. Es steht einfach Pivot Painter da. Man paintet nichts.

Man speichert einfach nur die Pivot-Daten irgendwo ab, damit sich halt ein paar Äste irgendwie oder Pflanzen schön um gewisse Pivots rotieren können, weil das einfach besser aussieht, als wenn man sie einfach nur auf XY irgendwie ein bisschen hin und her wippeln lässt.

Aber ich weiß nicht, warum das Painter heißt. Ich habe mir am Anfang immer vorgestellt, dass man da irgendwas malt, so wie beim wenn man, wie heißt das, habe ich vergessen, wenn du Rigging machst, dann paintest du ja die Waits, Waitpainting. Da paintet man wirklich was.

Kai

Können wir mir vorstellen, also ich habe mir jetzt das Video nicht angeguckt, im Endeffekt speichert man die Informationen, was wahrscheinlich auch mal trotzdem in die Vertex-Daten. Und vielleicht ist das Programm, was die Daten dort reinspeichert, also der Computer, das für dich painted quasi.

Simon

Keine Ahnung. Na gut, aber dann ist ja alles so ein bisschen Painting. Dann gibt es den, weiß ich nicht, dann ist der Garbage Collector oder ein Garbage Manager, der den Memory handelt, auch ein Memory Painter oder so.

Kai

Ja, es war jetzt nur so mein Versuch, das irgendwie.

Simon

Ja, also ich konnte auch nicht rausfinden, warum das Painter heißt. Perplexity AI hat gesagt, das ist nur so ein metaphorischer Name. Was ich aber interessant fand und das ist wieder so ein Ding, Ich habe vor einer Weile mal von Pivot Painter gehört. Ich habe es selbst tatsächlich noch nie so richtig benutzt. Also zumindest das Pivot Painter Tool ist offizielle von Unreal. Und verlinke ich euch auch eine Dokumentation. Und was ich gar nicht wusste, es gibt nämlich eine 2.0 Version davon.

Und da benutzen sie Texturen, um die Pivot Daten zu speichern. Sie speichern das Data nicht mehr in dem Mech, in den Vertex Daten ab. Und was ich leider nicht herausfinden konnte, ist, warum sie das machen. Weil ich hätte jetzt gesagt, eigentlich wäre es doch immer günstiger, das einfach in die Vertex-Daten zu speichern, selbst bei komplexeren Bäumen.

Ich habe die Dokumentation anguckt, ich habe auch nochmal Perplexity AI gefragt und geguckt, was da, also wenn ihr das nicht kennt, dieses Perplexity AI, ich benutze das nicht so oft, aber bei diesen Fragen mache ich das manchmal ganz gern, weil das gibt dann so einen Text aus, AI generiert natürlich. Aber das Gute ist, das liefert immer Quellen mit dazu. Und dann klicke ich einfach auf die Quellen. Das ist mancher besser, als wenn man so googelt.

Auch da habe ich dann leider nichts gefunden, warum jetzt ganz konkret Texturen besser sind als würdiges Daten. Wenn ihr also euch da auskennt, könnt ihr gerne mal in den Thread schreiben bei uns auf dem Discord. Da gibt es ja für jede Folge einen Thread. Und da Feedback da lassen. Das würde mich wirklich mal interessieren, was die Vorteile dabei sind. Mal etwas Lightweight wieder. mal etwas rausgezoomt. Ihr entwickelt ja mit Unity.

Und ich hab mir schon eine Frage selbst beantwortet, weil ihr habt mit 2020 angefangen, mit der Unity-Version, da hab ich gedacht, so, ah, habt ihr irgendwann gewechselt und dann tatsächlich wurde in 2022 auf eine neuere Version abgegradet. Jetzt seid ihr mit dem Spiel durch und es gab ja noch dieses Unity-Desaster mittendrin. Und da stellt sich natürlich die Frage, habt ihr da ...

Ach, genau, ihr habt nämlich, kann ich auch verlinken, ihr habt nämlich auf Twitter, beziehungsweise X, auch ein Statement gemacht dazu damals. Ein richtiges eigenes Bild gemacht mit einem Text drauf, wo im Grunde draufsteht, ja, wir sind jetzt zu tief drin im Projekt, wir können jetzt nicht wechseln. Aber, genau, es ist ein bisschen offen, Weil auf dem Bild steht, solange Unity mit den derzeitigen Plänen weiterführen will, werden wir nach Alternativen gucken.

Jetzt haben sie ihre Pläne ja geändert, sie haben ja zurückgerudert. Was ist denn so jetzt die Lehre daraus? Habt ihr vielleicht auch mal drüber überlegt, ob man irgendwie Godot wechselt oder so? oder?

Kai

Also so wie es da immer noch steht, we will be looking for features, das hatten wir auch ein bisschen gemacht, also wir haben dann in Godot ein bisschen reingeschaut, eher so ein bisschen noch aus Neugier einfach so ein bisschen, auch so ein bisschen unseren Publisher gefragt, hey, wie ist das eigentlich, habt ihr so Erfahrungen mit anderen Engines, läuft das gut, läuft das schlecht? Und entsprechend waren wir jetzt erstmal vom Mindset da schon drauf offen.

Wir haben damals auch initial viel angefangen mit Mono, nennt sich das, oder XNA, das sind so Frameworks, keine ganzen Engines, die in C-Sharp sind, mit denen wir auch viel Spaß hatten und Und zum Glück war es dann noch weit weg, dass wir jetzt wirklich sagen, alles klar, wir machen das jetzt oder so. Zumindest haben wir die Fühler ein bisschen ausgestreckt, aber auch im Endeffekt haben sie es dann auch zurückgenommen. Und deswegen bleiben wir jetzt auf jeden Fall auch erstmal bei Unity.

Aber natürlich, dadurch, dass du Software von jemand anderes verwendest, der da so, sag ich mal, volle Kontrolle mehr oder weniger drüber hat, ist man dann natürlich dann auch irgendwo, gefangen ist das falsche Wort, aber irgendwie auch schon. Du weißt, was ich meine, einfach so muss man aufpassen. Und... Ja, erst mal hoffen wir so, dass es erst mal so positiv für uns weiter bleibt.

Simon

Also ihr macht das mal bei Unity.

Kai

Genau, genau.

Simon

Na, die Chasing Carrots haben halt gewechselt. Die haben für Hearts of Torment, haben sie jetzt Godot benutzt. Das hatte gar nichts damit zu tun mit diesem Debakel. Das war nämlich schon davor, haben sie gewechselt. Aber davor gab es auch schon immer Kompatibilitätsprobleme mit irgendwie Software, die da nicht weitergeführt wird. Und dann hast du keinen Codezugriff. gefunden. Das war ein bisschen unangenehm und mit Godot haben sie halt die volle Kontrolle.

Kai

Ich glaube auch Godot wäre das erste, wohin wir nach aktuellem Stand so ein bisschen wechseln würden. Wobei wir da aber auch viel gehört haben, dass gerade Portierung auf gewisse Plattformen, was weiß ich, Nintendo oder sowas, alles noch ein bisschen trickiger sei.

Simon

Ja.

Kai

Also Switch, als jetzt zum Beispiel was mit Unity abgeht. Aber ja, muss man mal auf jeden Fall im Auge behalten.

Simon

Vorhin hattest du übrigens gesagt, dass ihr ein Tool benutzt habe, um diese ganzen Dialogbäume zu gestalten für die ganzen NPCs. Und ich habe zwei Sachen gefunden, einmal Node Canvas und einmal Flow Canvas. Und ich habe mich gefragt, ob eins davon dafür zuständig war.

Kai

Also im Endeffekt ist sowohl Flow Canvas als auch Node Canvas von demselben Macher und ist auch mehr oder weniger das selbe Framework. Ich glaube, Flow Canvas baut auf Node Canvas auf. Das heißt, beides würde ich jetzt einfach unter Node Canvas ein bisschen zusammenfassen.

Simon

Und was macht das nochmal?

Kai

Genau, also Flow Canvas nutzen wir gar nicht so viel, das nutzen wir glaube ich nur für unsere Quests. Im Endeffekt ist unser Quest, wie die so ein bisschen vonstatten geht, wann ein Tagebuch triggert oder wann hast du so ein bisschen weitergeht, das ist so ein Flow Graph quasi.

Das wird darin sozusagen definiert und im Node Canvas, das ist unsere AI, also wie sich unsere Gegner verhalten, das ist eine State Machine und auch unser Dialogsystem selbst ist auch über Node Canvas und hat dann so Dialogbäume und so weiter. Also im Endeffekt ist es ein generisches Framework, einfach um Graphen zu authern.

Simon

Zu bestellen. So wie man das jetzt auch, diese ganzen Node-Editoren kennt, wie man Materialien in Unreal baut und so. Achso, das heißt, eure KI ist gar nicht in C-Sharp geschrieben oder so, sondern ist alles mit diesem … Genau.

Kai

Genau, genau. Also natürlich gibt es dann, jeder Knoten repräsentiert sozusagen eine C-Sharp-Klasse, die dann irgendwas Gewisses tut oder sowas. Und wir haben auch eigene Knoten hinzugefügt, die eigene Dinge tun, aber im großen Ganzen werden die dann zusammengestöpselt über das Grafensystem.

Simon

Ah, okay. Aha. Genau, ich hatte dann auch gesehen, Odin-Inspektor, das haben wir schon mal gehabt. Ich habe leider vergessen, was das Ding eigentlich nochmal macht, aber wir haben es schon mal erwähnt hier im Podcast.

Kai

Das ist auch ein Unity-Ding, also im Endeffekt im Unity hast du ja so einen kleinen Inspektor, wenn du ein Objekt anklickst, hast du so einen Inspektor, der sagt, jo, es hat folgende Eigenschaften, es ist auf folgender Position, bla bla bla. Und was Odin eigentlich nur macht, ist das Ding auf Steroide setzen, quasi.

Es ist sozusagen, es macht seinen eigenen Inspektor, den man deutlich einfacher editieren kann und der von, auch ohne, dass man ihn editiert, deutlich schöner und sinnvoller und übersichtlicher gestaltet, als was Unity bei Default macht. Genau, mehr macht das eigentlich nicht. Einfach den Inspektor schöner und gibt uns mehr Macht, den Inspektor auch zu editieren.

Simon

Ah, okay. Dann Unitask. Also ich liste das hier gerade so ein bisschen auf für Leute, die da interessiert sind, weil es kann ja mancher spannend sein, was ihr für Tools benutzt habt. Und diese Tools übrigens, die habe ich aus den Credits. In den Credits sind die ganzen aufgelistet. Und da gibt es noch eins. Unitask. Provide an efficient allocation free async arrayed integration for Unity.

Kai

Ja, auf jeden Fall sehr, sehr geil. hätte ich das früher gekannt, ich hätte es am liebsten für alle meine Projekte, die ich damals verwendet hätte, schon verwenden wollen würden. Johannes hat das per Zufall so ein bisschen entdeckt. Und im Großen und Ganzen ist das ein kleines Framework, womit man asynchrone Methoden erzeugt, die dann zum späteren Zeitpunkt etwas tun. Ist jetzt ein bisschen erstmal abstrakter. Das gibt es von Unity von sich aus auch auf zwei Formen.

Einmal als Koroutinen und einmal einfach nur als Async-Await. Und Coroutine sind sehr performance-unschön in Unity, weil eigentlich jeder Aufruf von, hey, warte mal einen Frame oder sowas erzeugt dein Garbage. Jetzt sind wir wieder beim Garbage-Kollektor. Und ja, genau. Und Async-Await, soweit ich gerade das richtig im Kopf habe, ist in Unity oder genau, ist in Unity eigentlich genauso implementiert wie Coroutine. Unity hat ja so ein bisschen eine eigene Implementierung von seinem C-Sharp.

Das ist ja kein echt richtiges C-Sharp. Dort ist Async-Await ein bisschen anders aufgebaut. Und Unitask macht im Endeffekt, gibt ein Framework an, wo man Methoden genauso aufruft wie mit Async Await, aber ohne, dass Garbage erzeugt wird und was viel so ein bisschen weg abstrahiert. Ja, und ist dadurch einfach sehr schön zu verwenden für asynchrone Calls.

Simon

Genau, für alle, die jetzt sich denken, so hä, was soll das hier? Es ist halt so, wenn man ein Skript hätte und dort eine kleine ... Schleife macht zum Beispiel, die die ganze Zeit weiterläuft und die nie endet, dann würde das gesamte Spiel einfach blockieren. Und diese Schleife könnte sowas sein wie, ich weiß nicht, warte mal auf eine ganz bestimmte Sache, die im Spiel passiert. Und nur dann soll irgendwas ausgeführt werden.

Und das ist natürlich ein Problem, weil diese Schleife, die muss ja irgendwann nochmal wieder verlassen werden. Ja, genau. Und dafür gibt's diese, ich kenn das als Yield. Da schreibt man dann so rein Yield. Und das bedeutet, dass die Schleife einmal ausgeführt wird. Es wird gesehen, ach guck, diese Condition ist noch nicht erfüllt, auf die ich jetzt die ganze Zeit erwarte. Und dann kann der Rest des Spiels erst mal weitermachen und im nächsten Frame

gucke ich einfach wieder da rein und führe die Schleife aus. Ist das so grob?

Kai

Genau, genau. Das ist eigentlich genau so. So nutzen wir das. So ist auch der Anwendungsfall häufig.

Simon

Genau, dass mal kleine Skripte hat, das fühlt sich so ein bisschen an, wie halt, dass das alles parallel läuft.

Kai

Genau, genau, genau.

Simon

Genau. Aber ja, okay, das heißt, dieses Unitask ist einfach cool, weil es performanter ist.

Kai

Genau. Und sehr schön anzuwenden und rechts eigentlich auch intuitiv ist und sehr elegant. So aus programmiertechnischer Sicht finde ich das.

Simon

Okay. Dann habt ihr noch einen Hap-Profiler, der wahrscheinlich dazu da ist, irgendwie den Speicher zu analysieren und was worum liegt und so. Aber es gibt eigentlich die Debugger-Tools von Unity, die schon mit sind. Das ist eine Sache, die mag ich sehr gerne in Unity. Die sind nämlich ziemlich cool, sehr einfach erreichbar und laufen sogar on the fly mit. Kann man einfach während das Spiel schon läuft, kann man sagen,

hier, lass mal Performance checken. Das ist in Unreal immer ein bisschen hakeliger. Und da habe ich mich gefragt, so warum ... Also der muss dann ja richtig, richtig cool sein, damit er den eigentlich Eingebauten nicht benutzt.

Kai

Also wir haben den Eingebauten trotzdem verwendet. Also es ist nicht so, dass das den jetzt irgendwie replaced hat. Wenn ich mich gerade nicht täusche, sagt sogar, der Memory-Profiler, den wir dort eingebaut haben, jo, ich bin so ein bisschen deprecated, nutz mal den von Unity. Aber irgendwie, er war sehr schnell, also wir haben vor allem den Memory-Profiler viel genutzt und der braucht sehr lange.

Zum Beispiel liest er den kompletten Speicher aus. Und wenn ein Spiel im Editor 8 GB groß ist, also mit Editor-Kram, dann hast du einen Memory-Print von, keine Ahnung, deutlich mehr. Und das hat es schnell so ein bisschen überschossen und das war irgendwie langsam. Und wenn du Dinge angeklickt hast, dann hat er mir ein komplettes Projekt durchsucht, dann musst du zwei Minuten warten, dass du wieder was anklicken kannst.

Und irgendwie hat sich das super detailliert, aber in seiner Anwendungsform irgendwie so ein bisschen clunky. Und der Heat-Profiler, ich weiß nicht genau, was der anders macht, der hat einfach, du klickst ein Objekt an, zack, bis da. Und die Ansicht war einfach ein bisschen anders. Du kannst nach bestimmten Sonder-Cases, zum Beispiel Empty-Shell-Objekten haben wir viel gesucht, das ist jetzt auch wieder recht technisch, um einfach herauszufinden, wo vielleicht Speicher hängen bleibt.

Und im Endeffekt war es für uns einfach ein zusätzliches Tool zum Memory-Profiler und von den ganzen Profilern generell von Unity. Ich glaube, es kommt auch von Unity, wenn ich mich gerade nicht täusche und nicht von irgendjemand anders. Und ja, einfach ein zusätzliches Tool, was einfach eine andere Ansicht und ein bisschen schöneren Workflow für uns gegeben hatte.

Simon

Na, es stimmt schon, was du sagst, weil ich habe tatsächlich ein Zitat gefunden, was, genau, was hier, ich verlinke das auch mal, die GitHub-Seite, da steht nämlich, wir spulen mal ein Jahr vor, Unity Technologies hat angekündigt, dass sie auch eine Memory Profiler arbeiten und this disrupted my plans for heap Profiler. Also, ja, das scheint eine Unity-unabhängige Person zu sein, die tatsächlich das Ding...

Und dann steht halt hier, ja, und jetzt ist es einfach nicht mehr kostentragend sozusagen, dass ich jetzt hier ganz viel Zeit rein rein investiere, wenn Unity da eh irgendwas macht. Ich weiß aber nicht. Vielleicht, ich meine, wir kennen Unity, da wird ja auch gern mal was einfach dann deprecated und nicht mehr weiterentwickelt oder kommt dann doch nicht, wie es angekündigt war oder so. vielleicht lohnt es sich trotzdem noch dieses Ding weiter zu.

Genau, hier vor zwei Monaten steht hier auf GitHub, dass die, genau, die Version von diesem Programm wurde vor zwei Monaten abgegradet. Also anscheinend gibt es da trotzdem noch Support.

Kai

Ja, also wie gesagt, ich finde es auch ein sehr schönes Tool und ja, wenn ihr euer Spiel so ein bisschen profilen wollt oder nach Speicher-Lags oder sowas suchen wollt, ist das auf jeden Fall eine Empfehlung von mir oder von uns.

Simon

Genau, und das letzte Tool, was ich noch aufgelistet habe, ist der Asset Usage Detector. Da kann man wahrscheinlich einfach feststellen, ob Asset überhaupt benutzt wird.

Kai

Also im Endeffekt kannst du einen Rechtsklick auf irgendein Asset machen und dann suchen wir Referenzen. Das hat Unity auch von sich aus, aber irgendwie findet er gefühlt nur eine Richtung. Also entweder, ich weiß gar nicht, welche Richtung, ich habe es lange nicht verwendet, wer verwendet mich oder von wem werde ich verwendet, aber nicht beides. Und der Asset Usage Detector durchsucht nicht nur auf Asset-Ebene, sondern kann auch Szenen durchsuchen, ist generell auch recht flott.

Recht zuverlässig. Du kannst ja ein bisschen konfigurieren, wie du wann was und wie viel Tiefe möchtest du suchen und so weiter. Und das war einfach für uns hilfreich, um, was weiß ich, da ist ein Acid, wir denken, es wird nicht mehr verwendet, lassen wir kurz gucken, wird es wirklich nicht verwendet, dann können wir es löschen oder sowas. Das, genau. Auch ein schönes Tool.

Simon

Ja, okay. So, das bringt vielleicht jetzt anderen Leuten noch was, die auch coole Tools suchen. Ihr habt aber nicht nur Tools benutzt, sondern auch welche selbst entwickelt.

Kai

Ziemlich viele.

Simon

Ja, was sind denn so die Top-3- Tools?

Kai

Also, kommt wahrscheinlich so ein bisschen drauf an, wen du aus dem Team fragst. Für unsere Level-Designer haben wir, ich habe es ein Level-Design-Toolbox genannt, gibt es jetzt auch nicht nach außen hin oder sowas, womit man zum Beispiel in diesen Boden reinzeichnen kann, also das Texture-Splitting.

Du sagst, hey, hier male ich jetzt Steine rein, hier male ich jetzt Erde rein, hier male ich jetzt Sand rein und sowas, was dann auch diese Meshes quasi auf Vertex-Ebene sozusagen bemalt, damit sie die richtigen Vertex-Daten haben, damit es dann auch hinterher schön dargestellt wird und über das Tool kann man aber auch zum Beispiel einzelne Objekte platzieren.

Bei Unity von sich heraus kann tatsächlich, in der Regel nimmst du ein Prefab und hast ein Projekt an sich, ziehst es in die Szene und das machst du dann, bis deine Welt platziert ist. Und das ist teilweise einfach sehr nervig. Und da haben wir ein kleines Tool gemacht, wo du quasi eine kleine View hast von ganz vielen Prefabs. Du wählst irgendjemand an und dann kannst du einfach Linksklick gedrückt halten, malst einfach in die Szene und platzierst ganz viel davon.

Und dann kannst du ja auch mit dem Rechtsklick wieder löschen oder du kannst einen gewissen Radius angeben oder sagen, ein paar Prozentsatz, von denen ich place, werden auch automatisch geflippt oder genau. Das ist auf jeden Fall ein großes Ding.

Simon

Sowas kennt man ja vor allem, wenn man so Gras in Szenen painted. Da hat man wie so ein Brush und dann zieht man einmal da rum und dann werden, ganz viele kleine Grasbüschel platziert.

Kai

Und sonst, was für viel, wir haben ein eigenes LOCA-System, also wie unser Spiel übersetzt wird in verschiedenen Sprachen. Da haben wir ein eigenes Dateiformat, sag ich mal.

Da haben wir ein kleines Tool, was mittlerweile, vor allem im Nachhinein gern verwendet wird, um einfach zu sagen, hey, Es gab zum Beispiel einen Rechtschreibfehler, da steht jetzt höhere statt höhere und dann kannst du einfach höhere eintippen und dann suchst du so eine ganz loka Datei und sagst dann alles klar, hier ist das, das ist der Key und so weiter und kannst auch dort direkt vor Ort editieren.

Das war ganz praktisch. Ich würde jetzt nicht sagen, das war das Größte, aber war auf jeden Fall auch nochmal hilfreich.

Dann haben wir einen object bookmarker das ist so ein kleines zusätzliches fenster für unity, normalerweise hat man diese projekt an sich das ist einfach die eins zu eins die ordnerstruktur verfestplatte aber manchmal möchtest du zum beispiel verschiedene objekte aus verschiedenen ordnern in einer gemeinsamen in einem virtuellen ordner sozusagen haben im endeffekt ist das so eine art system womit wir eigene virtuelle ordner machen können die so nicht existieren aber so wirken als ob sie,

da sind. Ja, und dann ganz viel Kleinigkeiten irgendwie zum Beispiel, wenn ich irgendwas selektiere und dann selektiere ich was anderes und dann möchte ich eigentlich am liebsten zurück zu meiner alten Selektion, dann haben wir einen kleinen Button eingebaut und dann klickst du Back und dann gehst du zurück zu einer alten Selektion, aber es sind so ganz viel Kleinigkeiten. Von diesen Kleinigkeiten haben wir einfach sehr, sehr viel.

Simon

Okay, das freut mich zu hören, weil ich bin ein großer Fan von guten Tools und guten Workflows. Eine Frage, die ich, ich bin ein bisschen verwundert, dass ihr so ein Terrain-System selbst schreiben musstet. Ich hätte jetzt schon gedacht, dass Unity da was mitbringt irgendwie. Also gerade so verschiedene Texturen ineinanderblenden ist jetzt ja wirklich so ein Standardding.

Kai

Ich glaube, also es gibt es auch, nennt sich einfach Terrain, Editor, keine Ahnung. Aber es ist halt erstens auf 3D ausgelegt, das heißt, du hast dann auf jeden Fall auch immer Koordinaten, die du an sich nicht brauchst. Damals konnte man es auch nicht auf beliebenden Achsen drehen, ich glaube, das geht mittlerweile. Du hattest immer dieses Mesh auf der X-Z-Achse. Unser Spiel befindet sich aber auf der XY-Achse, zumindest als wir damals angefangen haben.

Und damals konnte man, glaube ich, dieses Mesh sozusagen nicht rotieren, nicht drehen. Es musste immer auf der XY-Achse liegen. Mittlerweile geht es, glaube ich, anders, aber dann haben wir es auch nicht mehr verwendet. Und zusätzlich der Spezialfall ist halt dieses Textures Plattling, was wir implementiert haben, versucht halt pixelgetreu zu bleiben.

Und das Terrain-Mesh von Unity, du kannst ja auch Dinge mischen, aber irgendwie hast du nicht so eine richtige Kontrolle, wie und wann werden sie gemischt, also die verschiedenen Splits sozusagen und deswegen haben wir uns dazu entschieden, ein eigenes zu machen, auch weil es sich dann angeboten hat, es in unser Chunking System vernünftig einzufügen.

Das Terrar ist genauso groß wie ein Chunk. In Unity ist das glaube ich immer, also die können das in sich auch irgendwie streamen, aber ja, es hat sich für uns einfach irgendwie sinnvoller angefühlt, das selber zu machen.

Simon

Aber das ist ja schon interessant, dass ihr so viele Tools, also das haben wir in dem anderen Podcast schon ausgearbeitet, dass ihr ja vorher nicht viel Erfahrung hattet in Spielentwicklung. Ihr habt ein paar kleinere Projekte gemacht und ihr habt ja auch Informatik studiert, das heißt, da war schon eine ganze Menge Knowledge da, aber jetzt nicht spezifische Erfahrungen mit, ja, wie mache ich ein Spiel?

Und meine erste, ja, also mein, also ich habe so viel Respekt vor diesen ganzen Sachen, dass meine Herangehensweise Also wäre okay, entweder benutze ich ein Plugin, was irgendwer gemacht hat, oder ich muss mein Spiel eben irgendwie anpassen, dass es sich so in die vorhandenen Tools reinarbeitet, weil jetzt neue Tools auch noch zu entwickeln, das ist ja nochmal ein…, Ja, also nochmal ein riesiger Button an Arbeit.

Kai

Man muss auf jeden Fall auch dazu sagen, unsere Tools sind sehr spezifisch auf uns zugeschnitten. Und sie haben auch sehr spezifische Bugs. Also der Workflow ist natürlich so, dass es uns hilft. Aber wir haben mittlerweile auch gelernt, also unsere Tools sind alle so 80 Prozent fertig, vielleicht manchmal sogar weniger. Sie tun so, was sie wollen, aber eigentlich können wir sie noch viel krasser und geiler machen. Und für sowas sind dann oft Assets vielleicht auch ganz sinnvoll.

Wobei wir aber auch viel die Erfahrung gemacht haben, dass Assets, die man sich kaufen kann, oft eigentlich gar nicht so konkret das tun, was man eigentlich tun möchte, sondern halt so flexibel gehalten sind, dass man zwar seinen Use Case auch machen kann, aber irgendwie nicht ganz so, wie man es gern hätte. Und daher sind viele von unseren Tools, glaube ich, recht flott in der Implementierung gewesen.

Es gibt einzelne Ausnahmen, zum Beispiel diesen Object Placer oder auch dieses Splatplane-Bemalen hat schon so ein bisschen was gedauert, aber, ja, es hat sich für uns einfach ausgezahlt und oft sind die Sachen, die man findet, auch zum Beispiel nicht auf Pixelart ausgelegt oder spezifisch eher 3D statt 2D. Oder, oder, oder. Also irgendwie gab es immer so ein Drawback, wo man gesagt hat, na, irgendwie fühlt es sich jetzt nicht so schön an, das jetzt dafür zu verwenden.

Und wir haben einfach Spaß auch dran, solche Tools zu entwickeln. Irgendwie macht es Spaß, Dinge zu automatisieren oder auch Use Cases festzustellen, hey, alles klar, irgendwie Objekte platzieren Unity sind richtig scheiße, was können wir denn da machen? Und dann hat es klein auch oft angefangen.

Einfach nur so, hey, hier ist eine kleine Liste und dann kannst du ein bisschen was placen, das hatte keine Zusatzfeatures und dann hat Julian zum Beispiel viel damit gearbeitet und meinte so, hey, wäre nicht voll cool, wenn man noch das machen könnte. Wenn man das halt zu dem Zeitpunkt noch dazu gebaut. Also nicht so, dass wir gesagt haben, alles klar, wir bauen jetzt das Tool ein und dann ist es fertig. Es ist über die Zeit des Projektes immer mitgewachsen.

Und auch die Anforderungen haben sich dann immer mal wieder verändert. Und deswegen, all in all, hat es sich nicht nach so viel Aufwand angefühlt, sie einzubauen.

Simon

Vielen Dank. Okay, weil es immer als kleiner Task startet und dann über die Zeit wächst, ja. Und gab es auch mal den Fall, dass ihr, also dass zum Beispiel Level Design hat irgendwie Sachen platziert irgendwie und dann wurde gemerkt, ey, das ist doch alles blöd, wir machen hier ein neues System und das bedeutet aber dann auch, dass die alte Arbeit so ein bisschen verloren ist, weil das neue System irgendwie, weiß ich nicht, die Daten anders abspeichert.

Gab es schon mal auch den Fall, dass dann Sachen nochmal gelöscht werden mussten, größere Teile, weiß ich nicht, der Spielwelt oder so und dann eben in das neue System übertragen werden mussten?

Kai

Also so einen großen Change von irgendeinem System hatten wir, glaube ich, nicht. Aber es gab schon Sachen wie, zum Beispiel wenn man Stühle oder Betten ist ein besseres Beispiel. Wenn man ein Bett in unserer Welt platziert, dann gibt es so ein Default-Exit-Position. Und das ist zum Beispiel immer südlich vom Bett. Aber manche Betten sind halt dort platziert, wo südlich im Bett eine Wand ist.

Und dann gab es zumindest den Case, dass man irgendwie in die Szene nochmal rangehen musste und du müsstest alle Betten nochmal durchgehen, um die Exit-Position nochmal zu setzen. oder vielleicht haben sie sich auch immer mal resetet und dann musste man die nochmal alle setzen. Aber das waren eher so kleinere Subsysteme oder Subdaten, die gesetzt werden mussten und nicht irgendwie alles nochmal fresh oder sowas. Sowas hatten wir nicht.

Da haben wir auch immer sehr früh drauf geachtet, dass wir sagen, alles klar, wir fangen erst an, was weiß ich, alle Routinen von allen NPCs zu definieren, weil wir wissen, das System funktioniert auch halbwegs. Oder wenn es dort vielleicht ein Fragezeichen gab, funktioniert das eigentlich? Dann haben wir erst mal noch ein bisschen gewartet, weil das war auch, ja, wir wollten halt nicht, dass genau so ein Fall mal eintreten würde.

Simon

Aber das ist interessant, genau, Exit Position, also dorthin, wo NPCs aufstehen.

Kai

Genau, oder der Spieler auch selber, genau.

Simon

Genau, das ist übrigens ein guter Punkt. Warum kann man sich hinsetzen auf Stühle?

Kai

Warum nicht? Ja, ja, ich verstehe schon die Frage. Es hat keinen Effekt.

Simon

Oder?

Kai

Genau, nee, es hat keinen Effekt. Im Großen und Ganzen, wir sind ja sehr stark an Gothic inspiriert und in Gothic gibt es sehr viele von solchen Interaktionen. Ich setze mich irgendwo hin oder ich rühre da irgendwie mit dem Summkrautstampfer in diesem Eimer rum oder was auch immer. Es hatte sehr viele so kleine Interaktionen in der Welt, die sich sehr lebendig oder immersiv angefühlt haben.

Und ich finde, es hat ein sehr immersives Gefühl. Du hast ein Lagerfeuer, du hast ein Stuhl, ich setze mich hin und ich chill einfach mal und kann ein bisschen Roleplay damit betreiben. Genau, es hat keinen tieferen Sinn und Zweck, es ist einfach nur schön und NPCs machen das ja auch einfach nur um die Szene aufzulockern, warum dann nicht auch dem Spieler das erlauben zum Beispiel.

Simon

Aber ich kann mich auch hinhocken und das bringt auch nichts.

Kai

Ja genau, es ist so ein bisschen aus WoW inspiriert, da gibt es einen extra Button, der X-Button, um sie auf den Boden zu setzen und irgendwie fühlt sich das einfach immersiv und cool an.

Simon

Ja, aber ich glaube, hier ist es Hocken wirklich, nicht sitzen.

Kai

Ja genau, Nehmen wir uns ein Socken, ja.

Simon

War das mal ein Pickpocket-System, was hätte kommen sollen?

Kai

Nee. Das fand ich ganz witzig, als wir drüber released haben, waren einzelne Leute so, ja, irgendwie hat der mich gesehen, obwohl ich hier gehockt habe. Also manche Leute haben das tatsächlich so als Stealth-System missverstanden, was ich sehr interessant fand. Ja, ja.

Simon

Letzte Interaktion, die mir aufgefallen ist, man kann trinken aus Fässern.

Kai

Hatte lange Zeit keinen Effekt. Entweder mit dem letzten oder vorletzten Patch haben wir aber eingeführt, dass so einen kleinen Gesundheitsspot bekommst und das halte ich ein bisschen. Davor war es auch einfach nur so ein bisschen, ja, sieht ganz cool aus.

Simon

Okay, ähm ... Ich habe in einem, warte, in einem Video was gefunden. Das Video heißt, genau das ist von euch, der 26. DevBlog, da geht es um technische Schuld. Was ist denn technische Schuld?

Kai

Im Endeffekt ist das ein Begriff, der beschreibt, wie sauber die Code-Basis ist, auf der man arbeitet, sage ich mal. Und die technische Schuld steigt dann an, wenn man zum Beispiel quick und dirty irgendeinen Bug fixt. so, hey, irgendwie funktioniert das hier nicht, ich weiß nicht warum, aber wenn ich das tue, dann klappt das prinzipiell häufiger.

Man klebt so Pflaster drauf und irgendwann hat man so ein Frankenstein-Monster, was eigentlich überall auseinanderfällt, aber es wird gerade noch so zusammengehalten. Und man versucht die technische Schuld möglichst gering zu halten, weil oft Seiteneffekte sehr schwer erkennbar sind. Und eigentlich ist es schön, halt eine clean Code-Basis zu haben, die tut das, was sie tun soll.

Und technische Schuld hat aber mehrere Metriken zum Beispiel, auch wie lang ist deine Methode, weil je länger deine Methode ist, desto wahrscheinlicher ist vielleicht auch, dass da irgendwas drin ist, was da vielleicht nicht reingehört, weil der Name vielleicht nicht mehr das ganz angibt, was der Inhalt der Methode ist. Das hat so mehrere Metriken und im Großen und Ganzen heißt das einfach, man versucht den Quellcode clean zu halten.

Simon

Genau, um, damit die zukünftige Arbeit einfach schnell und effektiv sein kann und nicht sich alles ewig hinzieht und eine Änderung alles kaputt macht, da muss man dann ewig rumfixen, ne, irgendwie.

Kai

Wobei, passiert trotzdem irgendwann wieder. Und auch jetzt gegen Ende, gerade auch mit dem Patchen und kurz vor Release, ist auf jeden Fall sehr viel noch reingekommen, was wahrscheinlich nicht so schön ist für künftige Projekte. Das müssen wir dann wieder ausbauen oder so.

Simon

Genau, und um die technische Schuld wieder runterzubringen, da muss man dann refactoren. Also mal neu schreiben. Genau, und es gibt eine andere Sache, die man in diesen, also ihr habt ganz viele Devlogs gemacht, sowohl auf TikTok als auch auf YouTube vor allem dann. Und da habt ihr noch eine andere Sache und da genau, das habe ich in der letzten Episode habe ich gesagt, darüber sprechen wir, haben wir aber gar nicht gemacht, deswegen muss ich das hier mit einbringen.

Es gibt ein Plakat in eurer WG oder es gab ein Plakat und das war signifikanter Content für TikTok.

Kai

Hängt hier auch noch schräg gegenüber, ich habe es im Blick von hier aus.

Simon

Ah, okay, genau, du weißt, worüber ich spreche und zwar ist das Big O Cheat Sheet. Das ist, ich habe es beschrieben mit Zeitprogrammierungsplakat. Das ist ... Ja, wie spreche ich das? Das ist ein, ach genau, es gibt, Algorithmen werden komplexer oder weniger komplexer, je nach Datenstruktur oder so. Und dann heißt das, ich gucke jetzt hier O, Klammer 1, O, Klammer N und das bedeutet, und hier O, Log, Klammer N, das bedeutet einfach ganz schlimm, schlimm, ein bisschen schlimm. Ja, ja.

Kai

Ja, schöne Zusammenfassung.

Simon

Also wie lange einfach Algorithmen brauchen, um sich irgendwie durch Datenberge zu arbeiten. Und du musst jetzt sozusagen wissen, je nachdem, ob man zum Beispiel ein Array benutzt oder irgendeine Liste oder irgendein, ich gucke jetzt hier mal, ein Red Black Tree, was auch immer das sein soll. Ich finde die Bezeichnung gerade ganz geil. Es gibt einen Cartesian Tree, einen Binary Search Tree.

Es gibt aber auch ein Red-Black-Tree, ein Splay-Tree, das klingt wie ein Jugendwort des Jahres, Splay, und ein AVL-Tree und ein KD-Tree, das sind irgendwelche Datenstrukturen, ich habe keine Ahnung, was ich hier gerade vorlese. Und dann muss man irgendwie dazu in so einer Tabelle raussuchen, welcher Algorithmus wann für welche Aktion der effektivste ist. Ja?

Kai

Ja.

Simon

Ist das so?

Kai

Also ob man das so machen muss, ist nochmal eine andere Frage.

Simon

Na, ihr habt euch immer so Fragen gestellt.

Kai

Ja, ja, ja, ja.

Simon

Ich habe eine Liste und ich will in dieser Liste suchen. Was ist das Beste, was ich dann machen kann?

Kai

Ich weiß gar nicht mehr, wie wir in die Zwerf die Idee gekommen sind. Also wir hatten, also Chris hatte dieses Bild, dieses Poster. Einfach, ja, weiß ich gar nicht warum eigentlich. Wahrscheinlich fürs Studium, weil man hat viel von diesen Algorithmen und Datenstrukturen und so weiter im Studium gelernt. Und da musste sie auch lernen und hatte das einfach privat irgendwie rumhängen. Und wir haben dann TikTok aufgenommen und das war irgendwie eine super spontane Idee.

So, hey Kai, sag mir das und das mit wie auch immer. Ja, und das war unser erstes, wie reiztes Video bei TikTok. Aus irgendeinem Grund. Wir wissen nicht genau, wieso. Wahrscheinlich, weil dann viele Leute irgendwie mitsprechen konnten, die so ein bisschen auch nötig waren. Ich weiß es nicht.

Ich vermute eher, dass dieses Big-O-Cheat-Sheet entweder, wie gesagt, so ein bisschen als Unterstützung zum Lernen verwendet werden würde oder könnte oder aber auch, alles klar, was du eigentlich auch meintest, so hey, ich möchte jetzt irgendwas suchen oder irgendetwas sortieren, was wäre denn jetzt eigentlich die beste Datenstruktur davor und wir haben es halt so ein bisschen als Content verwendet. Giver, missbraucht, sage ich mal.

Simon

Aber jetzt meine naive Frage. Also, wenn es die perfekte Lösung, zum Beispiel, ich möchte etwas, ich lese das jetzt hier ab, ja, ich weiß es nicht auswenden. Ich möchte etwas in einen Red-Black-Tree inserten. Warum macht das der Code dann nicht automatisch mit der besten Lösung, die es dafür gibt? Also, warum ist in Unity nicht dieses Plakat einprogrammiert und dann wird das automatisch gemacht?

Kai

Weil das auch von seinen Use-Cases oft abhängt, weil du möchtest vielleicht nicht nur etwas einfügen, sondern du möchtest vielleicht auch etwas suchen. Und dann hast du nicht nur den einen Punkt, wo der vielleicht, wo der Red-Black-Tree gut ist, aber auch den anderen Punkt, wo er vielleicht schlecht ist.

Und das ist das, was ich vorhin auch wieder meinte. Du siehst ja auch, okay, es gibt ein paar, die sind dolle grün, aber auch die haben irgendwie was Gelbes und andere sind woanders irgendwie ein bisschen positiver und so weiter. Alles hat irgendwie so seine Vor- und Nachteile. Und diese Trees sind teilweise auch in C-Sharp, glaube ich, implementiert.

Aber das Projekt oder das Programm kann ich vorher wissen, bevor du es verwendest oder welche Daten du hast, welche Datenstrukturen vermutlich dafür am besten wäre. Das ist eine Entscheidung, die man als Programmierer dann im Endeffekt treffen muss, weil man seine Daten hoffentlich kennt und das Programm kann ja nicht, weil sonst müsste ja das Programm aus sich herauskommen und auf seinen eigenen Programmcode gucken, um dann festzustellen, du bräuchtest diesen oder jenen Tribü.

Können wir schon vorstellen, dass das KI-mäßig vielleicht in der Zukunft irgendwann geht.

Simon

Ja, das wäre jetzt auch meine Frage. Wäre das mal ein ordentlicher Einsatzzweck für KI?

Kai

Wenn ich ehrlich bin, ich bin gar nicht so ein großer Fan von diesem Big-O-Cheat-Sheet, weil das ist alles so ein bisschen sehr theoretisch.

Simon

Das sagt jetzt aber nicht Chris und nicht den ganzen Fans nach den tausend Videos, die ihr gemacht habt. Ich fall vom Baum.

Kai

Bleib unter uns. Weil da auch viel Hardware mit drin steckt. 90 Prozent aller Fälle ist das Array am schnellsten, weil wenn du auf Daten zugreifst, die im Speicher liegen, hat jeder Rechner heutzutage so einen Mechanismus implementiert, das nennt sich Caching. Der greift nicht nur die Daten zu, die du gerade haben willst, sondern auch ein paar Daten links davon, ein paar Daten rechts davon.

Und dann ist es oft leichter oder schneller eigentlich auf einem Array Dinge zu tun, weil die Sachen dann im Cache liegen. Und dieser Effekt, dass Dinge im Cache liegen, ist so signifikant schneller, dass eigentlich diese ganzen, also oft, nicht immer, gibt es schon auch andere Use Cases, bla bla bla, dass die ganzen anderen positiven Sachen, die dort drinstehen, oft nicht mehr ins Gewicht fallen und Array einfach trotzdem am schnellsten ist.

Und das hatte ich auch lange, während des Studiums, lange nicht auf dem Schirm, bis ich das irgendwann gelehrte, war so wow, cool, mein ganzes, nicht mein ganzes Studium, aber viel von dem, was ich im Studium gelernt habe, ist eine Lüge quasi. Und deswegen bin ich da mittlerweile, ich nutze ein Array und nutze eine Liste und ich nutze ein Dictionary und alles andere, was da draufsteht, ist eigentlich ja, whatever.

Simon

Ich muss sagen, ich habe eine Sache, die ich jetzt, also wo mir es doch gut tun würde, Ahnung davon zu haben. Und zwar habe ich ja vorhin erzählt von meinem kleinen Prototyp, wo ich diese tausend Sprites auf dem Bildschirm hatte. Und was mir auch bei meinem kleinen Spiel aufgefallen ist, das ist so ein Bullet Heaven, wo ganz viele Gegner auf dem Bildschirm sind. Und es dauert relativ lange, rauszufinden, zum Beispiel, welcher dieser 1000 ist am nächsten bei mir.

Und dafür gibt es, glaube ich, dann einen Binary Tree.

Kai

Binary Spatial, Spatial, Spatial, Petition, Spatial, ja, ich weiß auf jeden Fall, was du meinst.

Simon

Das ist irgendwie so eine Art, da weiß ich nicht, da teilt man irgendwie den Bildschirm in ganz viele kleine Bereiche auf und da kann man dann super gut sortieren und super, super schnell rausfinden, okay, wer ist am nächsten zu wem. Und dafür muss man die Daten in einer ganz gewissen Seite strukturieren. Das war irgendwie, ich habe da einmal KI für verwendet. Ich wollte nämlich sagen, hier, ich habe Godot, mach mir das mal. Hat nicht funktioniert.

Also muss ich sagen, also der hat zwar Code ausgespuckt und das sah auch irgendwie aus. Und wahrscheinlich, wenn man, also du könntest wahrscheinlich diesen Code nehmen und in Godot dann auch zum Laufen bringen, aber ich nicht. Also habe ich schon gesehen, so KI, man muss da schon noch Ahnung haben. Das kann man, das kann, in meinem Fall zumindest, konnte ich das nicht einfach nur copy-pasten. Leider. Genau, und da habe ich schon gemerkt, da wäre es wahrscheinlich wirklich praktisch.

Aber das ist wahrscheinlich so ein Spezialfall. Hattet ihr denn mal so, also ich meine, gut, da ist die Frage jetzt insofern geantwortet, dass du jetzt meinst, okay, du benutzt meistens die Standardsachen, aber gab's einen Fall, wo ihr doch schon irgendwie so krasse Datenmengen und Sortierungen dann hattet vielleicht irgendwo so ganz spezielle, wie bei mir zum Beispiel mit, okay, du hast ja tausend, Enemies auf dem Bildschirm und musst rausfinden, wer ist wo am nächsten?

Kai

Also wir haben natürlich auch ähnliche Abfragen bei uns im Code. Wir machen das so ein bisschen, lassen Unity für uns arbeiten und zum Beispiel sagen, alles klar, ich möchte, wer ist am nächsten von mir als Spieler?

Und dann machen wir zum Beispiel einfach einen Circlecast um den Spieler halt darauf herum und fischen durch Unity, durch sein Physiksystem einfach erstmal, welche Entity ist überhaupt in der Nähe und dann gehen wir da nur noch linear drüber und fragen alle ab, wer ist denn davon jetzt am nächsten weil das einfach ein viel kleineres Subset ist als wenn du die ganze Welt abfragst, insofern nutzen wir sowas ähnliches auf jeden Fall schon.

Im Endeffekt ist unser Chunking-System eigentlich etwas ähnliches also wie die Welt geladen werden, ist sozusagen auch eine Datenstruktur, sag ich mal ein 2D-Array übertrieben gesagt, wo man dann wo bestimmte Objekte in dieses Area einfach einsortiert sind und dann gehören sie zu dieser zelle und dann könntest du zum beispiel sagen alles klar ich möchte jetzt anhand einer welt position die id im 2d array berechnen kannst einfach durch breite und höhe eines

chunks quasi ein bisschen dividieren und dann hast du den direkten zugriff auf alles klar dieses objekt an dieser position liegt auf jeden fall in diesem chunk und dann musst du noch objekte in diesem chunk zum beispiel durchsuchen und nicht global was auch eine kleine hilfestellung ist. Und was ähnliches tue ich auch mit diesem Object Placer, den ich vorhin hatte.

Wenn ich ganz viele Objekte in der Szene platziere und ich möchte auch wieder welche löschen, dann muss ich ja im Endeffekt herausfinden, welches Objekt ist eigentlich unter meinem Mauszeiger. Zur Editor-Zeit, nicht zur Laufzeit. Und da frage ich im Endeffekt auch, gehe ich alle Liste ab, alle Objekte, welches ist jetzt mein Mauszeiger am nächsten? Ist da dieses? Und es ist auch im Radius des Mauszeigers, also lösche ich dieses.

Aber das ist auch noch mal einsortiert in quasi so eine 2D-Array-Struktur, wo ich dann auch wieder von World Positions auf IDs komme, von IDs dann auf nur die Objekte, die auch in diesem Quadranten sozusagen liegen.

Simon

Ja, ansonsten wäre es sehr langsam.

Kai

Genau. Ist es auch tatsächlich auch so noch ein bisschen an bestimmten Stellen, vor allem wenn du den Mauszeiger sehr, sehr groß machst, dass du sagst, hey, ich möchte alle Objekte 12.000 Pixel um diesen Mauszeiger löschen, dann wird es auch wieder langsam. Genau.

Simon

Aber umfährt zu sein, das ist ja selbst in Photoshop so und da arbeiten sie seit irgendwie 35 Jahren dran und haben da drei Millionen Engineers drauf, dass wenn du den Bereich sehr groß einstellst, dann ist auch Photoshop, und das ist ja schon optimiert, also.

Kai

Naja, ähnliches Problem hatten wir auch mit unserem Texturesplating, da haben wir auch ein Tool, um in die Szene und den Boden direkt zu malen. Wenn es sehr groß war, hat das auch sehr lange gedauert, aber das lag daran, dass ich dort initial eine Undo-Funktion eingebaut habe und es sozusagen in den, damit man Undo machen kann, musst du ja den State vorher wissen und den neuen State.

Und eigentlich hat es nur lange gedauert, es quasi in diese Datenstruktur des Stacks fürs Undo einzufügen, weshalb unser Tool, wenn man den Boden zu malen, es kann kein Undo. Also du musst auffassen, wenn du was machst. Damit es einfach flüssig läuft. Was ich auch immer ganz interessant fand.

Simon

Aber kann ich speichern und wenn es mir dann nicht gefällt, was ich gemalt habe, einfach nochmal neu laden? Okay.

Kai

Klar, das geht. Oder auch mit Git nutzen wir ja. Kannst du auch sagen, ich reverte einfach die Szene, wo ich jetzt was gemacht habe oder so.

Simon

Ah, okay, ja. Ach, ihr benutzt, okay, ihr benutzt dafür auch gibt.

Kai

Also generell einfach für Unity.

Simon

Auch für alle Assets?

Kai

Ja, genau.

Simon

Also ist das schon groß dann?

Kai

Außer die gebakten Texturesplanes. Die werden zu groß, alles andere passt gut rein.

Simon

Aber ich sag mal so, warum werden die eigentlich zu groß? Also klar, wir haben jetzt festgestellt, das ist, 1600x1600, aber du hast ja gesagt, das sind JPEGs. Und ich sag mal so, jeder von uns hat wahrscheinlich, Tausende Fotos auf der Festplatte liegen.

Kai

Also zu groß heißt jetzt auch nicht, dass das 100 Gigabyte groß ist, sondern einfach so groß, dass Git das nicht mehr so mag. Oder andersrum. Unser Projekt ist mittlerweile auch so groß, dass wir hart an der Grenze sind. Das Git sagt, jo, euer Projekt ist ein bisschen zu groß. Entweder braucht ihr da irgendwie, weiß ich, Premium oder was auch immer.

Sonst hätten wir es wahrscheinlich auch mit hochgeladen. Aber es hat da, glaube ich, einfach den Budget gesprengt und deswegen haben wir es dann rausgenommen.

Simon

Wie groß ist denn das Projekt gerade so?

Kai

Das Problem ist, Also, ich baue ja auch regelmäßig an meinem Rechner immer mal wieder Versionen. Ich glaube, im Peak war ein Ordner von dem Projekt schon mal 80 Gigabyte groß, aber da liegen sehr viele Libraries und gecachede Daten und ein paar Bildversionen rum. So, das reine Projekt ist ungefähr ... Warte, es rechnet gerade. Es kann aber sein, dass da die Texture-Plans drin sind. Fünf Gigabyte. Ich gucke mal kurz drin, ob da die Texture-Plans drin liegen.

Simon

Und dann ohne die Rohdaten von Grafik, ne, also ... Ohne A-Sprites oder irgend sowas.

Kai

Ach so, genau. A-Sprites liegt extra. Das nutzen wir nur zwar eine Cloud für. Aber die exportierten Daten von A-Sprites, die sind wiederum mit drin.

Simon

Aha. War es eine Cloud? Also das heißt, jemand schmeißt eine Dropbox irgendwie?

Kai

Nee, also wir haben eine eigene, also was heißt eigene Cloud? Nextcloud nennt sich das. Ist sowas wie Dropbox, aber ist auf unserem eigenen Server quasi gehostet. Aber ist ja wie Dropbox eigentlich.

Simon

Das heißt, die Grafik-Rohdaten haben gar keine richtige History dann sozusagen?

Kai

Ja, genau.

Simon

Oh, stimmt.

Kai

Ich glaube, Nextcloud hat ein bisschen von History, aber so richtig verwenden tun wir es nicht.

Simon

Ah.

Kai

Ich glaube, im Endeffekt ist es bei uns so ein bisschen vom Workflow her, dass die Artists ihre Sachen in ihrem eigenen Workspace editieren, bis sie sagen, jo, ich bin jetzt fertig, es ist Export-Ready. Da kommt es in einen extra Ordner und das ist einfach immer die up-to-dateste Version.

Simon

Okay. Ja, und das ist wichtig, weil du hast ja vorhin gesagt, dass auch aus den Aceprite-Dateien, ach nee, warte, der Exporter ist in Aceprite. Das habt ihr für Aceprite geschrieben.

Kai

Genau.

Simon

Das heißt, die Dateien werden nicht noch mal vom Spiel angefasst oder so.

Kai

Nee, nee, nee, nee.

Simon

So, jetzt haben wir festgestellt, dass du diese super, das O-Cheat-Cheat, also diese ganzen Sachen, welche Algorithmen man wie wo einsetzt und so, das sind halt Themen auch gewesen aus dem Studium. Haben wir festgestellt, hättest du dich sparen können.

Kai

Also fürs Studium brauchte ich schon was, es waren auch Abfragen in Klausuren oder sowas.

Simon

Nee, mein ich, genau, fürs Spiel. Nein, übertrieben, aber Caching löst viele Probleme. Und ich habe mich gefragt, ob es noch andere Dinge aus der theoretischen Informatik so gibt, die ins Spiel eingeflossen sind. Also ich frage halt deswegen, weil gerade wenn es um theoretische Informatik geht, ist manchmal so die Frage, hä, wofür brauche ich das?

Vielleicht fragt man sich das im Studium auch mal so hä, warum mache ich das eigentlich und dann, wenn jetzt alle zuhören hier alle InformatikstudentInnen die können jetzt aufhorchen und sagen also hoffentlich sagst du jetzt gleich irgendwas was total praktisch war, was im Studium, drin war und was im Spiel geholfen hat und das dann voll die gute Motivation weiterzumachen.

Kai

Gib mir eine Gedenkmenü.

Simon

Ja, ich hab halt zum Beispiel gedacht, also mir würde das zum Beispiel helfen, wüsste ich diese ganzen Sachen, dann hätte ich viel bessere Performance gehabt bei meinem Cozy Space Survivors Spiel, weil dann hätte ich diesen Binary Spatial Tree eingesetzt und ja, dann.

Kai

Also, ich glaube, einerseits bin ich vielleicht auch blind dafür, was ich im Studium gelernt habe, was ich jetzt verwende, weil vieles vielleicht auch so ein bisschen automatisch so ein bisschen da ist.

So, das ist erst mal der erste Punkt. Der zweite Punkt zum Beispiel, was gerade mit den BSB-Tree meint, den kenne ich eigentlich nur, weil ich mich selber mit Spieleentwicklung befasse neben dem Studium und ich dann YouTube-Videos geguckt habe oder Tutorials oder was auch immer und es dann halt irgendwann entdeckt habe. Und ich weiß, es thematisch im Studium thematisiert wurde.

Dinge, die schon thematisiert sind, die praktisch waren, Wir haben zum Beispiel Pathfinding, ASTAR, also wir haben ASTAR-Algorithmus implementiert im Studium. Das haben wir jetzt im Endeffekt nicht verwendet, weil wir ein Plugin dafür verwendet haben, aber das hätte man selber implementieren können. Und sonst, ich finde es schwierig. Ich habe das Gefühl, die meisten Sachen, die ich jetzt eigentlich verwende oder aktiv sind, habe ich mir mehr oder weniger selber beigebracht.

Vieles würde ich aber, also gerade aus dem Bereich der Mathematik, würde ich sagen, sind es eigentlich so ein bisschen die Basics, was weiß ich, Dreisatz, Prozentrechnung, bla bla bla. Klar, die braucht man auf jeden Fall alle und die hat man hoffentlich auch ein bisschen im Studium.

Und wenn man auch in Richtung Shader gehen möchte oder auch vielleicht in 3D-Programmierung, auch lineare Algebra, also was du vorhin schon mal grob hattest, Rotation oder du hast irgendwie eine Matrix und dann multiplizierst du mit der Matrix und dann verhält sich dieses Objekt so und so oder ich fliege in diese Richtung, gib mir den orthogonalen Vektor davon oder so ein Zeug. Das finde ich relativ wichtig, wurde aber halt sehr theoretisch auch im Studium angegangen.

Aber ein grundlegendes Verständnis dafür ist relativ wichtig aus meiner Sicht für die Spielentwicklung. Und sonst sind es so, eine Sache habe ich sehr krass im Kopf, ist Lerb, Linear Interpolation, ist like Goldstandard, kannst du für fast alles verwendet. Du willst was rotieren, nimm Lerb. Du willst was von A nach B wegen, nimm Lerb. Du willst, dass irgendwas über eine Zeit passiert, nimm Lerb. Und das hatten wir zumindest im Studium so ein bisschen.

Und war für mich damals, als ich mein erstes Spiel gemacht hatte, das war ein sehr kleines Spiel, ich habe überall Lerb verwendet. Und das habe ich auf jeden Fall im Studium kennengelernt. Ja. Und ja. Ja, also ich kann gerade nicht so viel leider rezitieren, was ich glaube ich aktiv im Studium hatte, was noch Verwendung findet.

Simon

Ja, ich muss natürlich sagen, du hast natürlich das mathematische Grundkenntnis dann oder mehr als Grundkenntnis, um dich auch sehr schnell in Dinge einzuarbeiten. Wie ich gesagt habe, ich habe das nicht zum Laufen bekommen, diesen BSP-Tree, aber du hättest es garantiert hinbekommen. Zum Thema LURP übrigens, also das ist die lineare Interpellation und da gibt es noch einen sehr lustigen anderen Begriff, das ist SLURP. Das klingt einfach lustig, wenn man es sagt.

Und das ist tatsächlich eine Interpretation, wo wirklich rotiert wird. Das ist ganz interessant für Vektoren, damit die auch korrekt rotiert werden und nicht irgendwie ...

Kai

Nicht, dass sie einmal kurz verschwinden und plötzlich auf der anderen Seite wieder auftauchen oder so.

Simon

Ja, genau, nicht irgendwie gestaucht werden, wenn man sie da rumschwubbelt. Ich wollte eigentlich vorhin überleiten, das habe ich ganz vergessen, und zwar, als wir über die Tools gesprochen haben. Genau, da habe ich ja gefragt, was habt ihr noch für Tools entwickelt? Und da gibt es ein Tool, da muss ich sagen, Das hat mich am meisten beeindruckt und zwar habt ihr ein saugeiles Feedback- und Bug-Reporting-Tool geschrieben.

Und das ist so toll, da habe ich gedacht, also für jemand, also für ein Team, was eigentlich vorher gar keine Erfahrung hatte mit Spielentwicklung, ist das, also da hätte ich gesagt, okay, die haben schon irgendwie seit 10, 15 Jahren Spiele gemacht und die wissen, was für ein Pain es ist, so ein Tool nicht zu haben. Und deswegen haben sie es gebaut. Ich finde das total beeindruckend, dass ihr das gebaut habt. Also diese Weitsicht dafür einfach ist schon, wir hatten das nicht überlegt.

Wir können gleich dazukommen, was es genau damit auf sich hat.

Kai

Aber genau, also ich glaube im Großen und Ganzen ist fast, nicht alle Tools, aber viele von den Tools und viel von dem, wo du meinst, das Weitblick erforderlich von Chris der hat irgendwie, weiß ich, glaube, wenn er seine Augen schließt, er funktioniert wie anders und irgendwie ist er irgendwie sehr Meter immer weit voraus, und ist ganz interessant und ich glaube, vermutlich kommt das initial von ihm, aber auch, weil wir vorher auch den Pain in der Entwicklung schon gespürt hatten,

hey, hier ist irgendwie ein Bug, okay, cool, aber auch aus Erfahrung von zum Beispiel Nebenjobs. Zum Beispiel Johannes hat im Nebenjob gearbeitet und wenn du da ein Bugreport oder ein Bugreporten wolltest, musstest du manuell rangehen, deine Logdatei raussuchen und irgendwie anheften und was weiß ich was. Und ja, wir haben einfach recht früh festgestellt, dass das wahrscheinlich recht painful wird. Initial natürlich nur erstmal für uns in der Entwicklung verwendet.

Haben dann aber auch schnell festgestellt, wäre es nicht richtig geil, wenn Leute das einfach auch verwenden für uns, damit wir einfach, ja, und so kam das dann im Endeffekt zustande. Hat auch viele Iterationen so ein bisschen hinter sich auch so ein bisschen welche Daten mitgesendet werden, welche nicht und wie die Daten dann verarbeitet werden, aber unser Ziel war es halt möglichst wenig manuellen Aufwand zu haben wenn jemand sich entschließt hey hier ist ein Bug, den ich reporten möchte.

Simon

Genau und um auf das Tool anzugehen das ist einfach saugeil, man drückt F2 im Spiel und kann dann einen kleinen Text eingeben und entweder Feedback schreiben sagen hey das Spiel ist super oder einen Bug senden und was halt so Cooles dabei, dass automatisch ein Safe Game erstellt wird und das wird mitgesendet.

Und es war dann so, dass ich war, ihr habt live gestreamt und ich hatte einen Bug, ich habe einfach irgendwas gesagt, ich finde irgendwie die Karte nicht, also es gibt da so einen NPC, der verkauft halt Karten und der war aber nicht da und dann habe ich gefragt, wo ist denn der? Und dann hat Chris gesagt, der ist dort und dort, dann bin ich hingelaufen, der war nicht da. Und dann war, glaube ich. Ich glaube, Chris hat gesagt, ja, pass auf, mach einfach ein Bug-Report.

Und dann habe ich kurz das Spiel aufgemacht, habe einfach kurz den Bug-Report geschrieben und dann hat in der Sekunde einfach Chris dieses Save-Game dann plötzlich geöffnet, live im Stream, was ich eine Sekunde vorher abgeschickt habe. Also ich hab's ja noch nicht mal abgeschickt. Ich hab einfach nur F2 gerückt im Spiel, hab einen kleinen Text geschrieben hier, das ist das mit der Karte, und dann konnte er trotzdem das automatisch erstellte Savegame öffnen.

Konnte dann, also war dann plötzlich in meinem Spiel sozusagen drin, hat das Savegame bei sich geladen, konnte dann relativ schnell über die ganze Karte sausen mit irgendeinem Cheat-Mode, den ihr da habt. Und hat sofort gesehen ... Ach, genau, und das fand ich auch nämlich noch interessant. Nicht nur hat er jetzt das Spiel gestartet und ein Savegame geladen und einen Cheat-Mode aktiviert, er hat das Savegame in Unity geladen.

Also er war in der Lage, in Unity da noch alle Variablen zu checken und hat superschnell da einfach so klickle-klick hier da geguckt und hat gesehen, oh, da ist ein Bug tatsächlich, weil ich habe irgendwas gemacht vorher und dann war der NPC einfach nicht da. Und das war innerhalb von fünf Minuten, war das gefixt. Und ich fand das total auch beeindruckend, dass das in Unity dann geladen werden konnte, das Safe-Game. Ich weiß nicht, ob das normal ist oder ob ihr da irgendwas gemacht habt.

Kai

Im Großen und Ganzen, sofern sich das Spiel nicht zu krass im Bild unterscheidet vom im Editor, nutzen wir einfach dasselbe Safe-Game-System. Äh, und, weil im Editor möchtest du ja auch Save Games laden, du willst ja irgendwie dein Progress speichern, du willst ja, und so weiter. Im Endeffekt fiel das so ein bisschen automatisch ab, dass man's dort einfach auch, also für uns laden konnte.

Ich weiß nicht, es gibt auch bestimmte Plugins oder so mit Speichern laden, da haben wir auch was Eigenes programmiert, ich weiß nicht, wie's bei denen aussieht, Unity hat von sich aus jetzt erstmal nichts, was Speichern laden angeht. Äh, genau, äh, und ja, das hat sich so ein bisschen, glaub ich, so automatisch ergeben damit, das haben wir eigentlich, glaub ich, initial gar nicht so geplant, aber ist natürlich so sehr praktisch zu haben.

Auch zum Beispiel, was weiß ich, manchmal habe ich was, auf meinem eigenen Rechner rechts habe ich Steam offen mit Drover, links habe ich Editor offen und dann ist auch der Datenexchange relativ flott. Ich speichere rechts und kann es links direkt laden, ohne sich schließen muss und so weiter. Und das ist schon, ja, schon ziemlich cool auch. Gehe ich schon mit.

Simon

Ey, das ist so cool, das Tool. Und ich finde, das fühlt sich auch so jetzt aus meiner Perspektive als Konsument total gut an. Also da macht es auch richtig Spaß, irgendwie Feedback zu geben und auch Bugs zu reporten. Und da muss man nicht irgendwie, ja, geh halt auf diese Seite.

Ne, gibt's ja mal, wenn du in Houdini zum Beispiel ein Bug-Report machen willst, da musst du dann auf, ja, halt gehst ins Forum und sagst du, hier, ich hab einen Bug, was soll ich machen, da sagen die hier, da suche du mal die Seite raus und dann musst du dort irgendwie so ein Jira-Ding erstellen, also ist kein Jira, aber irgendein System und irgendwas eingeben, bla bla und dann vielleicht noch was attachen und hier einfach zack drücken, wird automatisch Safe Game erstellt, ist so geil, also.

Kai

Ich weiß auch nicht, warum nicht mehr Programme oder Spiele oder Firmen oder Software sowas tut, weil ja, weiß ich nicht. Das ist eine gute Frage.

Simon

Und das Coole ist ja, dieses Savegame, was erstellt wird, ist auch nur temporär im Hintergrund und unsichtbar. Ich habe nämlich am Anfang gedacht so, muss ich vielleicht eins anlegen? Also ich hatte erst noch gefragt so, soll ich ein Savegame speichern und euch das dann schicken? Und da war die Antwort, nö, wird automatisch gemacht, ist schon eins dabei. Okay, krass. Das ist super cool.

Kai

Wir schicken tatsächlich auch nicht nur den, also in dem Moment, wo du F2 drückst und auf Absend klickst, wird ein Savegame gemacht und der wird dann mitgeschickt. Wir schicken aber auch den zuletzt Autosave mit, weil manchmal ist dann ja der Bug zu spät. Du bist ja schon weiter zeitmäßig und der Bug ist ja schon passiert. Deswegen versuchen wir beim Autosave, das dann noch mal zu reproduzieren. Was aber ganz interessant ist, manchmal ist das leider auch fehlerhaft.

Zum Beispiel, wenn du in einem Dialog einen F2-Bug-Report machst und wir den dann laden, unser Dialogsystem speichert sich quasi nicht korrekterweise. Das heißt, wenn du einen Dialog startest, muss er auch zu Ende geführt werden. Dazwischen darf eigentlich nicht gespeichert werden, aber das Tool ignoriert das. Und wenn wir dann einen Bug davon bekommen, muss uns bewusst sein, dass das passieren kann.

Sonst kann sein, dass das Spiel durch den Bug-Report, zumindest auf unserer Seite, nicht für die Seite des Users, kaputt sein kann, wenn wir es einfach laden. Und es war in der Mitte eines Dialoges, und dann ist irgendwie alles kaputt. Das heißt, da hätten wir vielleicht auch noch was anders machen können. Aber das ist so der einzige Edge-Case, wo das manchmal tricky ist.

Simon

Ja, also sehr beeindruckend, find ich toll. Überall Einzug erhalten, ja.

Kai

Und vielleicht auf unserer Seite auch nochmal was ganz Schönes. Wir schicken ja auch die Log-Datei zum Beispiel mit, die auch oft erstellt wird. Und auch ein Screenshot von der Position, wo du dich gerade befindest, das wird auch nochmal ein Screenshot gemacht. Das heißt, man kann auch örtlich gut schnell einschätzen, wo das ist. Zusätzlich schicken wir aber zum Beispiel auch die Kamera-Position mit. Das heißt, wir haben ein Tool in Unity. Hey, gehe zu der Position von diesem Bug-Report.

Und dann bist du auch direkt da. Du musst nicht, wo ist denn das? Wo muss ich denn hin? Okay, ich scrolle mal ein bisschen durch die Welt. Ist das in dem Chunk? Nee, ist das in dem Chunk? gesagt, schack, du bist halt da. Und auch das Laden von dem Save-Game geht recht flott. Die haben alle eine ID und in Unity haben wir ein Tool, ein kleines Fenster, da gibt es für die ID-Einklicks auf Laden und dann wird es geladen.

Du musst nicht irgendwie erst noch die Datei runterladen und dann irgendwie irgendwo hinkopieren oder so. Und das ist schon, macht das Leben sehr angenehm.

Simon

Ja, das war eine Sache, die hat mir auch sehr gut gefallen in X-Rebirth.

Da war es so, wenn du im Spiel bist und Steuerung C drückst, dann wird in die Zwischenablage deine aktuelle Kameraposition und Rotation einfach gespeichert und das ist einfach so ein kleiner Text-String, also einfach ein paar Zahlen und die konntest du dann super easy in Jira reinpacken, wenn du ein Bug-Report machst, kannst du einfach sagen und wenn du diese Zahlenfolge mit STRG V ins Spiel gepastet hast, einfach während das Spiel läuft,

einfach STRG V drücken und wenn es in der Zwischenablage eben so eine, Zahleninformation war, dann hat das Spiel ist dann automatisch zu dieser Position gesprungen und das war so praktisch, weil wenn du so eine Weltraumsimulation, die ist ja wirklich groß, und dann hast du so eine Raumstation, die auch ultra groß ist und dann gibt es so ein Bugreport wie hier an dieser einen Stelle, da ist die Beschriftung auf dem Metall ist irgendwie kaputt,

dann willst du halt nicht diese Raumstation abfliegen und gucken, wo da jetzt was ist und dann kannst du super easy die Position, rauskopieren und reinpasten und das war eine echt große Hilfe. Ja. Was mich auch interessiert, weil ich habe mich da letztens das erste Mal mit Safe Games ein bisschen beschäftigt. Das ist ja ganz interessant, wie man eigentlich so eine ganze Welt abspeichert. Da wollte ich mal fragen, wie habt ihr das eigentlich gemacht mit Safe Games?

Kai

Also wie wir was speichern?

Simon

Naja, also es ist ja so, also der naive Approach könnte sein, man hat so eine Art Management Script und in dem schreibt man manuell irgendwie rein, Pass auf, such dir mal alle NPCs raus und speichere mal irgendwie in eine Textdatei von hier aus rein, wo die gerade sind. Und dann such mal, weiß ich nicht, irgendwelche andere Sachen. Also, dass man das alles manuell definiert, was eigentlich überhaupt in so ein Savegame rein soll.

Weil, also, irgendwie muss man ja sagen, okay, was soll da eigentlich rein? Und da muss man es auch wieder auslesen. Und jetzt habe ich ein neues Code-Pattern oder Design-Pattern gelernt, dass alle Objekte eine kleine Klasse haben oder eine Methode haben. Die auf, es ist schwierig zu schreiben, also jedes Objekt weiß sozusagen, was es abspeichern möchte von sich.

Also zum Beispiel reicht vielleicht da bei einem Objekt, dass nur die Position gespeichert werden soll und nicht irgendwie noch andere Informationen wie die Lebenspunkte oder so, weil die einfach, weiß ich nicht, von mir aus eh resettet werden bei jedem Spielstart oder irgend sowas und es gibt dann ein Event. Das feuert man ab. Das ist so wie, hallo, ich möchte gerne, also man sagt damit allen Bescheid, wir speichern jetzt.

Und dann kann jedes Objekt, empfängt dieses Event, hängt seinen eigenen kleinen Daten an das Event dran, sozusagen. Also ich hoffe, ich beschreibe das korrekt. Also es ist ein bisschen so, wie man vorher ein Paket ab schickt, das zu jedem Objekt, jedes Objekt legt dort seine Daten rein, die es gerne abgespeichert haben möchte und das Paket kommt dann irgendwann wieder zurück zum Hauptmanagement-Skript und dann wird alles, was in dem Paket ist, abgespeichert.

Und das Code-Pattern ist sozusagen dabei, dass es nicht eine zentrale.

Komponente gibt, die weiß, okay, wenn das ein NPC ist, dann speichere ich die und die Daten ab und wenn es eine Kamera ist, dann nehme ich die und die, sondern jedes Objekt, hat das in sich definiert und schmeißt einfach in dieses kleine Paket, was einmal rumgeht, wie so eine kleine Kirche, wie in der Kirche, wenn so die Kollekte eingesammelt wird, schmeißt einfach jedes Objekt seine Daten mit rein und irgendwann kommt das kleine Körbchen wieder

zurück und dann speichert man alles, was da drin ist, ab. Ich hoffe, ich habe das einigermaßen ...

Kai

Ja, nee, das ist ... Wir machen es ähnlich. Also wir speichern auf jeden Fall nicht alles ab. Wir speichern nur das Notwendigste ab. Als Beispiel zum Beispiel, manche spinnen, wenn sie sterben, hinterlassen so eine Giftpfütze auf dem Boden. Wenn du speichern würdest und lädst, dann wäre die dann noch weg. Oder du schießt gerade ein Energieprojektil ab oder ein Pfeil und du speicherst und lädst, dann ist der Pfeil da auch nicht mehr.

Simon

Ja.

Kai

Also bestimmt, wir speichern nur das Nötigste sozusagen ab, um einfach den Prozess des Abspeicherns möglichst schnell zu gestalten und auch das Laden schnell zu gestalten, auch dass das Savegame klein ist. Das Abspeichern selber, das ist ein Extrascript, das sind Saveables, haben wir so genannt bei uns. Das ist zum Beispiel ein Saveable Actor und das definiert dann, was kann einem im Actor alles gespeichert werden und das ist ähnlich, wie du geschrieben hast, das hat eine Methode Load und Save,

sage ich mal. Wenn man ein Load aufgerufen wird, dann weiß es, es bekommt seine Daten, es bekommt sein eigenes individuelles, bei uns ist es ein bisschen anders. Es gibt dieses große Paket, was bei dir rumgereicht wurde. Das gibt es bei uns sozusagen nicht. Es gibt bei uns einen Raum, wo alle Pakete drin liegen, um so als eine Metapher zu bleiben. Und wenn safe und laut aufgerufen wird, geht jemand rum und bringt jedem Objekt ein kleines Subpaket aus dem Raum, was für ihn relevant ist.

Und er kann dann doch etwas hineinlegen oder etwas auslesen und genau. Aber die Objekte können auch von sich aus Anfragen machen an den Raum und sagen, ich möchte jetzt unabhängig, ob du jetzt speicherst, nicht, wenn das nächste Mal gespeichert werden würde, dann update mal bitte mein Paket. Also, update jetzt mein Paket, damit brauche ich es später nicht mehr, sozusagen.

Genau, diese Events haben wir trotzdem, aber die meisten Objekte, zumindest beim Speicherevent, tun selber nichts mehr, weil sie dann schon Sachen in ihr Paket legen, wenn eine Veränderung stattfindet. Ah, okay. Das machen wir deswegen, weil, lass mich kurz überlegen, wir haben, das ist eigentlich da nicht mehr relevant gewesen. Wir hatten früher, oder ist das relevant? Doch, ja, genau. Und zwar, wir haben jetzt Chunks und Chunks werden rausgeladen.

Und Objekte, die in einem Chunk liegen, wollen ja aber auch gespeichert werden. Zum Beispiel, ich töte einen Ripper in einem Chunk. Das ist jetzt ein doofes Beispiel, weil Ripper werden eigentlich anders gespeichert, aber wir nehmen mal an, der Ripper ist in diesem Chunk und der Chunk wird entladen, also wird auch der Ripper rausgeladen. Und danach speichere ich, Aber ich habe den Ripper vorher getötet. Und jetzt bekommt der tote Ripper, der nicht mehr existent ist,

ein Event, hey, speicher dich mal. Und das geht ja nicht. Also muss der Ripper ja schon, bevor er gespeichert wird, ihm Bescheid sagen, ich bin jetzt tot, ich bin jetzt lebendig, ich habe so und so viel Lebensenergie. Und deswegen verweitet jedes Objekt selber von sich aus sozusagen, wann es welche Daten bereits in die Kiste legt, für den Fall, dass gespeichert wird, dass sie auch up to date sind. Genau. Aber sonst nutzt man ein recht ähnliches Pattern eigentlich.

Simon

Das ist natürlich interessant, wieder so ein Spezialfall mit, wenn es dann um Streaming geht. Aber das, okay, das heißt aber ganz am Anfang, ganz, ganz am Anfang, habe ich ja dieses Beispiel aufgemacht mit, was ist denn mit einem NPC, der durch die Welt läuft? Da hast du gesagt, es gibt dann trotzdem noch so ein temporäres Objekt, was immer noch da ist. Aber das gilt dann nicht jetzt, wenn wir über diesen Ripper reden. Der ist halt weg, wenn der Chunk entladen wird.

Kai

Deswegen, ich meine, Ripper ist ein blödes Beispiel. der ist auch schon, auch global vorhanden. Deswegen meine ich gerade, wir nehmen jetzt mal an, er lege in einem Chunk gut er eigentlich nicht, der ist eigentlich auch global drin mit diesem Nebenobjekt.

Aber auch in dem Fall passiert das ja auch, weil dieser Ripper wird irgendwann zu einem Placeholder-Ripper und wenn der echte Ripper tot ist und der zum Placeholder-Ripper wird und wir würden dann erspeichern, dann erst Sachen in den Karton legen, dann wüssten wir ja gar nicht, ist der Ripper jetzt tot oder nicht sozusagen.

Deswegen in dem Moment, wo er auch hin und her swapt zwischen seiner Fake-Referenz und dem Echten quasi, legen wir in der Regel auch wieder Sachen schon ab oder auch wenn er bereits Lebensergie verloren hat, unabhängig davon, ob er jetzt tot ist oder nicht.

Simon

Aber wenn du die ganzen Status Stati ähnlich hast, wenn der rausgeladen ist, warum hast du denn überhaupt noch ein temporäres Objekt?

Kai

Ich meine, im Endeffekt ist es auch wieder dem gemeinsamen System geschuldet. Es liegt primär daran, dass NPCs sich durch die Welt bewegen. Und sowohl Gegner als auch unsere NPCs sind beides Ektoren bei uns im Spiel und deswegen laufen sie einfach über dasselbe System. Aber ja, eigentlich bräuchte man das dann da nicht.

Aber der Vorständigkeit halber ist es dann trotzdem da. Es kann auch zum Beispiel sein, du tötest den Ripper, er ist eigentlich an der Position 10-10 und du kitest ihn durch die ganze Welt auf 1000-1000 und tötest ihn dann dort, dann müssten wir ja trotzdem nochmal Daten abspeichern, wo ist der jetzt eigentlich konkret.

Und er könnte sich vielleicht auch entscheiden, auch wenn er dann zurückzuhst auf 10-10, du hast ihn noch nicht getötet, dann würde er, glaube ich, auch wieder zurücktingeln auf 10-10 mit der Zeit.

Simon

Ich habe übrigens sehr oft versucht, Gegner wegzuziehen. Ich habe Babsi sehr lieben gelernt, weil Babsi ist eine Jägerin, die da rumsteht und ich habe versucht, möglichst viele, böse kleine Viecher zu ihr zu ziehen, damit sie die für mich umhaut. Aber irgendwann drehen die um. Also man kann die gar nicht über die gesamte Map mitzern. Ja, leider.

Kai

Zu einem früheren Zeitpunkt ging das mal, wir hatten das dann irgendwann so ein bisschen ausgebaut, aber ja.

Simon

Ja, ich habe mich auch noch gefragt, genau, Cutscenes. Das ist auch nochmal so ein Tool-Ding.

Kai

Ein bisschen, ja.

Simon

Habt ihr da auch ganz viel selbst programmiert? Oder gab es da irgendwelche coolen, Also irgendwelche Timelines, wo man einfach sagen kann, okay, NPC dahin, du dahin, dann Dialog, dies und das. Weil das ist ja durchaus kompliziert. Also man muss ja sagen, erstens, Player-Kontrolle geht weg. Zweitens, Kamera wird jetzt übernommen und wird jetzt soft irgendwo anders hingeschoben, damit man dort, weiß ich nicht, eben, ja, also dort, wo eben die Cutscene stattfinden soll.

Dann, verschiedene NPCs laufen von ihrer Position zu der Position, dann gibt es vielleicht eine kurze Pause, dann startet jemand mit dem Sprechen, dann muss ja jemand anders darauf reagieren und so. Also, da ist ja schon eine ganze Menge, was da so nacheinander abläuft. Und ich frage mich, wie das definiert und gestaltet wurde, ob es da irgendwie Unity-Timeline gibt, ob ihr das irgendwie alles geschrieben habt.

Kai

Also Unity hat so ein Timeline-Tool. Das haben wir aber nicht verwendet. Wir haben es, glaube ich, initial mal damit angefangen. Aber es hatte irgendwelche Probleme, an die ich mich nicht erinnere, weil es zu viele Jahre zurückliegt.

Die meisten Bedingungen, die du gerade schon meinst, wir hatten, das Spiel pausiert, die Player-Kontrolle ist weg oder was auch immer, das hatten wir eigentlich alles schon so übers Dialogsystem eh, weil du möchtest ja auch nicht, dass der Spieler sich im Dialogsystem bewegt.

Oder du möchtest, dass der NPC der Rede von der Kamera fokussiert wird und deshalb haben wir unser cutscene system quasi eigentlich in das dialogsystem integriert in diesem dialog tree gibt es da eine knoten der nennt sich cutscene knoten und wenn der traversiert wird also wenn der aufgerufen wird dann weiß dieser knoten was passiert und dieser knoten ist im großen ganzen wir haben es recht simpel gehalten es sind einfach quasi kleine.

Die zum Beispiel sagen, alles klar, geh von A nach B und mehr tut das Skript nicht. Und diese Skripte werden dann aber gescheduled quasi und um dann irgendwas Komplexes darzustellen. Warte eine Sekunde, setze eine Variable, trigger irgendeinen Effekt. Aber jedes Skript an sich ist relativ klein, aber es wird sozusagen so ein bisschen choreografiert oder gescheduled bei diesem Knoten. Man kann auch Dinge so ein bisschen parallel schalten und sequenziell schalten.

Aber es ist nicht so richtig ein Tool. Wir nutzen eigentlich im Großen und Ganzen eigentlich nur den Default-Unity-Inspektor, um diese ganzen Sachen zu definieren. Ist auch so im Nachhinein so ein bisschen eine kleine Schwachstelle, weil wir haben schon einige Cutscenes, die recht komplex und auch lang sind.

Und was da immer sehr problemlos ist, und da wäre Timelines eigentlich cool gewesen, da hätte man vielleicht nochmal, ich gehe nochmal kurz zurück, ich pass das nochmal an, lass das nochmal spielen. Und bei uns war es so, eine Cutscene ist so ein One-Shot. Also wenn irgendwas an der Cutscene nicht gefallen hat, dann musst du das Spiel beenden, du musst das Spiel laden, du musst die Cutscen komplett von vorne beginnen, um dann diese eine Sache irgendwo in der Mitte zu editieren oder so was.

Oder um dann noch mal zu gucken, ob es dann besser ist. Und ich hab dann irgendwann angefangen, mit OBS mir die Cutscen aufzunehmen, damit ich dort wenigstens so ein bisschen Timeline-mäßig mir das noch mal angucken kann, wie es eigentlich konkret war. Aber das Editieren an sich war sehr ... Das ist auf jeden Fall ein Punkt, den wir wahrscheinlich für das nächste Projekt auch noch mal verbessern wollen, wenn wir weiterhin so viele Cutscenes haben werden.

Simon

Ja, okay.

Kai

Aber es ist eigentlich relativ simpel gestaltet.

Simon

Aber, okay, aber das heißt, es muss irgendwo eine zentrale Cutscene-Datei geben oder irgendeine Struktur, wo ich dann sage, führe bei Sekunde 0 dieses Skript aus und das schiebt die Kamera irgendwo hin. Und dann muss irgendwo stehen, fünf Sekunden später starte bitte das Skript für NPC1, läuft auf Position XY. Also irgendwo muss ja definiert sein, ja, irgendwo muss die Timeline ja definiert sein, auch wenn es keine visuelle gibt, sozusagen.

Kai

Also es ist, ähm, es kommt so ein bisschen ... Zufällig, also beschreibe ich das? Also im großen Ganzen sind es diese Skripte, was ich meinte, die sketcheln sich ein und dein Skript sagt irgendwann, also sagen wir, zuerst kommt das Skript gehe von A nach B. Das sketchelt sich jetzt ein, das wird jetzt aufgerufen. Wie lange das Skript jetzt eigentlich läuft, das weiß das Skript an sich nicht.

Zum Beispiel, wenn ich von A nach B gehe und es ist zehn Pixel entfernt, dann brauche ich vielleicht eine halbe Sekunde. Aber es weiß nicht selber, ich brauche eine halbe Sekunde. Und wenn das Skript durch ist, dann kommt das nächste Skript. Und so erstellt sich implizit eine Timeline, weil die Skripte von sich heraus einfach Dinge für eine gewisse Zeit tun.

Aber es ist nicht quasi gescheduled im Sinne von bei Sekunde 5 passiert das, bei Sekunde 10 passiert das, sondern es ist so, es schiebt sich selber so ein bisschen zurecht.

Simon

Aber wie kannst du dann drei in PCs gleichzeitig irgendwo hinlaufen lassen? Weil da musst du ja parallel drei Skripte starten.

Kai

Genau, wir haben zwei so Hauptskripte, also es gibt einmal eine Sequenz, das ist das, was ich gerade gemeint habe, es passiert A, dann B, dann C, dann D und es gibt Parallel. Und wenn das halt aufgerufen wird, dann sind es im Endeffekt wie zwei Einzelsequenzen oder mehrere Einzelsequenzen, die dann ihr Part für sich jeweils tun, die dann aber zeitgleich abgespielt werden, weil sie von dem Parallel-Knoten oder nicht Knoten, Skript aufgerufen wurden.

Simon

Und dann muss das System automatisch so lange warten, bevor das nächste gestartet wird, wie das längste Skript in diesem parallelen Block ist, oder? Weil wenn du jetzt ein Skript hast, was quasi eine Sekunde dauert und das andere drei und das andere vier.

Kai

Dann… Ja, ich glaube, ich bin mir nicht hundertprozentig sicher, aber ja, ich glaube, das parallele Skript ist erst dann fertig, wenn alle Subskripte durch sind.

Simon

Aha.

Kai

Genau. Ja, also war manchmal tatsächlich auch Timing manchmal ein bisschen nervig, weil angenommen, du fügst am Anfang irgendwas ein bisschen ein, dann verschiebt sich alles nachfolgend. Und dann musst du manchmal Timings hinterher nochmal ein bisschen reduzieren, damit es dann wieder eigentlich auf dem eigentlichen Punkt liegt, wo es eigentlich liegen sollte.

Da ist es manchmal schöner, von Anfang an direkt Sachen parallel zu schalten, weil dann kannst du auf dem Parallelstrang sagen, warte fünf Sekunden und dann tue etwas, was dann sozusagen identisch ist zu tue bei Sekunde fünf etwas. Und dann haben wir so ein bisschen baustellmäßig. Das hat sich ein bisschen angefühlt wie Lego, so konnte man so ein bisschen kreativ Dinge zusammenstöpseln.

Simon

Okay. So, ich gucke gerade, die Liste ist sogar noch ein bisschen lang, aber ich glaube, wir müssen langsam mal zum Ende kommen.

Kai

Das ist okay.

Simon

Ich hatte nur noch eine Frage, die ich sehr spannend fände, weil ich die überraschend komplex fand. Und zwar die, so was, wie ihr verhindert, dass man aus Versehen mal NPCs tötet oder haut, wenn man irgendwie mit der Waffe drum ist.

Und du kannst natürlich dann auch, wenn du jetzt irgendwie in der Liste noch Sachen siehst, wo du denkst, boah, das müssen wir aber auch noch erwähnen, dann kannst du auch gern noch mal sagen, also es gibt natürlich schon noch interessante Sachen, aber ja, keine Ahnung. Wir haben jetzt schon auch wieder über drei Stunden gequatscht und es ist immer noch nicht fertig, über dieses Spiel zu sprechen.

Weil was zum Beispiel super spannend ist, ist auch, ihr habt dieses Raumfading, also dass man, wenn man in einer Höhle ist, dass man nicht die gesamte Höhle die ganze Zeit sieht, sondern dass das so ein bisschen, ist nicht wie Sichtlinien, aber dass man halt so den nächsten Höhlenbereich nicht sieht. Und so eine Sache, da habe ich mich natürlich auch gefragt, wie ist das denn wohl definiert und gemacht und so.

Aber ich wollte jetzt eigentlich auf was anderes hinaus. Genau, und zwar es gibt ja freundliche und feindliche Entitäten dieser Welt. Bei manchen kann das auch wechseln, aber, Genau, es gibt nämlich verschiedene States von NPCs und ich habe mich da gefragt, ob das kompliziert war, das alles unter einen Hut zu bringen.

Also nur mal ein Beispiel, es gibt zum Beispiel den Fall, ich greife eine Person an und plötzlich sehen alle drumherumstehenden, hey, da greift unsere Freundin an, jetzt hauen wir denen alle aufs Maul und dann stürmen die alle auf mich los und wollen mich umhauen. Es gibt aber dieselbe Situation auch und dann sagen die anderen nur ohne Schlägerei und gucken einfach zu.

Und das sind ja schon mal, also die Aktion ist die gleiche, ich greife jemanden an, aber die Reaktion der anderen NPCs ist anders. Dann habe ich mich auch gefragt, wie ist es denn, wenn ich gerade im Kampf mit einem Monster bin, aber aus Versehen einen NPC treffe? Da muss ja irgendwie gesagt werden, ja, das war nicht so gemeint. Und ich habe mich halt gefragt, wie dieses System funktioniert oder ob das vielleicht viel einfacher ist, als ich mir das vorstelle.

Aber ich stelle es mir irgendwie kompliziert vor, dann genau zu wissen, wann dürfen NPCs feindselig werden und wann bleiben sie freundlich und wann reagieren die anderen NPCs böse oder gucken nur zu oder Da.

Kai

Muss ich auf jeden Fall auch einmal vorweg, das sind alles so ein bisschen Systeme aus Johannes-Bereich. Also der könnte da auf jeden Fall auch wieder ein bisschen deutlich besser antworten. Aber im Großen und Ganzen ist jeder NPC ist halt einer Fraktion zugehörig. Das müssen nicht unbedingt die Fraktionen sein, wie sie auch im Spiel sind. Es kann so Subfraktionen geben, wie zum Beispiel, okay, Banditen sind auch im Spiel.

Im Großen und Ganzen passt das schon eigentlich auf die Fraktion auch im Spiel. Also Nemeton, Ruinlager, Banditen. Es gibt aber auch Neutral, also Leute, die so zu nichts irgendwie dazugehören. Und die Definition, ob sie jetzt jubeln oder nicht jubeln. Nee, doch, das gibt ... Warte, ich muss kurz gucken.

Simon

Also, ja ... Genau, ich glaube nämlich in der Mine, es gibt so eine Mine und ich glaube, da war einer und der hat mich gehauen und dann sagen die anderen nur, oder ich habe den gehauen, na und dann gucken die anderen nur zu.

Kai

Ja, ja. Nee, genau, genau. Also wir haben in der Mine zum Beispiel die Wachen und die Hauer selber, sind zwei verschiedene Factions. Und die Wachen würden einander helfen, wenn jemand angegriffen werden würde. Wenn man jetzt aber, also die Hauer sind die Miner sozusagen, die helfen sich nicht gegenseitig, auch untereinander nicht. Das heißt, wenn ich jetzt jemanden, der Hauer angreife oder Miner angreife, dann kommen die anderen nicht zur Hilfe.

Die können, glaube ich, nochmal explizit überschrieben werden, bei zum Beispiel, die beiden sind befreundet, deswegen helfen die sich doch, ob du deren Grundfraktion das nicht sagt. Genau auf die Art und Weise ist das im Großen und Ganzen definiert. Und wie das funktioniert ist, soweit ich weiß, wenn du halt einen der, also ein Kampf ist ja schon was Explizites bei uns, also du kannst nicht jemanden zufällig treffen oder hauen.

Du musst da deine Waffe ziehen, zu ihm hingehen und da kommt eine kleine Bar, die sich füllt und erst wenn sie voll gefüllt ist und davor nicht abgebrochen ist, erst dann kämpfst du aktiv gegen den. Deswegen gibt es zum Beispiel diesen Case eigentlich mit Gegnern, nicht dass du irgendwie zufällig einen NPC triffst. Kann es trotzdem gehen. Nee, eigentlich nicht, eigentlich nicht.

Simon

Warte, jetzt überlege ich gerade. Was für eine Bar? Ich weiß nicht, ob mir das aufgefallen ist.

Kai

Also wenn du mit einer gezogenen Waffe an einen freundlichen NPC herangehst, dann kriegt er ein rotes Outline. Ähnlich wie wenn du mit ihm reden würdest, ist es weiß, aber dann ist es halt rot. Und dann musst du Linksklick gedrückt halten oder Angriff gedrückt halten. Dann lädt sich diese Bar. Und wenn die dann voll ist, dann schlägst du erstens zu. Und zweitens hast du dann eine Rauferei mit ihm initiiert. Und das passiert eigentlich nicht aus Versehen im Kampfgeschehen.

Simon

Ja, ist schon zu lange her. Habe ich mich jetzt gar nicht mit dran erinnert.

Kai

Genau, aber wenn das dann passiert, wirft der NPC, soweit ich weiß, ein kleines Event. Jo, ich wurde angegriffen. Das ist im Endeffekt wie so ein Hit-Kollider, der drumherum ist. Und alle, die das sozusagen hören, die würden sich dann halt entweder auf die positive oder auf die negative Art und Weise quasi mit einmischen. Und das System aber dahinter ist auch, was die sagen und so weiter und wo sie sich auch hinstellen und so weiter. Das ist alles, das kann ich nicht gut beantworten.

Simon

Aber wieder ein Beispiel für ein doch wieder sehr komplexes System, weil es gibt ja noch die neutrale Art, ich gucke einfach nur zu und sage, cool, die kloppen sich. Und ja, genau, spannend, okay.

Kai

Aber auch da gab es immer mal wieder Probleme, zum Beispiel gibt es, du meinst ja, es gibt Leute, die wechseln ihre Fraktion, da gab es zum Beispiel im Taverne jemand, der dich übers Ohr hauen will und wenn du denen dann folgst, dann wird er von Freund zu Feind, hat aber selber einen Komplizen und während du noch befreundet mit ihm bist, aber seinen Komplizen schon haust, denkt er nicht, dass das tatsächlich sein Komplize ist und hilft dir dann mit ihm seinen eigenen Komplizen zu hauen,

um dann fünf Sekunden später zu sagen, jo, wir haben dir eine Falle gestellt und dann werden sie plötzlich Freunde und sind dir feindlich gegenüber und würden dann zusammen auf dich gehen. Also es gibt schon auch einige Edge Cases, die wir immer mal wieder abfangen mussten. Aber passieren auf jeden Fall witzige Dinge damit.

Simon

Ja, okay. Ja, du, ich weiß nicht, was sagst du denn? Hast du noch etwas, was dir vielleicht auf dem Herzenliebe, wo du sagst, boah, das war so cool, da müssen wir noch drüber reden?

Kai

Vielleicht ein paar Kleinigkeiten. Die Wasserreflexion fände ich noch ganz interessant. Ich weiß nicht, ob du die konkret hier nicht mit drin hattest.

Simon

Meinst du die kleinen ...

Kai

Nee, dass man sich selber im Wasser sieht.

Simon

Ja, erzähl mal.

Kai

Das und Silhouetten von NPCs finde ich sehr interessant, weil beides wirkt voll Magic und beides ist ultra trivial.

Simon

Okay, ich will noch kurz untermalen, dass Reflektion in 2D spielen, finde ich, sieht man nicht so oft und warte, Divine, wo ist es denn? Genau, und auf meinem Blog habe ich nämlich genau das mal zum Thema gemacht, weil ich das so toll fand, dass in Divine Divinity, ich poste es hier, da hat man das nämlich schon. Divine Divinity, das ist hat nichts mit, also ist nicht, ich meine, ist nicht Divinity Original Sin, sondern wirklich die beiden Divinity.

Das erste Spiel von Larian Studios und da, das war nämlich auch 2D und da gibt es auch Reflektionen und da wird das Sprite halt irgendwie, gemürrert, denke ich mal, und dann aber auch verschwubbelt, dass sich das so ein bisschen bewegt und das ist mir damals schon aufgefallen und das hat mir sehr gut gefallen, das war in 2013. Krass, so alt ist der Artikel schon. Genau, deswegen freue ich mich natürlich, dass ihr auch Reflektionen drin habt. Genau, so und jetzt erzähl mal, was ist da die Magic?

Kai

Also im Großen und Ganzen, ich weiß nicht genau, wie Divinity das macht. Wir machen es auch nicht perfekt und das sieht man immer mal wieder. Wir haben ja ein Kleidungssystem und unser Kackler ist ja, sag ich mal, du kannst ihn ja ausziehen und kannst Rüstung A anziehen oder aber auch Helm B und Waffe C und kannst ja so ein bisschen mischen und matchen. Und das dann in die Reflektion zu gießen, das war ein bisschen tricky,

weil das soll natürlich auch alles mit in die Reflektion. und am Best-Case hättest du eigentlich, sag ich mal, das passiert jetzt dynamisch zur Laufzeit, dass du diese Klamotten trägst. Also es gibt keinen Sprite-Atlas, der sagt, so ist die Kombination sozusagen. Und das heißt, wir rendern das einfach, auch wenn du dir das im Debugger, im Rendering-Debugger anguckst, kommt erst Layer A, B, C, D und dann ist dein Charakter irgendwann fertig.

Und genau, im Großen und Ganzen wäre es eigentlich cool gewesen, wenn man das in einer Extratextur hatte, um diese Textur einfach extra zu zeichnen, also zu dem jeweiligen Zeitpunkt. Aber irgendwie hat das nicht so richtig funktioniert, wie ich es mir vorgestellt habe.

Und was wir eigentlich machen ist, wir erzeugen eine Kopie vom Spieler, aber eigentlich nur sein Visual, flippen das dann halt auf der Y-Achse, keepen aber seine X-Achse, keepen seine Position und ja, dann ist es unter dem Spieler. Aber dann siehst du es natürlich immer. Das heißt, dann muss man es noch rausmaskieren, dass du es nur im Wasser siehst und da kommt wieder das Denzelbuff ans Spiel.

Und im Endeffekt steht im Stencil-Buffer drin, auch hier wieder übertrieben gesagt, wo eine Eins steht, ist eine Reflektion, wo Null steht, ist keine Reflektion. Das hat aber gerade, oder andersrum. Und dann wollen wir aber natürlich auch im Wasser, ist es ein bisschen transparenter, so ein bisschen ausfaden.

Und da ist aktuell das Problem, wenn man es einfach nur ausfadet, weil du aus mehreren Ebenen bestehst, dann siehst du plötzlich Klamotten oder zum Beispiel deine Hautfarbe unter den Klamotten. Weil deine Klamotte ist ja semi-transparent und deswegen kommt die Haut darunter langsam zu Vorschein. Und deswegen werden die Wasserreflektionen bei uns, sind nicht farbtechnisch akkurat mit dem eigentlichen Charakter.

Und um das so ein bisschen zu kombiten, gibt es einen extra Shader, der basierend auf der Farbe des Pixels, was ausfadet, verändert es nochmal seine Farbe, um so ein bisschen auszumachen. Weil zum Beispiel sehr helle Farben fallen sehr stark auf und sehr dunkle Farben fallen weniger stark auf. Und deswegen fäden wir helle Farben stärker aus als dunkle Farben, um das in der Reflektion quasi zu kaschieren, dass die Farben nicht richtig matchen.

Simon

Aber was meinst du jetzt mit Faden? Ich zeige auch gerade mal ein Bild an, aber man kann es sich so vorstellen, die Wasserreflektion sieht halt aus wie das Original-Sprite, so mit einem drum und dran, nur ein bisschen dunkler. So würde ich es jetzt beschreiben.

Kai

Sage ich mal.

Simon

Ich sehe da jetzt aber nicht, also ich sehe da jetzt nicht zum Beispiel, dass die Reflexion nach unten hin immer mehr ausfädelt oder sowas. Also du siehst schon so eins zu eins ein Spiegelbild eigentlich.

Kai

Also nicht nach unten hin, sondern generell. Also du hast so ganz leicht, hier sieht man es auch, glaube ich, weil du hast eine dunkle Rüstung. An dunkle Rüstungen fäden weniger aus. Das ist das, was ich vorhin meinte. Du hast zum Beispiel im Wasser so kleine Steine, die so ganz leicht andersfarbig sind. Und die würden auch ein bisschen durchkommen.

Simon

Ah, okay, also das Spiegelbild an sich ist ein bisschen transparenter.

Kai

Genau, genau. Aber das sieht man jetzt hier wirklich nicht, weil du gerade wirklich einen recht dunklen Charakter hier als Beispiel hast. Also sowohl von der Rüstung als auch von der Hautfarbe.

Simon

Und das Problem ist, dass es halt nicht ein Sprite ist, sondern es eben aus verschiedenen Teilen besteht.

Kai

Genau, genau.

Simon

Also Körper, Haut, darüber dann die ganzen Rüstungsteile. Und jedes davon wird ja ein bisschen transparenter.

Kai

Genau, genau, genau.

Simon

Aber sag mal, wäre es nicht möglich gewesen, den Charakter in eine neue Textur zu rendern, also zur Laufe Zeit.

Kai

Genau, genau, genau. Das wäre eigentlich das Schönste gewesen, dass man sagt, eigentlich zu jedem Zeitpunkt im Spiel, zumindest von den Charakteren, die eine Reflektion haben sollen, rendert man das irgendwie nochmal offscreen in eine Extra-Textur und zeigt die dann da irgendwie an. Aber ich hab das einfach nicht, ich sag, hab ich irgendwie nicht hinbekommen.

Ich weiß nicht, ob das an Unity liegt oder so. Ich hatte nicht irgendwie das Gefühl, dass ich etwas gut einfach offscreen rendern kann, weil sonst hätte ich den Charakter irgendwie, weiß ich, teleportiere ich für ein Frame oder für x Millisekunden im Frame ins Nirvana, dann nehme ich den auf, dann muss ich den aber zurück teleportieren und sowas und das war irgendwie alles sehr tricky und sehr unschön. Aber das wäre eigentlich der Way to go gewesen. Ja, da gehe ich mit.

Simon

Ah, okay. Ja, krass. Okay, aber dann hast du einfach, genau, ist eine Kopie mit allen Layern. Das ist natürlich, okay, das sind auch mehrere Drawcalls, ne? Dann?

Kai

Yes.

Simon

Genau. Und dann aber mit dem Spezialshader die Farben so angepasst, dass es nicht auffällt, dass da irgendwie die ...

Kai

Es fällt immer noch manchmal auf, wenn du eine bestimmte Kombination von Rüstung und Charakter hast, sieht man manchmal, dass die Farben nicht so richtig matchen. Du hast jetzt hier ein perfektes Beispiel eigentlich, wo es ganz gut funktioniert.

Es gibt leider Beispiele, wo es leider nicht so gut funktioniert, wo wir auch manchmal immer wieder Bug-Reports bekommen, wo die Leute zum Beispiel ihren Oberkörper durch die Rüstung schimmern sehen und sagen, mein Charakter, meine Reflektion hat gar keine Klamotten an. Und das ist leider nicht so ganz schön. Was auch impliziert aktuell tatsächlich ist, dass die Kopie von deinem Charakter dauerhaft unter dir ist, selbst wenn du dich nicht in der Nähe von Wasser befindest.

Was auch noch mal nicht so schön ist, sowohl für die Performance als auch fürs Rendering, weil im Endeffekt rendere ich dann sozusagen Dinge ins Nichts, aber es muss trotzdem gerendert werden. Genau, und da haben wir auch ein paar Optimierungen, aber an sich ist der Ansatz tatsächlich recht simpel, also so algorithmisch simpel.

Simon

Ja klar, weil ansonsten müsstest du ja noch detekten, wann du in die Nähe von Wasser kommst, weil du kannst das Spiegelbild ja nicht erst anzeigen, wenn du im Wasser stehst, weil du kannst ja schon deinen Kopf sozusagen spiegeln sehen, während du noch am Ufer stehst.

Kai

Genau, das war auf jeden Fall auch sehr tricky, aber hat auf jeden Fall auch einen sehr coolen Effekt.

Simon

Ja, es ist, ja ... Auf jeden Fall.

Kai

Weil wir es aber auch wiederum nur für Menschen machen. Wir hatten irgendwann mal einen Ansatz, dass wir alles im Wasser reflektieren. Also angenommen, da stünde ein Baum nördlich vom Wasser, dass auch der Baum dort reflektiert wird. Aber der Ansatz mit diesem wir erzeugen Duplikate und so weiter war da nicht sonderlich sinnvoll.

Simon

Ja, vor allem, weil das ja dann auch für alle Bäume, die auch sehr entfernt wurden.

Kai

Und ich glaube sogar auch, dass Ripper und sowas keine Reflektion haben, wenn ich gerade richtig im Kopf habe. Ich glaube, es sind tatsächlich nur Menschen. Was ich interessant finde, weil gefühlt fällt das eigentlich niemandem so richtig. Aber obwohl doch.

Simon

Nee, ist mir auch nicht aufgefallen, glaube ich.

Kai

Aber ich bin mir gerade nicht sicher. Vielleicht haben Ripper doch eine Reflexion.

Simon

Die Fliege wäre auch eine Frage.

Kai

Ja, stimmt. Das müsste man ja in deinem GIF eigentlich sehen, oder? Die steht ja auf, die hatte, glaube ich, keine.

Simon

Nee, fällt aber auch nicht auf.

Kai

Ja, finde ich ganz spannend irgendwie, dass es nicht auffällt.

Simon

Ja. Ja, cool. Genau, Wasser. Und warte, du hattest noch was anderes. Ach, genau. Und zwar die Pixel Outlines.

Kai

Ja, ja, ja.

Simon

Genau.

Kai

Ist im Endeffekt eigentlich genau das selbe. so ein bisschen. Eigentlich wäre es schön gewesen, die Textur off-screen zu haben, um dann einen Shader zu haben, der dann tatsächlich die echte Outline rendert. Hatten wir aber auch nicht. Und wir hatten auch super lange, weil jedes Kleidungsstück hat dann seine eigene Outline.

Zum Beispiel in dem Beispiel, was du hier hast, dann hätte die Haare zwischen Kopf und Haare wäre dann eine Outline und zwischen der Waffe, die sie in der Hand hat und dem BH und der Hose, überall sind dann weiße Linien plötzlich drin. Weil jeder Sprite seine eigene Outline bekommen, weil es wieder aus mehreren Layern besteht. Und das war auch sehr lange im Projekt so drin, und auch sehr lange in den alten Versionen, die wir online hatten.

Und da hatte ich auch super viele Ansätze gesucht und der aktuelle Ansatz ist auch jetzt gerade wieder, dass man eine Kopie vom NPC oder von was auch immer erstellt und dann auch einfach quasi, nee, andersrum. Wir erstellen eine Kopie, die rendern wir in komplett weiß, aber hinter, also vor dem Ektor. So hast du Ektor die Kopie, die ein weißer Pix, also weißt du, wie ich meine, oder?

Ist noch nicht gut erklärt. Okay, wir nehmen den NPC, wir duplizieren ihn, rendern ihn in komplett weiß und ein Pixel größer im Großen und Ganzen. Und der wird hinter, jetzt in dem Fall Cassia gerendert. Und dann kommt Cassia eigentlich drüber. Und deswegen hat sie dann quasi eine Outline, weil sie in komplett weiß dahinter noch mal existiert.

Simon

Ja, okay, aber warte mal. Aber du sagst das so mit nur einem Pixel größer. Aber ist das denn so einfach? Also weil eine richtige schöne Outline, um einen Sprite zu machen? Also klar, in Photoshop ist es einfach. Das mache ich manuell. Da male ich einfach überall, ziehe ich einfach eine Outline manuell lang. Aber im Code, also ...

Kai

In fact, das ist ja im Shader. und wir befinden uns jetzt hier auf Texturebene, wenn man das dann quasi rendert. Und das ist schon einfach, weil du hast die Auflösung deiner Textur und du sagst dann im Endeffekt, jo, ich checke meinen Pixel oben, unten, links, rechts, ob irgendein Pixel davon einen Alpha-Wert gesetzt hat. Und wenn ja, dann mache ich mich selber einfach weiß.

Und für alle Pixel, die dann quasi außerhalb der Silhouette sich befinden, würde sie sagen, oben, unten, links, rechts ist nichts. Also man muss immer so aus der Sicht des eigenen Pixels, das dann gerendert wird, denken. Da ist nichts, also bin ich komplett transparent.

Simon

Ja, aber warte mal, im Shader hast du diese Information doch nicht. Also, weil wenn ich jetzt im Shader bin, kann ich ja nicht sagen, if Pixel neben mir ist red, denn du das ist ja das Problem. Also zwar auf der Grafikkarte werden zwar immer zweimal zwei Pixel gerendert, aber im Shader habe ich ja immer nur Zugriff auf mich selbst.

Kai

Genau, genau. Und deswegen checke ich für mich selber, also da wird ja eine Textur gerendert. Du musst ja die Farbe für deinen eigenen Pixel schon aus der Textur lesen. Und deswegen hast du ja in der Regel auch sowas wie, hey, lese die Farbe von meiner Position, um mein Pixel zu bekommen.

Simon

Genau.

Kai

Und du könntest aber auch sagen, lese nicht die Farbe, wo ich gerade bin. Du hast ja so ein Parameter, also du gibst ja im Endeffekt die UV-Koordinaten an. Du kannst auch sagen, gib mir den Pixel auf meiner UV-Koordinate plus ein bisschen nach oben, ein bisschen nach unten, ein bisschen nach links und ein bisschen nach rechts. Und dieses bisschen, wie viel weiter ich gucke, ist einfach die Auflösen der Textur.

Also beziehungsweise eins durch Texturgröße sozusagen. Und im Endeffekt passiert dann das schon im Shader, dass ich sage, alles klar, ich rendere mich selber. Und ich gucke aber auch, also ich lese auch aus der Textur oben, unten, links, rechts. Im Endeffekt sind es keine If-Abfragen. Im Endeffekt multipliziere ich die Werte, um so ein bisschen Ifs zu vermeiden. Aber das ist ein anderes Thema.

Simon

Ah, also du hast einen Vorloop im Shader sozusagen.

Kai

Ja.

Simon

Du machst das viermal im Shader. Okay.

Kai

Genau. beziehungsweise korrekterweise, glaube ich. Ich weiß gar nicht, ob ich die Diagonalen auch checke. Ich glaube nicht.

Simon

Es gibt noch eine andere, da habe ich einen alten Artikel von mir, da ging es um Outlines, ich kann ja mal ein Video schicken, wie es auch geht, in dem Spiel Move or Die, Und wird so gemacht, dass das Sprite für die Outline achtmal gezeichnet wird. Und zwar einmal ein bisschen nach links verschoben, einmal ein bisschen nach oben, einmal nach rechts, einmal nach unten und dann noch auf die Diagonalen.

Einfach so ein, in eurem Fall wäre es ein Pixel weiter nach links, rechts, oben, unten und so weiter. In Move or Die ist es kein Pixelspiel, aber so wurden da die Outlines gefakt. Das ist natürlich Overdoor-mäßig nicht so super optimiert, aber funktioniert.

Kai

Ja, ich meine, Mufordai ist, glaube ich, also nicht kleines Spiel, aber so, du hast ja eine kleine Stage mit deinen Charakteren und so weiter. Und ich glaube, die haben ja keine ganze Open World, die dauerhaft geladen wird und so weiter. Ich glaube, da kann man sich sowas schon mal erlauben. Aber ja, gibt es ja viele interessante Methoden, Outlines zu machen. Auch im 3D ist ja auch oft, dass du deine Vertices irgendwie so ein bisschen, aufbläst in verschiedene Himmelsrichtungen oder sowas.

Simon

Genau.

Kai

Aber das klappt halt im 2D leider nicht und deswegen sind das ja ähnliche Ansätze.

Simon

Genau, dazu, ich kann den Artikel auch mal verlinken, der heißt Cell Shading, aber der zeigt genau das, dass man eben das Modell, das Mesh sozusagen dupliziert, invertiert und anhand der normalen nach außen skaliert und dann kriegt man in 3D eine klassische, also das ist wirklich so dieser ganze Oldschool-Trick, um eine Outline in 3D zu machen.

Ich glaube Borderlands hat da wesentlich andere Techniken und da habe ich tatsächlich einen sehr coolen Video letztens gesehen und zwar habe ich nämlich, kann ich hier Eigenwerke machen, Ich habe nämlich ein Newsletter jetzt auf Simon schreibt, das ist so ein TechArt VFX Newsletter und da habe ich nämlich gerade letztens erst, genau hier ist das Video, hat jemand nachvollzogen, wie der Death Stranding Scan Effekt gemacht wird und da ist auch eine Outline-Technik erklärt,

die auf Pixelschitter Basis funktioniert und nicht irgendwie hier mit Duplizieren von Mech, das ist wirklich old school. Aber ja, genau. Verlinke ich euch natürlich auch für alle, die sich da interessieren.

Kai

Schiebe ich definitiv mal in meine Watchlater-Liste bei YouTube.

Simon

Ja, war ein schönes Video. War ein sehr schönes Video, genau. Ja, cool. Dann würde ich sagen... Können wir mal zum Ende kommen?

Kai

Können wir gerne machen. Die Zeit auch verfliegt in so einem Podcast, finde ich sehr spannend.

Simon

Ja, ist krass, oder? Also man kann auch mal vier Stunden quatschen und denkt so, hä?

Kai

Ja, ja, ja, ja.

Simon

Wo ist die Zeit hin? Genau. Ja, du, hast du denn noch etwas, was du an die Menschen da draußen geben möchtest, wenn jetzt Leute zuhören? Und also Studierende hören hier zu oder Professionals oder also durch die Bank einfach weg und weiß ich nicht, vielleicht hast du ja, keine Ahnung, vielleicht irgendwas, was dir auf dem Herzen brennt, wo du vielleicht denkst, ey, damals als ich studiert habe, hätte ich mir gewünscht, dass das mir mal jemand sagt oder irgend sowas.

Kai

Boah, ist natürlich jetzt ein sehr allgemeiner Call, den man alle Menschen da so draußen gibt Ich glaube, wenn ich es so möglichst allgemein fassen wollen würde, ist es natürlich hey, macht das, worauf ihr Bock habt macht, wofür ihr brennt und auch, dass Droh war jetzt entstanden es liegt eigentlich nur darauf, dass ich eigentlich während des Studiums eigentlich schon eine ganze Zeit Spielentwicklung gemacht habe, aber eigentlich nur so ein bisschen für mich und dann mit anderen

Teammitgliedern und dann aber kleine Spiele gemacht und Game Gems und ich hatte nie einen Plan, dass das hier mal hinfüllen würde, wo es jetzt hingeführt ist und deswegen weiß ich, geht euren Hobbys nach, geht euren Leidenschaften nach und wer weiß, wo das mal hinführt oder welche Türen es öffnet, welche Menschen ihr kennenlernt und was ihr zusammen so für coole Sachen irgendwann mal auf die Beine stellt.

Ich höre das öfter irgendwie, dass Leute irgendwie Hobbys vielleicht nicht nachgehen, weil das bringt ja nichts oder kann ich ja eh nie was mitmachen oder die sich da so ein bisschen auch demotivieren lassen oder auch das Hobby nicht mehr als Hobby empfinden, sondern dann, ich mache das jetzt, um irgendwann Geld zu verdienen und dann macht es aber auch irgendwann keinen Spaß mehr oder sowas und sich einfach so ein bisschen ja von seinen Leidenschaften leiten lassen.

Dann aber im Umkehrschluss aber auch, lasst euch nicht zu krass von euren Leidenschaften verleiten. Weil es kann auch echt manchmal Spaß an der Sache nehmen oder auch einen sehr stressen oder dass man nicht gut schläft oder sowas, wenn man so sehr mit einer Sache irgendwie so gefangen ist. Dass man auch wenig Platz für andere Sachen hat, auch vielleicht mal für Pause oder auch mal ein bisschen, was weiß ich, Sport, gesund ernähren, was auch immer, bla bla bla.

Alles im Maßen, aber lasst euch so im Großen und Ganzen von Leidenschaften leiten.

Simon

Ja gut, vielen Dank für das Schlusswort und vielen Dank, dass du so lange mit dabei warst und deine Expertise hier geteilt hast. Das war sehr, sehr spannend. Bin gespannt auf das Feedback.

Kai

Ja, ich auch.

Simon

Und ich bin auch gespannt und wünsche euch das Beste für was jetzt kommt als nächstes.

Kai

Ja, bin ich auch sehr gespannt. Dankeschön.

Simon

Just2D, genau, das ist spannend. Also ganz tolles Projekt. Habe sehr gerne gespielt. Und ja, also großen Respekt. Es ist wirklich krass. Also ich finde es sehr beeindruckend, was ihr da auf die Beine gestellt habt. Ganz, ganz toll. Ja.

Kai

Dankeschön. Ja, ich auch nochmal danke, dass du mich hier hattest, gehostet hast quasi, zugehört hast, gute Fragen gestellt hast und auch echt für deine Recherche vorher. Also nochmal Respekt, das hatte ich nie so auf dem Schirm. Also ich belege jetzt auf Podcaster auf völlig andere Art und Weise, wenn jeder mindestens so viel Effort da reinsteckt wie du.

Ja, also auch Respekt an das, was du tust. Und wie gesagt, ich hatte dich ja auch immer mal früher auf dem Schirm und auch so im Studium immer mal wieder und finde ich cool, was du tust. und ja.

Simon

Ja, vielen Dank. Ihr habt es sehr einfach gemacht, weil ihr halt so toll dokumentiert habt, das ganze Projekt. Das war wirklich dann eine Freude, da nachzurecherchieren. Das macht es auch einfacher, coole Fragen zu finden. Genau, cool. Ja, dann ganz, ganz viel Erfolg für die Zukunft und Tschüssi.

Kai

Mach's gut.

Transcript source: Provided by creator in RSS feed: download file
For the best experience, listen in Metacast app for iOS or Android