游戏自动化:智能体的双手与双眼
真实的游戏是最终的裁决者。循环是:启动 → 导航 → 设置场景 → 操作 → 截图并读取日志 → 决策。为每个游戏构建一次,之后你的每一次改动都可以在一分钟内得到验证。
Windows(原生或从WSL):um win
um win setup # 一次性设置:PowerShell工具 + 带gfxcapture的ffmpeg,自动选择NVENC/AMF/QSV/x264
um win ps # 窗口化进程:PID、名称、标题
um win launch --steam 105600 # 或者:um win launch "C:\Games\Foo\Foo.exe" -- -windowed
um win shot --exe Terraria.exe shot.png --scale 0.33 # 全帧 + 一张1/3尺寸的副本,便于低成本查看
um win drive --proc Terraria "focus" "click 640 360" "key 0x1B" "type hello" "hold 0x44 1500"
um win drive --proc Terraria "hold 0x20 150" "sleep 200" "hold 0x20 150" # sleep <ms> 在步骤间暂停
um win drive --proc Terraria idle # 用户上次触摸鼠标或键盘以来的秒数(不等待)
um win kill <pid> # 仅限确切的PID
um win reg get "HKCU\Software\..." # 注册表(reg set会先备份键值)
从Python(用于更长的脚本)使用:from um.win import Drive, shot, Recorder,然后 d = Drive("AoE2DE_s"),d.focus(),d.click(x, y),d.key("0x0D")。
WinDrive命令(um/ps1/WinDrive.ps1;stdin协议,每行一个回复)。坐标位于游戏窗口的客户区内。
- 鼠标:
move x y、click x y [right]、mdown/mup、drag x0 y0 x1 y1、rel dx dy(FPS摄像机/原始输入)、wheel 120。 - 键盘:
key <vk> [tap|down|up]、hold <vk> <ms>、type <text>、scanmode on(DirectInput/使用原始输入游戏,忽略虚拟按键事件)。 - 窗口:
focus、rect、size <w> <h>(设置客户区大小)、title、fg、idle、untop。 - 计时:
sleep <ms>在一次调用中在步骤间等待。每次um win drive调用都会启动PowerShell(耗时1-2秒),因此请将需要计时的组合操作放在一次调用中。 - 虚拟键码:Esc 0x1B、Enter 0x0D、Space 0x20、W/A/S/D 0x57/0x41/0x53/0x44、F1 0x70、Shift 0x10、Ctrl 0x11、方向键0x25-0x28。
行路规则
- 切勿在用户打字时,将焦点置于带有在线模式的游戏上。 这在GTA V中曾发生过:智能体将焦点切到GTA以点击故事模式,而用户的按键输入却击中了GTA的登陆页面,导致GTA警告“使用修改版访问GTA Online服务器”。ScriptHookV阻止了它;不要依赖它。检查
idle,请用户点击,并在关闭反作弊的情况下启动游戏,这样在线模式就无法启动。参见knowledge/techniques/driving-real-games-safely.md。 - 输入只发送给游戏。 当其他应用程序在前台时,WinDrive拒绝发送。唯一的例外是当没有任何应用在前台且光标位于游戏上方时——在窗口化游戏中,点击时游戏会失去前台状态,从而触发此情况。
- 用户可能正在使用电脑。 如果
idle时间少于一分钟,请在操控前询问用户,并保持会话简短。一旦用户同意,无人值守运行是可以的。 - 截图消耗令牌。 查看
--scale 0.33的副本。将坐标乘以3进行点击,并在MODLOG.md中维护一个菜单点击点表格,只需测量一次。 - 为什么使用gfxcapture: 使用GDI捕获时,GPU渲染的游戏会呈现黑色。gfxcapture(Windows.Graphics.Capture)能够抓取一个窗口的真实帧,即使它被覆盖。它无法捕获最小化的窗口。
- HDR显示器: 当Windows Auto HDR为SDR游戏开启时,截取的画面会显得发白(亮度高2-3倍,偏青色),因此无法判断颜色。
um win shot/record在开启时会发出警告;请在捕获时关闭游戏的Auto HDR(设置 > 系统 > 显示 > 图形 > 游戏 > Auto HDR),并在之后根据用户需要重新开启。
使窗口可预测
- 固定客户区大小的窗口模式。 每个游戏都将此设置隐藏在某个地方:
- ini文件(UE
GameUserSettings.ini中的[/Script/Engine.GameUserSettings],Unity在HKCU\Software\<公司>\<产品>下的Screenmanager Fullscreen mode/Resolution注册表值); - 启动参数(
-windowed -w 1920 -h 1080,Unity-screen-fullscreen 0 -screen-width 1920 -screen-height 1080,Source引擎-sw -w 1920 -h 1080); - 或游戏自身的注册表(AoE2:
Mode Display0 +Windowed Width/Height)。 um win drive --proc X "size 1920 1080"也能调整大多数窗口化游戏的大小。
- ini文件(UE
- 跳过开场动画: 使用启动参数(
-skipintro、-nosplash、Unity-popupwindow),或删除/重命名游戏副本中的开场视频。 - 直接进入游戏: 加载器参数(tModLoader
-skipselect Player:World)、用于测试的存档、场景自动加载、开发控制台命令。 - 后台节流: 许多游戏在未获得焦点时会节流或暂停。找到相应设置(Terraria:
Main.instance.InactiveSleepTime = TimeSpan.Zero;Unity:Application.runInBackground = true;UE:t.IdleWhenNotForeground 0)。
比点击更好:脚本化场景或桥接
- 在你的模组中使用聊天或控制台命令 来获取物品、生成敌人和传送。它们使测试变成一行命令(
/arsenal、/mothership)。 - 测试场景: 模组侧的时间线(在第N帧生成一波敌人,在第N+30帧开火)、带有触发器的场景(通过AoE2ScenarioParser的AoE2)、带有原始备份的专用测试世界。
- 智能体桥接: 模组内部在
127.0.0.1上的JSON行套接字(参见examples/terraria-tmodloader/reference/AgentBridge.cs)。- 命令如
observe(菜单选项或世界状态文本)、click <id>、controls、step。 - 在游戏主线程上,在一次更新后处理每个请求,以确保回复的一致性。
- 从UI树中通用地读取菜单,以便智能体看到玩家所能看到的。排除破坏性按钮(例如删除)。
- 智能体随后可以完全无需像素地进行游戏。
- 命令如
- 进程外后端: 保持游戏内部分轻量,将逻辑放在外部(HTTP/文件拖放)。这种模式可以扩展到AI NPC和跨游戏混搭。
崩溃与清理
- 崩溃报告器(BugSplat
BsSndRpt64.exe、CrashReportClient.exe、UnityCrashHandler64.exe)可能会残留,导致Steam显示“已在运行”。使用um win ps发现它们,使用um win kill <pid>清除它们。 - 切勿使用
pkill -f或通配符taskkill /IM。该模式可能匹配到你自己的shell或其他应用程序。 - 崩溃后,先读取加载器或游戏日志(模组适配任意游戏技能列出了它们),然后查看Windows事件查看器(应用程序日志)以了解原生崩溃信息。
Linux 和 macOS
- Linux (X11):
xdotool search --name "Game" windowactivate --sync key Escape,xdotool mousemove --window $W 640 360 click 1。截图:import -window $(xdotool search --name Game) shot.png,或使用ffmpegx11grab。 - Linux (Wayland): 使用 ydotool +
grim。Proton游戏是Wine下的Windows游戏:启动选项(WINEDLLOVERRIDES、PROTON_LOG=1)放在Steam中。 - macOS:
screencapture -l <windowid> shot.png(通过GetWindowID或AppleScript获取窗口ID),使用osascript/cliclick进行输入。输入和屏幕录制需要为终端授予辅助功能和屏幕录制权限。