Codex, SpriteShip, Godot을 활용하여 브라우저 기반 전략 게임 제작하기
요약
본 기사는 Codex와 SpriteShip, Godot을 활용하여 브라우저 기반 2D 전략 게임 'Emberhold: The Last Hearth'를 제작한 과정을 소개합니다. 초기에는 장르와 비전만 제시했으나, Codex에게 PRD 작성을 요청하며 명확한 방향성을 확보했습니다. 이후 Codex가 코딩과 도구 호출을 담당하고 Godot이 시스템 통합을 맡아 완성도 높은 게임 빌드를 구현할 수 있었습니다.
핵심 포인트
- Codex를 활용하여 제품 요구사항 문서(PRD) 작성으로 기획 단계의 구체화.
- Codex는 코드 수정, 명령어 실행, SpriteShip API 호출 등 개발 전반에 걸쳐 사용됨.
- Godot 엔진이 다양한 시스템과 에셋을 통합하는 역할을 수행함.
- SpriteShip은 일러스트 에셋 및 내보내기 데이터를 공급하여 시각적 기반을 제공함.
우리는 나무, 돌, 금, 식량을 모으고 정착지를 건설하며, 병사를 모집하고, 구조물을 업그레이드하며, 궁극적으로 군대를 이끌고 전투에 임할 수 있는 2D 전략 게임을 원했습니다.
영감의 원천은 클래식 RTS(실시간 전략) 게임의 정착지 구축 루프와 영웅에게 직접적인 통제권을 부여하는 것이었습니다. 세계관과 캐릭터는 오리지널로 제작되었습니다. 이 게임은 브라우저에서 실행되어야 했고, 모든 일러스트 에셋은 SpriteShip에서 가져와야 했습니다.
그 결과물은 스토리 캠페인, 평화로운 샌드박스, 그리고 공개 웹 빌드를 갖춘 Godot 게임 Emberhold: The Last Hearth입니다.
Codex가 코딩과 툴 기반 구현을 담당했습니다. SpriteShip은 일러스트 에셋과 그 내보내기 데이터를 공급했습니다. Godot이 시스템들을 하나로 통합했습니다.
실제로 이 과정이 어떻게 진행되었는지, 아직 개선해야 할 부분까지 포함하여 소개합니다.
에셋 목록이 아닌 게임 비전으로 시작하기
우리의 초기 요청은 장르와 시각적 목표를 설명했을 뿐입니다. 모든 건물, 캐릭터, 퀘스트 또는 밸런스 값까지 구체적으로 명시하지는 않았습니다.
저희는 Codex에게 이를 구현 전에 제품 요구사항 문서(product requirements document)로 작성해 달라고 요청했습니다. 간결하게 다듬어진 개요는 다음과 같습니다:
Build an original 2D settlement strategy game in Godot for the web.
The player gathers resources, constructs and upgrades buildings,
...
이러한 기획 단계가 아트와 메커니즘에 공통의 방향성을 부여했습니다.
캐प्टन 엘라라(Captain Elara)는 생존자들과 마지막 살아있는 화로에서 나온 석탄을 가지고 폐허가 된 계곡에 도착합니다. 정착지를 재건하면서 군대를 모집하고, 세 개의 비콘을 다시 밝히며, 재정(Ash Regent)인 베이르(Veyr)와 대면하게 됩니다.
캠페인은 다섯 개의 장으로 구성되어 있습니다. 진행 과정은 자원 수집 및 건설에서 병력 모집, 탐험, 비콘 해방을 거쳐 최종 전투로 이어집니다.
PRD는 리포지토리와 함께 구현 내용도 제공됩니다.
Codex에게 도구와 명확한 작업 흐름을 부여하기
이 빌드에서 Codex는 리포지토리를 검사하고 수정하며, 명령어를 실행하고, SpriteShip의 API/MCP 도구를 호출하며, 내보내기(export) 파일을 다운로드하고, 결과로 생성된 게임을 검토할 수 있습니다.
또한 저희는 SpriteShip의 현재 에이전트 지침도 제공했습니다. 이 지침에는 생성, 내보내기 계약(export contracts), 동기화, 충돌 메타데이터(collision metadata), 품질 검토, 그리고 비용 지출 통제가 포함되었습니다.
여기에는 두 가지 유용한 계층이 있습니다. 도구는 동작(operation)을 노출하는 반면, 스킬은 그 주변의 작업 흐름(workflow)을 설명합니다. 이는 OpenAI 공식 문서의 스킬에서도 설명된 구분입니다.
저희가 만든 프로덕션 스크립트에서는 루프가 다음과 같이 되었습니다:
정의된 에셋과 그 역할
→ 생성 견적(generation quote) 획득
→ 승인된 예산과 비교 검토
...
이 스크립트들은 요청 상태를 유지하고 유료 작업에 대해 Idempotency Key를 사용했습니다. 또한 여러 프로덕션 작업이 공유 상태를 업데이트할 때 파일 잠금(file locking)도 필요했습니다.
핵심은 에이전트의 작업을 검사 가능하게 만드는 것이었습니다. 어떤 에셋이 요청되었는지, 어떤 작업이 완료되었는지, 무엇이 가져와졌고, 실제로 얼마만큼 크레딧이 소모되었는지를 파악할 수 있어야 했습니다.
일관성 있는 아트 팩 구축하기
저희는 비스듬한 탑다운(angled top-down)의 페인팅 판타지 스타일을 선택했습니다. 이끼 낀 녹색, 상아색 돌, 구리 지붕, 따뜻한 정착지 조명, 그리고 황화된 듯한 적색의 적군 악센트가 특징입니다.
SpriteShip 프로젝트는 일러스트레이션 된 메뉴 장면, 지형(terrain), 자연 소품(nature props), 자원 매장지, 구조물, 요새화된 건물 변종, 랜드마크, 캐릭터, 아이콘, 그리고 장식적인 UI까지 제공했습니다.
캐릭터 라인업에는 엘라라(Elara), 정착민, 경비병, 레인저, 기사, 약탈자, 그리고 중장갑 거구들이 포함됩니다. 최종 보스는 다른 규모의 거구 아트워크를 사용합니다.
Godot 코드는 조명(lighting), 파티클(particles), 텍스트, 인터페이스 레이아웃, 그리고 게임플레이를 제공합니다. 음악과 사운드 효과는 생성된 오디오 파일로 가져오는 대신 런타임에 합성됩니다. 글꼴은 SpriteShip을 통해 라이선스 고지와 함께 도착했습니다.
나중에 계정의 워터마크 설정을 변경하고, 전체 캐릭터, 지도, UI 번들 등 선택한 모든 에셋을 다시 다운로드했습니다. 저희는 워터마크를 로컬에서 덧칠하지 않았습니다.
이 재설정 과정은 또한 유용한 제작 규칙을 강화시켜 주었습니다. 만료되는 다운로드 URL 대신 로컬 에셋 바이트와 안정적인 식별자를 저장해야 한다는 것입니다.
네이티브 내보내기는 통합을 구체화한다
SpriteShip의 Godot 캐릭터 번들에는 네이티브 .tres 애니메이션 리소스, 스프라이트시트(spritesheets), 매니페스트(manifests), 그리고 통합 지침이 포함되어 있습니다. 이 자체 설명형(self-describing) 내보내기는 Codex 통합 가이드에 설명되어 있습니다.
Codex는 스프라이트시트 레이아웃을 임의로 만들지 않고, 전달된 애니메이션 이름, 프레임 순서, 재생 데이터를 읽었습니다.
저희 프로젝트는 에셋 잠금 파일(asset lock file)과 로컬 런타임 매니페스트를 유지합니다. 잠금 파일은 가져온 엔티티와 버전을 기록하며, 런타임 매니페스트는 게임 아키타입을 해당 로컬 아트 및 애니메이션 리소스로 연결해 줍니다.
최종 동기화 확인 과정에서는 18개 항목이 검토되었으며, 모두 다운로드된 버전과 일치했습니다.
놀랍도록 까다로운 부분: 발
캐릭터는 개별 프레임에서는 멋져 보일 수 있지만, 애니메이션을 전환할 때 잘못 보일 수도 있습니다.
각기 다른 클립은 서로 다른 양의 투명 패딩(transparent padding)을 가지고 있었습니다. 캘리브레이션 없이 서 있거나 걷는 동작이 캐릭터의 크기나 지면 접촉 상태를 변화하는 것처럼 보일 수 있었습니다.
저희는 가시적인 높이와 발 앵커(foot anchor)를 캘리브레이션하기 위해 각 클립에 대해 고정된 중립-첫 프레임 참조를 사용했습니다. 이는 매 프레임마다 변경되는 크롭(crop)이 아니라, 클립별 렌더 조정입니다.
움직임 발자국은 전신 부상 박스 메타데이터(full-body hurtbox metadata)와는 별도로 SpriteShip에 작성된 후, 새로운 네이티브 내보내기로 다운로드되었습니다. 전체의 자르지 않은 논리적 프레임 좌표가 유지되었습니다.
브라우저 배포를 위해 캐릭터 시트와 이에 상응하는 모든 아틀라스 사각형에 50% 스케일링을 적용했습니다. 이미지만 스케일링할 경우 아틀라스가 잘못된 픽셀을 가리키게 됩니다. 전체 해상도의 네이티브 소스는 로컬에 보관되었습니다.
이러한 통합 세부 사항은 작업의 상당 부분을 차지했습니다. 이미지를 생성하는 것은 단지 한 단계였을 뿐입니다.
Godot에서 게임 시스템 구축하기
배포된 게임은 Godot 4.7.2와 GDScript를 사용합니다. Node.js는 프로덕션 및 빌드 도구링을 처리하며, 게임플레이 엔진이 아닙니다.
주요 시스템에는 다음이 포함됩니다:
- 영웅 이동, 상황별 채집, 근접 공격, 치유, 대시.
- 매장지로 이동하여 자원을 자율적으로 수집하는 정착민들.
- 11가지 구조물 유형, 건설 진행도, 업그레이드, 수리, 인구 제한.
- 따르기(follow), 방어(defend), 집결(rally), 공격(assault) 명령을 가진 경비병, 레인저, 기사 모집.
- 연구, 원거리 투사체, 방어 타워, 적 진영, 에스컬레이팅 레이드.
- 세 개의 비콘, 보호된 성채, 최종 보스, 캠페인 진행도, 저장/불러오기.
작성된 계곡은 4096 × 3584 픽셀입니다. Godot은 AStarGrid2D를 사용하여 장애물 인식 내비게이션(obstacle-aware navigation), 탐험, 안개 효과(fog), 상호 작용, 그리고 지도 데이터의 게임플레이 의미를 처리합니다.
소스는 식별 가능한 책임으로 분할됩니다: game.gd가 시뮬레이션과 저장을 소유하고, world.gd가 렌더링 및 애니메이션 선택을 처리하며, hud.gd가 인터페이스를 관리하고, data.gd가 유닛, 건물, 스토리 정의를 담고 있습니다.
Godot 프로젝트 소스에서 이러한 분할을 검사할 수 있습니다.
스크린샷이 아닌 액션 테스트하기
우리는 두 가지 다른 종류의 유효성 검사를 사용했습니다.
첫째, 네이티브 Godot 승인 시나리오를 통해 채집, 정착민 이동, 내비게이션 경로, 배치, 업그레이드, 완료된 모집 큐, 연구, 수리, 투사체, 저장, 비콘 활성화, 최종 승리를 테스트했습니다.
이러한 테스트는 적절한 경우 준비된 자원과 제거된 비콘 가드를 사용합니다. 이는 완전한 수동 캠페인 플레이나 측정 가능한 캠페인 기간의 증거가 아닌 시스템 테스트입니다.
둘째, 격리된 Chromium 브라우저를 사용하여 실제 마우스 및 키보드 입력을 이용했습니다. 이 브라우저는 Elara를 이동시키고, 구조물을 배치하며, 정착민들이 자원을 수집하기를 기다리고, 병력을 모집하고, 막사를 업그레이드하며, 저장하고, 다시 불러와서 정착지를 계속 운영했습니다.
이 브라우저는 또한 군대를 첫 번째 비콘으로 이끌어 다섯 명의 적을 물리치고, 치유를 사용하며, 비콘에 불을 지폈습니다. 우리는 이러한 점검들을 공개 GitHub Pages 빌드에서 반복했습니다.
공개 사이트 실행은 일곱 가지 캐릭터 아키타입이 모두 등록되었고 브라우저 콘솔이나 페이지 오류가 0건인 상태로 통과했습니다. 스크린샷에는 여러 데스크톱 뷰포트 크기가 포함되었습니다.
브라우저 테스트는 읽기 전용(read-only) 상태 스냅샷을 검사하며, 자원을 부여하거나 목표를 완료하기 위해 디버그 API를 사용하지 않습니다.
GitHub Pages를 통해 웹 빌드 배포하기
이 저장소에는 이미 Last Light라는 다른 게임이 호스팅되어 있었습니다. 우리는 Emberhold가 그 옆에 함께 존재할 수 있도록 그 Pages 빌드를 확장했습니다:
https://spriteship.github.io/sample_games/emberhold/
우리는 Godot의 Compatibility 렌더러와 단일 스레드 웹 내보내기(single-threaded Web export)를 사용했습니다. 단일 스레드 내보내기는 스레드 기반 빌드가 요구하는 교차 출처 격리 헤더(cross-origin isolation headers)를 피할 수 있어, 정적 호스팅에 실용적인 적합성을 제공합니다. Godot의 웹 내보내기 문서를 참조하세요.
Linux CI 빌드는 고정된 Godot 버전을 설치하고 일치하는 Web 템플릿을 설치하며, 이들의 SHA-256 체크섬을 검증하고, 테스트를 실행하며, 게임을 내보내고, 두 게임 모두를 Pages 아티팩트로 패키징합니다.
생성된 웹 빌드는 Git 외부에 보관됩니다. 저장소에는 소스 및 일러스트레이션 자산이 포함되어 있으며, CI가 배포 가능한 파일을 재빌드합니다. 이 게임을 플레이하거나 배포하는 데 SpriteShip API 키는 필요하지 않습니다.
로컬에서 재빌드하려면 Godot 4.7.2와 일치하는 Web 내보내기(export) 템플릿, 그리고 Node.js 22 이상을 설치한 후 다음 명령어를 실행하세요:
git clone https://github.com/spriteship/sample_games.git
cd sample_games
npm ci
...
로컬 게임은 http://localhost:4174에서 실행됩니다. 공개 사이트의 저장 데이터는 로컬호스트(localhost) 저장 데이터와 별개입니다.
비용 및 개선 필요 사항
감사된 SpriteShip 제작 사용량은 승인된 30,000 크레딧 상한선 대비 14,360 크레딧 순액이었습니다. 여기에는 생성 실패 및 원본 제공업체 환불 내역이 장부에 기록되어 있습니다. 이는 개발의 총비용이나 달러 가격 추정치가 아닌, 예술 제작에 대한 수치입니다.
원래 기획안에서는 AAA 스타일의 2D 비주얼을 요청했습니다. 이것은 야망이었지, 결과물의 인증은 아니었습니다.
이것은 하나의 지도에서 플레이 가능한 싱글 플레이어 캠페인 및 샌드박스입니다. 여전히 애니메이션 다듬기, 더 광범위한 하드웨어 테스트, 그리고 긴 밸런스 플레이테스트가 필요합니다. 특히 다음 사항들이 있습니다:
- 각 리소스마다 별도의 애니메이션을 갖는 대신 수집 재사용(Gathering reuses) 시 타격/도끼질 클립을 사용합니다.
- 영웅 사망 시 현재 체력을 회복하고 Elara를 즉시 집으로 돌려보내는데, 여기에는 더 명확한 죽음과 회복 순서가 필요합니다.
- 세 가지 게임 플레이 빌딩 레벨이 두 개의 전달된 아트워크 티어를 공유하며, 레벨 III는 왕관 마커와 함께 요새화된 아트를 재사용합니다.
- 일부 선택적 공격 방향은 제공업체에서 실패했기 때문에, 전달된 애니메이션이 대체재로 사용됩니다. 품질 검토 플래그는 계속 문서화되고 있습니다.
멀티플레이어, 음성 연기(voice acting), 모바일 터치 제어 또는 다중 지도 캠페인은 포함하지 않습니다. QA 기록에서 검증 및 제한 사항을 설명합니다.
핵심 요약
Codex 덕분에 계획, 구현, 에셋 오케스트레이션(asset orchestration), 디버깅, 테스트, 배포를 하나의 지속적인 워크플로우로 처리할 수 있었습니다. SpriteShip은 이 워크플로우에 에이전트가 검사하고 통합할 수 있는 네이티브 내보내기 데이터가 포함된 일러스트레이션된 에셋 소스를 제공했습니다.
가장 유용했던 조합은 명확한 게임 기획서(game brief), 일관된 아트 디렉션(art direction), 구체적인 에셋 계약(asset contracts), 제한된 예산 집행(bounded spending), 그리고 실제 플레이어 행동을 테스트하는 테스트였습니다.
아직 다듬어야 할 부분이 있습니다. 하지만 결과물은 여러분이 플레이할 수 있는 공개 게임이며, 검사할 수 있는 소스 코드와 따라 할 수 있는 제작 프로세스를 갖추고 있습니다.
Emberhold를 시도해 보거나, 리포지토리를 둘러보거나, SpriteShip과 게임 아트 프로젝트를 탐색해 보세요.
직접 플레이해보시고, 정착지 진행 속도(settlement pacing), 군대 제어(army controls), 그리고 다음에 개선하는 것이 가장 중요하다고 느끼는 부분에 대한 피드백을 주시면 감사하겠습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기