MAKING · 제작기
최후의 파도 제작기: 검투사 게임을 네 번 갈아엎은 기록
2D 검투사 대전에서 매치-3 퍼즐, 3D 대전을 거쳐 3D 웨이브 생존 로그라이트가 되기까지. 한 저장소에서 장르가 네 번 바뀐 과정과 창 던지기 하나를 고치는 데 9일이 걸린 이야기를 커밋 기록으로 돌아봤습니다.
최후의 파도는 콜로세움에서 몰려오는 적을 버티는 3D 생존 로그라이트입니다. 그런데 이 게임의 저장소 이름은 아직도 gladiator-fight입니다. 처음에는 검투사끼리 일대일로 싸우는 2D 대전 게임이었기 때문입니다. 2026년 5월 16일 첫 커밋부터 8월 말까지, 같은 저장소 안에서 게임의 장르가 네 번 바뀌었습니다. 매번 이전 코드를 거의 다 들어내고 다시 쓴 전면 재작성이었습니다. 이 글은 그 기록을 따라간 제작기입니다. 개발은 처음에는 Claude Code, 8월부터는 Cursor의 코딩 에이전트와 함께 했습니다.
1막: 2D 검투사 대전 (5월 16일)
첫 버전은 Phaser 3와 TypeScript로 만든 옆에서 보는 2D 대전 게임이었습니다. 5라운드 3선승, 라운드당 60초, AI 난이도 세 단계와 한 기기 2인 대전을 지원했습니다. 검투사는 세 종류였습니다.
- 무르밀로 — 체력 120, 공격 12, 방어 5, 속도 5. 가드로 피해를 절반으로 줄이고, 방패 밀치기로 상대를 기절시킵니다.
- 레티아리우스 — 체력 90, 공격 10, 방어 2, 속도 7. 삼지창을 쓰고, 그물을 던져 2초 동안 묶습니다.
- 디마카이루스 — 체력 100, 공격 15, 방어 1, 속도 6. 쌍검으로 3연타를 넣습니다.
그림과 소리는 파일 없이 코드로 만들었고, 게임 규칙은 엔진과 분리해 테스트 19개로 지켰습니다. 그날 하루 동안 모바일 가로 화면의 레터박스 문제, 세로 화면에서 회전 안내가 뜨지 않는 문제를 고치며 터치 조작을 붙였고, 화면 방향도 가로에서 세로로 바꿨습니다.
2막: 매치-3 퍼즐 (5월 16일 ~ 7월)
그리고 같은 날, 커밋 제목이 이렇게 바뀝니다. "pivot to match-3 (Ancient Relics), clean up gladiator code." 검투사 코드를 정리하고 같은 색 보석을 맞추는 매치-3 퍼즐 「고대 유물」을 만들기 시작했습니다. 이 버전은 두 달 가까이 이어졌고, 날짜 시드로 모두가 같은 판을 받는 데일리, 둘이 하는 듀오 모드, 도전장 링크, 도굴꾼과 여기사 캐릭터, "도굴 서바이벌" 모드까지 붙었습니다.
7월 18일에는 three.js로 이 퍼즐을 3D로 옮기는 시제품도 만들었습니다. 이 브랜치에는 저장소에서 보기 드문 피드백 기록이 남아 있습니다. "너무 누렇고 아이템 구분이 안 된다 → 컨셉 교체", 그리고 "너무 어둡다는 피드백 반영." 이 3D 퍼즐 시제품은 결국 본선에 합쳐지지 않았습니다.
3막: 3D 콜로세움 대전 (8월 15일)
8월 15일, 다시 전면 재작성이 이뤄집니다. "Three.js 3D 콜로세움 격투로 전면 재작성." 어깨 너머 시점에 상대를 고정하는 카메라, 약공격·강공격, 무적 시간이 있는 회피, 가드와 스태미나를 갖춘 3인칭 일대일 대전이었습니다. 여기사(체력 120, 약공격 12, 강공격 28)가 도굴꾼과 싸웠습니다. 이 버전의 첫 버그 수정은 "공격 판정이 첫 프레임 빗나감에 묶이던 문제"였습니다.
그런데 이 대전은 본선에서 하루도 채 살아남지 못했습니다.
4막: 웨이브 생존 로그라이트 (8월 16일 ~)
다음 날 커밋입니다. "3D 콜로세움 생존 로그라이트로 전면 재작성 — 1v1 여기사/도굴꾼 격투 루프를 웨이브 생존 런으로 교체한다. 자동 공격, XP 흡인, 파도 사이 3지선다 강화, 절차 생성 오디오." 프로젝트 문서에는 지향점이 "Vampire Survivors / Brotato 계열의 3D 생존 런"이라고 적혀 있습니다.
솔직히 말하면, 장르를 바꾼 이유는 커밋 기록에 남아 있지 않습니다. 기록은 무엇을 바꿨는지는 꼼꼼히 적고 있지만, 왜 바꿨는지는 적지 않았습니다. 다만 네 번의 재작성 모두 이전 버전의 코드를 아까워하지 않았다는 점은 분명히 보입니다.
3D로 오자 생긴 문제들
웨이브 생존 버전이 자리를 잡은 뒤 2주는 대부분 3D 특유의 문제와 씨름한 기록입니다.
- 전원 T자 자세 — 같은 캐릭터 모델을 여러 개 복제했더니 모두 팔을 벌린 기본 자세로 굳었습니다. 일반 복제는 뼈대(스켈레톤)를 원본에 묶어 두기 때문이었고, 뼈대까지 복제하는 방식으로 바꿔 해결했습니다.
- 허공을 치는 자동 공격 — 자동 공격이 적이 아니라 걷는 방향의 허공을 쳤습니다. 모델에 씌운 180도 회전 보정 때문에 창이 적 반대편을 향하고 있었습니다.
- 모션만 나가고 타격은 없음 — 공격을 시작할지 판단할 때는 "무기 사거리 + 적의 몸 반지름"을, 실제로 맞았는지 판단할 때는 사거리만 보고 있었습니다. 휘두르는 모션은 나가는데 피해가 들어가지 않았습니다.
- 한 프레임만 움직이는 스틱 — 모바일 가상 스틱이 한 프레임만 움직이고 멈췄습니다. 터치 취소 이벤트를 손을 뗀 것으로 처리한 탓이었습니다.
- 모래가 단색 — 원형 바닥의 텍스처 좌표가 잘못 읽혀 모래 무늬가 사라지고 단색으로 보였습니다.
창 던지기 하나에 9일
가장 오래 걸린 것은 삼지창 던지기 연출입니다. 8월 22일부터 30일까지 다섯 번 넘게 손을 댔습니다. 기록에 남은 문제들만 봐도 이렇습니다.
- 원래 쓰던 던지기 동작은 짧은 투척물용이라, 긴 창이 몸을 관통했습니다.
- 창이 날아가는 방향을 보게 하는 함수를 쓰자 창이 바닥에 누운 것처럼 보였습니다.
- 회전 순서를 바꿨더니 창이 진행 방향과 직각으로 누웠습니다.
- 던지는 도중 몸을 180도 돌리거나 목표가 바뀌면 창이 등 뒤로 날아갔습니다.
마법사 모델도 비슷했습니다. 직접 만든 마법사 모델을 넣었다가 기존 무료 에셋으로 되돌리고, 다음 날 다른 무료 에셋으로 다시 바꿨습니다. 활은 화면과 평행한 면에 놓여 있어서 비스듬한 시점에서는 가는 막대기처럼만 보였습니다. 마지막으로 픽셀 비율 상한, 창과 적 객체 재사용, 관중·횃불·빛 번짐 효과 비용 절감으로 크롬과 휴대폰에서 끊기는 문제를 줄였습니다.
지금의 최후의 파도
- 한 판 — 5~10분. 웨이브를 버티고, 경험치와 골드를 빨아들이고, 강화 카드 3장 중 하나를 고르고, 다음 웨이브로. 8번째 웨이브의 보스 「뿔왕」을 쓰러뜨리면 승리입니다.
- 웨이브 8개 — 입성의 함성, 창의 숲, 광기의 모래, 철벽 전진, 빗발치는 볼트, 맹수의 우리, 군중의 갈증, 뿔왕의 입성.
- 적 11종 — 체력 11의 모래잡이부터 체력 62의 철벽, 엘리트 백부장(132), 보스 뿔왕(460)까지. 적 체력은 웨이브가 하나 지날 때마다 기본값의 20%씩 늘어납니다.
- 강화 카드 27장 — 무기 카드 9장(삼지창, 검, 궤도, 오라, 포탑, 투창, 활 등)과 능력치 카드 18장.
- 영웅 3명 — 검을 든 기사, 지팡이를 든 마법사, 활을 든 레인저.
기술적으로는 three.js 위에 TypeScript와 Vite를 썼고, 게임 규칙은 그래픽 코드와 완전히 분리해 테스트 약 140개로 지킵니다. 소리는 여전히 파일 없이 코드로 합성하고, 3D 모델은 KayKit, Quaternius, Kenney의 무료(CC0) 에셋을 씁니다.
돌아보며
석 달 반의 기록에서 가장 눈에 띄는 것은 재작성을 두려워하지 않았다는 점입니다. 2D 대전은 하루, 3D 대전은 하루도 안 돼 버려졌습니다. 그 대신 매번 남은 것이 있었습니다. 코드로 그림과 소리를 만드는 방식, 게임 규칙을 엔진과 분리해 테스트하는 습관, 그리고 콜로세움이라는 무대입니다. 저장소 이름이 여전히 gladiator-fight인 것도 그 흔적입니다.