본문으로 건너뛰기

폴더 구조 개선 v2 — 상세 설계

작성: Planner | 2026-03-30 | Status: Draft 선행 문서: project-restructure-design.md (v1, Docusaurus+대시보드 통합)


1. 목표

게임 코드를 game/ 폴더로 묶어 Godot 프로젝트를 격리하고, 문서(docs/)·운영 데이터(ops/)·스크립트(scripts/)를 명확히 분리한다.

1.1 핵심 변경점 (v1 대비)

#v1 (현재)v2 (목표)이유
1루트 = Godot 프로젝트 (project.godot 루트)game/ = Godot 프로젝트게임/도구/문서 역할 분리
2res/data/ — 밸런스 JSONgame/data/ — 밸런스 JSONres/ 밖으로 분리하되 game/ 내부 유지
3docs/ 안에 문서+운영+태스크 혼합docs/ = 기획/설계만, ops/ = 운영관심사 분리
4scripts/ 플랫 구조 (31개 파일)scripts/{game,agent,ops,gpu}/ 서브폴더탐색성 향상

2. 목표 폴더 구조

the-hon-joseon/
├── game/ # Godot 프로젝트 루트
│ ├── project.godot
│ ├── .godot/ # Godot 에디터 캐시 (gitignore)
│ ├── addons/ # GdUnit4 등
│ ├── src/ # GDScript 소스코드
│ │ ├── autoloads/
│ │ ├── player/
│ │ ├── weapons/
│ │ ├── enemies/
│ │ ├── souls/
│ │ ├── equipment/
│ │ ├── systems/
│ │ ├── ui/
│ │ ├── hub/
│ │ ├── components/
│ │ ├── pickups/
│ │ ├── main.gd
│ │ └── main.tscn
│ ├── res/ # 리소스 (스프라이트, 오디오, UI, 타일셋)
│ │ ├── sprites/
│ │ ├── audio/
│ │ ├── tilesets/
│ │ └── ui/
│ ├── data/ # 밸런스 JSON (res/data/에서 승격)
│ │ ├── characters.json
│ │ ├── enemies.json
│ │ ├── weapons.json
│ │ ├── souls.json
│ │ ├── equipment.json
│ │ ├── stages.json
│ │ ├── levelup.json
│ │ ├── yinyang.json
│ │ ├── resonance.json
│ │ ├── curses.json
│ │ └── waves/
│ │ └── wave_XX.json
│ └── test/ # GdUnit4 테스트

├── tools/
│ └── dashboard/ # Docusaurus + 대시보드 (변경 없음)

├── docs/ # 기획/설계 문서만
│ ├── game/ # GDD, IA/UI, 시스템 설계
│ ├── design/ # 기술 설계 (아키텍처, ADR 아닌 설계서)
│ ├── decisions/ # ADR (결정 로그)
│ ├── setup/ # 셋업 가이드 (현 ops/에서 셋업만 이동)
│ └── comfyui_workflows/ # ComfyUI 워크플로우 JSON

├── ops/ # 운영 데이터 (신규 최상위)
│ ├── tasks/
│ │ └── backlog.json
│ ├── changelog.json
│ ├── milestones.json
│ ├── daily/
│ └── guides/ # 운영 가이드/체크리스트 (현 ops/에서 가이드만)

├── scripts/ # 자동화 스크립트 (서브폴더 분류)
│ ├── game/ # 게임 실행/테스트
│ │ ├── run-game.sh
│ │ ├── run-tests.sh
│ │ └── gdscript-lint.sh
│ ├── agent/ # 에이전트 관리
│ │ ├── start-agents.sh
│ │ ├── stop-agents.sh
│ │ ├── log-agent-idle.sh
│ │ ├── log-agent-start.sh
│ │ ├── log-agent-stop.sh
│ │ ├── log-notification.sh
│ │ ├── log-task-completed.sh
│ │ └── log-tool-use.sh
│ ├── ops/ # 운영/태스크/Slack
│ │ ├── update-task.sh
│ │ ├── add-changelog.sh
│ │ ├── slack-post.sh
│ │ ├── slack-template.sh
│ │ ├── slack-upload.sh
│ │ ├── check-pending-commands.sh
│ │ ├── check-review.sh
│ │ └── get-review-feedback.sh
│ └── gpu/ # GPU/에셋 파이프라인
│ ├── gpu-status.sh
│ ├── wol-wake.sh
│ ├── wol-sleep.sh
│ ├── comfyui-generate.sh
│ ├── acestep-generate.sh
│ ├── convert-audio.sh
│ ├── make-spritesheet.sh
│ ├── palette-remap.sh
│ └── validate-asset.sh

├── .claude/ # 에이전트 설정 (위치 유지)
├── .gitattributes
├── .gitignore
├── .env
└── README.md

3. 파일 이동 매핑

3.1 Godot 프로젝트 → game/

현재 경로목표 경로비고
project.godotgame/project.godotGodot 프로젝트 루트 변경
.godot/game/.godot/에디터 캐시, 재생성됨
addons/game/addons/GdUnit4
src/game/src/전체 이동
test/game/test/전체 이동
res/sprites/game/res/sprites/스프라이트
res/audio/game/res/audio/오디오
res/tilesets/game/res/tilesets/타일셋
res/ui/game/res/ui/UI 에셋
res/assets.jsongame/res/assets.json에셋 매니페스트
res/data/game/data/res/ 밖으로 승격

3.2 문서 재배치

현재 경로목표 경로비고
docs/game/docs/game/변경 없음
docs/design/docs/design/변경 없음
docs/decisions/docs/decisions/변경 없음
docs/comfyui_workflows/docs/comfyui_workflows/변경 없음
docs/ops/Mac_셋업.mddocs/setup/Mac_셋업.md셋업 → docs/setup/
docs/ops/Windows_셋업.mddocs/setup/Windows_셋업.md셋업 → docs/setup/
docs/ops/에이전트_셋업.mddocs/setup/에이전트_셋업.md셋업 → docs/setup/
docs/ops/운영_가이드.mdops/guides/운영_가이드.md운영 → ops/
docs/ops/운영_체크리스트.mdops/guides/운영_체크리스트.md운영 → ops/
docs/CLAUDE.mddocs/CLAUDE.md내용 업데이트 필요
res/CLAUDE.mdgame/res/CLAUDE.mdgame/ 내부로 이동
src/CLAUDE.mdgame/src/CLAUDE.mdgame/ 내부로 이동

3.3 운영 데이터 → ops/

현재 경로목표 경로비고
docs/tasks/backlog.jsonops/tasks/backlog.json태스크보드
docs/changelog.jsonops/changelog.json변경이력
docs/milestones.jsonops/milestones.json마일스톤
docs/daily/ops/daily/데일리 로그

3.4 스크립트 서브폴더 분류

현재 경로목표 경로카테고리
scripts/run-game.shscripts/game/run-game.shgame
scripts/run-tests.shscripts/game/run-tests.shgame
scripts/gdscript-lint.shscripts/game/gdscript-lint.shgame
scripts/start-agents.shscripts/agent/start-agents.shagent
scripts/stop-agents.shscripts/agent/stop-agents.shagent
scripts/log-*.sh (6개)scripts/agent/log-*.shagent
scripts/update-task.shscripts/ops/update-task.shops
scripts/add-changelog.shscripts/ops/add-changelog.shops
scripts/slack-*.sh (3개)scripts/ops/slack-*.shops
scripts/check-*.sh (2개)scripts/ops/check-*.shops
scripts/get-review-feedback.shscripts/ops/get-review-feedback.shops
scripts/gpu-status.shscripts/gpu/gpu-status.shgpu
scripts/wol-*.sh (2개)scripts/gpu/wol-*.shgpu
scripts/comfyui-generate.shscripts/gpu/comfyui-generate.shgpu
scripts/acestep-generate.shscripts/gpu/acestep-generate.shgpu
scripts/convert-audio.shscripts/gpu/convert-audio.shgpu
scripts/make-spritesheet.shscripts/gpu/make-spritesheet.shgpu
scripts/palette-remap.shscripts/gpu/palette-remap.shgpu
scripts/validate-asset.shscripts/gpu/validate-asset.shgpu

4. 경로 참조 변경 목록

4.1 Godot res:// 경로 — 핵심 영향

Godot의 res://project.godot가 있는 디렉토리를 기준으로 한다. project.godotgame/으로 이동하면:

현재 res:// 경로res:// 경로이유
res://src/...res://src/...변경 없음 (src/는 game/ 안에서 상대위치 동일)
res://res/...res://res/...변경 없음 (res/도 game/ 안에서 동일)
res://res/data/...res://data/...변경 — data/가 res/ 밖으로 승격
res://addons/...res://addons/...변경 없음
res://test/...res://test/...변경 없음

핵심: game/ 내부에서의 상대 구조는 현재와 거의 동일. 유일한 변경은 res://res/data/res://data/.

4.2 GDScript 코드 수정

파일현재변경 후영향도
src/autoloads/data_manager.gd:6const DATA_PATH = "res://res/data/"const DATA_PATH = "res://data/"HIGH — 모든 JSON 로딩의 기준 경로

data_manager.gdDATA_PATH 하나만 수정하면 모든 JSON 로딩이 자동 반영됨. 다른 GDScript 파일은 DataManager.get_weapon() 등 API를 사용하므로 직접 경로 참조 없음.

4.3 .tscn 파일 내부 경로

.tscn 파일은 res:// 기반 경로를 사용한다. 현재 확인된 res:// 참조:

res://src/main.tscn              → [ext_resource ... path="res://src/..."]
res://src/systems/game_world.tscn
res://src/player/player.tscn
res://src/enemies/enemy_base.tscn
...

src/, res/가 game/ 내부에서 동일 위치이므로 .tscnres://src/..., res://res/... 경로는 수정 불필요. 단, .tscn 내에 res://res/data/ 참조가 있다면 res://data/로 수정 필요 — 현재 .tscn에서 data JSON 직접 참조는 없음 (DataManager 경유).

4.4 project.godot 내부 경로

run/main_scene="res://src/main.tscn"              # 변경 없음
EventBus="*res://src/autoloads/event_bus.gd" # 변경 없음
...
enabled=PackedStringArray("res://addons/gdUnit4/plugin.cfg") # 변경 없음

game/ 내부 상대 구조 유지이므로 project.godot 내부의 모든 res:// 경로 수정 불필요.

4.5 스크립트 내부 경로 참조

스크립트참조변경 내용
scripts/update-task.sh:14$PROJECT_ROOT/docs/tasks/backlog.json$PROJECT_ROOT/ops/tasks/backlog.json
scripts/add-changelog.sh:16$PROJECT_ROOT/docs/changelog.json$PROJECT_ROOT/ops/changelog.json
scripts/run-tests.shGodot 실행 경로프로젝트 루트 → game/ 지정 필요
scripts/run-game.shGodot 실행 경로프로젝트 루트 → game/ 지정 필요
scripts/comfyui-generate.shres/sprites/ 출력 경로game/res/sprites/
scripts/acestep-generate.shres/audio/ 출력 경로game/res/audio/
scripts/validate-asset.sh에셋 경로 검증game/ 접두사 반영
scripts/make-spritesheet.shres/sprites/ 참조game/res/sprites/
scripts/palette-remap.sh이미지 경로game/ 접두사 반영
scripts/start-agents.sh:64./scripts/stop-agents.sh./scripts/agent/stop-agents.sh
scripts/log-notification.sh:30./scripts/slack-post.sh./scripts/ops/slack-post.sh

$PROJECT_ROOT 유지: 모든 스크립트는 $PROJECT_ROOT를 기준으로 경로를 해석하므로, PROJECT_ROOT는 여전히 레포 루트를 가리킨다. 변경되는 것은 그 이후의 상대 경로.

4.6 .claude/ 에이전트 설정 참조

파일현재 참조변경 필요
.claude/CLAUDE.mddocs/tasks/backlog.json, res/data/, scripts/전면 업데이트
.claude/agents/planner.mdres/data/*.json, docs/game/, res://data/waves/경로 업데이트
.claude/agents/leader.mddocs/tasks/, docs/changelog.json, scripts/*.sh경로 업데이트
.claude/agents/coder.mdsrc/, test/game/src/, game/test/
.claude/agents/artist.mdres/sprites/, scripts/game/res/sprites/, 스크립트 경로
.claude/agents/composer.mdres/audio/, scripts/game/res/audio/, 스크립트 경로
.claude/agents/devops.mdscripts/, tools/dashboard/스크립트 서브폴더 경로
.claude/rules/json-data.mdres://data/, res/data/game/data/, res://data/
.claude/rules/gdscript-style.mdres://data/변경 없음 (이미 res://data/)
.claude/rules/pixel-art.mdscripts/validate-asset.sh서브폴더 경로
.claude/settings.json./scripts/log-*.sh서브폴더 경로
docs/CLAUDE.mdtasks/, changelog.json구조 업데이트
src/CLAUDE.mdres/data/data/ (game/ 내부 상대경로)

4.7 대시보드 참조

파일현재변경
tools/dashboard/server/api.js:20docs/tasks/backlog.jsonops/tasks/backlog.json
tools/dashboard/CLAUDE.mddocs/tasks/backlog.jsonops/tasks/backlog.json
tools/dashboard/docusaurus.config.jsdocs 경로 ../../docs확인 필요 (상대경로 동일)

4.8 .gitattributes — 변경 없음

현재 패턴(*.png, *.ogg 등)은 확장자 기반이므로 폴더 이동에 영향 없음.

4.9 .gitignore — 업데이트 필요

현재변경
.godot/game/.godot/
기타 Godot 관련 패턴game/ 접두사 추가

5. Godot project.godot 이동 시 고려사항

5.1 res:// 경로 체계

  • Godot의 res://project.godot 위치 기준
  • project.godotgame/으로 이동하면, game/이 새로운 res:// 루트
  • game/ 내부에 src/, res/, addons/, test/, data/를 배치하므로 기존 res://src/..., res://res/... 경로 유지
  • 유일한 변경: res://res/data/res://data/ (data/ 승격)

5.2 .godot/ 캐시

  • .godot/는 Godot 에디터가 자동 생성하는 캐시 디렉토리
  • 이동 후 Godot 에디터를 game/project.godot으로 열면 game/.godot/가 자동 재생성됨
  • 기존 루트의 .godot/는 삭제 가능 (gitignore 대상)
  • 주의: .godot/imported/에 임포트 캐시가 있으나 재빌드 가능하므로 이동 불필요

5.3 에디터 실행 방법 변경

# 현재
godot --path .

# 변경 후
godot --path game/

# 또는
cd game/ && godot

5.4 GdUnit4 테스트

  • test/game/test/로 이동하므로 res://test/... 경로 유지
  • scripts/run-tests.sh에서 --path 인자를 game/으로 변경 필요

5.5 .uid 파일

  • Godot 4.x는 *.uid 파일을 사용하여 리소스 고유 ID 관리
  • git mv로 파일 이동하면 .uid 파일도 함께 이동되어 ID 유지
  • .godot/uid_cache.bin은 재생성 가능

6. 스크립트 내부 상호 참조

6.1 현재 확인된 상호 참조

# start-agents.sh → stop-agents.sh 참조
scripts/start-agents.sh:64 → ./scripts/stop-agents.sh

# log-notification.sh → slack-post.sh 참조
scripts/log-notification.sh:30 → ./scripts/slack-post.sh

6.2 해결 방안: $SCRIPTS_ROOT 변수

각 스크립트에 SCRIPTS_ROOT 변수를 도입하여 상호 참조를 유연하게 처리:

# 모든 스크립트 공통
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SCRIPTS_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
PROJECT_ROOT="$(cd "$SCRIPTS_ROOT/.." && pwd)"

# 사용 예
"$SCRIPTS_ROOT/ops/slack-post.sh" dashboard "메시지"

6.3 .claude/settings.json 훅 경로

현재 hooks에서 ./scripts/log-*.sh를 직접 참조하고 있다:

"command": "./scripts/log-tool-use.sh"
"command": "./scripts/log-notification.sh"
"command": "./scripts/log-agent-idle.sh"
"command": "./scripts/log-task-completed.sh"

변경 후:

"command": "./scripts/agent/log-tool-use.sh"
"command": "./scripts/agent/log-notification.sh"
"command": "./scripts/agent/log-agent-idle.sh"
"command": "./scripts/agent/log-task-completed.sh"

또한 inline command에서:

"command": "... ./scripts/slack-post.sh ..."

"command": "... ./scripts/ops/slack-post.sh ..."

7. Docusaurus에서 game/data/ 참조 방법

7.1 현재 상태

대시보드(tools/dashboard/)는 docs/tasks/backlog.json만 API로 서빙. 밸런스 JSON(res/data/)은 대시보드에서 직접 참조하지 않음.

7.2 옵션 비교

방법장점단점
A. Symlink단순, 즉시 반영Windows 호환성 (Git), CI 환경 주의
B. Docusaurus 플러그인빌드 시 복사, 깨끗빌드 필요, 실시간 아님
C. API 엔드포인트실시간, 유연서버 필요

7.3 권장: C. API 엔드포인트 (기존 패턴 확장)

현재 server/api.js에서 GET /api/tasksbacklog.json을 서빙하는 패턴이 이미 있다. 동일 패턴으로 확장:

// server/api.js에 추가
const DATA_DIR = path.join(PROJECT_ROOT, 'game/data');

// GET /api/data/:category — 밸런스 JSON 서빙
// 예: GET /api/data/weapons → game/data/weapons.json

Docusaurus 페이지에서 fetch('/api/data/weapons') 호출하여 밸런스 시트 표시.

7.4 문서 경로 (Docusaurus)

docusaurus.config.js의 docs 디렉토리 설정은 현재 ../../docs를 가리키며, docs/의 실제 위치는 변경 없으므로 수정 불필요.


8. 마이그레이션 단계별 순서

Phase 0: 사전 준비 (의존성 없음)

  1. 백업: git tag pre-restructure-v2 으로 현재 상태 태그
  2. 신규 디렉토리 생성: game/, ops/, ops/tasks/, ops/guides/, ops/daily/, docs/setup/, scripts/{game,agent,ops,gpu}/

Phase 1: 운영 데이터 이동 (독립적, 가장 안전)

  1. docs/tasks/ → ops/tasks/ (backlog.json)
  2. docs/changelog.json → ops/changelog.json
  3. docs/milestones.json → ops/milestones.json
  4. docs/daily/ → ops/daily/
  5. docs/ops/운영_가이드.md → ops/guides/운영_가이드.md
  6. docs/ops/운영_체크리스트.md → ops/guides/운영_체크리스트.md
  7. docs/ops/Mac_셋업.md → docs/setup/Mac_셋업.md
  8. docs/ops/Windows_셋업.md → docs/setup/Windows_셋업.md
  9. docs/ops/에이전트_셋업.md → docs/setup/에이전트_셋업.md
  10. 스크립트 경로 업데이트: update-task.sh, add-changelog.sh
  11. 대시보드 경로 업데이트: server/api.js

Phase 2: 스크립트 서브폴더 분류

  1. git mv로 각 스크립트를 서브폴더로 이동
  2. 스크립트 내부 상호 참조 수정 ($SCRIPTS_ROOT 패턴 도입)
  3. .claude/settings.json 훅 경로 업데이트
  4. 기능 테스트: update-task.sh, add-changelog.sh, slack-template.sh

Phase 3: Godot 프로젝트 → game/ (가장 큰 변경)

  1. mkdir game/
  2. git mv project.godot game/
  3. git mv addons/ game/addons/
  4. git mv src/ game/src/
  5. git mv test/ game/test/
  6. git mv res/sprites/ game/res/sprites/
  7. git mv res/audio/ game/res/audio/
  8. git mv res/tilesets/ game/res/tilesets/
  9. git mv res/ui/ game/res/ui/
  10. git mv res/assets.json game/res/assets.json
  11. git mv res/data/ game/data/ (res/ 밖으로 승격)
  12. git mv res/CLAUDE.md game/res/CLAUDE.md
  13. .godot/ 삭제 (루트의 기존 캐시)
  14. game/src/autoloads/data_manager.gdDATA_PATH 수정: "res://res/data/""res://data/"
  15. .gitignore 업데이트: .godot/game/.godot/
  16. scripts/game/run-game.sh--path game/ 추가
  17. scripts/game/run-tests.sh--path game/ 추가
  18. Godot 에디터로 game/project.godot 열어 .godot/ 재생성 확인

Phase 4: 설정 파일 업데이트

  1. .claude/CLAUDE.md — 프로젝트 구조, 경로, 도메인 전면 업데이트
  2. .claude/agents/*.md — 각 에이전트 파일 도메인 경로 업데이트
  3. .claude/rules/*.md — glob 패턴, 경로 참조 업데이트
  4. docs/CLAUDE.md — 폴더 구조 설명 업데이트
  5. game/src/CLAUDE.mdres/data/data/ 참조 수정
  6. tools/dashboard/CLAUDE.md — 데이터소스 경로 수정
  7. 서브디렉토리 CLAUDE.md 파일 (weapons, enemies, souls 등) — res/data/data/ 참조 수정

Phase 5: 검증

  1. godot --path game/ --headless --quit — 프로젝트 로드 검증
  2. ./scripts/game/run-tests.sh — GdUnit4 테스트 전체 실행
  3. ./scripts/ops/update-task.sh start "test" — 스크립트 동작 확인
  4. 대시보드: cd tools/dashboard && npm start — API 정상 응답 확인
  5. Godot 에디터에서 게임 실행 — res://data/ JSON 로딩 확인

9. 롤백 계획

9.1 즉각 롤백

git reset --hard pre-restructure-v2

모든 변경을 한 번에 되돌린다. 태그 pre-restructure-v2는 마이그레이션 시작 전 상태.

9.2 Phase별 부분 롤백

각 Phase는 독립 커밋으로 만든다:

commit: "refactor: move ops data (docs/ → ops/)"
commit: "refactor: organize scripts into subfolders"
commit: "refactor: move Godot project into game/"
commit: "chore: update all path references"

특정 Phase에서 문제 발생 시 해당 커밋만 git revert:

git revert <phase-commit-hash>

9.3 주의사항

  • git mv를 사용하여 파일 히스토리를 보존한다
  • .godot/ 캐시는 이동하지 않고 재생성한다 (롤백 시에도 재생성)
  • LFS tracked 파일(.png, .ogg 등)도 git mv로 정상 이동됨

10. 리스크 및 완화 방안

#리스크확률영향완화
1.tscn 내부 res:// 경로 누락 수정낮음높음Phase 5 검증에서 Godot 로드 테스트
2스크립트 상호 참조 누락중간중간grep -r "scripts/" 전수 검사
3대시보드 API 경로 깨짐낮음중간Phase 5 API 테스트
4에이전트 훅 경로 실패 (무음 실패)중간낮음훅은 실패해도 작업 진행 가능
5GdUnit4 플러그인 경로 문제낮음높음res://addons/ 상대 위치 유지로 완화
6LFS 파일 git mv 시 깨짐매우 낮음높음git lfs 정상 동작 확인 후 진행

11. 작업 예상 시간

Phase담당예상 시간비고
Phase 0DevOps5분태그 + mkdir
Phase 1DevOps15분파일 이동 + 스크립트 수정
Phase 2DevOps20분서브폴더 + 상호참조 수정
Phase 3DevOps + Coder30분Godot 이동 + data_manager 수정
Phase 4DevOps + Planner20분설정 파일 업데이트
Phase 5Leader (검증)15분전체 검증
합계~1.5시간

12. Phase별 커밋 메시지 (권장)

1. refactor: move ops data from docs/ to ops/ (tasks, changelog, milestones, daily)
2. refactor: organize scripts into game/agent/ops/gpu subfolders
3. refactor: move Godot project into game/ directory
4. refactor: promote res/data/ to game/data/ and update DataManager path
5. chore: update all path references in .claude/, CLAUDE.md files, and dashboard

Appendix A: 전체 grep 검색 대상 (마이그레이션 시 확인)

# 이동 후 반드시 실행하여 잔여 참조 확인
grep -rn "res/data/" --include="*.{gd,md,json,sh,js,ts,cfg}" .
grep -rn "docs/tasks/" --include="*.{gd,md,json,sh,js,ts,cfg}" .
grep -rn "docs/changelog" --include="*.{gd,md,json,sh,js,ts,cfg}" .
grep -rn "docs/milestones" --include="*.{gd,md,json,sh,js,ts,cfg}" .
grep -rn "docs/daily/" --include="*.{gd,md,json,sh,js,ts,cfg}" .
grep -rn "docs/ops/" --include="*.{gd,md,json,sh,js,ts,cfg}" .
grep -rn "./scripts/[a-z]" --include="*.{sh,json,md}" . # 서브폴더 없는 직접 참조