itch.io 업로드 방법: 웹게임 ZIP을 butler로 올리고 사흘 만에 조회 0을 본 기록
itch.io 업로드 방법은 index.html이 맨 위에 있는 ZIP 하나를 HTML 게임으로 올리는 것이고, 저는 butler push로 바뀐 판만 자동으로 올립니다. 웹게임 RAYFRAME을 10월 28일에 올리며 바꾼 빌드 설정, ZIP 검사 스크립트, 첫 사흘 조회 26회와 그 뒤 0이 된 숫자를 적었습니다.
itch.io에 웹게임을 올리는 방법은 단순합니다. index.html이 맨 위에 있는 ZIP 파일 하나를 「HTML 게임」으로 올리면 됩니다. 저는 웹 화면에서 한 번 올린 뒤로는 itch.io의 명령줄 도구 butler로 새 판을 올립니다.
이 글은 제가 만드는 웹용 3대3 메카 슈팅 RAYFRAME을 2026년 10월 28일 itch.io에 올린 기록입니다.
10월 27일 밤에 준비를 시작해 다음 날 오전에 공개했으니 올리는 일은 하루가 안 걸렸습니다. 어려운 쪽은 그다음이었습니다. 사흘째부터 하루 조회가 0이 됐습니다.
왜 itch.io로 옮겼나
10월 27일에 CrazyGames가 Basic Launch 성적으로 RAYFRAME을 거절했습니다. 평균 플레이 3분 20초, 다음 날 재방문(D1) 1.2%였습니다. 마지막 7일 점수는 데스크톱·모바일 모두 15점 중 4점(통과선 9점)이었습니다.
제출 과정은 크레이지게임즈 개발자 제출 글에 적었습니다.
다음 후보는 Poki와 itch.io였습니다. Poki는 기본 계약이 웹 독점 5년이라 제 사이트 rayframe.flowoodz.com과 토스 미니앱을 그대로 둘 수 없었습니다.
itch.io는 심사도 독점도 없습니다. 포털별 조건은 웹게임 포털 6곳 비교 글에 정리해 두었습니다.
itch.io HTML5 ZIP 조건
itch.io 공식 문서가 정한 ZIP 조건은 이렇습니다.
- ZIP 안에
index.html이 있어야 하고, 그 파일이 게임의 시작점입니다 - 압축을 푼 뒤 파일 1,000개 이하, 전체 500MB 이하, 파일 하나 200MB 이하
- 파일 이름은 대소문자를 구분합니다
- 경로는 상대 경로여야 합니다. 게임 파일이 itch.io HTML CDN의 하위 폴더에 올라가기 때문에
/로 시작하는 절대 경로는 요청이 실패합니다
맥에서는 대소문자가 달라도 파일이 열립니다. 그래서 로컬에서 멀쩡하던 게임이 올린 뒤에 net::ERR_ABORTED 403으로 깨질 수 있다고 문서에 적혀 있습니다.
빌드에서 바꾼 세 가지
RAYFRAME은 Vite로 빌드합니다. npm run build:itch라는 빌드를 따로 만들고 .env.itch에 플랫폼 값을 넣었습니다.
VITE_PLATFORM=itch
# itch.io hosts only the files (an iframe on *.itch.zone): the socket always goes to the game server (DNS-only host)
VITE_WS_URL=wss://ws-rayframe.flowoodz.com/ws- 상대 경로:
vite.config.ts에 이미base: './'가 있어서index.html의 자산 경로가./assets/index-DNMg3G2h.js처럼 나옵니다 - 서비스 워커 없음: itch.io 판은 남의 도메인의 iframe 안에서 돕니다. 오프라인 캐시를 등록하지 않게 했습니다
- 소켓 주소 고정: 파일만 itch.io에 있고 경기는 제 서버에서 돌기 때문에, 소켓은 항상
VITE_WS_URL로 붙습니다
서버 쪽에는 접속의 Origin 헤더가 *.itch.zone이나 itch.io이면 플랫폼을 itch로 세는 줄을 더했습니다. 이 줄이 없으면 itch.io에서 온 사람이 다른 접속과 섞여서 효과를 따로 잴 수 없습니다.
ZIP 검사 스크립트
조건을 사람이 기억하면 언젠가 하나를 빠뜨립니다. 그래서 ZIP을 만드는 스크립트가 먼저 검사하고, 하나라도 걸리면 멈추게 했습니다.
abs=$(grep -lE '(src|href)="/[^/]' "$DIST/index.html" || true)
[ -z "$abs" ] || { echo "absolute paths in $abs" >&2; exit 1; }
[ ! -f "$DIST/sw.js" ] || { echo "$DIST/sw.js present: the itch build must not register a service worker" >&2; exit 1; }
[ "$files" -le 1000 ] || { echo "$files files (limit 1000)" >&2; exit 1; }
[ "$bytes" -le 500000000 ] || { echo "$bytes bytes (limit 500 MB)" >&2; exit 1; }
(cd "$DIST" && zip -qr -X "../../../$OUT" . -x '.DS_Store' '*/.DS_Store')처음에는 파일 하나 200MB 검사도 넣었습니다. 리뷰에서 뺐습니다. 지금 가장 큰 파일이 three.webgpu 번들 1,077,649바이트라서 200MB에 닿으려면 게임 구조가 완전히 바뀌어야 합니다.
다만 문서상 조건은 여전히 있으니, 큰 영상이나 음원을 넣게 되면 다시 넣어야 합니다.
10월 31일 판의 실측값은 파일 226개, 압축을 푼 크기 25,529,311바이트, ZIP 22,282,627바이트였습니다. 상한과 거리가 멉니다.
butler로 바뀐 판만 올리기
butler는 itch.io가 만든 업로드 도구입니다. 저는 v15.32.0 arm64를 씁니다. 올리는 명령은 한 줄입니다.
butler push "$WT/media/itch/rayframe-itch.zip" dunzkoi/rayframe:html5 --userversion "$VER"dunzkoi/rayframe:html5는 계정/게임:채널 형식입니다. 버전은 게임 제목 화면에 나오는 값과 같게 KST 날짜-커밋 앞 7자리로 넣습니다.
이 명령을 감싼 scripts/itch-upload.sh는 세 가지를 더 합니다.
- 지난 업로드 커밋 뒤로
apps/client나packages가 바뀌지 않았으면skip: client unchanged since …를 찍고 끝납니다. 서버만 고친 날에 같은 게임을 다시 올리지 않습니다 - 작업 폴더가 아니라
origin/main을 꺼낸 별도 워크트리에서 빌드합니다. 커밋하지 않은 파일이 섞여 올라가지 않습니다 - 빌드 전에 타입 검사와 테스트를 돌립니다. 하나라도 실패하면 올리지 않습니다
butler status로 보면 butler가 전체 파일이 아니라 차이만 올린다는 게 보입니다.
| html5 | #20090569 | ✓ #2260459 (from #2249807) | 20261031-1dde3ea |첫 판은 빌드 #2231206(20261028-e9b920c)이었습니다.
지금은 #2260459이고, 직전 빌드 #2249807에서 만든 패치로 올라갔습니다. 처리가 끝나면 그 판이 바로 플레이 화면에 나옵니다.
올린 뒤의 숫자
여기서부터가 잘 안 된 부분입니다. 10월 31일 12시 17분에 itch.io 통계 페이지와 제 서버 통계를 같이 확인했습니다.
| 날짜 | itch.io 조회 | 브라우저 플레이 | 서버의 itch 첫 방문 |
|---|---|---|---|
| 10-28 | 23 | 4 | 13 |
| 10-29 | 3 | 3 | 2 |
| 10-30 | 0 | 0 | 1 |
| 10-31 | 0 | 0 | 0 |
7일 노출은 609회, 클릭률은 1.97%였습니다. 평점·댓글·결제는 모두 0이었습니다.
30일 리퍼러 18회 중 11회가 newest, tag-mecha 같은 itch.io 목록에서 왔습니다. 새 게임 목록에 걸려 있는 이틀 동안만 사람이 들어왔다는 뜻으로 읽었습니다.
같은 게임이 CrazyGames Basic Launch 마지막 주에는 하루 새 플레이어 59161명을 받았습니다. itch.io로 옮긴 뒤에는 사람끼리 만난 경기가 하루 03판입니다.
3대3 온라인 게임이라 사람이 적으면 빈자리를 봇이 채우고, 그러면 다시 올 이유가 줄어듭니다.
r/itchio에 올린 글에는 「조금 렉이 있고, itch.io 페이지 테마를 손보면 좋겠다」는 댓글이 달렸습니다.
10월 31일에 커버를 전투 GIF로 바꾸고, 「한국 서버」라고만 적혀 있던 설명을 경기가 플레이어와 가장 가까운 서버(한국·도쿄·미국 서부·미국 동부·프랑크푸르트)에서 돈다는 문장으로 고쳤습니다.
미결
효과는 아직 모릅니다. 10월 31일에 기준을 정해 두었습니다.
11월 1~7일 하루 평균 itch 첫 방문이 5명 이상이면 페이지 개편이 통한 것으로 보고, 클릭률이 3%를 넘으면 커버가 통한 것으로 보기로 했습니다. 5명은 첫날 13명의 절반 아래로 잡은 추정값입니다. 비교하기로 한 날이 오늘이라 결과는 이 글에 넣지 못했습니다.
지금 판단은 이렇습니다. itch.io는 올리는 비용이 거의 0이라 안 올릴 이유는 없습니다. 하지만 사람을 데려오는 곳은 아니었습니다. 새 게임 목록에서 내려가면 유입은 제가 밖에서 끌어온 만큼만 남습니다.