MengLei-TFWR_Oracle_Runner icon

TFWR Oracle Runner

从外部工具运行和停止真实游戏脚本,收集 leaderboard 时间与资源快照。

Last updated 6 hours ago
Total downloads 2
Total rating 0 
Categories Tools
Dependency string MengLei-TFWR_Oracle_Runner-0.2.0
Dependants 0 other packages depend on this package

This mod requires the following mods to function

BepInEx-BepInExPack-5.4.2305 icon
BepInEx-BepInExPack

BepInEx pack for Mono Unity games. Preconfigured and ready to use.

Preferred version: 5.4.2305

README

TFWR Oracle Runner

让外部 Python 工具、编辑器和自动化程序调用 The Farmer Was Replaced 的真实脚本执行入口,并收集执行状态、leaderboard 时间和资源快照。

模组通过 BepInEx 5 与 Harmony 接入游戏。Thunderstore 依赖为 BepInEx-BepInExPack-5.4.2305。它执行存档中已有的脚本窗口,不提供外部 Python 解释器。

当前为预览版:已通过编译和发布包检查,游戏内加载、脚本控制及结果回读尚待实机验证。

安装到 R2

  1. 在 r2modman 的 TFWR profile 中安装上述 BepInExPack。
  2. 在 R2 的在线模组列表中搜索 TFWR_Oracle_Runner,选择作者 MengLei 的包并安装。也可导入发布 ZIP。
  3. 通过 R2 的模组启动入口打开游戏,手动进入工作区。
  4. 在 profile 中检查 BepInEx/config/mlj.tfwr.oracle-runner.cfg 和 BepInEx/LogOutput.log。日志会输出实际 state_file= 路径。

新配置默认 AutoPlayMainMenu=false。无人值守运行时可在配置中设为 true,由模组自动进入游戏。已有配置保留原值。

手动安装时,使用游戏安装目录下的 BepInEx 目录。BepInEx 5 和 6 的插件入口不同,本版本须在 BepInEx 5 下加载;迁移时使用独立的 R2 profile,避免混放两套加载器的 core 文件。客户端与模组须一起更新,以共同遵守文件锁协议。

连接 Python 客户端

客户端来自 TFWR_Simulator 仓库。需要 Python 3.11 或更新版本。从仓库根目录执行下面的命令;Windows 可将 python3 替换为 python。

在仓库 .env 中填写自己的路径:

TFWR_GAME_ROOT=D:\Steam\steamapps\common\The Farmer Was Replaced
TFWR_SAVE_ROOT=C:\Users\YourName\AppData\LocalLow\TheFarmerWasReplaced\TheFarmerWasReplaced\Saves\Save0
TFWR_BEPINEX_ROOT=C:\Users\YourName\AppData\Roaming\r2modmanPlus-local\TheFarmerWasReplaced\profiles\Default\BepInEx

TFWR_BEPINEX_ROOT 指向所选 profile 的 BepInEx 目录。可从 R2 打开 profile 文件夹后取得路径;不同安装方式可能使用不同位置。未设置时,客户端使用 TFWR_GAME_ROOT/BepInEx。也可通过 CLI 的 --bepinex-root 覆盖。WSL 支持上述 Windows 路径写法。

先通过 R2 启动该 profile 的游戏并进入工作区。使用 R2 profile 时,客户端只连接已有游戏进程;不会自行启动缺少 profile 参数的游戏 EXE。

查询状态:

python3 tfwr_orchestrator/tools/run_real_game_script.py --status-only

运行已有脚本 my_script.py,等待完成后打印结果:

python3 tfwr_orchestrator/tools/run_real_game_script.py --target-script my_script --request-timeout 20

只提交请求并立即退出:

python3 tfwr_orchestrator/tools/run_real_game_script.py --target-script my_script --request-timeout 60 --request-only

--request-only 可替换当前请求,会停止旧请求再启动新脚本。常规等待模式先等待 idle。本仓库的打榜工作流使用 lb_start 作为派生入口;单脚本部署与打榜参数见 协调器说明。

配置

配置文件:<BepInEx 根目录>/config/mlj.tfwr.oracle-runner.cfg。

配置项 默认值 用途
Enabled true 启用执行器
TargetScriptName lb_start 请求未指定目标时使用的脚本名
AutoPlayMainMenu false 自动进入游戏工作区
StartupPollIntervalMs 250 状态文件同步间隔,最小生效值为 50ms
ScriptReadyTimeoutSeconds 30 脚本窗口等待参数
DefaultRequestTimeoutSeconds 20 请求未指定超时时使用的秒数
RequestStopGracePeriodSeconds 3 停止较慢时输出进度提示的等待时间

文件协议

状态文件位于 <BepInEx 根目录>/config/mlj.tfwr.oracle-runner.state.json,只承载控制状态。最小请求如下:

{
  "request_id": 1,
  "status": "requested",
  "target_script": "my_script",
  "timeout_seconds": 20,
  "started_at": null,
  "finished_at": null,
  "last_error": null
}
  • request_id 为递增的非负 32 位整数;分配新 ID 和提交必须在同一次锁内完成。
  • timeout_seconds 为非负有限秒数;0 表示不限时,null 使用模组默认值。
  • 正常流转为 idle → requested → running → done/failed → idle。
  • 运行中可写入同一请求的 stop_requested;停止完成后进入 failed,last_error 保存停止原因。
  • 更大的请求 ID 替换旧请求。旧客户端观察到更大 ID 后按 superseded 结束,不再确认或清除新请求。
  • 模组的状态修改先排队,在下一次同步时落盘;执行监控和 leaderboard 观察仍逐帧进行。

两端通过独占创建 <状态文件>.lock 来保护读改写:C# 使用 FileMode.CreateNew,Python 使用 O_CREAT | O_EXCL。持锁期间重新读取状态,写入同目录临时文件并原子替换,最后释放锁。模组遇到占用或 I/O 错误时等待下一次轮询,不在主线程 sleep;客户端进行有限重试。

自写客户端须遵守相同的锁协议;直接覆盖 JSON 不具备并发保护。取消和终态确认还必须核对当前请求 ID。可复用 Python 模块中的 request_script_run、request_script_stop 与 acknowledge_terminal_state。

如果进程异常退出并留下 .lock,先停止游戏和全部客户端,再移除该残留锁并重新启动。程序不会按锁龄自动抢锁。无效 JSON 或未知状态会报告错误,不会被当成新会话重置。

输出

  • 游戏 output.txt:脚本 print(...) 和游戏原生输出;客户端从 TFWR_SAVE_ROOT 推导位置。运行中默认不读取,避免抢占游戏写入句柄。
  • <BepInEx 根目录>/LogOutput.log:模组生命周期、leaderboard start / run / summary、运行中每秒的 item_snapshot 和失败诊断。

客户端按字节偏移读取运行中的新增完整日志行,保留跨次读取的半行;检测到文件替换或缩短时重新开始读取。请求结束后分别回读两种输出,并在同一次文件事务中确认该请求的终态。

构建与打包

使用 Windows .NET SDK,并通过属性指定游戏目录和 BepInEx 5 目录。BepInEx 目录可来自 R2 profile,也可来自解压后的 BepInExPack:

dotnet build oracle_runner_mod/TFWROracleRunner.csproj -c Release -p:TFWRGameRoot="D:\Steam\steamapps\common\The Farmer Was Replaced" -p:TFWRBepInExRoot="C:\path\to\profile\BepInEx"

WSL 中使用 dotnet.exe,两个属性仍传 Windows 路径。MSBuild 也读取进程环境变量 TFWR_GAME_ROOT 与 TFWR_BEPINEX_ROOT,但不会读取仓库 .env。

生成 Thunderstore/R2 ZIP:

dotnet build oracle_runner_mod/TFWROracleRunner.csproj -c Release -t:PackageThunderstore -p:TFWRGameRoot="D:\Steam\steamapps\common\The Farmer Was Replaced" -p:TFWRBepInExRoot="C:\path\to\profile\BepInEx"

输出位于 oracle_runner_mod/bin/Release/netstandard2.1/。ZIP 包含 manifest、README、MIT 许可证、图标与本模组 DLL;加载器由依赖包提供,游戏程序集仅用于编译引用。

许可证

本模组采用 MIT 许可证,完整条款见包内 LICENSE。BepInEx、Harmony 和游戏程序集的许可由各自权利人提供。