10 KiB
10 KiB
Agent: Arena Picker
0. 필수
- 작업이 완료되면 작업에 관련된 모든 문서를 업데이트한다
1. 프로젝트 정의
Arena Picker는 Phaser 3 게임 엔진과 Vite 번들러를 기반으로 구축된 대규모 팀 전투 시뮬레이션 웹 애플리케이션입니다. 사용자가 입력한 여러 명의 참가자(닉네임)를 바탕으로 각 참가자를 하나의 팀으로 설정하고, 지정된 인원만큼의 캐릭터를 생성하여 자동 전투를 시뮬레이션합니다.
서버 런타임은 Fastify를 사용하며, MongoDB 커넥션 풀을 유지해 유니크 방문자 수와 전투 사망 통계를 기록하는 간단한 통계 API를 제공합니다.
2. 프로젝트 전체 구조 (Directory Tree)
├── index.html # 메인 HTML 진입점 및 UI 레이아웃
├── package.json # 프로젝트 의존성 및 스크립트 정의 (Phaser, Vite, Fastify, MongoDB)
├── config.json # 로컬 서버/MongoDB 설정 (git ignore)
├── config.json.sample # 공유용 서버/MongoDB 설정 예시
├── agent.md # 프로젝트 개요 및 기능 정의 (본 문서)
├── CONTEXT.md # 상세 개발 가이드 및 로직 설명
├── todo.md # 작업 내역 및 잔여 이슈 관리
├── server/ # Fastify API 서버 및 MongoDB 연결 관리
│ ├── index.js # Fastify 서버 진입점, Vite 개발 미들웨어, 정적 배포 서빙
│ ├── config.js # config.json 로드 및 MongoDB URI 조립
│ ├── db.js # MongoClient 커넥션 풀 생성/재사용/종료
│ ├── deathStats.js # 전투 종료 시 오늘 일자별 종족 사망 통계 누적 API
│ └── visitors.js # 유니크 방문자 체크 및 통계 API
├── public/ # 정적 리소스 (게임 에셋)
│ └── assets/
│ └── characters/ # 20종 이상의 캐릭터 스킨 및 투사체 에셋
│ ├── archer/, armored-axeman/, armored-orc/, ... (중략)
│ └── wizard/ # 각 폴더 내 애니메이션 시트 및 이펙트 포함
└── src/ # 소스 코드 root
├── main.js # Phaser 게임 인스턴스 생성, 옵션 drawer/재시작/일시정지 UI 제어
├── constants.js # 전역 물리/UI 상수 통합 관리 (공격력, 체력, 줌, 카메라 속도 등)
├── styles.css # UI 스타일링 (인트로, 옵션 drawer, 좌측 HUD 레일, 좌측 하단 킬로그, 상단 전투 안내바)
├── game/ # 게임 로직 모듈
│ ├── ArenaScene.js # 핵심 게임 씬 (카메라 추적, 승리 판정, pause, 사망 통계, 좌측 HUD badge/킬로그 제어)
│ ├── arenaRenderer.js# 경기장 바닥 및 격자 렌더링
│ ├── combat.js # 전투 AI 및 피격 판정 로직
│ ├── combatSettings.js# 전투 속도 및 이동 배율 관리
│ ├── fighterAssets.js# 스프라이트 시트 로드, 애니메이션 및 팀 색상 실루엣 마스크 생성
│ ├── fighterFactory.js# 캐릭터 객체, 히트박스, HUD, 개별 체력, 사망자 HUD 숨김 및 팀 색상 마커 동기화
│ ├── fighterManifest.js# 캐릭터 스킨/종족/전투/스탯/특성 데이터 정의 (20종 캐릭터 상세 설정)
│ ├── fighterSelection.js# 무작위 캐릭터 스킨 선택 로직
│ └── matchSetup.js # 닉네임 기반 팀 구성 및 스폰 좌표 계산
└── ui/
├── matchForm.js # 참가자 입력 폼, 팀 설정 UI 제어 및 localStorage 설정 유지
├── deathStats.js # 전투 사망 통계 API 호출
└── visitorCounter.js# 방문자 체크 API 호출 및 UI 갱신
3. 핵심 기능
- 닉네임 기반 팀 스폰: 입력된 각 닉네임을 독립된 팀으로 인식하고, 설정된 인원(1~100명)만큼 분신 캐릭터를 소환합니다. 리스폰 설정은 참가자별 전장 구역 안에서 시작하되 참가자별 시작 구역 배정도 매치마다 섞는
스타팅 지점 배치와 전장 전체에서 섞이는완전 랜덤 배치를 지원합니다. 캐릭터 특성에 따라 실제 출전 수가 달라질 수 있으며, Slime은 배정된 기본 스폰 슬롯마다 10마리로 확장됩니다. - 전투 진입 및 제어 UI: 최초 접속 화면은 로컬 저장 옵션과 분리된 10팀 x 팀당 5명 전투 프리뷰를 배경으로
Arena로고와Start버튼을 표시합니다.Start를 누르면 우측 옵션 drawer가 열리고, 홈에서 drawer가 열린 동안Start버튼은 숨기되Arena로고 위치는 유지합니다. 전투 시작 후에도 drawer는 compact 패널로 유지됩니다. 패널 우측 상단의옵션 접기/옵션 펼치기버튼으로 전장 시야를 확보할 수 있으며, 패널 안에서재시작과일시정지/계속을 제어합니다. - 전투 설정 유지: 참가자 닉네임, 숫자 입력과 슬라이더가 동기화되는 팀당 인원, 리스폰 배치 모드는 브라우저
localStorage에 저장되어 새로고침하거나 다시 접속해도 입력값이 유지됩니다. - 지능형 카메라 시스템:
- 자동 전투 관전: 화면 확대 시 인접한 교전 중인 캐릭터 쌍을 찾아 부드럽게 추적(Lerp)합니다.
- 미니맵 연동: 줌 인 상태에서 전장 전체 상황과 현재 뷰포트 위치를 미니맵에 가이드라인으로 표시합니다.
- 최종교전 연출: 생존 4명 이하에서는 카메라가 생존 캐릭터를 무작위로 전환 포커싱하고, 잔여 2팀의 생존 합이 8명 이하이면 생존 수가 더 적은 팀을 포커싱합니다.
FINAL_COMBAT_SLOW_MOTION_ENABLED를 켜면 이 최종교전 구간의 공격 시작에 진입/유지/복귀 완급이 있는 슬로우모션을 적용합니다.
- 역동적인 전투 연출:
- 캐릭터별 고유 공격 방식(근접, 투사체, 마법) 및 애니메이션.
ATTACK_DAMAGE_MIN/MAX로 기본 공격력 범위를 관리하고, 치명타(Critical) 적중 시Critical!문구를 띄우며 즉시 처치 및 화면 흔들림 효과를 적용합니다.- 상대를 처치한 캐릭터는 체력을 현재 체력 기준 30% 회복하고, 처치 누적 배율에 따라 크기, 공격속도, 이동속도가 함께 상승합니다. 누적 보상은
KILL_GROWTH_MAX_MULTIPLIER상한으로 제한해 캐릭터가 필드/히트박스를 벗어나 전투가 끝나지 않는 상황을 방지합니다. - 캐릭터별 종족(
human,orc,skeleton,slime,wolf,bear)과 스탯/특성을fighterManifest.js에서 정의할 수 있습니다. Slime은 최대 체력 1이며, 사망 시 50% 확률로 최대 체력 1인 Slime 2마리로 분열합니다. 분열체는 다시 분열하지 않습니다. - 사망한 캐릭터는 반투명하게 표시하고 살아있는 캐릭터보다 낮은 depth로 내려, 움직이는 전투원을 가리지 않도록 유지합니다.
- 상시 팀 색상 표시 및 선택 관전: 생존 캐릭터는 항상 팀 색상 실루엣 마커를 표시합니다. 캐릭터를 클릭하면 해당 캐릭터에 카메라가 고정되며, 팀 색상 마커는 선택 여부와 관계없이 유지됩니다. 좌측 팀 badge를 클릭하면 해당 팀의 생존 캐릭터 중 무작위 1명으로 시점이 고정됩니다.
- 실시간 경기 중계 UI: 팀 badge는 경기장 밖 좌측 HUD 레일에 고정되어 미니맵을 가리지 않습니다. 각 badge는 팀명, 구분선, 현재 생존 인원 순서로 표시되며, 클릭 가능한 관전 진입점으로 동작합니다. 전투 중 하단 안내바는 숨기고, 좌측 하단 킬로그에 처치자와 피처치자를 좌우로 나눠 작은 캐릭터 이미지, 팀명,
manifest.key, 칼 아이콘,처치표시를 목록으로 보여줍니다. 피처치자 아이콘에는 빨간 X를 겹쳐 사망 대상을 빠르게 구분합니다. 실제 전투가 5초 이상 지속되면 작은 상단 안내바에 오늘의 종족별 사망 집계를 2초 표시하고 10초 쉬는 주기로 재치 있게 보여줍니다. 승리 시 금빛 축하 배너와 컨페티, 짧은 팡파르로 결과를 알리고 무승부는 절제된 배너로 표시합니다. - 유니크 방문자 체크: 접속 시
POST /api/visitors/check를 호출하고, 서버가HttpOnly쿠키 기반 UUID로 MongoDB에 방문자 1명당 1개 문서를 유지합니다. 방문자 수는 메인 화면이 아니라 실제 전투 화면의 우측 하단에 작은 배지로 표시합니다. - 전투 사망 통계: 실제 전투에서 사망한 캐릭터를 종족별로 누적하고, 전투 종료 시
POST /api/death-stats/today로 오늘 일자별 집계 문서에 카운트를 더합니다. 별도의 매치별 사망 통계 문서는 저장하지 않습니다.
4. 기술 사양
- Framework: Phaser 3.90.0 (Arcade Physics 기반)
- Build Tool: Vite 7.1.12
- Server: Fastify 5.x (
@fastify/static,@fastify/middie) - Database: MongoDB 7.x Node Driver
- UI Logic: Vanilla JS & CSS (Flexbox/Grid 활용)
5. 서버/API 설정
- 개발/운영 서버는
npm run dev또는npm start로 실행하며 기본 포트는config.json의SERVER_PORT값인9736입니다. config.json은 로컬 설정 파일이므로 저장소에 커밋하지 않습니다. 새 환경에서는config.json.sample을 복사해 사용합니다.- 기본 API:
GET /api/health: 서버 및 MongoDB 설정 여부 확인.POST /api/visitors/check: 현재 브라우저 방문자를 체크하고 유니크 방문자 수를 반환.GET /api/visitors/stats: 전체 유니크 방문자 수 조회.GET /api/death-stats/today: 오늘의 종족별 전투 사망 통계 조회.POST /api/death-stats/today: 종료된 전투의 종족별 사망 수를 오늘 집계에 누적.
6. 관련 문서
- CONTEXT.md: 상세 개발 가이드 및 핵심 로직 설명 (필독)
- todo.md: 작업 내역 및 잔여 이슈 관리