Solution
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.
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.
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".
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.
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.
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.
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
Applications and Examples
Add New NPC
Set AI Variables
Add New Dialogs
Add New Spells
Add New World
Translation Patch
Installation
Requirements
Instructions
Troubleshooting
Is Ninja Active
Is Patch Loaded
Error Messages