For AI agents: the complete documentation index is available at https://renmori.mewbaka.cn/llms.txt, the full documentation bundle is available at https://renmori.mewbaka.cn/llms-full.txt, and this page is available as Markdown at https://renmori.mewbaka.cn/integration/ci.md.
  • 简体中文
  • CI 集成

    RenMori 是作用于标准 Ren'Py 发行版构建之上的单条构建期命令,无需改动游戏源码。其输入为任意包含 game/ 子目录的目录,即 Ren'Py 启动器 Build Distributions 的输出。

    本页仅说明 CI 场景下的用法。完整的命令行参数见 renmori protect,renmori.toml 配置项见 配置文件,输出格式、构建清单与退出码见 输出与退出码。

    流水线中的基本流程

    renmori protect <game-build-dir> -o <output-dir> --quiet
    renmori verify  <output-dir>

    protect 将 game/ 下的全部内容封入 game/renmori.rmc,变换已编译的 Ren'Py 脚本,移除明文原件,写入加载器扩展 game/renmori.rpe,并生成 renmori-manifest.json。verify 依据该清单重新校验受保护的构建(容器哈希、必需文件、无明文残留),适合作为 CI 门禁。

    使用 -o 时原始构建不会被改动(受保护的是副本),因此不会创建备份。不带 -o 的原地保护会先将原目录复制到同级的 <dir>_bak,若该目录已存在则运行失败;--no-backup 可跳过这一复制。

    stdout 的最后一行始终是一个 JSON 对象({"status": "ok", …} 或 {"status": "error", …}),进度信息输出到 stderr。JSON 的键与值在任何语言设置下均保持英文,因此流水线解析不受输出样式与语言的影响。使用 --quiet 时仅输出该 JSON。流水线应以退出码判断成败,各退出码的含义见 输出与退出码。

    非交互行为

    RenMori 仅在交互式终端(TTY)上显示确认提示,包括原地保护前的 [y/N] 确认与下载闭源插件前的确认。满足以下任一条件时,所有提示都会被跳过,流水线不会因等待输入而挂起:

    • 传入 -y / --yes
    • 传入 --quiet
    • stdin 不是 TTY(CI 中的常见情形)

    非 TTY 环境下颜色输出自动禁用,同时遵从 NO_COLOR。面向用户的输出语言跟随系统区域设置,可通过 --lang en|zh 或环境变量 RENMORI_LANG 固定。

    保护强度与闭源插件

    未设置 strength 时,RenMori 默认采用完整保护,即闭源插件所报告的最强强度;若没有可用的插件,运行将失败,而不会静默降级为基线格式。CI 中可按需选择:

    设置行为
    不设置(默认)使用插件报告的最强强度;无可用插件时运行失败
    --strength auto有可用插件时使用插件,否则使用基线格式
    --strength baseline强制使用开源基线格式,从不下载插件

    需要插件时,RenMori 依次查找 --plugin 参数或 RENMORI_PLUGIN 环境变量指定的路径、本地缓存,最后从公开 Release 下载插件,按 SHA256SUMS 校验后写入缓存。在非交互环境中下载不经确认直接进行。插件的完整说明见 闭源插件。

    在 CI 中缓存插件

    插件的缓存目录按插件发布标签区分:

    平台缓存目录
    Linux / macOS$XDG_CACHE_HOME/renmori/plugin/<tag>,未设置 XDG_CACHE_HOME 时为 ~/.cache/renmori/plugin/<tag>
    Windows%LOCALAPPDATA%\renmori\plugin\<tag>

    在 CI runner 之间复用该目录即可避免每次构建重复下载。以 GitHub Actions 为例,可在 Protect 步骤之前加入缓存步骤,缓存键应与 RenMori 所使用的插件发布标签保持一致:

    - uses: actions/cache@v4
      with:
        path: ~/.cache/renmori/plugin
        key: renmori-plugin-${{ runner.os }}-plugin-v1.0.0

    以下环境变量可进一步控制插件的获取方式:

    环境变量作用
    RENMORI_PLUGIN显式指定插件路径,跳过缓存与下载,适用于预先置备插件的离线 runner
    RENMORI_NO_DOWNLOAD=1禁止自动下载;无可用插件时按强度设置失败或回退到基线
    RENMORI_PLUGIN_BASE_URL插件文件与 SHA256SUMS 的下载地址,默认为公开 Release
    RENMORI_PLUGIN_TAG要拉取的插件发布标签,同时决定缓存子目录

    密钥管理

    [keys] 配置节仅作用于基线格式。使用闭源插件时,插件自行派生密钥,不读取这些设置。

    默认情况下,protect 为每次构建生成一个全新的随机主密钥和一个相互独立的脚本密钥,并将其内嵌于加载器扩展中(这是基线格式的占位方案,闭源运行时改为在运行时派生密钥)。如需自行管理密钥,可在 renmori.toml 中指定保存密钥的环境变量,每个密钥为 64 位十六进制字符(32 字节):

    [keys]
    master_env = "RENMORI_MASTER_KEY"
    script_env = "RENMORI_SCRIPT_KEY"

    请从 CI 的密钥库(secrets)中为这些变量赋值,切勿将密钥提交到仓库。若指定的变量未设置,RenMori 会回退为随机密钥并给出提示。

    Warning

    RenMori 仅读取 [keys] 中所指定名称的环境变量。若 renmori.toml 中没有 [keys] 配置节,仅在 CI 中设置 RENMORI_MASTER_KEY 等环境变量不会产生任何效果,每次构建仍使用随机密钥。

    即使固定密钥,不同构建之间的输出也不是逐字节可复现的(每个文件使用随机盐),这是有意为之的设计。流水线应针对 verify 的结果与清单中的文件列表进行断言,而不应跨构建比较容器哈希。

    GitHub Actions 示例

    仓库中的 examples/github-actions-protect.yml 演示了完整流程:构建游戏、renmori protect、renmori verify,然后将受保护的发行版构建上传为产物。

    # Example GitHub Actions workflow: build a Ren'Py game, protect it with renmori,
    # verify the result, and upload the protected build as an artifact.
    #
    # Copy to .github/workflows/protect.yml and adapt the build step to your project.
    # renmori runs on the CI runner (the build environment); the protected runtime
    # ships inside the game and needs no Python there.
    
    name: Protect Ren'Py build
    
    on:
      workflow_dispatch:
      push:
        tags: ["v*"]
    
    jobs:
      protect:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
    
          - uses: actions/setup-python@v5
            with:
              python-version: "3.12"
    
          - name: Install renmori
            run: pip install renmori
    
          # Replace this with your real Ren'Py build. It must produce a directory
          # that contains a game/ subdirectory, e.g. dist/MyGame-1.0-pc.
          - name: Build the game
            run: |
              # renpy.sh "$PWD" distribute   # or your existing build script
              echo "produce ./dist/MyGame-pc here"
    
          - name: Protect
            env:
              # Optional: manage keys yourself via secrets. Omit both to let renmori
              # generate a fresh random key per build (recommended for most teams).
              RENMORI_MASTER_KEY: ${{ secrets.RENMORI_MASTER_KEY }}
              RENMORI_SCRIPT_KEY: ${{ secrets.RENMORI_SCRIPT_KEY }}
            run: |
              renmori protect ./dist/MyGame-pc -o ./dist/MyGame-pc-protected --quiet
    
          - name: Verify
            run: renmori verify ./dist/MyGame-pc-protected
    
          - uses: actions/upload-artifact@v4
            with:
              name: MyGame-pc-protected
              path: ./dist/MyGame-pc-protected

    使用方法如下:

    1. 将该文件复制到项目的 .github/workflows/protect.yml
    2. 将 Build the game 步骤替换为项目实际的 Ren'Py 构建命令,该步骤须产出一个包含 game/ 子目录的目录
    3. 按需调整触发条件;示例在手动触发或推送 v* 标签时运行
    4. 按需加入上文的插件缓存步骤,避免每次运行重复下载插件

    RenMori 只在 CI runner(构建环境)上运行;受保护的运行时随游戏一同分发,玩家端不需要额外安装 Python。示例在默认强度下运行,因此会在 runner 上获取闭源插件。Protect 步骤中的密钥环境变量仅在使用基线格式且 renmori.toml 的 [keys] 配置节指定了这些变量名时生效,详见上文的密钥管理。

    针对真实引擎的端到端校验(可选)

    tools/verify_in_renpy.py 会保护一个示例游戏,并在真实的 Ren'Py SDK 中确认每一项资源都能逐字节无误地解密、Ren'Py 脚本已被变换且仍可解析、注入的脚本会被拒绝。使用时需指定一个 SDK 与一个游戏;在没有可用 SDK 的环境中该校验会被跳过。

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