AI가 만든 3D 게임, 시작 화면 다음에 검증할 두 가지

PC에서 돌아가는 듯한 너구리 게임이 휴대폰 화면에서는 제대로 보이지 않았다. 밤을 마친 뒤에는 다음 밤 버튼이 보이는데도 클릭이 막혔다. Simon Willison이 공개한 Raccoon Heist 제작 세션에서 유용한 부분은 완성 화면보다 이 두 실패가 발견되고 수정된 과정이다. 시작 화면과 오류 없는 콘솔만 확인했다면 놓쳤을 문제들이다.

독자에게 필요한 결정은 “AI가 게임을 만들 수 있나”라는 추상적인 찬반보다 구체적이다. AI가 건넨 브라우저 게임을 어디까지 인수하고, 어느 경로는 검증 대기로 남길 것인가? 이 글은 두 결함의 증거를 따라가며 표시·입력·상태 전환을 나눠 확인하는 인수 절차를 제안한다. 기능 인수와 재미 평가는 별도다.

이 글은 공개 세션과 고정 커밋을 읽은 분석이며, 게임을 새로 실행하거나 실제 휴대폰에서 재현한 결과가 아니다. 분석 대상은 2026년 8월 5일 사례다. 최신 모델 순위나 모든 AI 개발 도구의 성능을 대표하는 실험으로 읽어서는 안 된다.

1. ‘한 번의 프롬프트’ 안에는 여러 번의 검사가 있었다

원문의 초기 요청은 모바일 친화적인 브라우저용 3D 게임, 잦은 커밋과 푸시, 커밋마다 작업 기록을 남기는 방식이었다. 작성자는 추가 설계 질문 없이 진행하도록 맡겼다. 그러나 한 번 요청했다는 말이 모델 응답 한 번으로 구현·검사가 끝났다는 뜻은 아니다. 공개 세션에는 코드 편집, 브라우저 검사, 실패 로그 확인, 수정과 재검사가 이어진다.

이 차이는 인수 기준을 바꾼다. “완료했습니다”라는 보고를 받는 대신 어떤 화면 조건에서 무엇을 눌렀고, 그 뒤 상태가 어떻게 바뀌었는지 요구해야 한다. notes.md는 탐색 지도로 유용하지만 에이전트가 쓴 성공 요약 그 자체를 독립 검증으로 취급하지 않는다. 핵심 주장은 가능한 한 실제 도구 출력과 대응시킨다.

2. 모바일 문제: 그리는 크기와 보이는 크기는 다르다

원본 세션은 390×844 뷰포트, DPR 2의 모바일 에뮬레이션으로 canvas를 진단한다. DPR은 CSS 화면 크기와 그리기 버퍼 크기를 연결하는 배율이다. 진단 출력에서 canvas.width와 height는 780×1688이었고, clientWidth와 clientHeight도 780×1688이었다. 그리기 버퍼가 큰 것 자체가 문제는 아니다. CSS 표시 영역까지 화면보다 커진 것이 중요한 징후다.

수정 전 코드는 renderer.setSize() 뒤에 canvas.style.cssText를 대입했다. 세션은 이 대입이 크기 설정으로 만들어진 인라인 스타일을 덮어쓴 것으로 진단한다. 수정은 기본 스타일을 먼저 적용한 다음 setPixelRatio(), setSize()를 호출하는 순서로 바꾸는 것이었다. 고정 커밋의 main.js도 이 순서를 보여준다.

DPR 2 원본 진단에서 버퍼와 표시가 모두 780×1688이던 상태를 표시 390×844 목표 관계와 비교한 도식

수정 전은 원본 로그의 기록이다. 오른쪽은 확인할 크기 관계이며 수정 후 실측 배열이나 실제 휴대폰 검사 결과가 아니다. 출처: simonw.github.io/raccoon-heist/transcript/page-001.html.

수정 후 세션의 출력에는 모바일 상태 playing, 화면 390×844와 페이지 오류 없음이 기록돼 있다. 작업 노트는 투영 마커 검사로 플레이어 위치를 확인했다고 설명한다. 다만 이것은 해당 세션의 에뮬레이션 증거다. 모든 실제 휴대폰에서 문제가 생겼다거나 모두 해결됐다는 일반화는 하지 않는다. 재검사 출력에 수정 후 clientWidth 배열이 다시 실린 것도 아니므로, 그림의 정상 크기는 확인할 목표 관계로 구분했다.

실무에서는 canvas의 width/height와 clientWidth/clientHeight를 함께 저장하고, 뷰포트·DPR·플레이어 화면 위치를 같은 기록에 남기는 편이 좋다. 표시 영역과 버퍼를 구분하지 않으면 “해상도를 올렸으니 정상”이라는 잘못된 결론에 도달하기 쉽다. 실제 터치로 캐릭터를 움직이는 검사도 화면 위치 검사와 별도다.

3. 다음 밤 문제: 보이는 버튼이 입력을 받는 버튼은 아니다

다른 실패는 밤 종료 뒤에 나타났다. 원본 검사에서 다음 밤 버튼은 visible·enabled·stable 조건을 만족했지만 클릭이 완료되지 않았다. 로그에는 .stars 요소가 포인터 이벤트를 가로챘다는 원인이 찍혔다. 30000ms는 이 클릭의 타임아웃 설정이지, 버그를 고치는 데 걸린 시간이나 사용자의 실제 대기 시간 측정값이 아니다.

작업 노트와 수정 기록을 함께 보면 별점 표시의 stars 클래스가 제목 화면의 전체 화면 스타일과 충돌한 사례다. 수정은 별점 표시를 .rank-stars로 분리하는 것이었다. 같은 전환 검사를 다시 돌린 출력에는 두 번째 밤의 state가 playing으로 기록되고, 이후 실패 화면의 버튼 문구가 RETRY NIGHT 2로 나타난다.

보이는 버튼을 stars 요소가 가로막은 실패와 rank-stars 분리 뒤 다음 밤 playing 및 재시도 문구를 확인한 기록

클래스 충돌 해결 뒤 진행된 경로를 요약했다. 30000ms는 클릭 타임아웃이며 수정 소요 시간이 아니다. 출처: simonw.github.io/raccoon-heist/transcript/page-001.html.

여기서 확인된 범위를 좁게 읽어야 한다. 재검사 로그는 두 번째 밤으로의 전환과 재시도 버튼의 존재·문구까지 뒷받침한다. 그 마지막 출력만으로 재시도 버튼을 실제 클릭한 뒤 새 플레이 상태에 복귀했다는 사실까지 증명되지는 않는다. 기능 인수표에는 이 차이를 남겨야 한다.

테스트를 고칠 때 클릭 강제를 켜서 장애물을 무시하면 원인을 숨길 수 있다. 중요한 것은 다음 화면을 억지로 띄우는 일이 아니라 사용자의 입력이 의도한 요소에 도달하게 만드는 것이다. 버튼을 찾았다는 검사와 클릭 후 상태가 바뀌었다는 검사를 분리하면 이런 허점을 줄일 수 있다.

4. 두 결함을 인수 절차로 바꾸기

화면이 보인다는 증거, 입력이 전달된다는 증거, 다음 상태로 넘어간다는 증거를 따로 남긴다. 아래 절차와 판정표는 공개 사례를 바탕으로 구성한 편집 분석이며, 실제로 이번 환경에서 실행한 테스트 결과표가 아니다.

밤 종료에서 다음 밤 playing 및 실패 화면 문구 확인까지의 근거와 추가 재시도 클릭 제안을 구분한 흐름도

실선은 원본 로그로 뒷받침하는 흐름, 점선은 추가 검사 제안이다. 재시도 문구만으로 실제 재진입을 승인하지 않는다. 출처: simonw.github.io/raccoon-heist/transcript/page-001.html.

검사 경계 이번 사례에서 읽은 근거 다음 빌드에 요구할 기록 인수 판정
표시 DPR 2 환경에서 CSS 크기까지 커진 진단, 크기 설정 순서 수정 뷰포트·DPR, 버퍼와 CSS 크기, 플레이어 위치 데스크톱 한 장만으로 모바일 승인 불가
입력 visible인 다음 밤 버튼의 클릭이 .stars에 가로막힘 일반 클릭 결과, 가로챈 요소, 클릭 뒤 상태 DOM에 버튼이 있어도 통과 아님
상태 전환 재검사에서 두 번째 밤 playing과 재시도 문구 확인 밤 종료→다음 밤, 실패→재시도→playing 각각 문구 확인과 재진입 확인을 구분
재미 원저자는 구현을 높이 보면서도 기다림과 팀 기능 부재를 지적 디버그 없이 한 판 플레이, 선택·위험·대기 구간 관찰 자동 기능 통과로 재미 승인 불가

인수 요청은 “모바일에서도 확인해 주세요”보다 좁고 관찰 가능하게 쓰는 것이 좋다. 예를 들어 해당 기기의 뷰포트와 DPR을 기록하고 시작한 뒤, 플레이어가 보이는지와 터치 이동이 되는지를 따로 확인한다. 이어 성공 화면에서 다음 밤 버튼을 일반 입력으로 누르고 playing 복귀를 기록한다. 실패 경로에서는 재시도 문구를 보는 데서 멈추지 않고 다시 입력해 새 판의 타이머와 화면 상태가 초기화되는지 확인한다. 이는 독자가 적용할 제안이지 이번 글이 수행한 실행 주장이 아니다.

원본 진행 검사에는 addBank와 setTime 같은 디버그 훅이 쓰였다. 빠르게 전환 경계를 검사하는 데에는 유용하지만, 보통 플레이어가 점수를 모으고 시간을 보내는 자연스러운 한 판과는 다르다. 전환 회귀 테스트와 실제 플레이의 증거를 같은 칸에 합치지 않는 이유다.

5. 실행 구조가 단순해도 비용과 공개 범위는 남는다

작업 노트는 Three.js를 저장소에 포함하고, 생성한 텍스처·타이틀 이미지를 정적 파일로 배포하며, WebAudio로 소리를 만드는 구조라고 설명한다. 이미지 생성 스크립트는 환경 변수의 API 키를 읽어 빌드 시점에 이미지를 생성한다. 이것은 플레이할 때마다 이미지 생성 API를 호출한다는 구조와 다르다.

그러나 ‘실행 중 API 호출 없음’을 ‘제작비와 호스팅 비용이 모두 0’으로 바꿔 읽을 수는 없다. 이 자료만으로 전체 API 청구액, 사람의 작업 시간, 프로젝트 총비용은 확정되지 않는다. 저장소를 공개하기 전에는 키·작업 기록·불필요한 파일이 배포 대상에 포함되는지도 별도로 검토해야 한다. 이 글에서는 원본 생성 스크립트를 실행하거나 원본 게임 자산을 재배포하지 않았다.

또한 비공개 저장소가 비공개 미리보기를 뜻하지는 않는다. 선택 단계에서 보존한 GitHub 공식 Pages 생성 안내는 비공개 저장소의 Pages도 일반 인터넷에 공개될 수 있다고 경고한다. Free 계정은 공개 저장소가 필요하며 비공개 저장소 지원에는 해당 요금제 조건이 있다. 원저자의 약 30초 미리보기 경험도 보장 시간이 아니다. 같은 공식 안내는 변경 공개에 최대 10분이 걸릴 수 있다고 설명한다.

Pages 소개 문서는 보안 목적으로 방문자 IP 주소를 기록·저장한다고 밝힌다. 정적 사이트라는 말은 서버 측 게임 API가 없다는 구조 설명일 수 있지만, 방문 데이터가 전혀 남지 않는다는 뜻은 아니다. 비용·배포 권한·비밀값 검토를 기능 검사와 별도로 두어야 한다.

6. 기능 통과 뒤에도 남는 질문: 이 게임은 재미있는가

원저자는 결과를 인상적인 출발점이지만 완성된 게임으로는 아쉽다고 평가했다. 팀처럼 보이는 다른 너구리들은 실제 팀 기능을 하지 않고, 물건을 다 모은 뒤 새벽까지 기다리는 시간이 생긴다는 지적이다. 이는 한 작성자의 한 게임에 대한 주관적 평가이지 AI가 재미를 만들 수 없다는 보편적 증명은 아니다.

기능 검사인 표시·입력·상태 전환과 원저자가 지적한 팀 기능 부재·수집 후 대기를 다른 축으로 나눈 도식

구현이 작동하는 것과 재미있다는 평가는 다르다. 플레이 경험 지적은 한 작성자의 한 사례 평가다. 출처: simonwillison.net/2026/Aug/5/raccoon-heist.

이 사례에서 가져갈 결론은 프롬프트를 더 길게 쓰라는 조언이 아니다. 검증의 단위를 화면·입력·상태·재미로 나누면, 어디까지 확인됐고 무엇이 아직 남았는지를 구체적으로 말할 수 있다. 에이전트의 반복 수정은 출발점을 빠르게 만들지만, 검증되지 않은 경로와 플레이 경험을 대신 승인해 주지는 않는다.

참고 자료와 작성 범위

AI를 활용해 공개 자료를 검토하고 한국어 해설·독자용 판정표와 설명 그림을 구성했다. 그림은 원본 게임 화면이나 실제 재현 스크린샷이 아니라 출처에 근거해 새로 만든 도식이다. 기존 내부 글 목록은 중복 확인용으로만 사용했으며, 본문 관련성을 따로 검증하지 않은 내부 링크는 억지로 추가하지 않았다.

댓글

이 블로그의 인기 게시물

체크아웃은 분리됐는데 Git 상태는 공유된다: Codex 0.154 worktree의 세 경계

잠근 작업이 커밋 뒤 다시 나온다: PostgreSQL 에이전트 큐의 소유권 설계

코딩 에이전트는 API 문서보다 AGENTS.md를 먼저 읽었다