easthxxn

바이브 코딩으로 게임을 만들다 포기한 이야기

·
#vibe-coding#phaser#game-dev#retrospective
바이브 코딩 게임 개발 실패기

지난 글에서 바이브 코딩으로 블로그를 만든 이야기를 했다.

이번엔 게임에 도전했다.

어릴 때 재밌게했던 Battleheart 스타일의 실시간 전투 RPG.

배틀하트

결론부터 말하면, 코드는 됐는데 게임은 안 됐다.

기술 스택

Phaser 3 + TypeScript + Vite.

의존성은 phaser 하나다. 번들러로 Vite를 쓰고, 타입은 TypeScript로 잡았다.

게임 엔진 선택지에서 Phaser 3가 웹 기반 2D 게임에 가장 성숙한 선택이라 고민 없이 골랐다.

어디까지 만들었나

개발 기간 동안 7단계에 걸쳐 개발했다.

  1. Phase 1 — 프로젝트 세팅, 기본 씬 구조, 캐릭터 이동
  2. Phase 2 — 전투 시스템, 적 AI, 체력바
  3. Phase 3 — 4종 영웅 클래스 (전사/궁수/마법사/힐러), 스킬 시스템
  4. Phase 4 — 웨이브 시스템, 적 종류 확장, 난이도 스케일링
  5. Phase 5 — UI 개선, 스킬 쿨다운 표시, 데미지 텍스트
  6. Phase 6 — 사운드, 파티클 이펙트, 화면 전환
  7. Phase 7 — 밸런싱, 버그 수정, 최종 폴리싱

파일 구조를 보면 규모가 체감된다:

src/
├── scenes/
│   ├── BootScene.ts
│   ├── PreloadScene.ts
│   ├── MainMenuScene.ts
│   ├── GameScene.ts
│   ├── GameOverScene.ts
│   └── VictoryScene.ts
├── entities/
│   ├── Hero.ts
│   ├── Enemy.ts
│   ├── Projectile.ts
│   └── Entity.ts
├── systems/
│   ├── CombatSystem.ts
│   ├── WaveSystem.ts
│   ├── SkillSystem.ts
│   ├── SoundSystem.ts
│   └── ParticleSystem.ts
├── ui/
│   ├── HealthBar.ts
│   ├── SkillButton.ts
│   ├── WaveIndicator.ts
│   ├── DamageText.ts
│   ├── HeroSelectPanel.ts
│   ├── GameHUD.ts
│   └── MiniMap.ts
├── config/
│   ├── HeroConfig.ts
│   ├── EnemyConfig.ts
│   ├── SkillConfig.ts
│   └── GameConstants.ts
└── main.ts

6개 씬, 5개 시스템, 7개 UI 컴포넌트, 4종 영웅, 5종 적, 8개 스킬, 5웨이브.

개발 기간이 길지 않았는데, 이 정도 코드베이스가 나왔다. 바이브 코딩의 생산성은 진짜다.

레포는 여기에 공개해뒀다.

그래서 왜 실패했나

코드는 잘 돌아간다. 전투 시스템도 동작하고, 웨이브도 넘어가고, 스킬도 발동한다.

문제는 코드 바깥에 있었다.

에셋을 바이브 코딩으로 만들 수 없다

게임에는 스프라이트시트가 필요하다. 캐릭터 한 명당 idle, walk, attack, hurt, death 동작이 각각 여러 프레임으로 구성된 이미지 파일이다.

AI 이미지 생성(DALL-E, Midjourney 등)으로 이걸 만들 수 있을까?

안 된다.

스프라이트시트는 pixel-level 정밀도가 필요하다. 각 프레임의 크기가 정확히 같아야 하고, 캐릭터의 피벗 포인트가 일관되어야 하고, 프레임 간 간격이 균일해야 한다. AI 이미지 생성은 이런 제약을 이해하지 못한다.

물론 수준 높은 사이트도 존재한다. pixellab이 그것인데, 이런 것들은 당연히... 유료다.

결국 실제로 사용한 캐릭터는 soldier와 orc 2종뿐이다. 해당 assets들도 해당 사이트에서 무료로 찾은 것들인데, 역시 무료론 종류가 한정적이다.

결국 무료의 asset으로 4명의 영웅을 같은 스프라이트에 tint 색상만 다르게 입혀서 구분했다.

전사도 궁수도 마법사도 힐러도 전부 같은 모습이다.

누가 하겠는가 ;;

일관성이 없다

같은 프롬프트를 넣어도 매번 다른 스타일의 이미지가 나온다.

첫 번째 요청에서 나온 캐릭터와 두 번째 요청에서 나온 캐릭터는 머리 크기도, 선 굵기도, 색감도 전부 다르다. 컨텍스트나 세션이 바뀌면 더 심해진다.

예를들어 클레릭을 만들고 싶어서 만들어달라하면 아래처럼 잘 만들어 준다.

클레릭

근데 이 클레릭이 피격 당하는 스프라이트 시트를 만들어달라고 해보니, 전혀 다른 인물을 만들어준다 ;

클레릭 피격

이런 부분을 사실 파인 튜닝으로 손 볼 수 있겠지만, 그 일관성을 챙기는데 있어서 너무나도 많은 품이 드는건 사실이다.

게임은 모든 에셋이 하나의 아트 스타일로 통일되어야 한다.

캐릭터, 배경, UI 아이콘, 이펙트까지 전부. 이 일관성을 AI 이미지 생성으로 확보하는 건 현재로선 불가능하다.

캐릭터가 정상 동작하지 않는다

게임 캐릭터는 가만히 서 있는 한 장짜리 그림이 아니다.

idle 상태에서는 숨 쉬듯 미세하게 움직여야 하고, walk 시에는 다리가 교차해야 하고, attack에서는 무기를 휘둘러야 한다. 이걸 각각 4~8프레임의 스프라이트시트로 만들어야 한다.

각 프레임은 정확히 같은 크기(예: 64x64)의 셀 안에 캐릭터가 같은 위치에 있어야 한다. 발 위치가 1픽셀만 달라져도 캐릭터가 덜덜 떤다.

AI에게 "64x64 4프레임 idle 스프라이트시트"를 요청하면? 프레임 크기가 들쭉날쭉하고, 캐릭터 위치가 제각각이고, 심지어 캐릭터의 생김새도 프레임마다 미묘하게 다른 이미지가 나온다.

이걸 코드로 보정하는 데는 한계가 있다.

코드와 에셋의 경계

블로그는 성공했고, 게임은 실패했다.

둘 다 바이브 코딩으로 만들었다. 차이가 뭘까?

블로그는 코드 + 텍스트다.

둘 다 AI가 잘하는 영역이다.

코드를 생성하고, 글을 쓰고, 설정 파일을 만들고 전부 텍스트 기반이다.

게임은 코드 + 에셋이다.

코드는 AI가 잘 짜줬다. 그런데 에셋은 안 됐다. 스프라이트, 애니메이션, 사운드 이런 바이너리 리소스는 AI가 아직 정밀하게 생성하지 못한다.

바이브 코딩의 한계는 코드 생성 능력에 있는 게 아니다.

코드 바깥 영역인 에셋, 디자인, 물리적 정밀도가 필요한 리소스 에 있다.

그래도 배운 것

실패했지만 얻은 것도 있다.

  • Phaser 3의 씬 시스템, 물리 엔진, 스프라이트 관리 아키텍처를 빠르게 파악했다. 직접 문서를 읽고 처음부터 짰으면 소모한 개발 기간은 어림없었을 거다.

  • Phase 단위의 점진적 개발이 바이브 코딩에서도 유효하다는 걸 확인했다. 한 번에 다 만들어달라고 하면 망하고, 단계별로 쌓아가면 된다.

  • 게임 개발에서 에셋 파이프라인이 얼마나 중요한지 몸으로 체감했다. 코드가 아무리 잘 돌아가도 에셋이 없으면 게임이 아니다.

  • 코드베이스는 살아있다. 에셋만 제대로 갖춰지면 언제든 부활할 수 있다.

정리

코드는 만들 수 있다. 게임은 아직이다.

AI 이미지 생성이 게임 스프라이트 수준의 정밀도와 일관성을 확보하는 날이 오면, 그때 다시 이 레포를 꺼낼 생각이다.

댓글

0/100

불러오는 중...