For AI agents: the complete documentation index is available at https://renmori.mewbaka.cn/en/llms.txt, the full documentation bundle is available at https://renmori.mewbaka.cn/en/llms-full.txt, and this page is available as Markdown at https://renmori.mewbaka.cn/en/technical/plugin-interface.md.
  • English
  • Plugin interface

    RenMori is open-core. The open renmori command-line tool is the integration point: it parses configuration, prepares the output and backup, drives the user-facing flow, and always ships the baseline container format. The strong protection (the per-build polymorphism engine, runtime key derivation, and the native core and launcher) lives in a closed plugin that is distributed as a prebuilt component and never as source.

    This page defines the stable process contract between the two. The contract is public so that the open tool and the closed plugin can be versioned and released independently; only the plugin's implementation is closed.

    Discovery

    The open tool locates the plugin in this order:

    • The --plugin <path> argument to renmori protect
    • The RENMORI_PLUGIN environment variable
    • No plugin found: the tool runs the baseline format and refuses any non-baseline strength

    <path> is an executable, or a .py script that the open tool runs with the current Python interpreter. A plugin is used only after a successful capabilities handshake (see below); a plugin that fails the handshake is treated as absent, and the baseline path is taken.

    Current CLI behavior

    Beyond the explicit paths above, the current CLI also checks a local cache and, when needed, downloads the plugin from the public release, verifies it against SHA256SUMS, and caches it. With strength unset the default is full protection, and the run fails if no plugin is available; --strength auto falls back to the baseline without a plugin; --strength baseline never downloads the plugin. See Closed plugin.

    Transport

    Every call is one short-lived subprocess, and the first argument selects the operation. The request, when one is needed, is a single JSON object on stdin; the response is a single JSON object on stdout. All human-readable logging goes to stderr, so stdout stays machine-parsable. The exit code is 0 on success and non-zero on failure. All field names and enumerated values are ASCII and locale-independent.

    Both objects carry an integer interface field. The open tool sends the highest version it supports and refuses a plugin whose capabilities do not include that version.

    Operations

    capabilities

    No request body. The plugin prints a JSON object describing itself and exits with 0:

    FieldMeaning
    interfaceHighest interface version the plugin supports
    namePlugin display name
    versionPlugin release version
    strengthsThe strength values the plugin accepts, strongest first
    platformsThe target platform keys the plugin can produce

    protect

    The request object on stdin:

    FieldMeaning
    interfaceInterface version chosen by the open tool
    source_dirThe distribution build to read; the plugin must not modify it
    output_dirWhere the protected build is written; the plugin creates it, and it must not already exist
    strengthOne of the plugin's advertised strengths
    platformsAn explicit list of target platform keys, or null to auto-detect from source_dir/lib/py3-*
    launcherWhether to bind the keys to a native launcher and ship it
    excludeGame-relative globs to leave outside the container
    chunk_sizeContainer chunk size in bytes, or null for the plugin's default
    lockdownWhether to disable the developer console, developer mode and data-export subcommands in the build
    keysAn object reserved for key material or key-source directives; empty by default

    The plugin copies source_dir to output_dir, packs every asset and Ren'Py script into the polymorphic container, ships each target platform's native core (and launcher, when requested), writes the runtime extension, removes the plaintext originals it packed, and prints the response object on stdout:

    FieldMeaning
    interfaceInterface version of this response
    status"ok"
    strengthThe strength actually applied
    platformsThe target platform keys produced
    containerThe container file name under game/
    container_sha256Hex SHA-256 of the container
    filesNumber of entries packed
    scriptsNumber of scripts transformed
    coresOne {platform, filename} per shipped native core
    launcherPer-platform launcher file names, or null

    On failure the plugin prints {"interface": N, "status": "error", "message": "<reason>"} and exits with a non-zero code. The open tool reports the message, exits with its runtime-failure code, and avoids leaving a partial output_dir wherever it can.

    Division of responsibility

    • The open tool owns: argument and renmori.toml parsing, the output and backup decision and any copy or move it entails, the pre-flight summary and confirmation, the manifest it writes from the response, and all localized output
    • The plugin owns: the container format and its per-build randomization, key derivation, the native core and launcher, and the exact on-disk result under output_dir

    In-place protection is expressed to the plugin as a plain source_dir → output_dir pair: the open tool first moves the original aside (to the backup, or to a temporary directory discarded afterwards) and passes the original path as output_dir, so the plugin never needs an in-place mode.

    Versioning and integrity

    interface is incremented only on a breaking change to the request or response shape. A plugin may support several versions at once, and the open tool selects the highest version both sides share. Additive, optional fields do not bump the version.

    A build produced by the plugin is intended to be distinguishable from one a third party assembles with the open framework and a hand-written weak engine: the manifest may carry a build fingerprint that the runtime checks. That binding is defined together with the closed component and is out of scope for this public contract.

    © 2026 笨猫工作室 MewBaka Studio. All Rights Reserved.