메인 칼럼 개발일지 작업물 연락처

무료 AI에게 pi로 아케이드를 통째로 시켰다 — 게임 12종, 비용 0원

pi를 print 모드로 스크립팅해서, 무료 Gemini(gemini-3.1-flash-lite)로 미니게임 12개와 아케이드 허브를 찍어냈습니다. 테트리스·스페이스슈터까지. 한 번에 안 된 녀석을 고친 과정과, 그 과정에서 배운 「진단은 사람 몫」이라는 교훈까지.

지난 편들에서 pi로 스네이크 하나를 만들어봤습니다. 이번엔 작정하고 한계까지 밀어봤습니다.

돈 한 푼 안 쓰고, 무료 AI에게 미니게임 12개 + 아케이드 허브를 만들게 했다. 테트리스도, 스페이스슈터도. 순수 빌드 시간 3분, 모델 호출 20여 회, 비용 0원.

말보다 결과가 빠르니, 일단 직접 해보세요. (보드를 클릭하고 화살표/마우스/스페이스)

▶ 전체 화면으로 아케이드 열기

pi가 만든 PI ARCADE 허브

전부 gemini-3.1-flash-lite — 구글의 가장 가벼운 무료 모델 하나로 만든 결과물입니다.


1. pi를 ‘게임 공장’으로 돌리기

핵심은 pi의 print 모드(-p). 프롬프트를 주면 도구를 알아서 쓰고 끝나는 비대화형 모드라, 셸 스크립트로 묶어서 줄줄이 찍어낼 수 있습니다.

공통 스타일을 변수로 빼두고, 게임별 메커닉만 바꿔가며 build()를 반복했습니다.

set -a; . ./.env; set +a

S="단일 HTML 파일. 배경 #121212, 액센트 #e8734d, 상단 좌측에 ← ARCADE 링크,
   점수 표시, 게임오버 오버레이(+Restart, Space/Enter)..."

build () {
  pi -p --provider google --model gemini-3.1-flash-lite \
     --api-key "$GEMINI_API" --no-session "$2" </dev/null
}

build arcade/pong.html   "$S PONG vs CPU ..."
build arcade/2048.html   "$S 4x4 슬라이드 머지 ..."
build arcade/memory.html "$S 카드 짝맞추기 ..."
build arcade/whack.html  "$S 두더지 잡기 ..."
build arcade/flappy.html "$S 플래피 ..."

게임 하나당 8~9초. 브레이크아웃, 퐁, 2048, 메모리, 두더지잡기, 플래피 — 줄줄이 떨어졌습니다.

게임결과
🐍 SNAKE이전 편에서 제작
🧱 BREAKOUT한 번에 성공
🏓 PONG한 번에 실패 (아래 참고)
🔢 2048한 번에 성공
🧠 MEMORY한 번에 성공
🔨 WHACK한 번에 성공
🐤 FLAPPY한 번에 성공
🟦 TETRIS한 번에 성공
🚀 SHOOTER한 번에 성공
💣 MINES한 번에 성공
🦖 DINO한 번에 성공
⭕ TICTAC한 번에 성공

두더지잡기와 2048 — 한 방에 동작

처음엔 7종으로 시작했는데, 욕심이 나서 테트리스와 스페이스슈터 같은 ‘보스급’ 까지 더 시켜봤습니다. 7개 회전 블록과 충돌·라인 클리어가 있는 테트리스, 적이 쏟아지는 슈터 — 가벼운 무료 모델한테는 무리겠거니 했는데, 둘 다 한 번에 돌아갔습니다.

테트리스 — 7종 회전블록·라인클리어까지 한 방에

실전 함정 하나. 처음엔 새로 만든 arcade/ 하위 폴더 안에서 pi를 돌렸더니 멈춰버렸습니다. 원인은 pi가 “새 디렉터리를 신뢰할지” 묻는 프롬프트를 띄우는데, 스크립트엔 입력할 터미널(TTY)이 없어서 무한 대기한 것. 이미 신뢰된 부모 폴더에서 돌리고 arcade/파일.html로 경로만 지정하니 깔끔히 해결됐습니다. 자동화할 때 꼭 기억해 두세요.


2. 한 번에 안 된 녀석 — PONG, 그리고 ‘진단’

퐁만 이상했습니다. 공은 보이는데 양쪽 패들이 안 보였죠.

고치기 전 퐁 — 공만 보이고 패들이 없다

저는 당연히 “패들이 안 그려진다” 고 판단하고 그대로 시켰습니다. 그런데 flash-lite가 고친 결과는 더 나빠졌습니다. 공마저 사라졌죠. 가벼운 모델이 “보이지도 않는 화면”을 상상해서 엉뚱한 데를 건드린 겁니다.

그래서 코드를 직접 열어봤습니다. 그랬더니 — 패들은 멀쩡히 그려지고 있었습니다.

ctx.fillStyle = '#e8734d';
ctx.fillRect(10, playerY, paddleW, paddleH);              // 왼쪽 패들
ctx.fillRect(canvas.width - paddleW - 10, cpuY, ...);     // 오른쪽 패들

진짜 범인은 따로 있었습니다. 캔버스가 width=800 인데 페이지 폭은 그보다 좁아서, 가운데 정렬된 캔버스의 양 끝(패들)이 화면 밖으로 잘려나간 것. 가운데 있는 공만 보였던 이유죠.

이번엔 정확한 진단을 줬습니다.

"패들은 잘 그려지고 있다. 진짜 문제는 레이아웃 —
 캔버스 800px가 화면보다 넓어 양 끝 패들이 잘린다.
 캔버스를 480x360으로 줄이고 공을 canvas.width/2 로 중앙 배치하라."

결과는 단번에 정상.

올바른 진단 후 — 양쪽 패들과 공이 모두 보인다

여기서 이 글의 진짜 교훈이 나옵니다.

모델은 화면을 보지 못한다. “무엇이 잘못됐는지”를 짚는 진단은 여전히 사람 몫이고, 그 수정의 손놀림은 모델이 빠르다. 내가 틀린 진단을 주면, 똑똑한 모델조차 틀린 답을 빠르게 내놓는다.


3. 숫자로 본 ‘극한’

  • 결과물: 미니게임 12종 + 아케이드 허브, 전부 단일 HTML 파일
  • 순수 빌드 시간: 다 합쳐 3분 남짓 (게임당 8~11초)
  • 모델 호출: 빌드 + 수정 합쳐 20여 회 — 무료 한도(분당 제한) 500회 중 손에 꼽을 정도
  • 비용: 0원
  • 사람이 한 일: 게임 선정, 프롬프트 설계, 결과 눈으로 검증, 퐁 버그 진단

가벼운 무료 모델 + 잘 만든 하네스(pi)의 조합이, 방향만 잘 잡아주면 빈 폴더를 아케이드로 바꾼다는 걸 확인했습니다.


4. 직접 해보기 / 가져가기

위에 띄운 아케이드가 진짜 결과물입니다. 각 게임은 단일 HTML 파일 하나라, 링크를 우클릭해 저장하면 서버도 빌드도 없이 어디서든 그대로 돌아갑니다.

브레이크아웃 — 벽돌·패들·공 전부 정상


마치며

“좋은 모델 없으면 코딩 에이전트는 못 쓴다”는 말, 이번에도 반례를 하나 더했습니다. 중요한 건 모델의 크기가 아니라, 작업을 어떻게 쪼개서 맡기고, 결과를 어떻게 검증하고, 막혔을 때 어디가 문제인지 짚어주느냐 였습니다.

무료 AI에게 아케이드를 통째로 시켜본 이 실험이, 여러분이 직접 pi를 켜볼 핑계가 되었으면 합니다. 만든 게임이 있다면 자랑해 주세요. 감사합니다! 🕹️

김현빈 Developer & Writer

기술, 포스팅 관련 질문, 프로젝트 협업 등 연락주시면 언제든지 회신 드립니다.