Patch.tjs Xp3filter.tjs -
The files Patch.tjs and Xp3filter.tjs are commonly associated with Kirikiri (KiriKiriZ), a popular game engine used for Visual Novels (often referred to as the .xp3 format).
Here is a breakdown of what these files typically do and how they are used:
Pitfalls and Considerations
- Engine differences: APIs and hook points differ across Kirikiri versions and forks—code must target the engine version.
- Performance: filters run during asset load; expensive operations (heavy decrypt/decompress) can slow startup or in-game loading.
- Encoding: ensure correct handling of text encodings (Shift-JIS, UTF-8); modifying scripts requires proper encoding conversions.
- Stability: incorrect monkey-patching can crash engine or cause inconsistent state; always preserve and call original functions when appropriate.
- Legal/ethical: modifying or decrypting proprietary assets may violate licenses or law—ensure you have rights to modify.
5. Interaction in Modification Workflows
In the context of Visual Novel Translation (VNT) or modding, these two components often work in tandem. Patch.tjs Xp3filter.tjs
Scenario: Translating a Game with Encrypted Archives
-
Phase 1: Extraction (The role of Xp3filter concepts) The translator must extract scripts from the game. The game reads files via an archive filter. To extract them, a tool (like KrkrExtract or GARbro) must replicate the logic found in the game's filter implementation. If
Xp3filter.tjsis present and uncompiled, it reveals the decryption logic. If compiled, reverse engineering is required. The files Patch -
Phase 2: Injection (The role of Patch.tjs) Once scripts are translated, they must be re-inserted. Instead of repacking the archive (which is difficult with custom encryption), translators often place translated scripts in a folder on the disk. They then create a
Patch.tjs. ThisPatch.tjsinstructs the engine: "When looking forscene1.ks, look in thepatchfolder first, before looking in the archive."
Common implementation details to highlight in the post
- Parsing XP3 headers: signature, version, file count, table offsets.
- Handling compression: zlib/LZ4/deflate variants; decompress before editing, recompress after.
- Maintaining block alignment (commonly 0x200 or 0x1000) and address fixing.
- Updating table checksums or file hashes if present.
- Atomic writes: write to temp file and rename to avoid corruption.
4. Comparative Analysis
| Feature | Patch.tjs | Xp3filter.tjs | | :--- | :--- | :--- | | Domain | Application Logic / Runtime | I/O and Storage / Data | | Execution Timing | Engine Initialization (Boot) | During File Access (Runtime I/O) | | Primary Use Case | UI Modding, Translation Injection, Code Hooking | Decryption, De-obfuscation, Compression | | Complexity | High (Requires knowledge of game scripts) | Medium (Requires knowledge of binary format) | | Visibility | Plain text script (usually) | Often compiled or native code in commercial games | Engine differences: APIs and hook points differ across
Part 4: The Symbiotic Relationship – How They Work Together
To create a stable game modification (e.g., an English translation), you rarely use one without the other. Here is the standard workflow:
- The Problem: The original game is packed in
data.xp3with AES-128 encryption. All scripts are inside. - The Bypass: The modder provides an
Xp3filter.tjs. This file tells Kirikiri: "Ignore the encryption flag on all .tjs files. Treat them as raw text." - The Hook: The modder places translated
scenario.tjsfiles in a folder calledpatch(not an archive). However, the game's original loading routine might still point to the encrypted.xp3version. - The Solution: The modder writes a
Patch.tjsthat modifies the file search priority:// Force the engine to check the "patch" folder first Storages.addAutoPath("patch", 0); System.inform("Patch.tjs loaded. Redirecting file I/O."); - Result: The game loads the modified script from the folder, using the modified decryption filter, leaving the original
.xp3untouched.
Purpose
Patch.tjs is a script manager/loader that coordinates modifications. While Xp3filter.tjs handles low-level file I/O, Patch.tjs operates at a higher level to:
- Load and apply multiple patches (translation, bug fixes, uncensoring).
- Override original classes/functions in game scripts.
- Manage patch order and conflicts.