
ClaudeCode와 Codex에 코딩을 전부 맡겨 상용 수준의 Unity 게임 개발하기【후편】
요약
ClaudeCode와 Codex를 활용하여 Unity 게임을 상용 수준으로 개발하는 워크플로우를 소개합니다. 단순 구현을 넘어 데이터 구조 설계와 문서화를 통해 기술적 부채를 방지하고 확장 가능한 코드를 유지하는 방법을 다룹니다.
핵심 포인트
- 데이터 구조 선 설계를 통한 기술적 부채 최소화
- 코드 품질 가이드라인 구축을 통한 가드레일 마련
- 작업 사이사이의 철저한 문서화(docs화)가 핵심
- AI 구현 시 발생하는 스파게티 코드 방지 전략
안녕하세요, Lise라고 합니다.
현재의 게임 개발 현장에서는 아마 어떤 회사든 어떤 프로젝트든, ClaudeCode나 Codex를 이용한 개발 AI 보조를 수행하고 있거나, 게임 잼(Game Jam) 등의 이벤트에서 "시험 삼아 AI에게 소규모 게임 프로그래밍을 시켜보자"와 같은 움직임이 있을 것이라고 생각합니다.
하지만 이미 AI를 활용하고 있는 엔지니어라도, 마음속 한구석에 걱정으로 남아 있는 것이 바로,
"게임 개발이나 설계를 통째로 AI에게 던질 수는 없는 걸까?" 라는 테마라고 생각합니다.
이 게시물은 그러한 "처음부터 게임 개발을 AI로 시도해 보았다"라는 챌린지의 비망록입니다.
전편의 총평·결론으로는
"ClaudeCode/Codex에 코딩을 전부 맡겨서 Unity 게임 개발을 할 수 있다"
였습니다.
단, 이것은 아무 생각 없이 AI에게 다 던져버려도 좋다는 이야기가 아니라,
- "데이터 구조를 먼저 설계"함으로써 기술적 부채(Technical Debt)가 발생할 여지를 줄이고,
- "코드 품질 가이드라인을 리뷰로부터 역산하여 만듦"으로써 기술적 부채가 발생하기 어렵게 만드는 가드레일을 효율적으로 구축한다
라는 전제가 있습니다.
이번에는 그 후속으로, 실제로 게임 개발을 계속하며 얻은 지견을 다시 정리해 보고자 합니다.
전편에서 말하지 않았습니다. 여기서는 다음과 같은 내용을 가리킵니다.
관점으로는
- AI에 의한 구현에서 흔히 발생하는 '돌아가기만 하는 스파게티 코드(Spaghetti Code)'를 만들지 않는 것
- 장래의 확장성을 고려한 기능 설계가 되어 있는 것
- AI를 더 이상 사용할 수 없게 되더라도, 인간 엔지니어가 인계받아 개수할 수 있는 코드 품질을 유지하는 것
입니다.
"아니, 내 손으로는 잘 되고 있는데"라고 생각하는 분도 계시겠지만,
제로 베이스에서 설계부터 AI에게 던지면 1파일에 5000행씩이나 채워지기 때문에,
도저히 프로젝트 시작 단계에서 개발 가능한 베이스로 이용할 수 없습니다.
이번에는 그것을 어떻게든 해결할 수 없을까 하는 이야기가 됩니다.
사실 전편과 비교해서 방침 전환이나 수법의 큰 변화는 없습니다.
이는 매우 좋은 소식으로, 일정한 퍼포먼스를 지속적으로 아웃풋(Output)할 수 있다는 뜻입니다.
(뭐, 실제로는 그 결과물을 이용해 게임 양산을 할 수 있어야 비로소 골(Goal)이겠지만요)
후편에서는 그 워크플로우(Workflow)와 사고방식, AI가 이용하는 규칙을 기재한 문서에 대해 해설하겠습니다.
빨리 보고 싶으신 분은 이쪽으로 오세요.
브랜치는 develop2입니다. (실수로 develop을 전편의 참조 브랜치로 설정해 버려서)
본론은 아니므로, 어떤 게임을 만들었는지에 대해서만 간단히 이미지와 영상, 그리고 WebGL 빌드만 올려두겠습니다.
AI로 게임을 만들어 본 경험이 있는 분도 계시겠지만,
적당히 만들게 하면 아마 이 정도의 복잡도에 도달하기 전에 한계에 부딪힐 것이라고 생각합니다.
↑WebGL 빌드로 실제로 플레이할 수 있습니다
카메라 이동: WASD
플로어 전환: Q/E
마우스로 선택
전편과 조금 겹치지만, 중간부터 보여드리면 이해하기 어려울 것 같아 처음부터 설명하겠습니다.
어차피 읽고 계신 분들은 다양한 AI 기사를 읽고 계실 테니, 중요하다고 생각되는 부분에 집중해서 써 내려가겠습니다.
한 가지만 미리 써두자면, 이 워크플로우 전체의 핵심은 작업 사이사이의 **docs화(문서화)**입니다.
스텝 2에서 자세히 해설하겠습니다.
"결정한다"는 것은 즉 "결정한다"는 것입니다.
"뭐, 대충 정해져 있는데"라고 생각하실 수도 있겠지만,
막연한 게임상을 가진 채로 프로그램을 쓰게 시키기 시작하면 반드시 길을 잃게 됩니다.
어떤 장르인지, 어떤 화면인지, 어떤 UI가 있는지, 어떤 조작이 가능한지, 어떤 게임 사이클(Game Cycle)인지, 어떤 체험을 하는지를 여기서 결정하십시오.
눈을 감고 게임을 머릿속으로 재현할 수 있을 때까지 다듬으십시오.
Claude와 벽치기(대화)를 해도 좋습니다.
여기서 결정하지 않으면 사양의 모호함이 이후의 데이터 설계에 나타나 바디 블로우처럼 아프게 다가옵니다.
데이터 설계라고 해도 일반적으로는 마스터 데이터(Master Data)와 도메인 객체(Domain Object) 두 종류가 있는데,
마스터 데이터 → 도메인 객체 순서로 설계하면 마음이 편합니다.
"마스터 데이터"란 게임 구동 중에 불변하는 데이터를 말합니다.
포켓몬으로 치면 이름이나 종족값, 출현하는 도로 등의 정보입니다.
"도메인 객체"란 게임 실행 중에 다루는 데이터 객체 중, 비즈니스 로직(Business Logic)에 이용되는 것입니다.
포켓몬으로 치면, "존재하고 상태를 가지며 변화하는 모든 것"입니다.
별로 적절한 비유는 아니지만, 뭐 게임 실행 중에 상태가 변화하는 정보를 가리킵니다.
우선 마스터 데이터(Master Data) 테이블 목록부터 만들어 봅시다.
이번 「모험가 길드 경영 게임」에서는
-
액터 (Actor)
-
액터 테이블 (Actor Table)
-
모험가 스테이터스 테이블 (Adventurer Status Table)
-
모험가 룩 테이블 (Adventurer Look Table)
-
몬스터 스테이터스 테이블 (Monster Status Table)
-
몬스터 룩 테이블 (Monster Look Table)
-
AI 테이블 (AI Table)
-
레벨 테이블 (Level Table)
-
...
-
아이템 (Item)
-
아이템 테이블 (Item Table)
-
무기 테이블 (Weapon Table)
-
장비 테이블 (Equipment Table)
-
...
-
던전 (Dungeon)
-
플로어 테이블 (Floor Table)
-
몬스터 스폰 테이블 (Monster Spawn Table)
-
던전 생성 설정 테이블 (Dungeon Generation Setting Table)
-
던전 룩 테이블 (Dungeon Look Table)
-
...
라는 느낌일까요.
코드를 작성하게 하기 전에, 테이블 이름과 열(Column) 이름만 있는 상태로 제3정규형 (3NF)까지 완료해 두는 것이 좋습니다.
ClaudeCode나 Codex에게 적절히 처리하도록 시켜봅시다.
참고 커밋 (노이즈가 다소 많습니다)
도메인 (Domain) 객체는 처음부터 완성할 수 없습니다. 게임의 기능은 나중에 계속해서 추가되기 때문입니다.
이 타이밍에 의식해야 할 점은,
- 도메인 객체의 본질이 「상태를 가지는 것」이라는 점
- 게임의 최소한의 루프에 필요한 상태만을 정의하는 것
입니다.
처음에는 액터라면 마스터 ID나 좌표 정보만 있어도 충분할 것입니다.
최종적으로는 이런 형태가 됩니다.
그 캐릭터가 어떤 이름이고 어떤 종족인지에 대한 정보는 마스터 데이터의 키(Key)를 가짐으로써 표현합니다.
여기서 문서화 (docs化) 이야기를 끼워 넣겠습니다. 이것은 워크플로(Workflow)의 특정 단계가 아니라, 단계 1~6의 개발 전체를 통해 병행하여 수행해야 하는 일입니다.
AI를 이용한 게임 개발 워크플로에서 가장 중요한 것이 바로 문서화 (docs化) 입니다.
Unity 프로그램은 일반적인 방식대로라면 1파일 1클래스(1 file 1 class)이지만,
파일 수가 많으면 AI가 전체상을 한 번의 컨텍스트 (Context)로 읽어 들일 수 없고, 인터페이스나 클래스 간의 관계를 파악하기에는 효율이 떨어지며 노이즈도 많습니다.
세상에는 「구현이 곧 사양서다」라고 주장하는 과격파가 있다는 것도 이해합니다만,
AI는 세션을 다시 연결할 때마다 읽어 들이는 과정이 필요하며, 코드에서만 읽게 하면 토큰 (Token) 사용량은 물론 가장 중요한 정확도가 묻혀버리고 맙니다.
자연어로 주석이나 향후 구상을 메모할 수 있다는 점도 중요한 포인트입니다.
이것은 「하는 편이 좋겠지」 정도의 이야기가 아니라, 반드시 해야 합니다.
단, 당신이 직접 쓸 필요는 없습니다.
「이런 것을 생각하고 있어」라고 AI와 대화(Wall-hitting)하며 결론을 내리면, 그것을 문서(docs)에 기재하도록 시키면 됩니다.
앞서 언급했듯이, ClaudeCode나 Codex는 그 특성상 정기적으로 세션을 리셋할 필요가 있습니다.
리셋하지 않고 계속 사용하면 점차 토큰 효율이 떨어지고, 베테랑 엔지니어 같은 풍모가 사라지며, 입력한 프롬프트 (Prompt)를 제대로 따르지 않게 됩니다.
신입 엔지니어가 프로젝트에 참여했을 때처럼,
처음에 읽혀주는 문서와 같이,
빠르게 캐치업 (Catch-up) 할 수 있도록 준비를 해두어야 합니다.
제가 이번 검증 개발을 통해 도달한 문서의 종류는 다음 4가지입니다.
게임의 사양을 두는 폴더.
생각한 것이나 향후의 구상, 게임 시스템, 기능 등은 모두 여기에 둡니다.
마스터나 도메인 객체의 설계 의도 등도 여기에 둡니다.
- 예
- 게임 전체 사양
- 전투 시스템
- 게임 사이클
- 액터가 할 수 있는 행동
- 아이템 및 골드 시스템
게임 구현 규칙에 관한 폴더
다른 프로젝트에도 유용하게 쓸 수 있는 것들을 여기에 둡니다.
이 검증 개발은, 가이드라인 (guidelines)을 작성·확충하여 정밀도를 높이기 위해 이번 게임을 만들고 있습니다
- 예
- 코딩 규칙
- 디버그 방법
- 프레임워크 사용법
- 리뷰 가이드라인
- 셀프 리뷰 프롬프트
새로운 게임을 만들 때, 이 파일들만 복사해서 이어받는 것이 이상적입니다.
게임 구현 로드맵
roadmap -> phase -> task 라는 부모-자식 관계
phase는 roadmap 내의 작업을 덩어리별로 나눈 단위입니다 (예: 「전투 시스템」, 「아이템 시스템」 등)
guidelines가 안정되면 roadmap 단위로 통째로 꽤 괜찮은 품질의 구현이 납품되게 됩니다.
- 「게임 개발 완료를 향한 로드맵을 docs/roadmap 아래에 md 파일로 만들어줘」
셀프 리뷰 보관소.
ClaudeCode와 Codex에게 각각 셀프 리뷰를 시킵니다.
성격 차이인지, 각자 적절한 지적을 꽤 잘 해주기 때문에 리뷰 내용을 머지(Merge)시키고 수정을 반복하게 합니다.
사양을 생각했을 때, 새로운 기능을 만들 때는 반드시 docs에 기재하여 영속화(Persistence)합시다.
(커밋(Commit)을 좀 더 제대로 나누어 두었더라면 하고 나중에 후회하고 있습니다.)
작성한 마스터 데이터(Master Data)와 도메인 객체(Domain Object)를 실제 코드로 구현합니다.
하지만 마스터 데이터를 위해 SQLite나 MasterMemory 등을 이 타이밍에 도입하면 비용이 높고, 무엇보다 ClaudeCode나 Codex가 부담 없이 편집하게 만들기 어렵습니다.
이번에는 전부 Dictionary를 사용하여 하드코딩(Hard-coding)으로 작성하도록 합니다.
아이템의 예.
불변성(Immutable)을 확인합시다.
마스터 1개 테이블에 대응하는 클래스를 하나 만듭니다.
Prefix나 Suffix의 역할에 대해 정리해서 올려둡니다.
('내가 이런 의미로 사용하고 있다'는 것만 적고, 일반적인 내용은 적지 않습니다.)
~Table- 마스터 데이터의 테이블을 표현하는 클래스
-
최종적으로는 SQLite나 MasterMemory가 될 것이므로 개발이 진행됨에 따라 사라지게 됨
~Master- 마스터 데이터의 1개 레코드를 표현하는 클래스
-
불변(Immutable) 데이터 클래스
-
내용은 마스터 데이터와 일치해야 함
~Spec- 마스터 데이터를 조합한 불변(Immutable) 데이터 클래스
-
상태를 가지지는 않지만 가공은 가능
-
마스터 단독으로는 표현하기 어려울 때 이용
-
예를 들어 Actor를 스폰(Spawn)할 때, 스폰 테이블 ID로부터 마스터를 참조하여 액터의 종류나 위치, 초기 무기, 장비 등의 정보를 가져와 이용하기 쉬운 형태로 제공함
~Orchestrator- 여러 UseCase를 이용할 수 있는 애플리케이션 계층(Application Layer)의 UseCase
-
반대로 말하면
~UseCase는 단일 책임(Single Responsibility)만 가질 수 있음 (Orchestrator로 승격 필요)
Advance~- 정기적으로 업데이트하는 처리
-
Update가 너무 다의적이기 때문에 자주 이쪽을 사용함
Product~- 프로덕트(Product) 측에서 미들웨어 등을 오버라이드(Override)할 때 사용하는 접두사(Prefix)
- 프로젝트 이름으로 하면 의도가 불분명해지므로 Product로 통일함
- 이 대책이 없으면
DungeonInnCameraManager
같은 비참한 이름이 되어버림
- 기타
다음으로 Orchestrator와 UseCase를 만듭니다.
Orchestrator란 UseCase를 호출할 수 있는 UseCase입니다.
일반적으로 "UseCase는 다른 UseCase를 호출할 수 있다"라고 하는 경우가 많지만,
거미줄처럼 의존성이 얽히는 것이 싫기 때문에 저는 분리하고 있습니다.
간단히 말하면 "UseCase란 데이터 조작 절차마다 만들어지는 클래스"입니다.
사실 이 시점에서 design 문서가 충실하고, 마스터 데이터와 도메인 객체를 제대로 만들어 두었다면, 이 작업을 전부 AI에게 맡길 수 있습니다.
이 단계는 **"design 내용에 맞춰서 UseCase를 만들어 주세요"**라고만 하면 됩니다.
AI가 알 수 없는 구현을 시작하는 이유는 "데이터 설계"와 그것을 이용하는 "처리"를 한꺼번에 만들게 하기 때문입니다.
Claude나 Codex가 이미 존재하는 구조의 수정이나 확장에서 발휘하는 힘은 말할 것도 없을 것입니다.
이제부터 드디어 roadmap에 의한 작업을 시작합니다.
데이터 설계부터 roadmap을 정의해도 좋지만,
데이터 설계는 Claude/Codex를 길들이기(Training) 전까지 고생할 것이라 생각되므로, 그때까지 어설프게 계획을 세워봤자 큰 효력은 없습니다.
또한, 이 워크플로우에서 roadmap md 파일을 만드는 목적은 "AI에게 던져줄 수 있도록 하기 위함"에 있습니다.
design에 기재된 게임 내용을 구현하여 완성하기까지의 roadmap을 md 파일로 만들어 주세요.
roadmap은 작업하기 쉽고 동작 확인이 가능한 단위로 나누어 파일화해 주세요.
roadmap에는 목표(Goal)와 대상 범위(Scope)를 기재해 주세요.
이것으로 충분합니다.
처음부터 어떤 구현을 할지 모든 roadmap에 구체적으로 써버리면,
해당 roadmap의 작업에 들어갈 때 노이즈(Noise)가 됩니다.
우선은 추상적인 예정만 기재합시다.
여기서부터는 이 roadmap 작업의 반복입니다.
단, 진행 방식이 중요합니다.
roadmap 작업을 시작하기 직전에 해당 roadmap의 내용을 기입합니다.
Step1. 기능의 상세 내용을 기재한다
roadmap{N}의 내용을 정밀 조사하여, 어떤 기능이 필요한지 상세히 기재해 주세요.
Step2. 기능의 이상적인 설계를 기재한다
roadmap{N}의 내용을 정밀 조사하여, 실제 코드를 참조하면서 이상적인 설계를 추가해 주세요.
단, 호환성을 유지하기 위한 구현이나 바이패스(bypass)는 일절 하지 마십시오.
이상적인 설계를 위해 수행되는 파괴적 변경(breaking changes)은 모두 허용합니다.
Step3. 기능을 구현한다
roadmap{N}의 내용을 구현해 주세요.
중요한 것은 구현 직전에 두 가지 단계를 끼워 넣는 것입니다.
Step1은, 그때까지의 작업으로 인해 프로젝트의 상태가 변했거나 방침이 바뀌었을 가능성이 있기 때문에, 이 타이밍에 코드를 확인하여 구체적인 작업 방침을 roadmap에 기재합니다.
Step2는, ClaudeCode나 Codex가 기능 구현 완료를 우선시하여 요령을 피우는 구현을 하는 것을 억제하는 효과가 있습니다.
AI는 특히 "돌아가기는 하지만, 이거 구현으로서 별로 아닌가?" 싶은 코드를 작성하는 경향이 있는데,
그것은 "작동시키는 것"을 목적으로 코드 설계(code design)를 하기 때문입니다.
숙련된 엔지니어는 이상적인 설계를 코드를 쓰면서 구축할 수 있지만,
AI는 NavMesh처럼 경로를 제대로 만들어 주지 않으면 벽에 부딪히고 맙니다.
이것은 특히 중요하므로, 복사해서 사용합시다.
결론적으로 충분한 코드 품질로 게임을 만들 수 있습니다.
완벽한 설계, 완벽한 구현과는 거리가 멀지만,
게임으로서 콘텐츠를 늘리기 쉬운 확장성(scalability) 높은 설계를 유지할 수 있습니다.
제 경험상, 실제 게임 개발 현장 기준으로 치면 편차치 55 정도의 코드 품질입니다.
작업 시간은 GW(4/295/6) 연휴 + 토요일 또는 일요일 + 평일 밤 12시간으로 대략 10인일(man-days) 정도이므로 충분한 성과라고 생각합니다.
- 게임 개발에서 AI에게 처음부터 100점 만점을 요구할 필요는 없다
- 설계에 능숙한 사람은 설계에, 구현에 능숙한 사람은 구현에, 50점과 50점을 얻을 수 있다면 그것으로 충분하다
- 이른바
divide and conquer(분할 정복)
🍆
- 개발 중에도 개선해야 할 동작이 보이면 guidelines에 계속 추가한다
- 정기적으로 (마일스톤마다) 셀프 리뷰(self-review)를 수행하게 한다
- EditModeTest/PlayModeTest뿐만 아니라 직접 실행하여 테스트하게 한다
- UnityCLILoop를 만들어 주셔서 감사합니다
"설계"와 "구현"을 한꺼번에 던져버리면, AI는 그것을 달성하는 데 에너지를 쏟기 때문에 범용성이나 확장성을 고려하지 않은 결과물이 나오고 만다.

각각에 목표를 설정하여 나누어 AI에게 전달함으로써, 설계로서 고품질인 목표와 구현으로서 고품질인 목표 모두에 도달할 수 있다.

이 그림은 필요 없었을지도 모르겠습니다.
업무용으로 진지하게 설계한 Unity 아키텍처를 MIT 라이선스로 공개했습니다!
씬 기반(scene foundation), 다이얼로그 기반(dialog foundation), 로컬라이즈(localize), 에셋 관리(asset management), 씬 애니메이션(scene animation), 입력 레이어 제어 등,
"게임 본편과는 상관없지만, 게임으로서 성립하기 위해서는 귀찮더라도 반드시 만들어야 하는 기능"
그런 부분들을 전부 맡길 수 있는 아키텍처 프레임워크입니다.
물론 AI와의 친화성도 ◎!
VContainer + UniTask + 클린 아키텍처(Clean Architecture)이므로,
뭐... 아주 조금 어려울 수도 있겠지만, Unity 개발에서 흔히 발생하는 버그가 줄어들고, 안정적인 품질을 고속으로 구현 및 개발할 수 있습니다!
그리고 지금이라면 AI가 안정적으로 이용할 수 있도록 하는 프롬프트(prompt)도 함께 제공됩니다!
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기