게임 자동화: 에이전트의 손과 눈
실제 게임이 오라클입니다. 루프는 실행 → 탐색 → 씬 설정 → 행동 → 스크린샷 및 로그 읽기 → 판단입니다. 게임마다 한 번만 구축하면, 이후 모든 변경 사항을 1분 안에 확인할 수 있습니다.
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 온라인 서버에 접근' 경고가 발생했습니다. ScriptHookV가 차단했지만, 이에 의존하지 마세요.
idle을 확인하고, 사용자에게 클릭을 요청하거나, 안티치트를 꺼서 온라인이 시작되지 않도록 실행하세요.knowledge/techniques/driving-real-games-safely.md를 참조하세요. - 입력은 게임으로만 전달됩니다. WinDrive는 다른 앱이 포그라운드에 있을 때 전송을 거부합니다. 유일한 예외는 포그라운드 앱이 없고 커서가 게임 위에 있을 때입니다. 창 모드 게임은 클릭 시 포그라운드를 떨어뜨리기 때문에 이런 상황이 발생할 수 있습니다.
- 사용자가 PC 앞에 있을 수 있습니다.
idle이 1분 미만이면 주행 전에 물어보고 세션을 짧게 유지하세요. 사용자가 승인하면 무인 실행도 괜찮습니다. - 스크린샷은 토큰을 소모합니다.
--scale 0.33복사본을 사용하세요. 클릭 시 좌표를 ×3으로 다시 곱하고, MODLOG.md에 측정된 메뉴 클릭 지점 테이블을 유지하세요. - gfxcapture를 사용하는 이유: GPU 렌더링 게임은 GDI 캡처 시 검은색으로 나옵니다. gfxcapture(Windows.Graphics.Capture)는 가려져 있더라도 한 창의 실제 프레임을 캡처합니다. 최소화된 창은 캡처할 수 없습니다.
- HDR 디스플레이: SDR 게임에 Windows Auto HDR이 켜져 있으면 캡처가 흐릿하게(2~3배 밝고 시안 색조) 나와 색상 판단이 불가능합니다.
um win shot/record가 이 상태를 경고하므로, 캡처 중에는 해당 게임의 Auto HDR을 끄고(설정 > 시스템 > 디스플레이 > 그래픽 > 게임 > Auto HDR), 사용자가 원하면 다시 켜세요.
창을 예측 가능하게 만들기
- 고정 클라이언트 크기의 창 모드. 모든 게임은 이 설정을 어딘가에 숨깁니다:
- ini 파일 (UE
GameUserSettings.ini의[/Script/Engine.GameUserSettings], Unity의Screenmanager Fullscreen mode/Resolution레지스트리 값HKCU\Software\<회사>\<제품>); - 실행 플래그 (
-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을 사용하지 마세요. 패턴이 자신의 셸이나 다른 앱과 일치할 수 있습니다. - 크래시 후에는 먼저 로더나 게임 로그를 읽고(모드-모든-게임 스킬에 나열됨), 그 다음 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(window id는GetWindowID또는 AppleScript로),osascript/cliclick로 입력. 입력 및 화면 녹화에는 터미널에 대한 손쉬운 사용 및 화면 녹화 권한이 필요합니다.