# 조작과 판정

> 조작은 눈으로 하고 판정은 로그로 합니다. 판정을 픽셀에서 옮긴 게 최대 개선이었습니다.

- 수치: RPC > 화면
- 상태: wip
- 사람이 보는 화면: https://aitryed.com/ko/built/android-qa/driving/
- 반대 언어: https://aitryed.com/en/built/android-qa/driving/index.md
- 이 사이트 안내(AI용): https://aitryed.com/ko/llms.txt

---

**게임 화면은 붙잡을 게 없어서, 사람처럼 «보고 누릅니다». 그런데 «됐는지 확인하는 일»까지 화면으로 하려다 크게 틀렸습니다. 판정을 화면에서 기록으로 옮긴 것이 이 프로젝트 최대의 개선이었습니다.**

> **[도판]** 조작은 눈으로 하고 판정은 로그로 한다. 처음엔 판정까지 비전으로 했는데, 그게 이 프로젝트에서 제일 크게 틀린 판단이었다.
>
> 기기에서 두 갈래가 나간다. 위쪽 조작 경로는 스크린샷과 비전을 거쳐 좌표 탭으로 이어지고, 아래쪽 판정 경로는 파일 로그에서 RPC와 상태 전이를 읽어 판정한다. 비전에서 판정으로 가던 처음 경로는 점선으로 표시돼 폐기됐다.

## 누르는 것은 화면을 볼 수밖에 없습니다

게임 화면에는 부품 이름이 없으니, **사진을 찍어서 보고 「저기다」를 판단해 누릅니다.** 사람이 하는 것과 같습니다.

이건 대안이 없습니다. **조작에는 여전히 눈으로 보는 방법밖에 없습니다.**

## 그런데 「됐는지 확인」까지 화면으로 하면 안 됩니다

처음엔 이것도 화면으로 했습니다. 누르고 나서 **화면이 바뀌었는지 사진으로 확인**했습니다.

**이게 이 프로젝트에서 제일 크게 틀린 판단**이었습니다.

## 화면으로 판정하면 안 되는 이유 — 「두 가지를 구분 못 합니다」

화면에는 **결과**만 나옵니다. 그래서 이 둘이 **똑같이 보입니다.**

| 실제 상황 | 화면 |
|---|---|
| **제대로 처리됐음** | 다음 화면으로 넘어감 |
| **처리는 실패했는데 화면만 넘어감** | **똑같이 다음 화면** |

그리고 반대도 있습니다.

| 실제 상황 | 화면 |
|---|---|
| **제대로 처리됐는데** 연출이 느려서 아직 안 바뀜 | **실패처럼 보임** |
| **진짜 실패** | 안 바뀜 |

즉 **화면이 같아도 속이 다르고, 속이 같아도 화면이 다릅니다.**

## 그래서 기록을 읽기로 했습니다 — 그런데 처음엔 「불가능하다」고 단정했었습니다

여기가 값을 치른 자리입니다.

저는 처음에 <strong>「기록으로는 게임 속 상태를 알 수 없다」</strong>고 단정했습니다. 근거는 **표준 기록 통로가 막혀 있었다**는 것이었습니다.

그런데 그건 **한 통로가 막힌 것**이었지 **기록이 없는 게 아니었습니다.** 다른 통로로 게임이 **서버와 주고받는 내용**이 그대로 남고 있었습니다.

거기엔 화면에 안 나오는 것까지 다 있습니다 — **어떤 요청을 보냈고, 서버가 뭐라고 답했고, 성공인지 실패인지.**

**화면보다 훨씬 정확한 판정 근거**가 처음부터 있었는데, 제가 **한 곳이 막힌 걸 보고 전부 없다고 단정**했던 것입니다.

## 그래서 지금 구조

| 단계 | 무엇으로 |
|---|---|
| **누르기** | 화면 (대안 없음) |
| **1순위 판정** | **서버와 주고받은 기록** |
| **2순위 판정** | 게임이 남긴 다른 기록 |
| **마지막 수단** | 화면 |

화면은 **완전히 버린 게 아니라 마지막 칸으로 내려갔습니다.**

2026-09 부터는 그 마지막 칸을 사람 대신 **AI 판독기**가 맡습니다. 틀린 통과가 나가지 않게 규칙을 둘러서요 — [사진 판독기](/ko/built/android-qa/judge/index.md)에 따로 적었습니다.

## 아직 무는 곳

정직하게 적어 둡니다. 네 가지가 남아 있습니다.

**하나 — 「아무 일도 안 일어난 채 멈추는 것」은 오류 카운터로 안 잡힙니다.**

오류가 나면 세면 됩니다. 그런데 **오류도 안 나고 그냥 멈춰 있는** 경우가 있습니다. 아무것도 실패하지 않았으니 카운터가 0입니다.

그래서 **화면이 얼마나 변했는지**를 별도로 재고, **변화가 없으면 단계적으로 복구를 시도**하다 안 되면 끊습니다.

**둘 — 사진을 누르기 «전»에 한 번 찍어야 합니다.** 새로 시작한 프로그램은 화면 배율 정보가 비어 있어서, 먼저 한 장 찍어야 채워집니다.

**셋 — 다시 켜면 옛날 기록이 다시 보입니다.** 그래서 **기록을 지우고 처음부터 읽어야** 합니다. 안 그러면 **지난번 결과를 이번 결과로 착각**합니다.

**넷 — 첫 화면은 「완전히 새 상태」로만 잴 수 있습니다.** 자동 접속이 기억해 둔 계정으로 그냥 내달려서, **처음 켠 사람이 보는 화면**을 재려면 앱 데이터를 지우고 다시 켜야 합니다.

## 여기부터는 자세한 기록입니다

붙잡을 게 없는 화면이니 조작 경로가 이렇게 된다.



## 최대 개선은 판정을 옮긴 것이었다

처음엔 "로그로는 게임 내부 상태를 알 수 없다"고 단정했다. 표준 로그 채널이 막혀 있었기 때문이다.

**틀렸다.** 막혀 있던 건 그 채널 하나였고, **엔진이 기기에 직접 쓰는 파일 로그에는 상태 머신 전이와 모든 RPC 송수신이 그대로 남아 있었다.**

여기서 증거 우선순위가 정해졌다.

> **수신 RPC > 상태 전이 > 화면**

## 화면이 왜 마지막인가

픽셀은 두 가지를 구분하지 못한다.

- **로딩 스피너와 멈춘 화면** — 둘 다 "돌고 있는 그림"이다
- **같은 화면이 뜻하는 두 가지 상태** — 예를 들어 요청이 처리 중인 화면과 이미 실패해서 되돌아온 화면이 같아 보일 수 있다

로그는 그걸 구분한다. 요청을 보낸 기록이 있고 응답을 받은 기록이 있으면, 화면이 무엇이든 **어느 상태인지가 결정된다.**

그리고 판정을 픽셀에서 로그로 옮기고 나서야 **무인 장시간 운전이 가능해졌다.** 비전 판정은 애매한 화면에서 사람을 부르는데, 사람이 없으면 부를 곳이 없다.

## 비전은 조작에만 남겼다

판정에서 뺐다고 비전을 버린 건 아니다. **조작에는 여전히 비전밖에 없다.**

버튼이 어디 있는지 알 방법이 그것뿐이라서다. 다만 조작과 판정은 요구가 다르다.

- **조작은 틀려도 복구된다.** 엉뚱한 데를 누르면 화면이 안 바뀌고, 안 바뀐 걸 알면 다시 찾는다.
- **판정은 틀리면 그대로 결과가 된다.** 잘못 PASS를 준 케이스는 아무도 다시 안 본다.

그래서 **틀려도 되는 자리에 비전을 두고, 틀리면 안 되는 자리에 로그를 뒀다.** 같은 도구를 두 목적에 쓰면서 신뢰도만 다르게 요구하는 건 성립하지 않는다.

**(2026-09 기준)** 로그가 끝내 못 정하는 검사(화면에 무엇이 보이나)는 이제 사진 판독기가 판정한다. 비전이 판정으로 돌아온 것이 아니라, 위의 비대칭 — 잘못 준 PASS 는 아무도 다시 안 본다 — 이 그대로 설계 조건이 됐다. 판정마다 근거 사진을 적게 하고, 그 근거를 코드 게이트가 확인하고, PASS 는 다른 모델이 한 번 더 본다. → [사진 판독기](/ko/built/android-qa/judge/index.md)

## 아직 무는 곳

- **무증상 정지는 에러 카운터로 안 잡힌다.** 아무것도 실패하지 않은 채로 멈춘다. 그래서 화면 변화량을 별도 축으로 두고, 변화가 없으면 단계적으로 복구하다 끊는다
- **캡처를 탭보다 먼저** — 새 프로세스는 화면 배율 상태가 비어 있다
- 재기동하면 옛 세션 로그가 로테이션 전에 다시 노출된다. 로그를 지우고 오프셋 0에서 읽어야 한다
- 자동 접속 체인이 기억된 계정으로 내달려서, 첫 화면 케이스는 앱 데이터를 지운 신규 부팅으로만 실측된다
