A runtime localization plugin for SKALD: Against the Black Priory that enables automatic text extraction and translation without modifying the game files.
TranslationMod is a BepInEx-based plugin that provides real-time localization capabilities for SKALD: Against the Black Priory. The plugin works entirely at runtime, meaning it doesn't require any modifications to the original game files. It automatically captures game text, manages translations, and applies them dynamically during gameplay.
- Runtime Translation: Translates game text on-the-fly without game modification
- Language Pack System: Supports customizable language packs with organized translations
- Font Management: Automatically handles font requirements for different character sets
- Translation Management: Loads and applies translations from organized CSV files
- In-game Settings Integration: Adds language selection to the game's settings menu
- BepInEx 6 (Beta) - BepInEx 5 doesn't work reliably with SKALD, use BepInEx 6 instead
- SKALD: Against the Black Priory - The plugin is designed specifically for this game
- Download BepInEx 6 (beta) from the official BepInEx GitHub releases
- Extract the BepInEx files to your SKALD game directory
- Run the game once to generate BepInEx configuration files
- The game will close after initial setup - this is normal
Follow the same steps as Windows/Linux above.
BepInEx doesn't natively support ARM architecture on macOS. To make it work:
-
Remove game signature (required for code injection):
codesign --remove-signature "SKALD: Against the Black Priory.app" -
Install BepInEx 6 (beta) in your game directory
-
Modify the launch script - Edit
run_bepinex.shand replace the final execution line:Replace this:
"${executable_path}" "$@"
With this:
current_path=$(pwd) exports="export LD_LIBRARY_PATH=\"$LD_LIBRARY_PATH\";export LD_PRELOAD=$LD_PRELOAD;export DYLD_LIBRARY_PATH=\"$DYLD_LIBRARY_PATH\";export DYLD_INSERT_LIBRARIES=\"$DYLD_INSERT_LIBRARIES\"" cdir="cd \"$current_path\"" exec="\"${executable_path}\"" a="\"$@\"" launch="arch;$cdir;pwd;$exports;$exec $a" echo "Launch Command: $launch" arch -x86_64 zsh -c "$launch"
-
Make script executable:
chmod +x run_bepinex.sh
-
Launch using the script:
./run_bepinex.sh
Solution adapted from BepInEx GitHub issue #513
- Complete BepInEx installation for your platform (see above)
- Download the latest TranslationMod release
- Copy
TranslationMod.dll, Newtonsoft.Json.dll, TranslationMod.cfgtoBepInEx/plugins/folder - Copy a language packs folder
- If you want create new language pack language pack please see Language Pack Creation below
- Launch the game - the plugin will automatically initialize
The plugin operates transparently in the background:
- Text Interception: Captures all text displayed in the game
- Translation Lookup: Checks for available translations in loaded CSV files
- Smart Text Processing: Handles complex text structures including HTML tags, numbers, and formatting
- Dynamic Replacement: Replaces original text with translations in real-time
- Plugin Integration: Seamlessly integrates with the game's text rendering system
LanguagePacks/
└── YourLanguage/
├── language_pack.json # Language pack configuration
└── fonts/ # Font and Logo textures folder
├── *.png # PNG files with textures
└── translations/ # Translation files folder
├── *.csv # UI translations
Creating a new language pack consists of three main steps:
Create language_pack.json configuration file with character mapping.
Important: Start character indices from 90 (first free index in the game that begins a new line in font textures).
Example for Russian language:
{
"languageCode": "ru",
"name": "Russian",
"description": "Russian language pack for the game",
"version": "1.0.0",
"fontFilesPath": "fonts",
"translationFilesPath": "translations",
"characterChart": {
"А": 90,
"Б": 91,
"В": 92,
"Г": 93,
"Д": 94,
"Е": 95,
"Ё": 96,
"Ж": 97,
"З": 98,
"И": 99,
"Й": 100,
"К": 101,
"Л": 102,
"М": 103,
"Н": 104,
"О": 105,
"П": 106,
"Р": 107,
"С": 108,
"Т": 109,
"У": 110,
"Ф": 111,
"Х": 112,
"Ц": 113,
"Ч": 114,
"Ш": 115,
"Щ": 116,
"Ъ": 117,
"Ы": 118,
"Ь": 119,
"Э": 120,
"Ю": 121,
"Я": 122,
"а": 126,
"б": 127,
"в": 128,
"г": 129,
"д": 130,
"е": 131,
"ё": 132,
"ж": 133,
"з": 134,
"и": 135,
"й": 136,
"к": 137,
"л": 138,
"м": 139,
"н": 140,
"о": 141,
"п": 142,
"р": 143,
"с": 144,
"т": 145,
"у": 146,
"ф": 147,
"х": 148,
"ц": 149,
"ч": 150,
"ш": 151,
"щ": 152,
"ъ": 153,
"ы": 154,
"ь": 155,
"э": 156,
"ю": 157,
"я": 158
}
}To add images of alphabet letters to the font textures, follow these steps using Pixelorama:
-
Open the PNG File: Use Pixelorama to open the font texture PNG file. This tool allows you to edit pixel art easily.
-
Set Up the Grid:
- Go to
Edit->Preferences->Canvas. - In the
Gridsection, create two grids:- The first grid should be 1x1 pixels, starting from x:0, y:0.
- The second grid should also start from x:0, y:0, but its size depends on the font. It should match the size of the pink grid in the image (e.g., for
TinyFont.png, use an 8x8 grid).
- Go to
-
Indexing: The index starts from the bottom left with 'A' = '0'. Ensure each character is placed at the correct position in the font texture atlas according to the indices specified in your character map.
-
Resize the Image: If you open the original PNG, you may need to resize the image. Go to
Project->Resize Canvasand adjust the height to be equal tonumber_of_rows * height_of_one_cell.
By following these steps, you can accurately place each character in the font texture atlas, ensuring proper alignment and indexing for your custom fonts.
Create translations of the original text in CSV files. For convenience, all original text is already categorized. The complete text is also available in a Google Sheet that you can duplicate and translate, then save in CSV format and transfer to the translations folder. Example of filled sheet is here: Russian Translation Sheet
CSV File Format (use comma , as separator):
original,translate
New Game,Nuevo Juego
Load Game,Cargar Partida
Settings,Configuración
Health,Salud
Strength,Fuerza- Exact matches: Include complete phrases for better accuracy
- Context matters: Use descriptive filenames to organize translations
- Special words: Do not translate special words in curly braces (e.g.,
{PLAYER},{ITEM}). These are placeholders that the game replaces with values.
Language pack contributions are welcome! Please follow the language pack creation guide and test thoroughly before submitting.
This plugin is provided as-is for the SKALD gaming community. Please respect the original game's terms of service when using this plugin.