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
BepInEx pack for Mono Unity games. Preconfigured and ready to use.
Preferred version: 5.4.2305README
TFWR Oracle Runner
让外部 Python 工具、编辑器和自动化程序调用 The Farmer Was Replaced 的真实脚本执行入口,并收集执行状态、leaderboard 时间和资源快照。
模组通过 BepInEx 5 与 Harmony 接入游戏。Thunderstore 依赖为 BepInEx-BepInExPack-5.4.2305。它执行存档中已有的脚本窗口,不提供外部 Python 解释器。
当前为预览版:已通过编译和发布包检查,游戏内加载、脚本控制及结果回读尚待实机验证。
安装到 R2
- 在 r2modman 的 TFWR profile 中安装上述 BepInExPack。
- 在 R2 的在线模组列表中搜索
TFWR_Oracle_Runner,选择作者MengLei的包并安装。也可导入发布 ZIP。 - 通过 R2 的模组启动入口打开游戏,手动进入工作区。
- 在 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:模组生命周期、leaderboardstart / 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 和游戏程序集的许可由各自权利人提供。