'클로드 코드로 시작하는 실전 에이전틱 코딩' 책의 실습 예제 프로젝트입니다.
클래식 스네이크 게임에 레벨 시스템, 파워업 아이템, 파티클 효과 등 현대적 요소를 추가한 웹 기반 게임입니다. TypeScript와 HTML5 Canvas API로 구현되었으며, MoAI-ADK(에이전틱 개발 키트) 를 활용한 SPEC 기반 자율 개발 워크플로우를 통해 만들어졌습니다.
이 프로젝트는 클로드 코드(Claude Code) 와 MoAI-ADK 를 활용하여 에이전틱 코딩이 실제 소프트웨어 개발에 어떻게 적용되는지 보여주는 예제입니다. SPEC 문서 작성부터 구현, 테스트, 문서화까지 전체 개발 라이프사이클을 AI 에이전트가 자율적으로 수행합니다.
에이전틱 코딩은 AI가 단순히 코드를 생성하는 것을 넘어, 자율적으로 계획을 세우고, 구현하고, 테스트하고, 문서화하는 개발 방식입니다. 개발자는 요구사항을 전달하고, AI 에이전트가 전문 역할(아키텍트, 백엔드 개발자, 프론트엔드 개발자, QA 엔지니어 등)을 분담하여 협업합니다.
graph LR
A[개발자] -->|요구사항 전달| B[MoAI 오케스트레이터]
B -->|SPEC 작성| C[manager-spec]
B -->|구현 위임| D[expert-frontend]
B -->|품질 검증| E[manager-quality]
B -->|문서 생성| F[manager-docs]
C --> G[SPEC 문서]
D --> H[소스 코드 + 테스트]
E --> I[품질 리포트]
F --> J[README + API 문서]
style A fill:#4CAF50,color:#fff
style B fill:#2196F3,color:#fff
style C fill:#FF9800,color:#fff
style D fill:#FF9800,color:#fff
style E fill:#FF9800,color:#fff
style F fill:#FF9800,color:#fff
이 프로젝트는 MoAI-ADK의 3단계 SPEC 워크플로우를 따라 개발되었습니다.
flowchart TD
subgraph Plan["Phase 1: Plan (계획)"]
P1["/moai plan 명령 실행"]
P2["manager-spec 에이전트가<br/>EARS 형식 요구사항 작성"]
P3["SPEC 문서 생성<br/>(spec.md, plan.md, acceptance.md)"]
P1 --> P2 --> P3
end
subgraph Run["Phase 2: Run (구현)"]
R1["/moai run SPEC-GAME-001"]
R2["expert-frontend 에이전트가<br/>TDD 방식으로 구현"]
R3["242개 테스트 통과<br/>85%+ 커버리지 달성"]
R1 --> R2 --> R3
end
subgraph Sync["Phase 3: Sync (동기화)"]
S1["/moai sync SPEC-GAME-001"]
S2["manager-docs 에이전트가<br/>문서 자동 생성"]
S3["README + CHANGELOG<br/>+ API 문서 생성"]
S1 --> S2 --> S3
end
Plan -->|SPEC 승인| Run
Run -->|구현 완료| Sync
style Plan fill:#E3F2FD,stroke:#1565C0
style Run fill:#E8F5E9,stroke:#2E7D32
style Sync fill:#FFF3E0,stroke:#E65100
이 프로젝트의 모든 개발은 SPEC-GAME-001 문서를 기반으로 진행되었습니다.
| 문서 | 위치 | 설명 |
|---|---|---|
| 명세서 | .moai/specs/SPEC-GAME-001/spec.md |
EARS 형식 요구사항, 게임 설계, 기술 명세 |
| 구현 계획 | .moai/specs/SPEC-GAME-001/plan.md |
4단계 마일스톤 구현 계획 |
| 수락 기준 | .moai/specs/SPEC-GAME-001/acceptance.md |
Gherkin(Given-When-Then) 형식 테스트 시나리오 |
게임은 4가지 상태를 가지며, 사용자 입력과 게임 이벤트에 따라 전환됩니다.
stateDiagram-v2
[*] --> MENU: 게임 로드
MENU --> PLAYING: 게임 시작
PLAYING --> PAUSED: ESC 키
PLAYING --> GAME_OVER: 충돌 발생
PAUSED --> PLAYING: 계속하기
PAUSED --> MENU: 메인 메뉴
GAME_OVER --> PLAYING: 재시작
GAME_OVER --> MENU: 메인 메뉴
note right of PLAYING
60fps 게임 루프 실행
입력 처리, 충돌 감지
점수/레벨/파워업 업데이트
end note
note right of PAUSED
게임 루프 일시 중단
일시정지 메뉴 표시
end note
점수를 획득하면 레벨이 올라가며, 난이도가 점진적으로 상승합니다.
| 레벨 | 목표 점수 | 속도 배율 | 장애물 수 | 난이도 |
|---|---|---|---|---|
| 1 | 50 | 1.0x | 0 | 입문 |
| 2 | 120 | 1.2x | 2 | 쉬움 |
| 3 | 200 | 1.4x | 4 | 보통 |
| 4 | 300 | 1.6x | 6 | 어려움 |
| 5 | 420 | 1.8x | 8 | 매우 어려움 |
| 6+ | +140/레벨 | +0.2x/레벨 | +2/레벨 | 극한 |
먹이를 3개 먹을 때마다 파워업 아이템이 스폰됩니다. 맵에는 동시에 최대 1개의 파워업만 존재하며, 미획득 시 10초 후 소멸합니다.
flowchart LR
subgraph Spawn["스폰 조건"]
A["먹이 3개 획득"] --> B{"맵에 파워업<br/>존재 여부"}
B -->|없음| C["가중 확률로 아이템 생성"]
B -->|있음| D["스폰 건너뜀"]
end
subgraph Effects["파워업 효과"]
E["속도 부스트<br/>5초 | 30% 확률<br/>속도 1.5x + 점수 1.5x"]
F["무적<br/>7초 | 20% 확률<br/>충돌 무시"]
G["점수 2배<br/>8초 | 50% 확률<br/>점수 2.0x"]
end
C --> E
C --> F
C --> G
style E fill:#FF5722,color:#fff
style F fill:#2196F3,color:#fff
style G fill:#FFC107,color:#000
최종 점수 = (기본 점수 10 + 레벨 보너스) x 파워업 배율
레벨 보너스 = 현재 레벨 x 2
파워업 배율 = 기본 1.0x | 속도 부스트 1.5x | 점수 2배 2.0x
계산 예시:
| 상황 | 기본 | 레벨 보너스 | 파워업 배율 | 최종 점수 |
|---|---|---|---|---|
| 레벨 1, 파워업 없음 | 10 | +2 | x1.0 | 12 |
| 레벨 3, 파워업 없음 | 10 | +6 | x1.0 | 16 |
| 레벨 1, 점수 2배 | 10 | +2 | x2.0 | 24 |
| 레벨 3, 속도 부스트 | 10 | +6 | x1.5 | 24 |
flowchart TD
A["뱀 머리 이동"] --> B{"먹이 충돌?"}
B -->|예| C["뱀 성장 + 점수 증가"]
B -->|아니오| D{"파워업 충돌?"}
D -->|예| E["효과 활성화"]
D -->|아니오| F{"무적 상태?"}
F -->|예| G["충돌 무시, 게임 계속"]
F -->|아니오| H{"장애물/벽/자기몸<br/>충돌?"}
H -->|예| I["GAME OVER"]
H -->|아니오| J["정상 이동"]
style C fill:#4CAF50,color:#fff
style E fill:#FF9800,color:#fff
style G fill:#2196F3,color:#fff
style I fill:#F44336,color:#fff
| 이벤트 | 파티클 수 | 지속 시간 | 색상 |
|---|---|---|---|
| 먹이 획득 | 8~12 | 0.5초 | 먹이 색상 |
| 레벨업 | 20~30 | 1.0초 | 골드/화이트 |
| 파워업 획득 | 12~16 | 0.7초 | 아이템별 색상 |
| 게임 오버 | 30~40 | 1.5초 | 레드/오렌지 |
성능 보장을 위해 화면에 동시에 존재하는 파티클 수는 최대 100개로 제한되며, 오브젝트 풀링으로 GC 부하를 최소화합니다.
| 분류 | 기술 | 버전 | 용도 |
|---|---|---|---|
| 언어 | TypeScript (strict mode) | 5.x | 타입 안전한 게임 로직 |
| 그래픽 | HTML5 Canvas 2D API | - | 60fps 게임 렌더링 |
| 빌드 | Vite | 6.x | HMR 개발 서버 + 프로덕션 빌드 |
| 테스트 | Vitest + jsdom | 3.x | 단위/통합 테스트 |
| 린팅 | ESLint + typescript-eslint | 9.x | 코드 품질 검사 |
| 포매팅 | Prettier | 3.x | 코드 스타일 통일 |
| 런타임 | Node.js | 20.x LTS+ | 개발 환경 |
프로젝트는 관심사 분리 원칙에 따라 5개 계층으로 구성됩니다.
graph TD
subgraph Entry["진입점"]
M["main.ts"]
end
subgraph Core["core/ - 핵심 엔진"]
G["Game.ts<br/>게임 루프 + 상태 관리"]
SN["Snake.ts<br/>뱀 엔티티"]
FD["Food.ts<br/>먹이 관리"]
GR["Grid.ts<br/>그리드 시스템"]
CL["Collision.ts<br/>충돌 감지"]
end
subgraph Systems["systems/ - 게임 시스템"]
IS["InputSystem.ts<br/>입력 처리"]
LS["LevelSystem.ts<br/>레벨 관리"]
PS["PowerUpSystem.ts<br/>파워업 관리"]
SS["ScoreSystem.ts<br/>점수 계산"]
end
subgraph Rendering["rendering/ - 렌더링 계층"]
RD["Renderer.ts<br/>Canvas 렌더링"]
PT["ParticleSystem.ts<br/>파티클 효과"]
AM["AnimationManager.ts<br/>애니메이션"]
UR["UIRenderer.ts<br/>UI 렌더링"]
end
subgraph UI["ui/ - UI 컴포넌트"]
MN["Menu.ts"]
GO["GameOverScreen.ts"]
LB["Leaderboard.ts"]
PM["PauseMenu.ts"]
HD["HUD.ts"]
end
subgraph Data["data/ - 게임 데이터"]
CN["constants.ts"]
LV["levels.ts"]
PW["powerups.ts"]
end
subgraph Utils["utils/ - 유틸리티"]
ST["storage.ts"]
MT["math.ts"]
RN["random.ts"]
end
M --> G
G --> SN & FD & GR & CL
G --> IS & LS & PS & SS
G --> RD
RD --> PT & AM & UR
G --> MN & GO & LB & PM & HD
LS --> LV
PS --> PW
SN & GR & RD --> CN
FD & PS --> RN
AM & PT --> MT
LB & SS --> ST
style Core fill:#E3F2FD,stroke:#1565C0
style Systems fill:#E8F5E9,stroke:#2E7D32
style Rendering fill:#FFF3E0,stroke:#E65100
style UI fill:#F3E5F5,stroke:#7B1FA2
style Data fill:#ECEFF1,stroke:#546E7A
style Utils fill:#FBE9E7,stroke:#BF360C
| 원칙 | 설명 | 적용 예시 |
|---|---|---|
| 단일 책임 | 각 모듈은 하나의 역할만 담당 | Snake.ts는 뱀 동작만, Renderer.ts는 화면 그리기만 |
| 관심사 분리 | 로직/렌더링/UI/데이터 분리 | 게임 로직은 렌더링에 의존하지 않음 |
| 느슨한 결합 | 이벤트/인터페이스 기반 통신 | 시스템 간 직접 참조 최소화 |
| 데이터 주도 | 게임 밸런스는 데이터로 조정 | src/data/ 파일만 수정하여 밸런스 튜닝 |
sequenceDiagram
participant B as Browser
participant GL as Game Loop
participant U as Update
participant R as Render
B->>GL: requestAnimationFrame(callback)
loop 매 프레임 (~16.7ms)
GL->>GL: deltaTime 계산
GL->>GL: accumulator += deltaTime
loop accumulator >= moveInterval
GL->>U: update()
Note over U: 입력 처리
Note over U: 뱀 이동
Note over U: 충돌 감지
Note over U: 점수/레벨/파워업 업데이트
GL->>GL: accumulator -= moveInterval
end
GL->>R: render(interpolation)
Note over R: 보간 기반 부드러운 렌더링
Note over R: 파티클 업데이트
Note over R: UI/HUD 렌더링
GL->>B: requestAnimationFrame(callback)
end
snake-game-2026/
├── index.html # HTML 진입점
├── src/ # 소스 코드 (26개 TypeScript 파일)
│ ├── main.ts # 애플리케이션 진입점
│ ├── types/index.ts # 공통 타입 정의
│ ├── core/ # 핵심 엔진 (Game, Snake, Food, Grid, Collision)
│ ├── systems/ # 게임 시스템 (Level, PowerUp, Score, Input)
│ ├── rendering/ # 렌더링 (Renderer, Particle, Animation, UI)
│ ├── ui/ # UI (Menu, GameOver, Leaderboard, Pause, HUD)
│ ├── data/ # 게임 데이터 (constants, levels, powerups)
│ └── utils/ # 유틸리티 (storage, math, random)
├── tests/ # 테스트 (14개 파일, 242개 테스트 케이스)
│ ├── core/ # 핵심 엔진 테스트
│ ├── systems/ # 시스템 테스트
│ ├── rendering/ # 렌더링 테스트
│ └── utils/ # 유틸리티 테스트
├── .moai/ # MoAI-ADK 설정
│ ├── specs/SPEC-GAME-001/ # SPEC 문서 (spec.md, plan.md, acceptance.md)
│ ├── project/ # 프로젝트 문서 (product, structure, tech)
│ └── config/ # 프로젝트 설정
├── package.json # npm 패키지 설정
├── tsconfig.json # TypeScript 설정 (strict mode)
├── vite.config.ts # Vite 빌드 설정
├── vitest.config.ts # Vitest 테스트 설정
├── eslint.config.js # ESLint 설정
└── .prettierrc # Prettier 설정
- Node.js 20.x LTS 이상
- npm 10.x 이상
# 저장소 복제
git clone https://github.com/modu-ai/snake-game.git
cd snake-game
# 의존성 설치
npm install
# 개발 서버 실행
npm run dev브라우저에서 http://localhost:5173으로 접속하면 게임을 플레이할 수 있습니다.
# 타입 체크 + 빌드
npm run build
# 빌드 결과 미리보기
npm run preview| 명령어 | 설명 |
|---|---|
npm run dev |
Vite 개발 서버 실행 (HMR 지원) |
npm run build |
TypeScript 타입 체크 + 프로덕션 빌드 |
npm run preview |
빌드 결과물 로컬 미리보기 |
npm run test |
Vitest watch 모드 실행 |
npm run test:run |
테스트 1회 실행 |
npm run test:coverage |
커버리지 리포트 포함 테스트 실행 |
npm run lint |
ESLint 코드 검사 |
npm run lint:fix |
ESLint 자동 수정 |
npm run format |
Prettier 코드 포매팅 |
npm run format:check |
포매팅 규칙 준수 확인 |
npm run type-check |
TypeScript 타입 체크 |
| 키 | 동작 |
|---|---|
| 방향키 / WASD | 뱀 이동 방향 전환 |
| Space | 게임 시작 / 일시정지 |
| ESC | 일시정지 / 메뉴로 돌아가기 |
- 먹이를 먹으면 뱀이 길어지고 점수를 획득합니다.
- 파워업 아이템을 획득하면 일정 시간 동안 특수 능력이 활성화됩니다.
- 벽, 자기 몸, 장애물에 부딪히면 게임이 종료됩니다 (무적 파워업 제외).
- 일정 점수에 도달하면 다음 레벨로 진행되며 속도와 장애물이 증가합니다.
- Top 10 점수를 달성하면 닉네임을 입력하여 리더보드에 기록할 수 있습니다.
이 프로젝트의 모든 요구사항은 EARS(Easy Approach to Requirements Syntax) 형식으로 작성되었습니다.
graph TD
subgraph EARS["EARS 요구사항 분류"]
U["Ubiquitous<br/>(항상 활성)"]
E["Event-Driven<br/>(이벤트 기반)"]
S["State-Driven<br/>(상태 기반)"]
UW["Unwanted Behavior<br/>(금지 행위)"]
O["Optional<br/>(선택 사항)"]
end
U --> U1["REQ-001: 60fps 게임 루프, 입력 응답, Canvas 렌더링, TypeScript strict"]
E --> E1["REQ-002: 방향 전환, 먹이 획득, 충돌, 레벨업, 파워업, 리더보드"]
S --> S1["REQ-003: 일시정지, 무적 효과, 점수 2배, 속도 부스트, 장애물"]
UW --> UW1["REQ-004: 반대 방향 전환 금지, 먹이/파워업 겹침 금지"]
O --> O1["REQ-005: 터치 입력, 반응형 Canvas, 리더보드 초기화"]
style U fill:#1565C0,color:#fff
style E fill:#2E7D32,color:#fff
style S fill:#E65100,color:#fff
style UW fill:#C62828,color:#fff
style O fill:#6A1B9A,color:#fff
| TAG | 요구사항 | 구현 모듈 | 마일스톤 |
|---|---|---|---|
| SPEC-GAME-001-CORE | REQ-001, REQ-002-01~03 | core/ |
M1 |
| SPEC-GAME-001-INPUT | REQ-002-01, REQ-002-08, REQ-005-01 | systems/InputSystem.ts |
M1, M4 |
| SPEC-GAME-001-LEVEL | REQ-002-04, REQ-003-05 | systems/LevelSystem.ts |
M2 |
| SPEC-GAME-001-POWERUP | REQ-002-05 |
systems/PowerUpSystem.ts |
M2 |
| SPEC-GAME-001-SCORE | REQ-002-02 | systems/ScoreSystem.ts |
M2 |
| SPEC-GAME-001-UI | REQ-002-07~09, REQ-001-05 | ui/ |
M3 |
| SPEC-GAME-001-STORAGE | REQ-002-07, REQ-004-05 | utils/storage.ts |
M3 |
| SPEC-GAME-001-RENDER | REQ-001-03, REQ-002-10~11 | rendering/ |
M4 |
4단계 마일스톤으로 체계적으로 구현되었습니다.
gantt
title SPEC-GAME-001 구현 마일스톤
dateFormat X
axisFormat %s
section M1: 코어 엔진
프로젝트 설정 (Vite + TS) :done, m1a, 0, 1
타입 정의 + 게임 상수 :done, m1b, 1, 2
핵심 엔진 (Game, Snake, Food, Grid) :done, m1c, 2, 4
충돌 감지 + 입력 시스템 :done, m1d, 4, 5
기본 렌더링 + 코어 테스트 :done, m1e, 5, 6
section M2: 게임 시스템
점수 시스템 :done, m2a, 6, 7
레벨 시스템 + 장애물 :done, m2b, 7, 8
파워업 시스템 :done, m2c, 8, 10
시스템 테스트 :done, m2d, 10, 11
section M3: UI + 리더보드
LocalStorage 헬퍼 :done, m3a, 11, 12
메뉴 + 게임오버 + 일시정지 :done, m3b, 12, 14
리더보드 + HUD :done, m3c, 14, 15
스토리지 테스트 :done, m3d, 15, 16
section M4: 비주얼 폴리싱
파티클 시스템 (오브젝트 풀링) :done, m4a, 16, 18
애니메이션 매니저 (이징 함수) :done, m4b, 18, 19
렌더링 개선 + 터치 입력 :done, m4c, 19, 20
| 마일스톤 | 내용 | 상태 |
|---|---|---|
| M1: 코어 엔진 | 프로젝트 설정, 타입 정의, Game/Snake/Food/Grid/Collision, 입력 시스템, 기본 렌더링 | 완료 |
| M2: 게임 시스템 | 점수/레벨/파워업 시스템, 레벨 데이터, 충돌 시스템 확장 | 완료 |
| M3: UI + 리더보드 | 메인 메뉴, 게임오버, 일시정지, 리더보드, HUD, LocalStorage | 완료 |
| M4: 비주얼 폴리싱 | 파티클 시스템, 애니메이션 매니저, 반응형 Canvas, 터치 입력 | 완료 |
14개 테스트 파일에 242개 테스트 케이스가 포함되어 있습니다.
pie title 테스트 분포
"core/ (핵심 엔진)" : 5
"systems/ (게임 시스템)" : 4
"rendering/ (렌더링)" : 2
"utils/ (유틸리티)" : 3
| 영역 | 목표 | 우선순위 |
|---|---|---|
src/core/ |
90%+ | 최우선 |
src/systems/ |
85%+ | 높음 |
src/utils/ |
85%+ | 높음 |
src/data/ |
70%+ | 보통 |
src/ui/ |
50%+ | 낮음 |
src/rendering/ |
30%+ | 최저 |
# Watch 모드
npm run test
# 1회 실행
npm run test:run
# 커버리지 리포트 포함
npm run test:coverage이 프로젝트는 MoAI-ADK의 TRUST 5 품질 게이트를 통과했습니다.
graph LR
T["Tested<br/>테스트됨"]
R["Readable<br/>읽기 쉬움"]
U["Unified<br/>통일됨"]
S["Secured<br/>안전함"]
TR["Trackable<br/>추적 가능"]
T --> T1["242개 테스트 통과<br/>85%+ 커버리지"]
R --> R1["TypeScript strict<br/>명확한 네이밍"]
U --> U1["ESLint + Prettier<br/>일관된 코드 스타일"]
S --> S1["입력 검증<br/>LocalStorage 에러 핸들링"]
TR --> TR1["SPEC ID 참조<br/>Conventional Commits"]
style T fill:#4CAF50,color:#fff
style R fill:#2196F3,color:#fff
style U fill:#9C27B0,color:#fff
style S fill:#F44336,color:#fff
style TR fill:#FF9800,color:#fff
| 항목 | 기준 |
|---|---|
| 게임 루프 | 60fps 유지 (파티클 100개 활성 시에도) |
| 입력 응답 | 1프레임(~16.7ms) 이내 |
| 초기 로딩 | 3초 이내 (프로덕션 빌드) |
| 빌드 크기 | 500KB 이하 (gzip 압축 후) |
- Chrome (최신)
- Firefox (최신)
- Safari (최신)
- Edge (최신)
- 모바일 웹 브라우저 (터치 제어 지원)
이 프로젝트는 MIT 라이선스 하에 배포됩니다.
- 도서: 클로드 코드로 시작하는 실전 에이전틱 코딩
- MoAI-ADK: AI 에이전트 기반 자율 개발 키트
- Claude Code: Anthropic의 공식 CLI 개발 도구
