Files
ProjectQuint/README.md
T

117 lines
6.8 KiB
Markdown

# ProjectQuint
유니티와 C#으로 만든 macOS 중심의 BMS 리듬 게임 클라이언트입니다.
4·5·6·7키와 왼쪽 스크래치를 지원하며, 사용자가 등록한 외부 BMS 폴더나 ZIP 파일을 읽습니다.
[프로젝트 사이트](https://projectquint.duckdns.org/)에서 사용 안내와 배포 정보를 확인할 수 있습니다.
## 독립 테스트 실행
[.NET 10 SDK](https://learn.microsoft.com/en-us/dotnet/core/install/)가 있으면 유니티를 설치하지 않고
판정·타이밍·파서와 주요 화면 상태 테스트를 실행할 수 있습니다.
macOS와 Linux에서는 저장소 루트에서 다음 명령을 실행합니다.
```bash
Tools/agentctl test
Tools/agentctl replay --notes 1000 --seed 42 --fps 30
Tools/agentctl replay --notes 1000 --seed 42 --fps 240
```
재생 검증에는 생성한 노트와 입력 이벤트만 사용하며 음악 파일이나 외부 채보를 읽지 않습니다.
두 재생 결과의 `result.judgement`는 같아야 합니다. `--fps`는 가상 프레임 갱신 간격이며
실제 게임의 초당 프레임 수를 측정하는 옵션은 아닙니다.
`Verification/`의 프로젝트는 실제 게임 소스와 테스트 파일을 직접 컴파일합니다.
검증용으로 별도의 판정 엔진을 구현하거나 유니티 API를 모방하지 않습니다.
첫 실행에는 테스트 패키지를 복원할 인터넷 연결이 필요합니다.
## 주요 기능과 구성
- **판정과 타이밍**: 렌더링 프레임과 분리한 판정 엔진, BPM·STOP을 처리하는 시간 변환,
롱노트 판정 정책을 순수 C#으로 구현했습니다.
- **입력과 오디오**: 입력 이벤트 시각과 DSP 시각을 사용하며, 키음 재생·프리믹스 캐시·동기화 보정을 분리했습니다.
- **라이브러리와 저장**: 팩별 곡 목록, 난이도표 연결, 검색과 정렬, 플레이 결과·프로필 저장을 관리합니다.
- **화면 구성**: UI Toolkit 화면과 프레젠터를 사용해 화면 표시와 세션 상태를 나눴습니다.
## 설계
### 프레임 갱신 빈도와 판정 결과 분리
입력을 처리한 프레임의 시각으로 판정하면 프레임 지연이 점수에 영향을 줄 수 있습니다.
`RhythmJudgementEngine`은 전달받은 곡 시각으로 판정하고,
`TempoMap`과 `ScrollMap`은 음악의 시간 변환과 화면 위치 계산을 나눠 담당합니다.
[판정 테스트](Assets/ProjectQuint/Tests/Core/RhythmJudgementTests.cs)와
[합성 입력 재생](Verification/ProjectQuint.Tests/CoreReplayTests.cs)에서 서로 다른 갱신 간격의 결과를 비교합니다.
### 비동기 작업의 수명과 화면 상태 분리
곡 교체는 준비한 리소스를 한 묶음으로 넘기고, 취소된 후보는 해제합니다.
업데이트 알림은 `UpdateSessionController`가 요청 세대와 화면 상태를 관리합니다.
취소된 요청의 늦은 응답은 무시하며, 게임 중에는 알림을 표시하지 않습니다.
[업데이트 상태 테스트](Assets/ProjectQuint/Tests/EditMode/UpdateSessionControllerTests.cs)는
중복 요청·취소 후 재요청·표시 가능한 화면·같은 응답의 중복 전달을 검증합니다.
### 입력 장치와 프로필 화면 상태 분리
`ProfileSessionController`가 탭, 난이도표별 레이팅, 수집 기록과 배지의 선택 상태를 소유합니다.
키보드와 UI 이벤트는 같은 상태 변경 메서드를 호출합니다.
표시할 데이터가 줄거나 비어도 선택 인덱스가 유효하도록
[프로필 상태 테스트](Assets/ProjectQuint/Tests/EditMode/ProfileSessionControllerTests.cs)에서 확인합니다.
## 측정 결과
합성 노트 10,000개와 입력 이벤트 18,822개를 사용하는 판정 코어 측정에서,
전체 입력 재생 시간의 중앙값은 **4.831 ms**였습니다.
엔진 생성은 별도로 측정했으며 중앙값은 **0.995 ms**였습니다.
이 입력 재생 구간에서 현재 스레드의 관리 메모리 추가 할당은 20회 모두 0바이트였습니다.
이 값은 macOS ARM64·.NET 10 환경에서 측정한 코어의 기준값입니다.
유니티 플레이어의 프레임 시간, 실제 입력·오디오 지연, FMOD 메모리 사용량을 뜻하지 않습니다.
[측정 조건·원자료·재현 방법](docs/verification.md)을 함께 확인할 수 있습니다.
## 주요 경로
| 경로 | 역할 |
| --- | --- |
| `Assets/ProjectQuint/Runtime/Core` | 채보 파싱, 타이밍, 판정, 게이지와 성장 계산 |
| `Assets/ProjectQuint/Runtime/Unity/Features` | 앱 흐름과 게임플레이·라이브러리 세션 |
| `Assets/ProjectQuint/Runtime/Unity/Audio` | 오디오 백엔드와 재생·캐시 |
| `Assets/ProjectQuint/Runtime/Unity/Persistence` | 플레이 결과와 프로필 저장 |
| `Assets/ProjectQuint/Runtime/Unity/UI` | 화면 프레젠터와 UI 리소스 |
| `Assets/ProjectQuint/Tests/Core` | 유니티와 .NET에서 공유하는 코어 테스트 |
| `Assets/ProjectQuint/Tests/EditMode` | 앱 상태·유니티 통합 테스트 |
| `Verification` | 독립 테스트 실행과 합성 입력·성능 측정 도구 |
| `Tools` | 빌드·배포 도구와 테스트 |
| `Website/projectquint-site` | 프로젝트 소개 사이트 |
## 프로젝트 열기
1. Unity Hub에서 유니티 `6000.3.20f1`을 설치합니다.
2. 이 저장소의 루트 폴더를 프로젝트로 등록합니다.
3. 패키지 복원과 에셋 임포트가 끝난 뒤 프로젝트를 엽니다.
유니티 에디터 활성화가 필요합니다. FMOD 패키지 접근과 사용 조건은 해당 공급자의 안내를 따릅니다.
BMS 음악과 채보는 포함되어 있지 않으므로, 플레이할 콘텐츠는 별도로 등록해야 합니다.
## 검증
독립 검증의 실행 방법과 검증 범위는 [검증 안내](docs/verification.md)에 정리되어 있습니다.
독립 테스트 통과만으로 유니티 화면·오디오·네이티브 연동이 검증되었다고 보지 않습니다.
유니티 Test Runner에서 `EditMode` 테스트를 실행합니다. 명령줄 실행 시에는
`-runTests -testPlatform EditMode -testResults <결과 파일> -logFile <로그 파일>`을 사용하고,
테스트 시작 전에 종료되지 않도록 `-quit`는 함께 전달하지 않습니다.
일부 통합 테스트는 별도로 등록한 외부 BMS 자료가 있어야 실행됩니다.
배포 도구의 테스트는 프로젝트 루트에서 실행합니다.
```bash
python3 -m unittest discover -s Tools/tests -v
```
## 콘텐츠와 라이선스
이 저장소는 ProjectQuint의 게임 소스, 테스트, 빌드·배포 도구를 관리합니다.
BMS 음악과 채보는 배포물에 포함하지 않으며, 사용자가 별도의 라이브러리로 등록합니다.
서드파티 구성 요소의 고지와 라이선스는 `ThirdParty/`에 보존되어 있습니다.