지금까지 PI의 설치·사용법·서브에이전트·패키지를 다뤘습니다. 이번엔 말로만 하지 말고 실제로 pi에게 게임 하나를 통째로 만들게 해봤습니다. 그것도 돈 한 푼 안 쓰고 — Gemini의 무료 모델 gemini-3.1-flash-lite로요.
이 글부터 3편에 걸쳐, 빈 폴더에서 플레이 가능한 스네이크 게임이 나오기까지의 과정을 명령어와 프롬프트 그대로 기록합니다.
0. 준비물
- pi 설치 (
pi --version→ 저는0.75.5) - 빈 작업 폴더 하나
- Gemini API 키 — 무료 티어로
gemini-3.1-flash-lite호출 가능
작업 폴더에 .env 파일을 만들고 키를 넣어둡니다.
# .env
GEMINI_API=AIza... # 본인 키
변수명은 자유롭게 정해도 됩니다. 저는
GEMINI_API로 뒀고, pi에는--api-key로 직접 넘겼습니다.
1. pi를 Gemini에 연결하기
pi --help를 보면 핵심 플래그가 보입니다.
--provider <name> Provider name (default: google)
--model <pattern> Model pattern or ID
--api-key <key> API key (defaults to env vars)
--print, -p Non-interactive mode: process prompt and exit
반갑게도 provider 기본값이 google 입니다. 즉 Gemini를 쓰기에 가장 손이 덜 갑니다. 모델 ID만 지정하면 pi가 구글 API로 바로 호출합니다.
먼저 키와 모델이 진짜 도는지 1회 호출로 핑 테스트부터 합니다. .env를 셸로 불러와서:
set -a; . ./.env; set +a # GEMINI_API 로드
pi -p --provider google --model gemini-3.1-flash-lite \
--api-key "$GEMINI_API" \
-nt -ne -ns -np --no-session \
"Reply with exactly: PI_OK"
출력:
PI_OK
연결 성공. 참고로 위에서 붙인 플래그들은 핑을 가볍게 만들기 위한 것입니다.
-nt도구 끄기(텍스트만)-ne익스텐션 로드 끄기-ns스킬 로드 끄기-np프롬프트 템플릿 끄기--no-session세션 파일 안 남기기
2. print 모드로 게임을 통째로 만들게 하기
이제 진짜입니다. -p(print) 모드는 프롬프트를 받고 도구를 알아서 쓰고 끝나는 비대화형 모드입니다. 즉 pi가 write/edit/bash 도구로 직접 파일을 만들어냅니다. 스크립트로 자동화하기에 딱이죠.
작업 폴더에서 이렇게 던졌습니다.
pi -p --provider google --model gemini-3.1-flash-lite \
--api-key "$GEMINI_API" --no-session \
"Create a single self-contained file named index.html implementing a classic Snake game. Strict requirements:
- Pure HTML/CSS/JS in ONE file, no external libraries or CDNs.
- HTML5 canvas, 20x20 grid, square board centered on the page, responsive.
- Controls: Arrow keys AND WASD. Never allow reversing directly into yourself.
- Food spawns at random empty cells; eating grows the snake and adds 10 points.
- Collision with walls or self => game over.
- Game over overlay shows final score and a Restart button; also restart on Space or Enter.
- Game loop around 10 fps.
- Modern dark UI: near-black background, a single bright accent color (#e8734d), rounded board, score at top, title 'PI SNAKE'.
- Write the complete file to index.html now using your write tool."
결과:
The Snake game has been implemented in `index.html`.
...
걸린 시간 약 8초, 만들어진 파일은 index.html 하나(4.4KB). 명령어 하나로 빈 폴더에 게임 파일이 떨어졌습니다.
프롬프트를 영어로 쓴 이유는, 가벼운 모델일수록 영어 지시를 더 또박또박 따라가는 경향이 있어서입니다. 한국어로 해도 되지만 요구사항이 많을 땐 영어가 안정적이었습니다.
3. 첫 결과물 — 보기엔 그럴듯한데
코드를 열어보니 UI는 의외로 깔끔했습니다. 제목, 점수, 액센트 컬러 테두리, Restart 버튼까지. flash-lite치고 인상적이었죠.
그런데 브라우저로 열자마자 이게 떴습니다.

시작하자마자 GAME OVER. 키 한 번 안 눌렀는데요.
원인은 코드를 읽으니 금방 보였습니다. 뱀의 초기 방향이 정지 상태(dx=0, dy=0)인데, 게임 루프는 곧바로 돌기 시작합니다. 그 첫 틱에서 “다음 머리 위치”를 계산하면 현재 머리와 같은 칸이 나오고, 자기 몸과 충돌한 것으로 판정되어 즉시 게임오버가 된 겁니다.
function update() {
const head = {x: snake[0].x + dx, y: snake[0].y + dy}; // dx,dy=0 → 제자리
if ( ... || snake.some(p => p.x === head.x && p.y === head.y)) // 자기 자신과 "충돌"
return gameOver();
...
}
가벼운 모델이 자주 내는 종류의 버그입니다. “정지 상태”를 예외 처리해야 한다는 걸 놓친 거죠. 요구사항엔 없었지만 당연히 필요한 디테일.
이번 편 정리
- pi는 provider 기본값이 google 이라 Gemini 연결이 쉽다.
pi -p --model gemini-3.1-flash-lite --api-key ...로 print 모드 자동화가 된다.- flash-lite도 한 번의 프롬프트로 게임 한 파일을 뽑아낸다.
- 다만 결과물엔 “정지 상태에서 자기 충돌” 같은 현실적인 버그가 섞여 있다.
다음 편에서는 이 버그를 pi에게 다시 시켜서 고치고(읽고-고치는 루프), 그리드·하이스코어 같은 디테일까지 더해 완성합니다. 감사합니다!