Skip to main content

A command-line tool to streamline the process of updating language files for Minecraft Java Edition modpacks.

Project description

UpLang

Minecraft Modpack Language File Synchronizer

A command-line tool to streamline the process of updating language files for Minecraft Java Edition modpacks.


Overview

UpLang automates the synchronization of language files between Minecraft mods and localization resource packs. It's designed specifically for modpack maintainers who need to keep their Chinese (zh_cn) translations up-to-date as mods are updated.

Key Features

  • Automatic Detection: Scans mod JARs and extracts language files
  • Smart Synchronization: Identifies added, modified, and deleted translation keys
  • Format Preservation: Maintains JSON key order and formatting (blank lines, indentation)
  • Intelligent Translation: Prioritizes mod-provided Chinese translations, falls back to English
  • Hash-based Caching: Only processes mods with changed language files
  • Parallel Processing: Multi-threaded mod processing for large modpacks
  • Forge/Fabric/NeoForge Support: Works with all major mod loaders

Installation

From PyPI (Recommended)

pip install uplang

From Source

git clone https://github.com/QianFuv/UpLang.git
cd UpLang
pip install -e .

Development Installation

pip install -e ".[dev]"

Quick Start

Basic Usage

Synchronize language files from mods to a resource pack:

uplang sync /path/to/mods /path/to/resourcepack

Check Differences (Dry Run)

Preview changes without modifying files:

uplang check /path/to/mods /path/to/resourcepack

List All Mods

View all mods and their language files:

uplang list /path/to/mods

Commands

uplang sync

Synchronize language files from mods to resource pack.

uplang sync <mods_dir> <resourcepack_dir> [OPTIONS]

Options:

  • --dry-run: Simulate without modifying files
  • --force: Ignore cache, process all mods
  • --parallel <n>: Number of parallel workers (default: 4)

Example:

uplang sync ./mods ./resourcepack --parallel 8

uplang check

Check differences without synchronizing (equivalent to sync --dry-run).

uplang check <mods_dir> <resourcepack_dir>

uplang list

List all mods and their language files.

uplang list <mods_dir>

Example Output:

Example Mod (examplemod) v1.0.0
  Type: forge
  JAR: examplemod-1.0.0.jar
  en_us.json: 42 keys
  zh_cn.json: 38 keys

uplang extract

Extract language files from a single mod JAR.

uplang extract <mod_jar> <output_dir>

Example:

uplang extract ./mods/examplemod-1.0.0.jar ./extracted

uplang diff

Show detailed differences for a single mod.

uplang diff <mod_jar> <resourcepack_dir>

Example Output:

Mod: Example Mod (examplemod) v1.0.0

English: +5 ~3 -2

Added keys (5):
  + item.examplemod.new_item: New Item
  + block.examplemod.new_block: New Block
  ...

Modified keys (3):
  ~ item.examplemod.sword:
    Old: Iron Sword
    New: Steel Sword
  ...

Deleted keys (2):
  - item.examplemod.old_item
  ...

uplang stats

Show translation statistics for the resource pack.

uplang stats <resourcepack_dir>

Example Output:

Total mods: 150
Total English keys: 12,543
Total Chinese keys: 12,543
Translated keys: 10,234
Translation coverage: 81.6%

uplang clean

Remove language files for mods that no longer exist (interactive).

uplang clean <resourcepack_dir>

uplang cache clear

Clear the cache to force full synchronization.

uplang cache clear <resourcepack_dir>

Global Options

Available for all commands:

  • --verbose, -v: Enable verbose output
  • --quiet, -q: Quiet mode (errors only)
  • --no-color: Disable colored output
  • --log-file <path>: Write logs to file
  • --version: Show version information
  • --help: Show help message

Example:

uplang sync ./mods ./resourcepack --verbose --log-file sync.log

Environment Variables

UpLang supports configuration via environment variables with the UPLANG_ prefix:

Global Options

  • UPLANG_VERBOSE=1: Enable verbose output
  • UPLANG_QUIET=1: Enable quiet mode
  • UPLANG_NO_COLOR=1: Disable colored output
  • UPLANG_LOG_FILE=/path/to/log: Set log file path

Command-Specific Options

Environment variables can also be used for command options using the format UPLANG_<COMMAND>_<OPTION>:

  • UPLANG_SYNC_PARALLEL=8: Set parallel workers for sync command
  • UPLANG_SYNC_FORCE=1: Force sync, ignore cache
  • UPLANG_SYNC_DRY_RUN=1: Enable dry-run mode

Example:

# Set verbose mode and log file via environment
export UPLANG_VERBOSE=1
export UPLANG_LOG_FILE=~/uplang.log

# Run sync with 8 parallel workers
UPLANG_SYNC_PARALLEL=8 uplang sync ./mods ./resourcepack

How It Works

Synchronization Logic

  1. Scan Mods: UpLang scans all JAR files in the mods directory
  2. Extract Language Files: Extracts en_us.json and zh_cn.json from each mod
  3. Check Cache: Uses hash-based cache to skip unchanged mods
  4. Compare: Identifies added, modified, and deleted keys
  5. Synchronize English: Updates resource pack's en_us.json with mod's English file
  6. Synchronize Chinese: For each key:
    • If key is new/modified: Use mod's Chinese translation if available, otherwise use English
    • If key is deleted: Remove from resource pack
  7. Preserve Format: Maintains original key order and JSON formatting

Cache System

UpLang uses a hash-based cache (.uplang_cache.json) to track mod changes:

{
  "version": "0.3.0",
  "last_updated": "2025-11-02T10:30:00",
  "mods": {
    "examplemod": {
      "jar_name": "examplemod-1.0.0.jar",
      "en_us_hash": "abc123...",
      "zh_cn_hash": "def456...",
      "last_sync": "2025-11-02T10:30:00"
    }
  }
}

Only mods with changed language files are processed, making subsequent syncs very fast.


Architecture

src/uplang/
├── __init__.py                # Package metadata, version
├── __main__.py                # Entry point (python -m uplang)
├── cli.py                     # CLI commands and interface
├── core/
│   ├── __init__.py
│   ├── scanner.py             # Scan JAR files in mods directory
│   ├── extractor.py           # Extract language files from JARs
│   ├── comparator.py          # Compare language files (set operations)
│   ├── synchronizer.py        # Synchronize language files
│   └── cache.py               # Hash-based change detection
├── models/
│   ├── __init__.py
│   ├── mod.py                 # Mod data class
│   ├── language_file.py       # Language file data class
│   └── sync_result.py         # Sync operation result
├── utils/
│   ├── __init__.py
│   ├── json_handler.py        # JSON read/write with format preservation
│   ├── hash_utils.py          # Hash calculation utilities
│   ├── path_utils.py          # Path and filename utilities
│   └── output.py              # Console output (colors, formatting)
└── exceptions.py              # Custom exception hierarchy

Development

Running Tests

pytest

With coverage:

pytest --cov=uplang --cov-report=html

Code Quality

UpLang follows these standards:

  • Language: English for all code (variables, functions, comments)
  • Documentation: Docstrings only, no inline comments
  • Architecture: Low coupling, high extensibility
  • Type Hints: Full type annotations

Examples

Example 1: Initial Setup

# First time setup - sync all mods
uplang sync ./mods ./resourcepack --force

# Output:
# UpLang v0.3.0 - Language File Synchronizer
# Mods directory: ./mods
# Resource pack: ./resourcepack
#
# Scanning mods...
# Found 120 mods
#
# Synchronizing with 4 parallel workers...
# examplemod: +42 ~0 -0
# anothermod: +156 ~12 -3
# ...
#
# Synchronization Summary
# ==================================================
# Total mods: 120
# Synchronized: 120
# Skipped: 0
# Failed: 0
#
# Total changes:
#   Added keys: 8,432
#   Modified keys: 234
#   Deleted keys: 56
# ==================================================

Example 2: Update After Mod Update

# After updating some mods
uplang sync ./mods ./resourcepack

# Output:
# ...
# Synchronizing with 4 parallel workers...
# examplemod: +5 ~3 -2
# anothermod: skipped (no changes)
# thirdmod: skipped (no changes)
# ...
#
# Synchronization Summary
# ==================================================
# Total mods: 120
# Synchronized: 1
# Skipped: 119
# Failed: 0
#
# Total changes:
#   Added keys: 5
#   Modified keys: 3
#   Deleted keys: 2
# ==================================================

Example 3: Check Before Syncing

# Preview changes
uplang check ./mods ./resourcepack

# Output shows what would change without modifying files

Troubleshooting

Issue: "No en_us.json found in mod"

Some mods don't include language files in the JAR. This is normal and can be ignored.

Issue: "Failed to parse JSON"

The language file may have invalid JSON syntax. UpLang will skip the file and log the error.

Issue: Cache not working

Clear the cache and resync:

uplang cache clear ./resourcepack
uplang sync ./mods ./resourcepack

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Submit a pull request

License

This project is licensed under the MIT License. See LICENSE for details.


Acknowledgments


Support


Made with ❤️ for the Minecraft modding community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

uplang-0.3.2.tar.gz (17.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

uplang-0.3.2-py3-none-any.whl (24.0 kB view details)

Uploaded Python 3

File details

Details for the file uplang-0.3.2.tar.gz.

File metadata

  • Download URL: uplang-0.3.2.tar.gz
  • Upload date:
  • Size: 17.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for uplang-0.3.2.tar.gz
Algorithm Hash digest
SHA256 4c13692031c3d9407584f19361f5e692041a7aeae0b43311a8eedb1b8528af93
MD5 c5fb178a03db3133f9d22acfcf3b3467
BLAKE2b-256 d634cf3a51a3af0766f095486f3f7ababa1cccb71a782a8dddcc00ef04ec5039

See more details on using hashes here.

Provenance

The following attestation bundles were made for uplang-0.3.2.tar.gz:

Publisher: publish-to-pypi.yml on QianFuv/UpLang

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file uplang-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: uplang-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 24.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for uplang-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a6cd0a7a423324ca1cbf3c48b4071241269e4f73ce3684372ae194cc06296bcb
MD5 a4317d6171ddd8c408a19220b842f128
BLAKE2b-256 a1dddce24e016ee50cd61a8c018445f8457ab6c1127c9aad0d698cca04548882

See more details on using hashes here.

Provenance

The following attestation bundles were made for uplang-0.3.2-py3-none-any.whl:

Publisher: publish-to-pypi.yml on QianFuv/UpLang

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page