-
-
Notifications
You must be signed in to change notification settings - Fork 0
Introduction
Modifications of the video games Gothic and Gothic 2 Night of the Raven have succeeded to impress for well over a decade. Graphical changes to the games may be deployed as modular patches running independently side-by-side. Other aspects of the games, such as the story, however, can only be replaced as a whole. This is due to the compiled formats in which these resources are collected. This has limited such modifications of the games to be exclusive in form of separate self-contained "games". To the frustration of many players, combining their favorite mods is not possible. Even the smallest improvement or bug fix of the original games demands an entirely independent "mod" incompatible with any other mods.
Ninja lifts this constraint by extending the scope of the aforementioned modular patches to any aspect of the game, instead of only mere graphical enhancements. This empowers them to the extent of mods, while retaining their modular behavior. Different from mods, they may be stacked and combined at will, enriching the modding landscape for players and raising it to a new level. Nevertheless, they are not to be understood to replace mods, but to complement them with small, independent features and enhancements.
This chapter aims to explain the problem that Ninja is solving.
Although the VDFS is explained in more detail elsewhere, this section serves to give a rough understanding about its functionality with respect to file preference.
All resources (e.g. textures, models, sounds) for the game are stored in VDF volumes, i.e. VDF files, in the Data directory. There are also MOD files that are typically in the subdirectory named ModVDF, but these MOD files are not important here. The volumes are containers for the resources, associated with a timestamp. They are loaded by Gothic in order of their timestamps where resources in later volumes take precedence and "override" any "older" ones. Should a file example.tex
exist both in the volumes volumeA.vdf
(timestamp 2010-01-01) and volumeB.vdf
(timestamp 2019-01-01), it will be loaded from the volume with the later timestamp, i.e. volumeB.vdf
.
This behavior is used to patch individual resources, by creating a VDF with a newer timestamp that contains the resource to change. In the previous example, the texture example.tex
in volumeB.vdf
might be a reworked version of the original example.tex
from volumeA.vdf
, which would then be displayed in the world everywhere in place of the original one. This technique has been the basis for patches as well as mods.
Creating a VDF with a newer timestamp allows replacing existing or adding new resources to the game. Although this method is straight forward, not all types of resources may be targeted individually. Here, the different resource types are divided into what we will call single-file formats and collected-file formats. As the names suggest, single-file resources can be individually replaced, while resources that are collected into one (virtual) file can only be replaced as a whole and overriding of individual parts is not possible. Below, only a list of the most commonly used file formats is given. More detailed information about the individual formats is available in the ZenGin documentation of the mod-kit and is beyond the scope of this documentation.
While several files of same type are not aggregated into one file, most of them are, nevertheless, expected in compiled form. All these listed types of files can and are patched in a modular way already without the need for Ninja.
- Textures (TEX)
- Models (MRM, MSH)
- Worlds (ZEN)
- Animations (MAN, MDH, MDM, MMB, MDL)
- Sounds/Speech (WAV)
The following files are compiled collections of their uncompiled counterparts. For this reason, their individual components cannot be overridden but only the entirety of the collection, i.e. the whole file. It is those file types for which Ninja offers solutions.
- Scripts (DAT)
- Animations (MDS/MSB)
- Output Units (BIN/CSL)
The collected-file formats pose a problem when only a specific component should be changed or a new one should be added.
When scripts are parsed they are saved collectively into one DAT file. Gothic is only able to load one such file and is not able to combine multiple files in any way. Replacing this file in a patch in order to add new script features also replaces compiled scripts from the underlying mod, which will thus cease to exist. Gothic cannot load more than one DAT file, because once compiled, any references within the scripts are resolved to exact positions within the file. Consequently, in order to make any changes to the scripts they need to be recompiled for Gothic to draw these references anew. Although modifying such a DAT file without de- and re-compiling is technically not entirely impossible, this is not feasible to do dynamically, i.e. on game start.
While animations are stored independently in their own files, they are defined in MDS files (or their compiled MSB counterparts in Gothic 2) for Gothic to find and refer to them. For each model, Gothic can only read one of these files and cannot append them. Replacing such a file with a patch, replaces any definitions the underlying mod has made. Consequently, the mod will no longer find its new animations and will no longer work properly.
Output units (i.e. dialog lines) are defined in OU.bin
or OU.csl
files. Any dialog line is written at a specific position within these files. Gothic will only load one such file at a time. When replaced by a patch to add new dialog lines, any dialog line from the underlying mod will be lost.
To find out how Ninja lifts this limitations, read on in the chapter Solution.
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
Patch Template
Patch Validator
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_ID_PATCHNAME
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