maxziebell
TUMULT HYPE 4 / EXTENSIONAll modules
Tools / GitHub project

HypeRuntimePatching

A comprehensive build system for applying patches to Tumult Hype runtime files

View on GitHub
HypeRuntimePatching — original repository artwork

Hype Runtime Patching

A comprehensive build system for applying patches to Tumult Hype runtime files. This project enables automated patching, minification, and compression of Hype runtime files with version tracking and detailed reporting.

Key Features

  • Automated Patching: JSON-based patch system for applying runtime fixes
  • Version Detection: Auto-detects Hype build number from installed app
  • Smart Minification: Uses Closure Compiler for optimal file size
  • Dual Compression: Both HypeCompressor and HypeLoader for maximum compatibility and efficiency
  • Advanced Compression: ZIP compression with self-decompression (28-34% smaller!)
  • Build Caching: Fast rebuilds with intelligent caching
  • Detailed Reports: Complete documentation of applied patches

Requirements

  • Hype4.app installed in /Applications/
  • Closure Compiler: Install via brew install closure-compiler or npm install -g google-closure-compiler
  • Terser: Install via npm install -g terser (for HypeLoader minification)
  • Python 3 (for compression and patching)

Quick Start

Run the build script:

./build.sh

The script will:

  1. Locate and detect your Hype installation
  2. Extract the build number (e.g., 778)
  3. Apply all applicable patches
  4. Generate minified and compressed versions
  5. Output versioned files to v{BUILD_NUMBER}/

Output Files

After building, you'll find patched runtime files in v{BUILD_NUMBER}/ with the following structure:

Patched files (minified with fixes applied):

  • patched/HYPE-{BUILD}.full.min.js - Minified full runtime with patches applied
  • patched/HYPE-{BUILD}.thin.min.js - Minified thin runtime with patches applied

HypeCompressor versions (in compressor/ folder):

  • compressor/HYPE-{BUILD}.full.min.js - HypeCompressor compressed full runtime ✅ Recommended
  • compressor/HYPE-{BUILD}.thin.min.js - HypeCompressor compressed thin runtime ✅ Recommended

HypeLoader versions (in loader/ folder):

  • loader/HYPE-{BUILD}.full.min.js - HypeLoader compressed full runtime ✅ Recommended
  • loader/HYPE-{BUILD}.thin.min.js - HypeLoader compressed thin runtime ✅ Recommended

Reports:

  • PATCHES_APPLIED.txt - Detailed patch report

Example: For Hype build 778, files are organized as:

v778/
├── patched/
│   ├── HYPE-778.full.min.js
│   └── HYPE-778.thin.min.js
├── compressor/
│   ├── HYPE-778.full.min.js
│   └── HYPE-778.thin.min.js
├── loader/
│   ├── HYPE-778.full.min.js
│   └── HYPE-778.thin.min.js
└── PATCHES_APPLIED.txt

Why Compressed Versions?

The compressed versions use advanced compression for superior file sizes:

HypeCompressor (in compressor/ folder):

  • Includes lightweight decompressor code
  • ZIP compresses the minified runtime
  • Auto-decompresses and executes in the browser
  • Result: 28-34% smaller than Tumult's original files!

HypeLoader (in loader/ folder):

  • Uses modern browser APIs (DecompressionStream)
  • No polyfills needed for modern browsers
  • Often more efficient than HypeCompressor
  • Result: 30-40% smaller than Tumult's original files!

Both compression methods are recommended for production use, with HypeLoader being preferred for modern browsers.

Patch System

This project uses a structured JSON-based patching system:

  • Patch Definitions: patches/ directory with multiple JSON files for organization
  • Patch Applicator: apply_patches.py - Python-based patch engine
  • Patch Reports: PATCHES_APPLIED.txt - Generated documentation of applied patches

Patch File Organization

Patches are organized into multiple JSON files in the patches/ directory:

  • tumult-patches.json: Official patches from Tumult (essential fixes)
  • community-patches.json: Community-contributed patches (create as needed)
  • experimental-patches.json: Experimental patches (create as needed)

The system automatically loads all .json files in the patches/ directory, making it easy to organize patches by source and purpose.

Current Patches

Fractional Steps with Symbols Fix (by Jonathan Deutsch, Tumult Hype)

  • Fixes fractional steps bug when using symbols and symbol timelines
  • Removes quantizeTime call for currentTimeInTimeline
  • Changes parameter in goToTimeInTimelineWithIdentifier call
  • Applies to: Hype build 778+

See the patches/ directory for complete patch definitions organized by category.

Patch File Template

Here's a template for creating new patch files:

{
  "patches": [
    {
      "id": "your_unique_patch_id",
      "name": "Your Patch Name",
      "description": "What this patch fixes or enhances",
      "author": "Your Name",
      "date": "2024-10-13",
      "min_build": 778,
      "max_build": null,
      "affects": ["HYPE.full.js", "HYPE.thin.js"],
      "replacements": [
        {
          "description": "What gets replaced",
          "search": "exact code to find (must match exactly)",
          "replace": "exact code to replace with",
          "context": "optional context hint"
        }
      ]
    }
  ]
}

Important: The search string must match the runtime code exactly (including whitespace, indentation, etc.). Use the actual runtime files as reference.

File Structure

.
├── build.sh                     # Main build script
├── build_compress.py            # HypeCompressor helper
├── build_compress_loader.py     # HypeLoader helper
├── apply_patches.py             # Patch application engine
├── HypeCompressor.js            # HypeCompressor source
├── HypeLoader.js               # HypeLoader source
├── patches/
│   ├── tumult-patches.json     # Official Tumult patches
│   ├── community-patches.json  # Community patches (create as needed)
│   └── experimental-patches.json # Experimental patches (create as needed)
├── .patch_temp/                # Working directory (cached, gitignored)
└── v778/                       # Output directory (versioned, gitignored)
    ├── patched/
    │   ├── HYPE-778.full.min.js
    │   └── HYPE-778.thin.min.js
    ├── compressor/
    │   ├── HYPE-778.full.min.js
    │   └── HYPE-778.thin.min.js
    ├── loader/
    │   ├── HYPE-778.full.min.js
    │   └── HYPE-778.thin.min.js
    └── PATCHES_APPLIED.txt     # Patch report

How It Works

  1. Source Detection: Reads runtime files directly from Hype4.app bundle
  2. Version Detection: Extracts build number from HYPE_XXX identifier in source
  3. Patching: Applies patches from patches/tumult-patches.json based on build number
  4. Minification: Uses Closure Compiler (for patched files) and Terser (for HypeLoader)
  5. Dual Compression:
    • HypeCompressor: ZIP compresses minified files and wraps with decompressor
    • HypeLoader: Uses modern browser APIs for efficient compression
  6. Caching: Both compressors are minified once and cached for fast rebuilds
  7. Reporting: Generates PATCHES_APPLIED.txt documenting all applied patches

Adding New Patches

To add a new patch, create a new JSON file in the patches/ directory (or add to an existing category file):

Create a new patch file (e.g., patches/community-patches.json):

{
  "patches": [
    {
      "id": "your_patch_id",
      "name": "Your Patch Name",
      "description": "What this patch fixes",
      "author": "Your Name",
      "date": "2024-10-13",
      "min_build": 778,
      "max_build": null,
      "affects": ["HYPE.full.js", "HYPE.thin.js"],
      "replacements": [
        {
          "description": "What gets replaced",
          "search": "exact code to find",
          "replace": "exact code to replace with",
          "context": "optional context hint"
        }
      ]
    }
  ]
}

Or add to an existing category file (e.g., patches/tumult-patches.json):

{
  "patches": [
    // ... existing patches ...
    {
      "id": "your_new_patch_id",
      "name": "Your New Patch",
      "description": "What this new patch does",
      "author": "Your Name",
      "date": "2024-10-13",
      "min_build": 778,
      "max_build": null,
      "affects": ["HYPE.full.js"],
      "replacements": [
        {
          "description": "What gets replaced",
          "search": "exact code to find",
          "replace": "exact code to replace with"
        }
      ]
    }
  ]
}

Key Fields:

  • id: Unique identifier for the patch
  • min_build/max_build: Control which Hype builds the patch applies to (null = no limit)
  • affects: Which runtime files the patch applies to
  • replacements: Array of search/replace operations
  • search: Exact string to find (must match exactly)
  • replace: Exact string to replace with

The system will automatically:

  • Apply only applicable patches based on build number
  • Track successful and failed replacements
  • Generate detailed reports showing what was applied

Using Patched Files

To use a patched runtime in your Hype project:

  1. Build the patched runtimes using ./build.sh
  2. Locate the files in v{BUILD_NUMBER}/
  3. In your Hype document, go to File > Advanced Export
  4. Check "Also save .html file"
  5. In the Resources tab, replace the runtime file:
    • For full runtime: Choose between:
      • patched/HYPE-{BUILD}.full.min.js (minified with patches)
      • compressor/HYPE-{BUILD}.full.min.js (HypeCompressor compressed) ✅
      • loader/HYPE-{BUILD}.full.min.js (HypeLoader compressed) ✅
    • For thin runtime: Choose between:
      • patched/HYPE-{BUILD}.thin.min.js (minified with patches)
      • compressor/HYPE-{BUILD}.thin.min.js (HypeCompressor compressed) ✅
      • loader/HYPE-{BUILD}.thin.min.js (HypeLoader compressed) ✅

Recommendations:

  • HypeLoader versions are preferred for modern browsers (smaller, more efficient)
  • HypeCompressor versions work in older browsers (includes polyfills)
  • Patched versions are useful for development/testing

Rebuilding

When you update Hype or want to rebuild with a new version:

  1. Remove old files from the output directory:
    rm -rf v778/
    
  2. Run the build script:
    ./build.sh
    

The build system will detect the new version and generate appropriately named files in all three folders (patched/, compressor/, loader/).

Credits

License

This project is for educational and development purposes. The patches are provided by Tumult for testing until they can be officially released in future Hype versions.

Contributing

To contribute a new patch:

  1. Define the patch in patches/tumult-patches.json (or create a new category file)
  2. Test thoroughly with the affected Hype builds
  3. Document the patch purpose and author
  4. Submit a pull request with patch details

For questions or issues, please open an issue on the project repository.