Portal-Zone Gothic-Zone Gothic II-Zone Gothic 3-Zone Gothic 4-Zone Modifikationen-Zone Download-Zone Foren-Zone RPG-Zone Almanach-Zone Spirit of Gothic

 

Page 1 of 7 12345 ... Last »
Results 1 to 20 of 121
  1. View Forum Posts #1 Reply With Quote
    Knight mud-freak's Avatar
    Join Date
    Dec 2005
    Posts
    1,226
     
    mud-freak is offline

    Ninja

    --- release of version 2.0 pending... ---

    [Bild: NinjaLogo_0.png]
    [English version below]

    Im Gothic Modding gibt es Grafikpatches, die man mit verschiedenen Mods und anderen Grafikpatches kombinieren kann. Mit Skriptänderungen geht das ja bekanntlich nicht - "Skriptpatches" in dem Sinne gibt es nicht.
    "Ninja" ist ein Versuch das zu ermöglichen, sowohl für Gothic 1 als auch Gothic 2.

    Ein Ninja-Patch ist jeweils eine VDF-Datei, die alle möglichen Skriptänderungen in jegliche Mod injizieren kann (ob Content, Menü, PFX, VFX, SFX, FightAI, Music oder Camera), als auch neue Animationen (ohne bestehende MSB-Dateien der unterliegenden Mod zu ersetzen). Was genau alles damit möglich ist, führe ich weiter unten auf. Des Weiteren lassen sich Ninja-Patches beliebig stapeln, z.B.: Freies Zielen + Bloodsplats + Ausdauersystem + ...


    Bevor ich darauf eingehe, wie man Patches erstellt und wie sie funktionieren möchte ich in diesem Post einige Beispiele vorstellen.

    1. Freies Zielen (Gothic 1, Gothic 2)
    Dieser Ninja-Patch führt so ziemlich alles vor was man mit Ninja machen kann: Es werden neue Animationen eingeschleust ohne etwaige neue Animationen der Mod zu beeinträchtigen, Ikarus und LeGo werden benutzt ohne die unterliegende Mod einzuschränken, falls sie LeGo schon verwendet, Menü-Einträge im Spielmenü werden eingefügt ohne das Spielmenü der Mod zu "resetten", dazu noch automatisch in der Sprache in der die Mod angeboten wird (deutsch, englisch, polnisch oder russisch).

    2. LeGo Bloodsplats (Gothic 2)
    Dieser Ninja-Patch fügt die LeGo Bloodsplats in eine Mod ein. Der Patch zeigt (ebenso wie der Ninja_GFA-Patch) wie man LeGo Pakete im Nachhinein hinzufügen kann, auch wenn es bereits von der Mod initialisiert wird.

    3. Workaround (Gothic 1, Gothic 2)
    Dieser Ninja-Patch ist besonders nützlich, um Workarounds für Storybugs zu ermöglichen. Eine Quest lässt sich nicht abschließen, ein Dialog wurde bereits zu früh gesprochen, eine Variable muss ihren Wert ändern, usw. Bis ein Mod-Team einen Fix bereitstellen kann, kann man damit also schon akute Probleme beheben. Weitere Infos in der Readme innerhalb der VDF-Datei.

    4. OreArmor (Gothic 2)
    Dieser Ninja-Patch fügt die Erzrüstung aus Gothic 1 in eine Mod ein (Insertcode: ore_armor_de oder ore_armor_en). Hierbei ist interessant, dass die Rüstung problemlos in der existierenden Humans.msb registriert wird, ohne neue Animationen der unterliegenden Mod zu beeinträchtigen.


    Weitere Ninja-Patches:

    5. Uriziel (Gothic 2)
    Dieser Ninja-Patch fügt das originale Uriziel aus Gothic 1 in eine Mod ein (Insertcode: uriziel_de, uriziel_en, uriziel_pl oder uriziel_ru).

    6. Mana Regeneration (Gothic 2) von johnnyboyy
    Mit diesem Ninja-Patch regeneriert das Mana des Helden ab einem konfigurierbarem (Gothic.ini) Schwellenwert mit konfigurierbarer Geschwindigkeit.


    - Ninja-Patches lassen sich beliebig stapeln, sodass man mit allen gleichzeitig spielen kann
    - Voraussetzung ist das SystemPack 1.7 (nicht tiefer, nicht höher)
    - Benutzung auf eigene Gefahr und vor allem: Kein Support
    - Ninja-Patches haben in einer ModKit-Installation nichts zu suchen

    In der Versionsinformation (üblicherweise unten rechts im Hauptmenü falls eingeschaltet) ist einzusehen, ob Ninja aktiviert ist ("2.6fx-S1.7-N1.2").




    [Bild: NinjaLogo_0.png]

    There are graphic patches for Gothic, that can be applied to the game and to various of the game modifications (in short "mods") and can be combined with other graphic patches.
    It is a well-known fact in Gothic modding, however, that this is not possible with scripts - there is no such thing as real "script patches".
    "Ninja" is an attempt to make that possible for both Gothic 1 and Gothic 2.

    A Ninja patch is a VDF that allows to inject any script changes into the game or modifications of it (whether it be content, menu, PFX, VFX, SFX, FightAI, music, or camera scripts), as well as new animations (without breaking existing animations or MDS/MSB files of the loaded mod). What exactly you can do with it is listed below in more detail. Furthermore, Ninja patches can be stacked at will, e.g. free aiming + blood splats + stamina system + ...

    Before I go into detail how a Ninja patch is created and how it works, I want to use this post to introduce a few examples.

    1. Free aiming (Gothic 1, Gothic 2)
    This Ninja patch demonstrates pretty much everything you can do with Ninja: New animation are added without compromising possibly new animations of the loaded mod, Ikarus and LeGo are used without compromising the loaded mod, in case it already uses them, menu entries are added to the game menu without "resetting" the game menu, additionally in in the correct language of the loaded mod (German, English, Polish or Russian).

    2. LeGo blood splats (Gothic 2)
    This Ninja patch adds the LeGo blood splats to a loaded mod. The patch shows (much like the Ninja_GFA patch) how LeGo packages can be added later on, even if the mod already initializes.

    3. Workaround (Gothic 1, Gothic 2)
    This Ninja patch is especially useful to introduce workarounds to common story bugs in mods; Close a dead quest, reset a dialog that was spoken too early, change the value of a variable, etc. Until the mod team can provide a fix, this Ninja patch is a great temporary solution for pressing bugs. For more information check out the readme file inside the VDF.

    4. OreArmor (Gothic 2)
    This Ninja patch inserts the ore armor from Gothic 1 into any mod (insert code: ore_armor_de or ore_armor_en). Here it is interesting, that the armor can be registered without problems into an existing Humans.msb without compromising any new animations the loaded mod might introduce.


    More Ninja patches:

    5. Uriziel (Gothic 2)
    This Ninja patch inserts the original Uriziel from Gothic 1 into any mod (insert code: uriziel_de, uriziel_en, uriziel_pl or uriziel_ru).

    6. Mana Regeneration (Gothic 2) by johnnyboyy
    This Ninja patch adds mana regeneration for the hero from an adjustable (Gothic.ini) threshold with adjustable speed.


    - Ninja patches may be stacked at will to allow playing with all of them at the same time
    - SystemPack 1.7 is required (no older or newer version is supported)
    - Use at your own risk: There is no support
    - Ninja patches have no business in mod-kit installations

    The version information (typically in the bottom right of the main menu, provided it's not turned off) shows whether Ninja is activated ("2.6fx-S1.7-N1.2").






    Changelog

    v1.2: Mar 23, 2018
    • Fix rare bug in animation ninja
    v1.1: Mar 14, 2018
    • Ninja for Gothic 1
    • Re-implementation of finding files: old VDFS no longer used = more stability and faster loading times
    • Minor fixes
    v1.0: Mar 7, 2018
    • Initial release
    Last edited by mud-freak; 27.06.2019 at 15:29. Reason: Adjust info of Mana Regeneration Ninja patch

  2. View Forum Posts #2 Reply With Quote
    Knight mud-freak's Avatar
    Join Date
    Dec 2005
    Posts
    1,226
     
    mud-freak is offline
    [English version below]

    Dieses Kapitel des Moddens richtet sich an erfahrene Modder, denn man kann dabei viel falsch machen und sollte ein gutes Verständnis von den Skripten haben und wie Ninja funktioniert. Falls Ninja sich bewährt und man einen Ninja-Patch erstellen will, ist dieser Post hier Pflichtlektüre.


    Der Name "Ninja"

    Der Name passt aus mehreren Gründen:
    • Die neun Ninjas, die ein Patch einsetzt, "infiltrieren" die Mod Skripte und "injizieren" Änderungen.
    • Sie sind schnell und agil: Sie winden sich um die existierenden Skripte ohne jegliche Kollision.
    • Sie sind leise aber tödlich: Es gibt keine großartigen Fehlermeldungen. Wenn der Patch nicht vernünftig ausgearbeitet ist, endet er für die Ninjas tödlich (Spiel stürzt ab).
    • Sie setzen sich mit Gewalt durch: Wenn man nicht aufpasst, kann man damit unterliegende Mods kaputt machen.

    Das Patching System

    Wie gesagt besteht das System aus neun Ninjas, die erst einmal alle auf dem selben Prinzip aufbauen (außer der Animation-Ninja dazu später mehr). Die Ninjas nehmen Aufträge entgegen und führen diese beim Start von Gothic nach folgendem Schema aus:
    • Gothic lädt die Gothic.dat ➞ der Content-Ninja führt seine Änderungen ein,
    • Gothic lädt die Menu.dat ➞ der Menu-Ninja führt seine Änderungen ein,
    • ...
    Nun, wie sehen solche Aufträge aus? Die Aufträge sind die uns bekannten SRC-Dateien. Die Ninjas nehmen die für sie entsprechenden SRC-Dateien entgegen und parsen sie nach dem Laden der entsprechenden DAT-Datei. Richtig: Parsen. Da die Ninjas infiltrieren und injizieren, werden die Skripte in unkompilierter Form benötigt. Das mag etwas ungewohnt sein und das würde zwar theoretisch auch mit DAT-Dateien gehen, das wäre aber um einiges aufwändiger - sowohl für die Ninjas und für den Ersteller des Patches. Das Parsen habe ich so abgewandelt, dass das Überschreiben von Symbolen (d.h. Variablen, Funktionen, usw.) erlaubt ist. Wie das reguliert ist, erkläre ich weiter unten.
    Um neue Skripte nicht nur einzuschleusen, sondern auch anzustoßen, kann man Initialisierungsfunktionen erstellen, die von Ninja aufgerufen werden (auch weiter unten erklärt).


    Implementation

    Wie geht das alles überhaupt? Das SystemPack bietet die Möglichkeit beim Starten von Gothic Maschinencode in die GothicMod.exe bzw. Gothic2.exe zu injizieren. In etwa so wie man das von Ikarus kennt, nur eben ganz zu Beginn und ohne die Abhängigkeit von den Skripten. Ich habe über 3100 Bytes Maschinencode geschrieben, der Parsing-Limitierungen aufhebt, Ninja-SRC-Dateien sucht und der Reihe nach parst, Initialisierungsfunktionen aufruft und Animationen einschleust.


    Angepasstes Parsen

    Wie gewohnt erstellt man jeweils eine SRC-Datei für jeden Parser, den man braucht (also jeweils einen Auftrag für jeden Ninja den man einsetzen will). Der Dateipfad setzt sich (ausgehend vom Gothic-Installationsverzeichnis) folgendermaßen zusammen: "Ninja\[Parser]_Ninja_[PatchName].src", wobei [Parser] der zuständige Ninja ist ("Content", "Menu", "Camera", "PFX", "SFX", "VFX", "Music", "Fight", "Animation") und [PatchName] eine eindeutige Bezeichnung des Ninja-Patches. In dieser SRC-Datei werden alle D-Dateien oder weitere SRC-Dateien verlinkt. Wichtig ist hier, dass die Ninjas keine Wildcards (* und ?) unterstützen, sodass jede Datei explizit genannt werden muss. Die Ninjas bringen Gothic dann dazu diese SRC-Dateien über die geladenen DAT-Dateien zu parsen.

    Damit häufig verwendete Pakete (wie Ikarus und LeGo) sowohl bei Mods, die diese verwenden, als auch bei Mods, die sie nicht verwenden, funktionieren, winden sich die Ninjas um Parserfehler, wie "Redefined Identifier" herum. Jegliche Symbole können also ersetzt werden, ob Variablen, Konstanten oder Funktionen. Klassen, Prototypen und Instanzen hingegen werden "gemerged" (dt. zusammengefügt), d.h. sie können nicht verkleinert, sondern nur verändert oder vergrößert werden. Weitere Ausnahmen sind leere Funktionen und die Ikarus-Symbole, die mit Sprüngen zu tun haben (MEM_Label, MEM_Goto, repeat, while). Diese werden beim Parsen ignoriert, sollten sie schon existieren. Das ist notwendig, um die Implementation der Ikarus-Sprünge nicht zu zerstören.
    Es ist unabdingbar, dass Ninja-Patches, die LeGo enthalten, fortlaufend auf die neuste LeGo Version aktualisiert werden, um andere zeitgleich geladenen Patches nicht zu beeinträchtigen, in dem sie neuere LeGo Versionen mit einer älteren überschreiben.

    Zwar sind die Ninjas sehr agil, allerdings stellen sie ihre Aufträge nie in Frage. Man sollte also mit dem Ersetzen von Symbolen äußerst vorsichtig sein! Ein leichtsinnig erstellter Patch, mit schlecht gewählten Variablennamen, kann schnell Dinge in der Mod überschreiben, die ungewünscht sind. Außerdem wird beim Überschreiben eines Symbols mit gleichem Namen auch der Typ des Symbols ersetzt. Normalerweise kein Problem, aber ein rücksichtsloser Patch-Ersteller könnte aus einer Integervariable eine Stringvariable machen. Damit wird es dann im laufenden Spiel zu Abstürzen kommen, die nicht leicht nachzuvollziehen sind. Das gilt nicht nur für Symbole aus der DAT-Datei, sondern auch für andere Ninja-Patches. Deshalb müssen Symbole in Ninja-Patches einzigartigen Namen haben (d.h. Patch-spezifische Variablen/Funktionen); Konvention: Konvention: Ninja_[PatchName]_[SymbolName], z.B. Ninja_GFA_MergeLeGoFlags. Daher die Richtlinie:
    Übliche Symbolnamen vermeiden (z.B. Var1 oder a, b, c) und Patch-spezifische Namen wählen.

    Gezieltes Überschreiben sollte allerdings auch nicht falsch verstanden werden und spärlich bis gar nicht verwendet werden. Die Init_Global zu überschreiben (um irgendetwas zu initialisieren) wäre beispielsweise ziemlich dumm, denn es macht alles zu Nichte was die unterliegende Mod möglicherweise schon dort initialisiert. Genau so wäre es dumm, das Hauptmenü zu überschreiben, nur um eine weitere Menü-Option hinzuzufügen - existierende, geänderte Menü-Einträge würden verloren gehen. Da kommt die Frage auf: Was bringen dann die Ninjas, wenn sie gar nichts überschreiben dürfen? Die Antwort darauf sind die Initialisierungsfunktionen (siehe unten).

    Etwas ganz anderes, was man im Hinterkopf behalten sollte ist, dass sich die Symbolindizes von Ninja-Patches verschieben, wenn der Spieler zwischen Speichern und Laden Ninja-Patches hinzufügt oder rauslässt. Da die DAT-Dateien immer zu erst in die Symboltabelle geladen werden, betrifft das nur die Ninja-Patches aber nicht die unterliegende Mod. Normalerweise ist das kein Problem, nur für komplexere Skripte die den Index von Symbolen abspeichern (z.B. LeGos Event-Handler).


    Initialisierungsfunktionen

    Was bringt eine neue Skriptfunktion, wenn niemand sie aufruft? Um nicht nur Dinge hinzufügen zu können, sondern auch bestehendes zu ändern (ohne es komplett zu ersetzen) bzw. die Neuerungen überhaupt anzustoßen gibt es zwei Initialisierungsfunktionen. Diese sind neue, Patch-spezifische Funktionen, die von Ninja aufgerufen werden. Die Idee dahinter ist es, aus ihnen heraus seine eigenen neuen Funktionen aufzurufen.

    Eine Initialisierungsfunktion gibt es für die Content-Skripte (wird immer direkt nach der Init_Global1 aufgerufen) und die andere für die Menü-Skripte (wird jedes mal aufgerufen wenn ein Menü erstellt, d.h. geöffnet wird). Von diesen Funktionen aus kann man Dinge ändern (z.B. LeGo initialisieren oder neue Menü-Einträge ins Menü setzen). Jeder Ninja-Patch kann (muss aber nicht) eine oder beide Funktionen bereitstellen und sie werden der Reihe nach für jeden Patch an den besagten Stellen ausgeführt. Die Funktionen werden von Ninja mittels ihrem Namen gefunden, der sich folgendermaßen zusammensetzt: func void Ninja_[PatchName]_Init() für Initialisierungen nach Init_Global1 und func void Ninja_[PatchName]_Menu(var int menuPtr) für Initialisierungen beim Öffnen von Menüs, wobei das Funktionsargument menuPtr, einen Zeiger auf das sich öffnende Menü (zCMenu) enthält.

    Die Funktionen müssen natürlich vom Content-Ninja geparst werden. Wenn man also nur einen neuen Menü-Eintrag hinzufügen will, bedarf es nicht nur einer SRC-Datei für den Menu-Ninja, sondern auch einer für den Content-Ninja, in der die Datei gelistet ist, die die Initialisierungsfunktion enthält.

    Wie man geschickt einen Menü-Eintrag einklinkt, wird im Freies-Zielen-Patch veranschaulicht.
    Wie man LeGo-Pakete initialisiert ohne ein bereits initialisiertes LeGo der unterliegenden Mod oder anderer Ninja-Patches zu beeinträchtigen, wird auch in den Beispielpatches gezeigt, am besten nachzuvollziehen im Bloodsplats-Patch. Verwendet man LeGo in seinem Patch ist das demonstrierte Vorgehen unumgänglich! Ebenso die einzigartigen Namen der damit zusammenhängenden Symbole (Ninja_[PatchName]_MergeLeGoFlags)!

    1 Da es in Gothic 1 keine Init_Global gibt, wird dort die Content-Initialisierungsfunktion nach der Init_[World], der entsprechenden [World] aufgerufen.


    Spezialfall: Der Animation-Ninja

    Obwohl für Animationen keine Daedalus-Skripte notwendig sind, funktioniert das Injizieren dort ähnlich. Die SRC-Datei wird nur benötigt, um den Patchnamen zu bestimmen ("Ninja\Animation_Ninja_[PatchName].src"). Der Inhalt der Datei wird also ignoriert. Mittels des Namens werden die zu injizierenden MDS-Dateien ermittelt. Diese sollten so benannt sein: "_work\Data\Anims\[PatchName]_[Model].mds", wobei [Model] jeglichem zCModelPrototype entspricht, also z.B. "Humans" für die "Humans.mds".

    Inhalt einer solchen Datei wird gemäß des herkömmlichen MDS-Formats erwartet. Da solch eine MDS-Datei nach Laden der MSB-Datei eingelesen wird, braucht sie nicht vollständig zu sein. Das bedeutet, wenn ich nur eine neue Animation für die Humans.mds hinzufügen will, braucht es nur den gewohnten Block
    Code:
    Model ("Hus")
    {
        aniEnum
        {
            [NEUE ANIMATIONEN HIER]
        }
    }
    ohne jeglicher Registrierung von Meshes oder Trees oder Aufführung bereits existierender Animationen. Ich verweise hier auf den Inhalt des Freies-Zielen-Patches für ein anschauliches Beispiel. Auch lassen sich damit neue Rüstungen registrieren. Dazu ist der OreArmor-Patch ein simples Vorbild.

    Referenzierte Animationen sollten im kompilierten Format am gewohnten Dateipfad im VDF-Archiv mitgeliefert werden (auch hier, siehe die beiden Patches als Vorlage).

    Der Animation-Ninja springt, wie auch das Laden der MDS/MSB-Dateien, immer dann an, wenn das entsprechende Model im Spiel zum ersten Mal angewandt wird (üblicherweise während des Spielladens oder später während des Anwendens von MDS-Overlays). Es wird dabei nur nach MDS-Dateien gesucht, deren Basis-Name mittels einer SRC-Datei angekündigt wurde.

    Hier ist zu beachten, dass man zwar die Eigenschaften einer existierenden Animation (Reverse-Flag, Event-Block, usw.) überschreiben kann, aber nicht die Animation selbst (tut man das trotzdem, wird die neue wortlos ignoriert). Um Animationen effektiv zu ersetzen bedarf es deshalb eines MDS-Overlays, das man dann ganz einfach mittels der Initialisierungsfunktion auf entsprechende NPCs anwenden kann (z.B. mit broadcasts).

    Außerdem ist wichtig zu verstehen, dass der Animation-Ninja sich durch die Engine windet und das Schreiben von entsprechenden Binärdateien aushebelt. Daher der Hinweis, dass Ninja nichts in einer ModKit-Installation von Gothic 2 zu suchen hat (Gothic 1 ist nicht direkt betroffen, der Hinweis gilt trotzdem).


    Debugging

    Die Ninjas können zum Reden gebracht werden, wenn man den zSpy auf Level 5 (oder höher) stellt und nach Informationen filtert (nicht nur nach Warnungen und Fehlern). Alle Ninja-Nachrichten sind durch den Autor-Prefix "J:" gekennzeichnet. Es werden alle angefügten MDS Dateien (inkl. der Anzahl der neuen Animationen) aufgeführt und die Namen der geparsten Ninja-Skriptdateien. Für noch mehr Informationen (zum Preis für verlängerte Ladezeit) kann das zSpy-Level auf 7 erhöht werden, um jedes einzelne von Ninja überschriebene Symbol auszugeben.


    Erstellen einer Ninja-VDF-Datei

    Innerhalb der VDF-Datei gibt es den Ninja-Ordner, der die SRC-Dateien und D-Skript-Datein enthält. Das Verhalten vom VDFS ist zu beachten: Jede einzlne Datei sollte einen einzigartigen Namen haben, um zu verhindern, dass sie von anderen Ninja-Patches überschrieben wird oder sie in anderen überschreibt. Eine gute Vorgehensweise ist es daher der Namenskonvention zu folgen: "Ninja_[PatchName]_[...].d". Ausnahmen sind natürlich häufig verwendete Skriptpakete wie Ikarus und LeGo. Werden weitere Daten benötigt (Texturen, Animationen, usw.) sind diese unter ihrem gewohnten Ordnerpfad ("_work\Data\...") zu finden. Neben den Ordnern "Ninja" und ggf. "_work" im Basisverzeichnis wird natürlich der Ninja-Maschinencode benötigt (erweiterte SystemPack-1.7-Patch-Datei), hier herunterzuladen: Gothic 1, Gothic2. Dabei ist der Dateiname unverändert zu lassen, sowie dass sich die Datei im Basisverzeichnis befindet. Nur unter diesen Umständen wird die Datei berücksichtigt. Ebenso wichtig ist es, dass sich die VDF-Datei folgender Namenskonvention annimmt: "Ninja_[PatchName].vdf".

    Letztlich ist es wünschenswert, dass sich im Basisverzeichnis eine "Readme_Ninja_[PatchName].txt" befindet, in der die Änderungen des Ninja-Patches beschrieben werden, auf mögliche Kompatibilitätsprobleme aufmerksam gemacht wird, notwendige Credits aufgeführt sind, sowie (ganz wichtig!) ein Vermerk um welche Ninja Version es sich handelt! (Derzeit Ninja v1.2) Sollte es eine weitere Version geben, ist diese Information auch für Spieler notwendig für die Kompatibilität mit anderen Ninja-Patches.
    Außerdem wäre es sinnvoll den Link http://tiny.cc/GothicNinja hinzuzufügen (zeigt momentan auf diesen Thread), damit mögliches Interesse an Ninja in die richtige Richtung gelenkt wird und nicht völlig falsche, destruktive Patches in Umlauf geraten. Ninja-Version und der Link sollten auch in den Infotext der VDF-Datei, damit diese Informationen ohne Entpacken für jedermann auszulesen sind. Hier auch wieder: Die oben verlinkten VDF-Dateien gehen mit gutem Beispiel voran.
    Code:
    ╔═══════════════════════╗
    ║ Ninja_[PatchName].vdf ║
    ╚╦══════════════════════╝
     |
     │  ┌────────┐
     ├─>| NINJA/ |
     │  └─┬──────┘
     |    |  ┌──────────┐
     │    ├─>| CONTENT/ |
     │    │  └─┬────────┘
     │    │    ├─> Ninja_[PatchName]_[...].d    // Content/menu Initialisierungsfunktionen falls benötigt.
     │    │    │
     │    │    ├─> Ninja_[PatchName]_[...].d    // Jegliche Content-Skript-Dateien. Man beachte die Dateinamen.
     │    │    ├─> Ninja_[PatchName]_[...].d
     │    │    └─> ...
     │    │  ┌─────────┐
     │    ├─>| SYSTEM/ |
     │    │  └─┬───────┘
     │    │    ├─> Ninja_[PatchName]_[...].d    // Jegliche System-Skript-Dateien. Man beachte die Dateinamen.
     │    │    ├─> Ninja_[PatchName]_[...].d
     │    │    └─> ...
     │    │
     │    ├─> Ninja_[PatchName]_[Parser].src    // Ninja SRC-Dateien, die D-Dateien auflisten. Man beachte die Dateinamen.
     │    ├─> Ninja_[PatchName]_[Parser].src
     │    └─> ...
     |
     │  ┌────────┐
     ├─>| _WORK/ |
     │  └─┬──────┘
     |    │  ┌───────┐
     │    └─>| DATA/ |
     │       └─┬─────┘
     |         |  ┌──────┐
     │         ├─>| .../ ├─> ...                 // Jegliche anderen Ressourcen. Dateien wie Texturen, Meshes oder Sounds.
     |         |  └──────┘
     │         │  ┌────────┐
     │         └─>| ANIMS/ |
     │            └─┬──────┘
     |              |  ┌────────────┐
     │              ├─>| _COMPILED/ |
     │              │  └─┬──────────┘
     │              │    └─> ...                // Jegliche neue Animationen, die in den MDS-Dateien referenziert werden.
     │              │
     │              ├─> [PatchName]_[Model].mds // Ninja MDS-Dateien. Eine entsprechende Ninja SRC-Datei ist notwendig.
     │              ├─> [PatchName]_[Model].mds
     │              └─> ...
     │
     ├─> CODE_[XXXXXXXX].patch                  // Ninja Machinencodedatei(en) für Gothic 1 oder Gothic 2.
     │
     └─> Readme_Ninja_[PatchName].txt           // Informationen zum Ninja-Patch.
     
    _

    Stabilität

    In der aktuellen Version sind keine Probleme bekannt.





    This chapter of Gothic modding is directed towards experienced modders, because there is a lot that can be done wrong and there should be a good understanding of the scripts and how Ninja works. Should Ninja catch on and you want to create a Ninja patch, this here document is compulsory reading material.


    The Name "Ninja"

    This name fits pretty well for several reasons:
    • The nine ninjas, that the patch deploys "infiltrate" the mod scripts and "inject" changes.
    • They are quick and agile: They traverse around existing scripts without any collision.
    • They are silent but deadly: There is no direct error handling. If a patch is not carefully designed, it ends deadly for the ninjas (game crashes).
    • They establish their goal by force: If you are not careful, they break the underlying mod.

    The Patching System

    The system consists of nine ninjas that are based on the same principle (except for the animation ninja, more on that later). The ninjas accept missions and execute them at the start of Gothic in the following fashion:
    • Gothic loads the Gothic.dat ➞ the content ninja injects his changes,
    • Gothic loads the Menu.dat ➞ the menu ninja injects his changes,
    • ...
    Now, what do these missions look like? The missions are nothing more that the usual SRC files. The ninjas take their respective SRC file and parse them after the loading of the corresponding DAT file. Yes: parse. Since the ninjas infiltrate and inject changes, the scripts have to be provided in uncompiled form (D files). This may sound a bit strange for a VDF and it would theoretically be possible to also do it with DAT files, but that would be way more complicated, for both the ninjas and the creator of the Ninja patch. I have altered the parsing such that symbols may be overwritten (variables, functions, etc.). Further below, I explain how this is regulated.
    In order to not only add new scripts, but to also trigger/call/use them, initialization functions may be provided that will be called from Ninja (also explained below).


    Implementation

    How is this even possible? The System Pack offers the option to inject machine code into the GothicMod.exe or the Gothic2.exe at start of Gothic, similar how this can be done with Ikarus, but at the very beginning and without dependencies on any scripts. I have written over 3100 bytes of machine code to circumvent parsing limitations, search and parse Ninja SRC files after one another, find and call initialization functions, and inject animations.


    Modified Parsing

    As per usual, you create one SRC file for each parser that you need (in other words: one mission for each ninja that you'd like to deploy). The file path (starting from the Gothic install directory) looks like this: "Ninja\[Parser]_Ninja_[PatchName].src", where [Parser] is the respective ninja ("Content", "Menu", "Camera", "PFX", "SFX", "VFX", "Music", "Fight", or "Animation") and [PatchName] is the unique identifier of the Ninja patch. In the SRC file all D files or further SRC files are listed. Keep in mind, however, that ninjas do not accept wildcards (* and ?), such that each file has to be listed explicitly. The ninjas then persuade Gothic to parse these SRC files on top of the previously loaded DAT files.

    In order to use common, reoccurring script packages (like Ikarus and LeGo) for mods that do not use them, as well as for mods that do have them, the ninjas evade parser errors like "Redefined Identifier". Any symbol can be replaced, whether it be variables, constants, or functions. Classes, prototypes and instances, on the other hand, will be merged, that is, they cannot be reduced, but only changed or enlarged. Additional exceptions are empty functions and the Ikarus symbols that implement jumps (MEM_Label, MEM_Goto, repeat, while). These will be ignored when being reparsed. This is necessary to not break the Ikarus jumps.
    It is inevitable that Ninja patches that include LeGo are kept up to date to the newest version of LeGo continuously in order not to compromise any other loaded patches by overwriting a newer LeGo version with an older one.

    Although the ninjas are very agile, they never question their missions. You should be very careful with overwriting symbols! A recklessly created patch with poorly chosen variable names may overwrite the wrong symbols unintentionally. Furthermore, the symbol type will also be overwritten. Usually that is not a problem, but a recklessly created patch might change an integer variable to a string variable which will cause crashes mid game that are not easy to track. Not only does this hold for symbols from the DAT file, but also for symbols from other loaded Ninja patches. Thus, symbols in Ninja patches must have a unique name (i.e. to make them patch specific variables or functions); convention: Ninja_[PatchName]_[SymbolName], e.g. Ninja_GFA_MergeLeGoFlags. For this reason, mind this guideline:
    Avoid common symbol names (e.g. Var1 or a, b, c) and instead choose patch specific names.

    Nevertheless, targeted overwriting of symbols should not be misunderstood and used only sparingly. As an example, overwriting the Init_Global (in order to initialize something) would not be very smart, because it throws out any initialization that the underlying mod might have made. Similarly, it would not be very smart to overwrite the main menu just to add one new menu entry - existing, modified menu entries of the mod would get lost. This raises the question: What are the ninjas good for, if they are not allowed to replace anything? The answer to that question are the initialization functions (details below).

    Another important thing to keep in mind is that the symbol indices of Ninja patches shift around if the player loads or unloads different patches between saving and loading. Since DAT files are always loaded into the symbol table first, this only affects Ninja patches, but not the underlying game/mods. Usually this is not a problem, but it should be kept in mind for more complex scripts that save the index of symbols (e.g. LeGo's Event-Handler).


    Initialization Functions

    What good is an added script function, if it is never called? In order to not only add, but to also change existing things (without replacing them completely), or to trigger/call/use these alterations, there are two initialization functions. These are new patch specific functions that are called from Ninja. The idea is to call your new functions from there.

    One of these initialization functions is for the content scripts. It is called every time directly after Init_Global1. The other one is for the menu scripts and is called every time a menu is created, that is, every time when it's opened. From these functions you can initiate changes (e.g. initialize LeGo or inject a new menu entry into the main menu). Each Ninja patch can (but does not have to) provide either one or both of these functions and they will be called one by one for each patch at the mentioned positions. The functions are detected by their names, that is composed like this: func void Ninja_[PatchName]_Init() for the initialization function after Init_Global1 and func void Ninja_[PatchName]_Menu(var int menuPtr) for the initialization function when opening any menu, where the function argument menuPtr is a zCMenu pointer to the menu that is being opened.

    Of course, both functions must be parsed by the content ninja. So if you, for example, want to add a new menu entry, you will not only need an SRC file for the menu ninja, but also one for the content ninja that includes the file that holds the menu initialization function.

    How to add a new menu entry neatly is demonstrated in the Free Aiming Ninja patch.
    How to initialize LeGo packages without breaking the existing LeGo initialization in a loaded mod or in another Ninja patch is also shown in the Free Aiming Ninja patch, as well as in the Bloodsplats Ninja patch (for a simple example). If you use LeGo in your patch, using the demonstrated procedure found in those patches is inevitable! Likewise it is very important that the corresponding symbols have unique names (Ninja_[PatchName]_MergeLeGoFlags)!

    1 Since there is no Init_Global in Gothic 1, the content initialization function is called after the respective Init_[World] in Gothic 1.


    Special Case: The Animation Ninja

    Although animations do not rely on Daedalus scripts, the injection works similarly there. The SRC file is merely needed to determine the patch name ("Ninja\Animation_Ninja_[PatchName].src"). The content of the file is ignored. With the name, the MDS files in question will be determined. These have to be named in the following manner: "_work\Data\Anims\[PatchName]_[Model].mds", where [Model] corresponds to any zCModelPrototype, e.g. "Humans" for the "Humans.mds".

    The contents of the MDS file is expected in the usual MDS format. However, since the file will be read after the MDS/MSB file has been loaded, it does not need to be complete. This means, if you simply want to add a new animation to the Humans.mds, you'll only need the usual block of
    Code:
    Model ("Hus")
    {
        aniEnum
        {
            [YOUR NEW ANIMATIONS HERE]
        }
    }
    without any registering of meshes or trees or the listing of already existing animations. I want to refer you to the contents of the Free Aiming Ninja patch for a good example. Similarly, it is just as easy to register new armors. Please check out the OreArmor Ninja patch for a simple demonstration.

    New animations should be provided in compiled format at the usual file path inside the VDF (again, use the existing Ninja patches as example).

    The animation ninja is initiated, just like the loading of the MDS/MSB files, every time when a corresponding model is loaded in the game for the first time (typically during loading of a game or later when applying MDS overlays). The animation ninja will only search for MDS files whose patch name has been announced with an SRC file.

    Keep in mind, that it is possible to overwrite properties of existing animations (reverse flag, event block, etc.), but you cannot overwrite existing animations themselves (if you do, the changes will be ignored silently). In order to effectively overwrite an animation, create an MDS overlay and a apply it to the desired NPCs via the content initialization function (e.g. with broadcasts).

    Furthermore, it is important to understand that the animation ninja sneaks through the engine while removing the writing of corresponding binary files. Therefore note: Ninja has no business in a mod-kit installation of Gothic 2 (Gothic 1 is not affected by this, the advice still holds, however).


    Debugging

    You may force the ninjas to talk by setting the level of the zSpy logging to 5 (or above) and filter for information (not only warnings or faults). All Ninja messages are indicated by the author-prefix "J:". You'll get insight into appended MDS files (incl. the number of new animations) and parsed Ninja script files. If you need even more information and don't mind the increased loading time, you can increase the zSpy level to 7 to list each and every symbol that the ninjas overwrite.


    Creating a Ninja Patch VDF

    Inside the VDF there is the Ninja directory in which the SRC files and the script D files are located. Keep in mind the mechanism behind the VDFS: Each and every of your files should have a unique name to prevent from overwriting or being overwritten by other Ninja patches. Best practice is to stick to the naming convention: "Ninja_[PatchName]_[...].d". Exceptions may of course be common script packages like Ikarus or LeGo. If further data is required (textures, animations, etc.), place it in the usual file path ("_work\Data\..."). Alongside the directories "Ninja" and (if necessary) "_work" in the root directory, the Ninja machine code is needed (extended SystemPack 1.7. patch file), available for download: Gothic 1, Gothic 2. The file name, as well as its location in the root directory cannot be changed! Only under these circumstances the patch file will be considered. It is equally important to name the VDF by the following naming convention: "Ninja_[PatchName].vdf".

    Finally, it is desirable that the root directory contains a file named "Readme_Ninja_[PatchName].txt", which lists the changes the Ninja patch performs, any compatibility warnings, necessary credits and (very importantly!) a note about with Ninja version is used! (Currently Ninja v1.2) Should there ever be a new version of Ninja, this information is very important even for players to determine the compatibility with other Ninja patches.
    Furthermore, it makes sense to include the link http://tiny.cc/GothicNinja, to steer possible interested people in the right direction and to prevent completely wrong and destructive Ninja patches to get into circulation. Ninja version and the mentioned link should also be included in the info text of the VDF in order to make this information accessible for anyone without unpacking the VDF. Again: Take the existing Ninja patches as example.
    Code:
    ╔═══════════════════════╗
    ║ Ninja_[PatchName].vdf ║
    ╚╦══════════════════════╝
     |
     │  ┌────────┐
     ├─>| NINJA/ |
     │  └─┬──────┘
     |    |  ┌──────────┐
     │    ├─>| CONTENT/ |
     │    │  └─┬────────┘
     │    │    ├─> Ninja_[PatchName]_[...].d    // Content/menu initialization functions if necessary.
     │    │    │
     │    │    ├─> Ninja_[PatchName]_[...].d    // Any content script files. Mind the file names.
     │    │    ├─> Ninja_[PatchName]_[...].d
     │    │    └─> ...
     │    │  ┌─────────┐
     │    ├─>| SYSTEM/ |
     │    │  └─┬───────┘
     │    │    ├─> Ninja_[PatchName]_[...].d    // Any system script files. Mind the file names.
     │    │    ├─> Ninja_[PatchName]_[...].d
     │    │    └─> ...
     │    │
     │    ├─> Ninja_[PatchName]_[Parser].src    // Ninja SRC files that list all D files. Mind the file names.
     │    ├─> Ninja_[PatchName]_[Parser].src
     │    └─> ...
     |
     │  ┌────────┐
     ├─>| _WORK/ |
     │  └─┬──────┘
     |    │  ┌───────┐
     │    └─>| DATA/ |
     │       └─┬─────┘
     |         |  ┌──────┐
     │         ├─>| .../ ├─> ...                 // Any new resources. Files like textures, meshes or sounds.
     |         |  └──────┘
     │         │  ┌────────┐
     │         └─>| ANIMS/ |
     │            └─┬──────┘
     |              |  ┌────────────┐
     │              ├─>| _COMPILED/ |
     │              │  └─┬──────────┘
     │              │    └─> ...                // Any new animations referenced in the Ninja MDS files.
     │              │
     │              ├─> [PatchName]_[Model].mds // Ninja MDS files. Corresponding Ninja SRC file necessary.
     │              ├─> [PatchName]_[Model].mds
     │              └─> ...
     │
     ├─> CODE_[XXXXXXXX].patch                  // Ninja machine code file(s) for Gothic 1 or Gothic 2.
     │
     └─> Readme_Ninja_[PatchName].txt           // Information about the Ninja patch.
     
    _

    Stability

    There are no known issues with the latest version.
    Last edited by mud-freak; 08.07.2018 at 00:43. Reason: Extended documentation

  3. View Forum Posts #3 Reply With Quote
    Ritter Moe's Avatar
    Join Date
    Jan 2009
    Location
    Oberösterreich
    Posts
    1,769
     
    Moe is offline
    Geil. Dankeschön!

    edit:

    Sehr geil. Jetzt auch für Gothic 1!
    Last edited by Moe; 14.03.2018 at 17:03.

  4. View Forum Posts #4 Reply With Quote
    now also in your universe  Milky-Way's Avatar
    Join Date
    Jun 2007
    Posts
    13,293
     
    Milky-Way is offline
    Das klingt erst mal ganz gut, aber ein wenig stellt sich für mich noch die Frage, wo / wann wir Ninja am besten verwenden können.

    1) Wenn ich eine bestimmte Idee habe und sie in einer bestimmten Mod drin haben möchte:
    a) Wenn ich die Skripte einer Mod habe, scheint es mir einfacher, meine Änderungen in diese Skripte einzubauen. So oder so muss ich meine Änderungen in Code umsetzen, und bei Ninja muss ich dann scheinbar etwas vorsichtiger sein / testen ist etwas schwieriger, damit alles klappt.
    b) Wenn ich die Skripte einer Mod nicht habe, könnte ich da theoretisch mit dem Gothic Sourcer ran. Das verursacht eventuell Probleme, aber wenn nicht, dann kann bin ich wieder im Fall oben. Wenn es doch Probleme gibt, dann kann ich mit Ninja kleine Sachen einbauen, größere aber vermutlich eher nicht, weil ich ja nicht weiß, was für Funktionen / Variablen, die modspezifisch sind, ich beim Überschreiben einer existierenden Funktion übernehmen sollte.

    2) Wenn ich eine bestimmte Idee habe und sie in "alle" / viele alte Mods einbauen möchte. Solange sich die Idee unabhängig von existierenden Skripten einbauen lässt, ist das ohne größere Probleme möglich. In diese Richtung scheinen mir deine Beispiele zu gehen. Ist das das ideale Szenario für Ninja? Dann wäre es vielleicht schön, gemeinsam ein wenig zu sammeln, was es an einzelnen Features gibt, die man gerne auch in alte Mods bringen würde. Freies Zielen ist da sicher ein guter Kandidat. Mir fallen spontan noch ein: gute Umsetzungen von Schildkampf / Kampf mit zwei Waffen / reiten, interessante Zauber, Monster / Pflanzen Respawn.

    Eine potenziell interessante Hilfe fürs Ninja-Skripten könnte es sein, auch Daedalus-Funktionen hooken zu können. Oder ist das bereits möglich? Ich werde aus deiner Beschreibung nicht ganz schlau. ("Um nicht nur Dinge hinzufügen zu können, sondern auch bestehendes zu ändern (ohne es komplett zu ersetzen) bzw. die Neuerungen überhaupt anzustoßen (was bringt eine neue Daedalus-Funktion, wenn niemand sie aufruft) gibt es zwei Initialisierungsfunktionen.") (Wenn ich z.B. etwas zusätzlich in die ZS_Dead eintragen möchte)

  5. View Forum Posts #5 Reply With Quote
    Serima Fisk2033's Avatar
    Join Date
    Dec 2010
    Location
    Dresden
    Posts
    5,414
     
    Fisk2033 is online now
    Quote Originally Posted by Milky-Way View Post
    b) Wenn ich die Skripte einer Mod nicht habe, könnte ich da theoretisch mit dem Gothic Sourcer ran. Das verursacht eventuell Probleme, aber wenn nicht, dann kann bin ich wieder im Fall oben.
    Hast du es schon mal geschafft, eine Mod mit Ikarus zu dekompilieren? Meines Wissens nach ist das nicht möglich... ich habs auch noch nie geschafft.

  6. View Forum Posts #6 Reply With Quote
    Knight mud-freak's Avatar
    Join Date
    Dec 2005
    Posts
    1,226
     
    mud-freak is offline
    Quote Originally Posted by Milky-Way View Post
    Das klingt erst mal ganz gut, aber ein wenig stellt sich für mich noch die Frage, wo / wann wir Ninja am besten verwenden können.
    Wenn es wie beim ersten Szenario nur um eine einzelne bestimmte Mod geht, ist man besser bedient sich die Skripte zu nehmen und es direkt einzubauen. (@Fisk2033 Skripte mit Ikarus kann man meiner Erfahrung nach gut mit DecDat dekompilieren.) Dafür lohnt sich ein Ninja-Patch nicht.

    Idealer Einsatz für Ninja ist es, Features für beliebige Mods bereit zustellen. So wie man Texturpatch-XY herunterlädt und mit (fast) jeder Mod kombinieren kann, so soll man das auch mit einem Ninja-Patch können. Freies Zielen war dabei bisher das sinnvollste Beispiel, was mir gekommen ist. Das bedeutet aber auch, dass sich solche Patches auf Story-/Welt-unabhängige Änderungen beschränken. Sobald es um einen bestimmten Fix in einer bestimmten Story geht, sind wir wieder beim ersten Szenario und brauchen Ninja nicht.

    Ninja ist hier nur als ein Sprungbrett gedacht. Schwimmen muss man dann mit Daedalus. In den meisten Fällen wird man in einem Ninja-Patch auf Ikarus zurückgreifen müssen, um seine Änderungen mit der Mod zusammenzufädeln.
    Ein Beispiel ist GFA: Ninja erlaubt es zwar alle Skripte und Animationen einzuschleusen ([1] parsen), die Änderungen irgendwie anzustoßen muss man dann selbst ([2] initialisieren). Und das macht man in den genannten Initialisierungsfunktionen. Eine der beiden ist so etwas wie eine Patch-spezifische Init_Global, die Ninja nach der eigentlichen Init_Global aufruft. So wie beim normalen Skripten, kann ich dort Initialisierungen wie Ikarus, LeGo, Hooks, FrameFunctions, usw. vornehmen und somit die unterliegende Mod meinen belieben nach "formen".
    Dieser Schritt ist das Schwierige an Ninja, weil man wissen muss, wie man solch eine Änderung angeht. In GFA war das ganz einfach, dort bedarf es glücklicherweise nur der Ausführung von GFA_Init. Bei anderen Sachen, wie du z.B. vorschlägst mit dem Hooken der ZS_Dead, wird es schon etwas kniffliger.

    LeGo erlaubt das Hooken von Daedalus-Funktionen, was in diesem Fall der nötige Lösungsansatz wäre. Allerdings hat Lehona dazu ein paar Bedenken geäußert (Spielladen/Neues Spiel). Bisher sind Daedalus-Hooks aber noch nicht offiziell Teil von LeGo, da müsste man noch warten, oder es selbst separat skripten.

    Insgesamt habe ich mich mit der Beschreibung von Ninja in den obigen Posts etwas schwer getan und man wird nicht drumherum kommen, sich die existierenden Patches anzusehen, wenn man es besser nachvollziehen will.


    Quote Originally Posted by Milky-Way View Post
    Dann wäre es vielleicht schön, gemeinsam ein wenig zu sammeln, was es an einzelnen Features gibt, die man gerne auch in alte Mods bringen würde. Freies Zielen ist da sicher ein guter Kandidat. Mir fallen spontan noch ein: gute Umsetzungen von Schildkampf / Kampf mit zwei Waffen / reiten, interessante Zauber, Monster / Pflanzen Respawn.
    So ein paar Ideen/Auflistungen wären tatsächlich schön. Viel weiter als freies Zielen hat da meine Fantasie noch nicht gereicht. Eine spannende Idee wäre ein Sprint-System (mit Ausdauer).
    Einige Sachen sind vielleicht auch nicht so sinnvoll. Würde ich eine in sich geschlossene ("Total conversion") Mod erstellen und plötzlich fangen Leute an darin mit nicht vorgesehenen Zaubern herumzufuchteln und erwarten von mir als Mod-Ersteller dann plötzlich bessere Balance, wäre ich sicher nicht sehr erfreut.

  7. View Forum Posts #7 Reply With Quote
    Ehrengarde Neconspictor's Avatar
    Join Date
    Jan 2009
    Posts
    2,611
     
    Neconspictor is offline
    Könnte man Ninja dazu verwenden um Ikarus und LeGo bereits im Menu zu initialisieren?

    Ansonsten:
    Ich wusste gar nicht, dass man über das SystemPack Maschinencode einschleußen kann.
    Kannst du vll. erklären wie das geht (oder auf einen Beitrag hinweisen)? Wäre super

  8. View Forum Posts #8 Reply With Quote
    Legend of Ahssûn TheEternal's Avatar
    Join Date
    Jun 2013
    Location
    Stuttgart
    Posts
    4,190
     
    TheEternal is offline
    Mega!!! Danke mud-freak. Das ist mal wieder ein Meilensteil im Gothic-Modding. Damit könnte man glaube ich fast so umfangreiches Modding wie bei Skyrim ermöglichen, wo man eben Mods stapeln kann und gleich mehrere Inhalte in eine Mod bzw das Original einschleusen kann.

    Ich bin begeistert

    @Moderatoren: Bitte Ninja Patches zentral sammeln und eventuell sogar eine eigene Rubrik unter Downloads anlegen.
    [Bild: LoA_Banner_Skyline2.jpg]
    LoA Website
    Checkout Cloudevo: unlimited Cloud-Drive

    Last edited by TheEternal; 08.03.2018 at 14:46.

  9. View Forum Posts #9 Reply With Quote
    Knight mud-freak's Avatar
    Join Date
    Dec 2005
    Posts
    1,226
     
    mud-freak is offline
    Quote Originally Posted by Neconspictor View Post
    Könnte man Ninja dazu verwenden um Ikarus und LeGo bereits im Menu zu initialisieren?
    Ja, das wird in Ninja_GFA-Patch sogar so gemacht, um die Menü-Option einzufügen. Allerdings braucht man dazu weder Ninja, noch irgendwo Maschinencode einzuschleusen:
    Das geht schon total einfach über die InitPerceptions (in "\_work\data\Scripts\Content\AI\AI_Intern\Perception.d"). Diese Funktion wird nach dem Laden der Gothic.dat bzw. nach dem Parsen der Gothic.src, also vor erstmaliger Erstellung des Spielmenüs von der Engine aufgerufen. Darin kannst du also MEM_InitAll oder LeGo_Init aufrufen und dich austoben (oder z.B. Engine-Hooks ins Spielmenü schlagen), bevor Gothic überhaupt "losgeht". Ich dachte eigentlich, das sei allgemein bekannt?


    Quote Originally Posted by Neconspictor View Post
    Ich wusste gar nicht, dass man über das SystemPack Maschinencode einschleußen kann.
    Kannst du vll. erklären wie das geht (oder auf einen Beitrag hinweisen)? Wäre super :)
    Das findest du im Startpost des SystemPacks unter "*.patch-Datei". Auch wenn das sehr einfach geht und sehr "benutzerfreundlich" eingerichtet wurde, geht das praktisch für eine Mod nur sehr beschränkt bis gar nicht: Das SystemPack liest genau nur eine Datei ein, in der aller Maschinencode geschrieben sein muss. D.h. wenn du eine erstellst, kann es gut sein, dass dann aber die eines möglicherweise geladenen Ninja-Patches bevorzugt wird, was deine ganze Mod zu Nichte macht. Für eine Mod bietet sich das also überhaupt nicht an.
    Besser ist es also, Ikarus in der InitPerceptions zu initialisieren und dort (wie gewohnt mit MemoryProtectionOverride) Maschinencode einzuschleusen. Ich denke, der Zeitpunkt sollte früh genug sein, oder? Hattest du etwas bestimmtes vor?


    Quote Originally Posted by TheEternal View Post
    Mega!!! Danke mud-freak. Das ist mal wieder ein Meilensteil im Gothic-Modding. Damit könnte man glaube ich fast so umfangreiches Modding wie bei Skyrim ermöglichen, wo man eben Mods stapeln kann und gleich mehrere Inhalte in eine Mod bzw das Original einschleusen kann.

    Ich bin begeistert §ice
    Ja, ich bin gespannt auf Ideen, was für Patches man so erstellen könnte.


    Quote Originally Posted by TheEternal View Post
    @Moderatoren: Bitte Ninja Patches zentral sammeln und eventuell sogar eine eigene Rubrik unter Downloads anlegen.
    Ich denke wir sollten erst einmal abwarten, ob sich Ninja bewährt und ob weitere Patches erstellt werden.

  10. View Forum Posts #10 Reply With Quote
    Ehrengarde Neconspictor's Avatar
    Join Date
    Jan 2009
    Posts
    2,611
     
    Neconspictor is offline
    Quote Originally Posted by mud-freak View Post
    Ja, das wird in Ninja_GFA-Patch sogar so gemacht, um die Menü-Option einzufügen. Allerdings braucht man dazu weder Ninja, noch irgendwo Maschinencode einzuschleusen:
    Das geht schon total einfach über die InitPerceptions (in "\_work\data\Scripts\Content\AI\AI_Intern\Perception.d"). Diese Funktion wird nach dem Laden der Gothic.dat bzw. nach dem Parsen der Gothic.src, also vor erstmaliger Erstellung des Spielmenüs von der Engine aufgerufen. Darin kannst du also MEM_InitAll oder LeGo_Init aufrufen und dich austoben (oder z.B. Engine-Hooks ins Spielmenü schlagen), bevor Gothic überhaupt "losgeht". Ich dachte eigentlich, das sei allgemein bekannt?
    Nein, das wusste ich bis dato leider nicht... aber, das ist super!


    Quote Originally Posted by mud-freak View Post
    Hattest du etwas bestimmtes vor?
    Mir geht es um das Laden einer DLL (meine DynItemInst DLL). Es funktioniert bis jetzt auch, wenn man es in der INIT_Global lädt, aber es ist weitaus komplizierter und hat mir viele Probleme bereitet. So kann ich das jetzt viel eleganter machen

  11. View Forum Posts #11 Reply With Quote
    Knight mud-freak's Avatar
    Join Date
    Dec 2005
    Posts
    1,226
     
    mud-freak is offline
    Quote Originally Posted by Neconspictor View Post
    Mir geht es um das Laden einer DLL (meine DynItemInst DLL). Es funktioniert bis jetzt auch, wenn man es in der INIT_Global lädt, aber es ist weitaus komplizierter und hat mir viele Probleme bereitet. So kann ich das jetzt viel eleganter machen :)
    Ah, das geht sogar um einiges einfacher: Erstelle eine Datei namens pre.load und schreibe einfach den Namen der DLL hinein. Dann schiebe die Datei nach Gothic\System\ bzw. Gothic II\System\. Das SystemPack wird die DLL dann reinladen.

  12. View Forum Posts #12 Reply With Quote
    Ehrengarde Neconspictor's Avatar
    Join Date
    Jan 2009
    Posts
    2,611
     
    Neconspictor is offline
    Quote Originally Posted by mud-freak View Post
    Ah, das geht sogar um einiges einfacher: Erstelle eine Datei namens pre.load und schreibe einfach den Namen der DLL hinein. Dann schiebe die Datei nach Gothic\System\ bzw. Gothic II\System\. Das SystemPack wird die DLL dann reinladen.
    Danke, funktioniert ausgezeichnet Auch das wusste ich nicht, dass das SystemPack anbietet.
    Mal schauen, wie ich es jetzt konkret löse. Beides hat so seine Vor-und Nachteile

  13. View Forum Posts #13 Reply With Quote
    Dea
    Join Date
    Jul 2007
    Posts
    10,168
     
    Lehona is offline
    Quote Originally Posted by mud-freak View Post
    Ja, das wird in Ninja_GFA-Patch sogar so gemacht, um die Menü-Option einzufügen. Allerdings braucht man dazu weder Ninja, noch irgendwo Maschinencode einzuschleusen:
    Das geht schon total einfach über die InitPerceptions (in "\_work\data\Scripts\Content\AI\AI_Intern\Perception.d"). Diese Funktion wird nach dem Laden der Gothic.dat bzw. nach dem Parsen der Gothic.src, also vor erstmaliger Erstellung des Spielmenüs von der Engine aufgerufen. Darin kannst du also MEM_InitAll oder LeGo_Init aufrufen und dich austoben (oder z.B. Engine-Hooks ins Spielmenü schlagen), bevor Gothic überhaupt "losgeht". Ich dachte eigentlich, das sei allgemein bekannt?
    Das habe ich noch nie gelesen/gehört, aber faszinierend, dass es sowas gibt. Kann man zu dem Zeitpunkt Ikarus überhaupt verwenden? Zum Bootstrappen der Funktionen wird ein NPC benötigt (alternativ könnte man aber im SystemPack Machinecode-Loader MEM_WriteInt() bereits patchen, so dass der NPC nicht mehr benötigt wird).

  14. View Forum Posts #14 Reply With Quote
    Knight mud-freak's Avatar
    Join Date
    Dec 2005
    Posts
    1,226
     
    mud-freak is offline
    Quote Originally Posted by Lehona View Post
    Das habe ich noch nie gelesen/gehört, aber faszinierend, dass es sowas gibt. Kann man zu dem Zeitpunkt Ikarus überhaupt verwenden? Zum Bootstrappen der Funktionen wird ein NPC benötigt (alternativ könnte man aber im SystemPack Machinecode-Loader MEM_WriteInt() bereits patchen, so dass der NPC nicht mehr benötigt wird).
    Ja erstaunlicherweise funktioniert das. Ich gehe davon aus, dass der NPC nicht zwingend in die Welt eingefügt werden muss. Auf jeden Fall wird die Warnung SPAWN: Spawnpoint TOT not found. Npc MEM_HELPER_INST cannot be spawned. ausgegeben. Trotzdem funktioniert (schon in der InitPerceptions) folgendes problemlos:
    Code:
    FUNC VOID InitPerceptions()
    {
        MEM_InitAll();
    
        var int a; a = 0;
        MEM_Info(IntToString(a)); // Output: 0
        MEM_WriteInt(_@(a), 1);
        MEM_Info(IntToString(a)); // Output: 1
    
        // ...
    };

  15. View Forum Posts #15 Reply With Quote
    Dea
    Join Date
    Jul 2007
    Posts
    10,168
     
    Lehona is offline
    Dann funktioniert es definitiv - das ist schön zu sehen.

    Damit könnte man LeGo auch so erweitern, dass es in Instanzen etc. funktioniert - das würde eines der größeren Probleme mit Ikarus/LeGo beseitigen

  16. View Forum Posts #16 Reply With Quote
    Knight mud-freak's Avatar
    Join Date
    Dec 2005
    Posts
    1,226
     
    mud-freak is offline
    Quote Originally Posted by Lehona View Post
    Damit könnte man LeGo auch so erweitern, dass es in Instanzen etc. funktioniert
    Sorry, die gedankliche Verbinden kann ich gerade nicht ganz nachvollziehen. Könntest du erklären, wie das mit dem Bootstrappen zusammenhängt?

  17. View Forum Posts #17 Reply With Quote
    Moderator TazmanDevil's Avatar
    Join Date
    Aug 2008
    Location
    Diesseits des grossen Teiches
    Posts
    31,853
     
    TazmanDevil is offline
    Frage zum zweiten VDFS: ist das dann nur für die Ninja-Dateien, oder läuft dann die ganze Mod wieder mit dem alten VDFS (welches ja nicht frei von Problemen und Einschränkungen war)?

  18. View Forum Posts #18 Reply With Quote
    Knight mud-freak's Avatar
    Join Date
    Dec 2005
    Posts
    1,226
     
    mud-freak is offline
    Quote Originally Posted by TazmanDevil View Post
    Frage zum zweiten VDFS: ist das dann nur für die Ninja-Dateien, oder läuft dann die ganze Mod wieder mit dem alten VDFS (welches ja nicht frei von Problemen und Einschränkungen war)?
    Nein, richtig, die Mod sollte weiterhin mit dem neuen VDFS des SystemPacks weiterlaufen. Die DLL wird nur für Ninja geladen und nur davon angesteuert.

  19. View Forum Posts #19 Reply With Quote
    Dea
    Join Date
    Jul 2007
    Posts
    10,168
     
    Lehona is offline
    Quote Originally Posted by mud-freak View Post
    Sorry, die gedankliche Verbinden kann ich gerade nicht ganz nachvollziehen. Könntest du erklären, wie das mit dem Bootstrappen zusammenhängt?
    Ohne Ikarus kein LeGo. Und wenn wir LeGo schon im Hauptmenü initialisieren können, dann würde man es auch in (NPC-)Instanzen nutzen können.

  20. View Forum Posts #20 Reply With Quote
    Knight mud-freak's Avatar
    Join Date
    Dec 2005
    Posts
    1,226
     
    mud-freak is offline

    Version 1.1 mit Gothic 1 Unterstüzung

    Es gibt eine neue Version.

    Ninja gibt es jetzt auch für Gothic 1! Das Prinzip läuft gleich.
    Beim Übertragen von Ninja auf Gothic 1 ist mir ein Speicherleck in in der alten VDFS-DLL aufgefallen. Ich konnte es nicht sinnvoll stopfen, deshalb habe ich Ninja nun intern so umgebaut, dass es nicht mehr auf das alte VDFS angewiesen ist. Die alte DLL wird also nicht mehr geladen. Das hat neben Stabilität auch den Vorteil, dass die zuvor entstandene längere Ladezeit weg fällt. Einen kleinen Changelog, habe ich am Ende des ersten Posts angehängt.

    Natürlich habe ich die Gelegenheit genutzt und sofort auch einen Freies Zielen Ninja-Patch für Gothic 1 erstellt.


    Um Kompatibilität mit späteren Ninja-Patches zu wahren, habe ich alle bestehenden Patches mit der neuen Version aktualisiert.

Page 1 of 7 12345 ... Last »

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
Impressum | Link Us | intern
World of Gothic © by World of Gothic Team
Gothic, Gothic 2 & Gothic 3 are © by Piranha Bytes & Egmont Interactive & JoWooD Productions AG, all rights reserved worldwide