Skip to content

Solution

szapp edited this page Jan 16, 2020 · 5 revisions

After Gothic loads the scripts, animations and output units from the game or mod the usual way, Ninja injects the changes introduced by patches on top. This is done by utilizing Gothic’s native file parsing functions to ensure high stability. More specifically, scripts to inject are parsed from uncompiled D files, animations are parsed from uncompiled MDS files and output units are read from a BIN or CSL file.

Ninja modifies these loading processes to suitably merge the parsed content with the prior loaded content. Scripts may, for example, overwrite previously defined symbols and output units may replace already existing dialog lines. This implementation allows changes to these resources equivalent to, for example, replacing or adding individual textures. This extends the scope of modular patches to all types of resources.

Implementation

Ninja is written in assembly mostly for "historical" reasons. Nevertheless, this ensures minimal and "high precision" modifications to the executables.

Since version 2.0, Ninja is implemented as Dynamic Link Library (DLL) that is loaded at start of Gothic. Patches and Ninja are thereby independent from each other. This increases compatibility. If the game is installed in the program files directory, Ninja requires administrative privileges to function properly.

For more information, see Technical Details.

Patch Structure

A patch is a VDF volume placed into the Data directory. Patches using Ninja are no different from traditional patches in any way. In fact, Ninja 2.0 was designed to extend the capabilities of traditional patches instead of evoking the idea of a new type of patch. Since Ninja 2.0 there is no such thing as a "Ninja patch".

VDF File Tree

As with any other patch, single-file resources (e.g. textures) to add or override are placed within the usual virtual file paths in the _work directory. Resources that the patch adds or changes with the aid of Ninja (scripts, animations and output units) are placed in specific directories with predefined file names for Ninja to detect them. The exact file names are listed in the respective section of this documentation.

This also allows patches to only optionally make use of Ninja. For example, a patch might replace all ground textures with snow textures to act as a "winter patch". It may also include necessary script changes to make it snow continuously. If Ninja is not installed, this patch would merely act as a texture patch. If Ninja is installed, the patch will additionally make it snow.

╔═══════════════╗
║ PatchName.vdf ║
╚╤══════════════╝
 │  ┌────────┐
 ├─►│ _work/ │                                             ┐
 │  └─┬──────┘                                             │
 │    │  ┌───────┐                                         │
 │    └─►│ Data/ │                                         ├► Traditional
 │       └─┬─────┘                                         │
 │         │  ┌──────┐                                     │
 │         └─►│ .../ │  Any "usual" resources              │
 │            └──────┘                                     ┘
 │
 │  ┌────────┐
 └─►│ Ninja/ │                                             ┐
    └─┬──────┘                                             │
      │  ┌────────────┐                                    │
      └─►│ PatchName/ │                                    ├► Ninja specific
         └─┬──────────┘                                    │
           ├─► ...      Resource files with specific names │
           └─► ...      Possible subdirectories            │
                                                           ┘

Ninja ignores all files in patches that do not adhere to the above directory structure.

VDF Header

Aside from the resources, VDF volumes also contain metadata collected in the VDF header.

Although not metadata, the file name of the patch is important. It defines the file path shown above, i.e. \Ninja\PatchName\. Since the patch will be identified by this name, it should not only be descriptive and concise, but can – for technical reasons – only contain alpha numeric characters and cannot start with a number.

The VDF comment should be used to provide a brief description of the patch. This description will also be visible in the in-game console to players, see Troubleshooting. Omitting this patch description possibly leaves players in the dark about what the patch does and they might be less inclined to use it.

The VDF timestamp decides the file preference among VDF volumes. Additionally, it determines the order in which Ninja processes them when injecting and initializing changes.

Due to the way that the timestamp is encoded in the header of a VDF volume, it cannot exceed the year 2039. It should also be considered good practice to always use the current date and time for the timestamp instead of a future date.

Batch Script

A Windows batch script is available to guide through the first steps of setting up a new patch and its VDF volume with all necessary instructions. Its use is highly recommended when creating a patch. It can be downloaded here (right click, save as). The script will create the necessary directories and initialize files depending on the choices provided.

To create a patch with Ninja, it is advised to first implement and to test all the desired changes in a normal Gothic mod-kit installation and to proceed once confident about the changes.

It is important to note that Ninja is a bad place to start if new to Gothic modding.

Inter-Game Compatibility

All patches are compatible with both Gothic and Gothic 2 NotR by design. On the one hand, this makes maintaining patches easier (there is no need for separate patches). And on the other hand, it encourages developers to create patches compatible with both games from the start.

When injecting changes from a patch, Ninja first looks for the files with a postfix specific to the current game (e.g. _G1 or _G2) and only if not found, falls back to files without postfix. This behavior is useful to deal with subtle differences between the games. It also allows (parts of) a patch to be exclusive to one game while being ignored by the other.


To find out how the changes are put in place, read on in the chapter Inject Changes.

Introduction
    Virtual Disk File System
    Formats
        Single File Formats
        Collected File Formats
    Limitations to Overcome
        Scripts
        Animations
        Output Units

Solution
    Implementation
    Patch Structure
        VDF File Tree
        VDF Header
    Batch Script
    Inter-Game Compatibility

Inject Changes
    Daedalus Scripts
        Overwriting Symbols
            Naming Conventions
            Preserved Symbols
        Initialization Functions
            Init_Global
            Menu Creation
        Ikarus and LeGo
            Initializing LeGo
            Modifications to LeGo
            PermMem and Handles
        Daedalus Hooks
        Inserting NPC
        Disallow Saving
        Helper Symbols
            NINJA_VERSION
            NINJA_MODNAME
            NINJA_PATCHES
            NINJA_SYMBOLS_START
            NINJA_SYMBOLS…PATCHNAME
        Common Symbols
        Localization
    Animations and Armor
    Output Units

Other Mechanics
    Remove Invalid NPC
    Safety Checks in Externals
    Preserve Integer Variables
    Detect zSpy
    Incompatibility List for Mods

Technical Details

Applications and Examples
    Add New NPC
    Set AI Variables
    Add New Dialogs
    Add New Spells
    Add New World
    Translation Patch

Debugging
    Console
    Logging

Installation
    Requirements
    Instructions

Troubleshooting
    Is Ninja Active
    Is Patch Loaded
    Error Messages

Download

Checksums
    Setup
    In-Game

Changelog

Support this project  

Acknowledgements

Contact and Discussion

Clone this wiki locally