Beiträge von Sturmvogel

    Nachdem da ein bisschen mehr dazu gehört als nur die Strukturen und Effekt Scripts, ist das portieren vmtl. eine Längerfristige Aufgabe, aber es gibt das hier: https://github.com/KDSKardabox…ald-Battle-Engine-Upgrade


    Ein bissl was auf einer englischen Feuerrot habe ich hier: https://github.com/SBird1337/s…/master/src/battle_engine


    Und für die englische Feuerrot gibt es ein Attacken Overhaul, wo ich aber gerade nicht genau sagen kann, wie sehr das funtkionsfähig ist: https://github.com/EternalCode/battle_engine


    Viel Spaß!


    ~Sturmvogel

    Wäre halt immer interessant zu wissen, was denn nicht geht. Auf den ersten Blick verursacht der Codeblock mal einen Assemblererror, weil mul ein binärer opcode ist: mul rD, rS multipliziert rD mit rS und speichert das Ergebnis in rD. Es kann sein, dass dir dein Assembler das durchgehen lässt, und deine Instruktion als mul r5, r7 assembliert, würd mich aber net drauf verlassen und mir über etwaige Seiteneffekte bewusst sein. Außerdem gibt es die Syntax ldr(b/h) rD, rP nicht, sondern nur ldr(b/h) rD, [rP, #imm] um zu suggerieren, dass du rP als Pointer behandeln willst, und von der Addresse in rP + imm einen Wert lesen, bzw. sofern du , #imm nicht schreibst, wird angenommen, dass imm = 0. E.G.: ldrb r1, [r5]


    Ansonsten: Du kannst ja deinen Code einmal debuggen, z.B. mit dem vba-sdl-h, wenn du dir nicht ganz sicher bist, ob das was du tust semantisch richtig ist, das ist bei Assembler nicht immer so leicht nachzuvollziehen, gerade am Anfang wenn man sich noch nicht so ganz auskennt, wenn "S" die Spezies ist, die in r5 kommt (sofern das stimmt)


    Code
    1. ldr r6, .Startoffset @r6 := .Startoffset
    2. sub r5, r5, #1 @r5 := S-1
    3. mov r7, #28 @ r7 := 28
    4. mul r5, r7 @ r5 := (S-1)*28
    5. add r5, r5, r6 @ r5 := (S-1)*28 + .Startoffset
    6. add r5, r5, #6 @ r5 := (S-1)*28 + .Startoffset + 6
    7. ldrb r1, [r5] @ r1 := [1 Byte von] ((S-1) *28 + .Startoffset +6)

    Was zumindest in der Theorie stimmen sollte, wenn du den ersten Typen des Pokémon mit Spezies S lesen willst, und dein Startoffset auf die Pokémon Basisdaten zeigt.


    Ein Wort zum Codestil: Es ist etwas befremdlich, wenn du Labels mit einem Punkt beginnen lässt, aus dem einfachen Grund, dass ein Compiler das im Regelfall auch nicht tut. Die Assemblersyntax zwingt dich nicht dazu, das zu tun. Außerdem solltest du deinen Labels Aussagekräftige Namen geben, sonst weißt du in 2 Monaten nicht mehr, was "Startoffset" sein sollte, und es schickt sich, zur besseren Lesbarkeit, Wörter in einer (konsistenten) Form zu trennen, z.B. UpperCamelCase, lowerCamelCase oder delimiter_seperated, das erhöht die Lesbarkeit deines Codes. Das ist gerade bei Assembler enorm wichtig, weil das Zeug gerne mal ungeheuer große Ausmaße annimmt, wenn man viel in Assembler programmiert.


    Außerdem: Es ist cool, dass du versuchst Assembler zu lernen, und es wird dir vermutlich viel bringen, v.a. wenn du das Spiel analysieren willst, wirst du da nicht drum rum kommen, weiter so! Es sei nur gesagt, dass es auch andere Programmiersprachen gibt, z.B. C/C++, die ebenfalls in ein vom GBA verstandenes Assembler kompiliert werden können, und wesentlich leichter zu lesen/schreiben sind. Beispielsweise könntest du in C so beide Typen eines Pokémon lesen, und hättest sogar noch starke Typisierung:


    Code
    1. //gets the type of a species, gets the secondary type iff second is true
    2. enum PokemonType get_pokemon_type(u16 species, bool second) {
    3. if(second)
    4. return pokemon_base_stats[species].type[1]
    5. else
    6. return pokemon_base_stats[species].type[0]
    7. }

    Man muss natürlich dem Compiler sagen, was z.B. eine PokemonSpecies ist, oder wie die pokemon_base_stats aussehen, aber wenn das erledigt ist, ist der Code um einiges einfacher zu lesen, als Assemblercode.


    Ich habe mir noch die Mühe gemacht und das in Godbolt reingefriemelt, damit man sehen kann wie der C Compiler damit umgehen kann: https://godbolt.org/z/4vg768 - Wie man sehen kann, macht der Compiler Sachen, auf die man als Mensch gerade am Anfang nicht so schnell kommen würde, z.B. vermeidet er die mul Instruktion um Zeit zu sparen, er berechnet zuerst 7s und multipliziert das dann mit 4, um auf 28s zu kommen, dazu verwendet er binäre Shift Operationen. (Was am Anfang vllt nicht unbedingt ganz so trivial ist)


    ~Sturmvogel

    Das sind bad instructions... Weil es bad instructions sind (welp) - Weil es die Instructions einfach nicht gibt. Ein exklusives oder ist ein EOR, und ein MOD, wobei ich annehme, das soll eine Ganzzahlige Division mit Rest sein, gibt es einfach nicht.


    Es gibt einen Software Interrupt (Eine Funktion, die schon im GBA BIOS implementiert ist, aber halt trotzdem Software) für Division, und Division mit Rest. Der Befehl um einen Software Interrupt auszulösen, ist swi <imm> und führt die durch <imm> indizierte Routine im BIOS aus. Die Division ist der swi 6 wobei in r0 der dividend ist, r1 der divisor, und nachdem die Kontrolle vom Interrupt Handler wieder an dich übergeben wird, hast du in r0 das Ergebnis r0 / r1, und in r1 das Ergebnis r0 % r1 - Ich weiß nicht wie genau die Konvention für die ISR ist, aber ich würde davon ausgehen, dass der Inhalt von r2 und r3 nach der Ausführung invalidiert wird, wenn du dort also wichtige Informationen hast, musst du die vorher sichern, entweder am Stack, oder in einem Callee Save Register (r4-r7, r8-r12)


    Hier kannst du mehr über die Software Interrupts lesen: https://problemkaputt.de/gbatek.htm#biosfunctions


    ~Sturmvogel


    E: Nachdem Assembly Code im Normalfall eine Qual zu lesen ist, und ich sowieso nicht genau weiß, was du tun willst, bzw. was deine Ausgangsbedinungen sind, spare ich mir mal ein Korrekturlesen, sorry :D - Ich schlage vor du probierst das einfach aus.

    Hey, also zuallererst, das was Wodka und Ich hier schreiben, ist C Code, also Programmcode. Der kann von einem C Compiler nach Assembly kompiliert werden. Nachdem du ARM/Thumb Code erzeugen willst, brauchst du einen ARM C Compiler, beispielsweise arm-gcc. Eine Version dieses Compilers ist in Devkit Pro vorhanden: https://github.com/devkitPro/installer/releases


    Zum "ausprobieren", was der Compiler mit deinem C Code tut, kannst du einen Compiler Explorer, z.B. Godbolt verwenden: https://godbolt.org/z/jMrO6R


    u32 ist der (selbst definierte) Datentyp. Es hat sich in der RH Szene eingebürgert, u32/u16/u8 für unsigned integer, short, byte zu verwenden, bzw. s32, s16, s8 für die Typen mit Vorzeichen, in dem godbolt example oben siehst du diese Definitionen auch. Das ist im Endeffekt alles Kram aus der C Syntax. Im Normalfall würden solche Definitionen dann in einer eigenen Datei stehen, und als Header inkludiert.


    Es gibt auch ein Tutorial, wenn man sich damit ein wenig mehr beschäftigen möchte: Programmieren für den GBA (Auch wenn du, zumindest für den Anfang, vllt nicht unbedingt ein Makefile verwenden willst, wie in dem Tutorial erklärt)


    ~Sturmvogel

    Um das ganze mal zu konkretisieren, was willst du denn erreichen? Das da oben ist ein ziemlich krummes Polynom mit einer Maximumsstelle bei ~ 100, also irgendwas mit Levelkurven?


    Im Endeffekt kannst du das natürlich approximieren, LUTs verwenden, etc. Gerade wenn es nur um Werte für die ersten, natürlichen Inputs geht, wird die LUT nicht einmal groß werden, und du brauchst theoretisch gar nichts mehr interpolieren, weil du ja alle Werte darstellen kannst.


    Wenn es doch um irgendwas anderes geht, und du auch rationale/reelle Eingabewerte hast, kannst du immer noch anfangen, linear zu interpolieren, wobei hier vermutlich kubische Splines wirklich bessere Werte liefern könnten. (Nicht, dass das notwendig wäre, je nach Anwendungsfall)


    ~Sturmvogel


    Edit: Wenn es wirklich um EXP Kurven geht, kannst du ja auch einfach mal versuchen, ein paar Fixpunkte zu setzen und dann dazwischen eine Funktion zu interpolieren^^

    Du musst nicht interpolieren, vergrößerst dabei aber den Fehler enorm, v.a. in Relation auf die Größe deiner Tabelle. Außerdem ist eine lineare Interpolation selbst auf dem GBA in annehmbarer Zeit durchgeführt. Probleme bekommst du vermutlich mit der floating point Arithmetik, die ist auf einem so alten Prozessor sehr teuer, weil es dafür keine Hardware gibt.


    Was ich nicht ganz verstanden habe ist, was du mit "jedem Wert" meinst, denn der Sinus ist für alle reellen Zahlen definiert, selbst wenn du nur das Intervall [0;pi] betrachtest, woraus du den Sinus vollständig beschreiben kannst, brauchst du eine unendlich große Tabelle. Theoretisch könntest du eine Tabelle für alle nach IEEE float/double definierten Zahlen in dem Intervall erstellen, aber das ist selbst auf moderner Hardware Irrsinn, weil die Genauigkeit selbst einfacher Methoden wie linearer Interpolation mehr als hinreichend sind, um die meisten Aufgaben zu bewältigen. Selbst eine LUT mit "nearest neighbor" interpolation (Also eine links/rechtsstetige Treppe) wird vermutlich, sofern groß genug, ausreichen, wenn du das nicht gerade brauchst um analytisch exakte Ausdrücke darzustellen.


    ~Sturmvogel

    Ich glaube, ich verstehe nicht so ganz, was du meinst, aber je nachdem was du modellieren willst, lässt sich das doch auch einfach mit arithmetischen Grundfuntkionen bauen. Das geht natürlich nicht mehr, wenn du irgendwelche komplizierten Terme hast, die kann man auf so einer Hardware wie dem GBA höchstens aproximieren.


    Die Funktion oben lässt sich z.B. recht einfach darstellen:


    Code
    1. u32 f(u32 x){
    2. return 3*x*x*x + 2*x*x + 7;
    3. }

    Bzw. das macht ein moderner C Compiler (Mit höchster Optimierung) daraus:


    Hier wird das Argument (x) in r0 übergeben und anschließend die Funktion in relativ wenigen Opcodes berechnet. (Kannst ja mal versuchen, nachzuvollziehen, wieso das funktioniert)


    Schwieriger wird es für Funktionen wie sin(x) oder z.B. natürliche Exponentialfunktion oder den natürlichen Logarithmus, Wie man sowas effizient berechnet, damit beschäftigt sich u.a. die Numerik, ein Teilgebiet der Mathematik.


    Ich hoffe damit kannst du was anfangen :)


    ~Sturmvogel

    Das ist zwar technically ein Fork, aber es gibt noch ein Repository vom VBA-SDL-H: https://github.com/cosarara/vba-sdl-h/releases


    ~Sturmvogel


    Edit: Nachdem das Release von oben nur ein Linux Build ist, habe ich mal den letzten mir bekannten Windows Build des Originalautors bei uns in die Filebase geschoben:

    Den Fork müsste man erst selbst für Windows bauen (Was beim VBA nicht unbedingt lustig ist, wenn ich mich so daran erinnere)

    Ich glaube schön langsam, ich antworte das auf gefühlt jeden zweiten Thread hier, aber naja... Wenn du ein Feature implementieren willst, dass es so noch nicht gibt, wird dir nichts anderes übrig bleiben, als es selbst zu bauen. Ich weiß nicht, wie sehr du dich mittlerweile mit Programmieren, bzw. C/Assembly auskennst, aber darauf wirds hinaus laufen. Ich denke es bringt dir auch nicht viel, wenn die etwas erfahreren hier jetzt anfangen mit Funktionsnamen und Offsets zu werfen. Es sollte, wenn man sich auskennt, nicht allzu schwierig sein, das was du vorhast umzusetzen, aber ein bisschen Research und Arbeit ist da halt von Nöten. Dazu: Eigeninitiative, einfach mal was machen, und schauen was dabei raus kommt, ansonsten wird man vermutlich nichts dazu lernen.


    Von Designersicht her weiß ich nicht ob das was du vor hast so sinnvoll ist. Man muss sich halt überlegen was das dann alles für Auswirkungen hat und inwiefern das Kampfsystem dadurch komplexer wird, vllt. sogar zu komplex. Wenn auf einmal 5 Effekte am Feld aktiv sind, die sich gegenseitig beeinflussen, hast du ggf. noch unerwünschte Nebeneffekte, die du nicht vorhersehen konntest. Inwiefern eine Unterscheidung in verschiedene Kategorien Sinn ergibt finde ich auch eher fragwürdig, da ist der Impact des Systems dann wieder nicht groß genug um etwas zu merken. Wettereffekte wirken sich im Normalen Spielverlauf ohnehin nicht großartig auf den Kampfverlauf aus, da ist es mir als Spieler dann auch eher egal, ob ich noch einen starken Regen habe, was auch immer der dann besser / schlechter macht, wenn der normale Regen schon nicht relevant ist.


    Vielleicht zum Schluss noch, wenn dir "jeglicher Ansatz" fehlt: Schau dir einfach mal an, was andere so tun, und was das Spiel selbst tut. Ich weiß, man will immer alles ganz groß und toll und glitzernd haben, aber am Anfang ist es vermutlich gescheiter, einfach mal zu lernen, und einfache Sachen zu Programmieren.


    ~Sturmvogel

    Es soll so funktionieren - sobald der spieler ein pokemon auf der route fängt, sollte keine wildes mehr auftauchen....

    So funktionieren Levelscripts nicht, das wirst du auch net umsetzen können, ohne dich da ein bisschen tiefer reinzuhacken.

    Bzw. Wie kann ich ein levelscript schreiben, dass startet sobald der trainer 2 pokemon in seinem team hat?

    Das sollte mit countpokemon recht einfach umzusetzen sein.


    ~Sturmvogel

    Der Schaden skaliert linear zum Level, das gleiche gilt für alle Stats, also ergibt es zumindest Überschlagsmäßig gerechnet Sinn, dass der Schaden bei so hohen Leveln ein bisschen eskaliert, v.a. bei sehr starken Angriffen wie Wutanfall. Je nach Effektivität kann es dir da aber auch passieren, dass Pokémon auf niedrigerem Level sich mit zumindest ordentlich viel Schaden machen. Hinzu kommt, dass die Base Stats von so Legendären Pokémon nochmal ein bisschen härter sind, bei Rayquaza vs. Mewtu hast du eine Differenz von ~60 zwischen den Base Stats(!) von Angriff und Verteidigung, was bei einem so hohen Level für einen gigantischen Modifier im Schaden sorgt.


    Prinzipiell würde ich sagen, dass alle Formeln für einen Bereich 1-100 konzipiert wurden, und man damit arbeiten sollte. Wenn dein Spiel so lange wird, dass Level 100 nicht genug ist, würde ich entweder die XP Skalierung so tweaken, dass das eben wieder passt, man levelt dann halt langsamer. Wenn du unbedingt die hohen Level willst, könntest du schauen, wie du die ganzen Kurven mathematisch so modellieren/skalieren kannst, dass deine Werte annehmbare Größen annehmen. Die einfachste Lösung wäre vermutlich alles über die 200 Level einfach zu strecken, wenn du die Funktionen für bestimmte Bereiche tweakst, wird mit an Sicherheit grenzende Warscheinlichkeit das Balancing drunter leiden.


    Wo die Routine, v.a. in Smaragd rumgeistert, kann ich dir nicht sagen, weil ich kein Smaragd (mehr) hacke.


    ~Sturmvogel

    Das sind vermutlich ein paar viele Sachen auf einmal...


    Was genau ist denn dein Problem, du beschreibst in einem Satz ein Problem, lieferst dann eine halbe Lösung für jenes, und fängst an ein anderes zu beschreiben.


    Ein paar Grundlegende Sachen: Das NPC System von Pokémon auf dem GBA ist auf eine begrenzte Anzahl von Paletten ausgelegt und so gebaut worden. Warum das so ist mag viele Gründe haben, vermutlich haben die Devs damals einfach gedacht, es wäre mit dem Grafikstil ohnehin besser zu vereinbaren, und für die "Frontend" Leute war es schlicht einfacher, genau kann man das natürlich nicht sagen. Nun gibt es da Mittel und Wege herum, so ohne weiteres geht das aber nicht. Hier findest du eine Implementation von einem Dynamic Loader für Paletten: https://github.com/SBird1337/s…world/dynamic_overworld.c - Ich sage gleich dazu, dass das nicht unbedingt die schönste herangehensweise an sowas ist, aber hey, it's called Rom"Hack" for a reason...


    Wenn dir der ganze C Code nichts sagt, dann würde ich das auf die schnell einfach mal vergessen. Klingt vermutlich doof, aber Codehacking ist einfach nicht das einfachste, und bei weitem auch nicht das wichtigste beim Romhacking, wenn dich das weiter interessiert kannst du dich hier gerne informieren, Tutorials lesen oder uns fragen, aber be warned: Ist nicht unbedingt das anfängerfreundlichste Thema.


    Der Protagonist teilt sich AFAIK die Palette mit dem Antagonisten und ein paar Spiegelungen, allzu sicher bin ich mir da auch nicht, am Ende des Tage haben die 100 noch was Sprites halt einfach eine begrenzte Anzahl an Paletten, damit muss man mehr oder weniger immer leben, weil der GBA nur "so" viele Farben darstellen kann.


    Wie man Custom Pokémon erstellt? Welp, was willst du denn tun? Jedes Pokémon hat Stats, Sprites, Icons, Dexlore, ... - Wie man das alles mehr oder weniger bearbeitet kannst du bei uns in der Tutorial Sektion nachlesen, wenn du konkrete Fragen hast, kann sie dir ein findiges Mitglied sicher beantworten.


    Noch viel Erfolg weiterhin, oh, und die Bilder: Dachte nie, dass ich das mal aktiv sagen muss, aber: DSGVO, basically, externe Bilder werden von der Forensoftware blockiert.


    ~Sturmvogel

    Altes Zeuch, ich persönlich kenne dafür so gut wie keine Tools, auch wenns möglich wäre, dass mal was existiert hat. Heute kümmert sich da auch noch kaum einer drum. Mir würde jetzt abgesehen von selbst researchen und Hex Editor nichts einfallen.


    Gibt es einen bestimmten Grund warum es nicht eines der Remakes geworden ist?


    ~Sturmvogel

    Newsflash: Leute, die hier an ihren Projekten arbeiten machen das in ihrer Freizeit, verdienen damit kein Geld (Und wollen das vermutlich auch nicht, schon allein aus rechtlichen Gründen) - Dazu eine einfache Frage: Wie kommt man darauf, von solchen Leuten etwas zu verlangen? Wenn du vom netten Eisverkäufer aus der Nachbarschaft mal eine Kugel Minz-Crunch geschenkt bekommst, gehst du dann nach 2 Wochen wieder hin und beschwerst dich darüber, was es nicht für eine Frechheit sei, dass du kein Eis mehr geschenkt bekommst?


    Wenn dir etwas an den Projekten hier liegt, kannst du dich ja einbringen, dich für ein Hack Team bewerben, oder dein eigenes Projekt starten. Und wenn es nur konstruktive Kritik ist, hilft das den Leuten schon.


    Verwarnen oder Santktionieren, weil jemand ein selbst gestecktes Ziel nicht einhalten kann- oder will, das wird hier natürlich niemand.


    ~Sturmvogel

    Hallo Community :)


    Ich habe in den letzten Tagen/Wochen an einem kleinen Projekt gearbeitet, das für den ein oder anderen vielleicht interessant ist. Falls man schon einmal mit IT Sicherheit näher beschäftigt hat, kennt man vielleicht den Begriff "CTF Contest" - Das ist nichts anderes als eine Sammlung von Aufgaben, die bestimmtes Wissen aus der Security erfordern. In diesem Fall handelt es sich um einen "RH CTF" - man braucht also Wissen über's Romhacking, um die Aufgaben zu lösen. Dabei lernt man vielleicht das ein oder andere über die Thematik. Eine kleine Vorwarnung, es sind Hacking Challenges, man muss sich also vermutlich ein bisschen mit der Materie beschäftigen, und das Hirn einschalten. Es sind sicher ein paar einfachere Aufgaben dabei, aber nicht alles ist trivial. Für die Challenges könnt ihr, wenn ihr euch anmeldet, Punkte sammeln, allerdings könnt ihr die Aufgaben auch lösen, ohne angemeldet zu sein (Zumindest sollte das gehen :P)


    Ein paar Richtlinien, die bitte zu beachten sind:

    • Es ist ein Contest, bitte verderbt euch nicht gegenseitig die Freude indem ihr Lösungen austauscht, ihr könnt natürlich im Team arbeiten, oder alleine, das ist ganz egal.
    • Es ist zwar ein Contest, aber es gibt keine Deadline, also könnt ihr solange basteln wie ihr wollt.
    • Falls ihr glaubt Fehler in den Challenges gefunden zu haben, schreibt mir bitte eine PM oder E-Mail mit eurem Lösungsweg, und postet eure Lösungsversuche nicht hier.
    • Es ist ein Hacking Contest, aber alle Aufgaben sind, sofern nicht anders spezifiziert, mit den mitgelieferten Dateien zu lösen, bitte fahrt keine Angriffe welcher Art gegen die CTF Umgebung!
    • Wenns irgendwo komplett hackt, gibt es für Punkte Hinweise zu "kaufen" - Ihr könnt natürlich auch mich oder andere Spieler nach Tipps fragen, es soll ja allen Spaß machen, und nicht zu kompetetiv sein.

    Eine kurze Einführung, wie so etwas funktioniert findet ihr in der ersten Challenge "Flag Format", auf der Startseite, und hier in ein paar Punkten:

    • Ihr bekommt meistens eine Datei mit einer vagen Aufgabenbeschreibung.
    • Zu finden sind in diesen Dateien "Flaggen", diese sehen so aus: rhCTF{Ein_valides_Flag_siEhT_so_aus}
    • Die Flags könnt ihr in der CTF Umgebung eingeben ("abgeben") und so Punkte erhalten.
    • Wenn ihr keinen Account auf der CTF Umgebung habt, könnt ihr trotzdem eure Lösungen überprüfen. (Zur Registrierung ist eine E-Mail erforderlich, dabei könnt ihr auch gerne eine Fake-Mail verwenden, ich sammle eure Daten ohnehin nicht)
    • Für die Challenges gibt es Punkte, diese spiegeln in etwas(nach meinem Ermessen...) die Schwierigkeit wider. Schwere Challenges geben mehr Punkte.

    Aktuell gibt es 5 Challenges in 3 Kategorien, die alle etwas mit dem GBA zu tun haben, solltet ihr Ideen für andere Challenges haben schreibt mir gerne eine PM / E-Mail. Solltet ihr selbst eine Challenge beitragen wollen, könnt ihr das auch => PM oder E-Mail. Beachtet dabei, dass andere die Challenge zum einen technisch lösen können müssen, und zum anderen ihr, als Challenge Autor, immer glaubt eure Challenge sei leichter als sie ist.


    Die CTF Umgebung findet ihr hier: https://ctf.karathan.at


    Ich hoffe einige haben eine Freude daran, Happy Hacking!


    ~Sturmvogel

    Es gibt eine Variable (0x4023) - die einen Schrittcounter darstellt, zumindest in Feuerrot. Die hört aber bei 0x5dc auf zu zählen, und bringt dir in deiner Situation auch nur bedingt etwas. Wie manuth schon gesagt hat, kannst du ansonsten halt mit "echtem" Code so ziemlich alles am Spiel ändern, und so ein Script auszuführen ist gar nicht allzu schwierig, man wird aber nicht drum rum kommen, sich ein bisschen mit der Materie zu beschäftigen, und wohl oder übel Programmieren lernen (müssen).


    Ein Beispiel wie sowas (In Raw ASM...) aussehen kann: https://github.com/SBird1337/s…yer_interaction/on_step.s

    In C wäre das vermutlich nicht so schlimm viel Code, und wäre besser zu lesen...


    ~Sturmvogel