Files

7.7 KiB

검증과 성능 측정

독립 테스트

.NET 10 SDK를 설치하고 저장소 루트에서 실행합니다.

Tools/agentctl test

기본 dotnet 대신 특정 실행 파일을 사용하려면 PROJECTQUINT_DOTNET을 지정합니다. Windows에서는 Verification 폴더에서 다음 명령을 직접 실행할 수 있습니다.

dotnet test ProjectQuint.Tests/ProjectQuint.Tests.csproj -c Release -p:RestoreLockedMode=true

패키지 버전과 간접 의존성은 packages.lock.json으로 고정합니다. 처음 패키지를 복원할 때는 인터넷 연결이 필요하며, 복원 후에는 --no-restore를 추가할 수 있습니다. 유니티 편집 모드와 .NET은 Assets/ProjectQuint/Tests/Core의 같은 테스트 파일을 사용합니다. 홈 화면 이동·프로필 선택·업데이트 상태 테스트 역시 유니티와 독립 실행에서 공유합니다.

라이브러리 설정과 채보 준비

키 모드는 명시적인 팩 설정, 난이도표 기본값, 채보 감지값 순서로 결정합니다. SongKeyModePolicy가 이 우선순위를 소유하며 스캔, 곡 목록과 플레이용 채보 준비가 같은 규칙을 사용합니다. SongLibraryEntry.KeyMode에서 선택된 키 수와 결정 근거, 팩 설정과 난이도표 기본값의 충돌 여부를 확인할 수 있습니다. 충돌이 있으면 팩 설정을 유지하며, 인덱스·새로고침·플레이 진단 로그에 표시합니다.

DifficultyTableRequest는 등록한 제공자 ID와 HTTPS 주소를 보존합니다. HTML 페이지의 헤더 링크는 그 페이지를 기준으로, 데이터 링크는 헤더 문서를 기준으로 해석합니다. DifficultyTableLibrarySource는 로컬 난이도표·코스 로딩과 온라인 갱신을 담당합니다.

LibraryConfigurationTests는 주소·상대 경로 해석, 키 모드 충돌과 반복적인 난이도표 적용을 검증합니다. SongChartPreparationTests는 합성 BMS 파일을 실제 게임의 파서·변환기로 읽어 최종 플레이용 채보의 키 수와 레인 배치까지 확인합니다. 음악 파일은 필요하지 않습니다. 두 테스트 묶음은 독립 테스트에서 실행하지만 실제 HTTP 요청이나 유니티 캐시 직렬화를 실행하지는 않습니다. 최초 스캔·캐시 재사용·키 모드 변경 시 캐시 무효화는 유니티 SongLibraryScannerTests의 검증 범위입니다.

합성 입력 탐색

Tools/agentctl list
Tools/agentctl replay --notes 1000 --seed 42 --fps 30
Tools/agentctl replay --notes 1000 --seed 42 --fps 240

replay는 합성 노트와 미리 시각을 정한 입력 이벤트를 시간순으로 병합해 실행합니다. 같은 노트 수와 시드에서 result.judgement를 비교하면 점수·콤보·판정 수·완료 여부를 확인할 수 있습니다. 입력에는 일반 노트, 롱노트, 고의적인 미입력과 조기 놓기가 포함됩니다. 가상 시간이므로 실제 곡 길이만큼 기다리지 않으며 음악이나 외부 BMS 폴더를 읽지 않습니다.

  • --notes: 1부터 100,000까지의 노트 수입니다.
  • --seed: 0 이상의 정수입니다. 노트별 입력 시각 변화를 재현합니다.
  • --fps: 1부터 10,000까지의 가상 갱신 빈도입니다. 실제 FPS 측정값이 아닙니다.
  • --output: 결과 JSON을 저장할 경로입니다. 상대 경로는 Verification 폴더를 기준으로 합니다.

list, replay, benchmark의 표준 출력은 JSON이며 빌드 진단과 진행률은 표준 오류로 분리합니다. 잘못된 인수와 실행 실패는 0이 아닌 종료 코드를 반환합니다. 검증 도구는 Assets 바깥에 있으므로 유니티 게임 빌드에 포함되지 않습니다. 이 도구는 코어 검증용이며 전체 게임 화면을 조작하는 인터페이스는 아닙니다.

성능 측정 재현

Tools/agentctl benchmark --notes 10000 --seed 42 --fps 240 --iterations 20 \
  --output ../_workspace/core-benchmark.json

워밍업 3회 뒤 요청한 횟수만큼 실행합니다. --iterations의 허용 범위는 1부터 100입니다. 각 회차마다 진행률을 표시하고, 출력 경로를 지정하면 완료된 샘플을 중간 저장합니다. 모든 회차를 마친 결과에만 complete: true가 기록됩니다. 측정 중 중단된 결과를 최종 결과로 사용하지 않습니다.

원자료: core-baseline.json.

항목 측정 조건 또는 결과
측정일 2026-09-06
실행 환경 macOS ARM64, .NET 10.0.11, 프로세스에서 관측한 논리 프로세서 18개
입력 노트 10,000개, 입력 이벤트 18,822개, 시드 42
가상 갱신 빈도 초당 240회
반복 워밍업 3회, 본 측정 20회
엔진 생성 시간 중앙값 0.995 ms, 최솟값 0.845 ms, 최댓값 2.797 ms
전체 입력 재생 시간 중앙값 4.831 ms, 최솟값 4.675 ms, 최댓값 5.243 ms
엔진 생성 중 관리 메모리 할당 중앙값 1,544,688바이트
입력 재생 중 관리 메모리 추가 할당 20회 모두 0바이트

시간은 Stopwatch로, 할당량은 GC.GetAllocatedBytesForCurrentThread로 측정했습니다. 합성 입력 생성과 결과 JSON 직렬화는 측정 구간에서 제외합니다. 엔진 생성과 입력 재생을 나눠 기록하므로 준비 비용을 무시하지 않습니다. 각 회차의 판정 결과가 워밍업과 같은지 확인하고, 다르면 측정을 실패 처리합니다.

이는 현재 구현의 기준 측정이지 최적화 전후 비교가 아닙니다. JIT 상태와 다른 프로세스의 부하에 따라 시간은 달라질 수 있으며 절대 시간으로 테스트를 실패시키지 않습니다. 관리 메모리 측정에는 다른 스레드·네이티브 할당이 포함되지 않습니다. 화면 렌더링·오디오 출력·앱의 판정 이벤트 구독자도 실행하지 않으므로, 이 결과로 실제 게임 전체의 무할당 동작이나 입력 지연을 주장할 수 없습니다.

유니티와 실제 플레이 검증

유니티 6000.3.20f1에서 EditMode 테스트를 실행합니다. 명령줄에서는 -runTests -testPlatform EditMode -testResults <파일> -logFile <파일>을 사용하며 -quit는 함께 전달하지 않습니다. 에디터 활성화와 프로젝트 의존성 복원이 필요합니다. 외부 BMS 자료가 필요한 테스트는 별도의 환경 변수로 경로를 받습니다.

독립 검증은 실제 FMOD 출력, 장치 전환, 화면 조작과 파일 선택 창을 검증하지 않습니다. 음악을 재배포하지 않는 범위에서 실제 플레이로 로딩 취소·다시 시작·장치 변경·프로필 화면을 확인해야 합니다. 자동화 서버에서의 연속 실행과 실제 플레이어 성능 측정은 별도 운영 범위입니다.

2026-09-06 검증에서는 독립 테스트 166개와 배포 도구 테스트 9개가 통과했습니다. 유니티 컴파일러를 이용한 어셈블리 11개의 컴파일도 확인했습니다. 유니티 Test Runner의 편집 모드 테스트는 891개 중 887개가 통과했고 실패는 없었습니다. 외부 BMS 자료가 필요한 통합 테스트 4개는 자료가 없어 건너뛰었습니다. 최초 스캔·캐시 재사용 시 명시적인 키 모드 보존과 키 모드 변경 시 캐시 무효화 테스트도 통과했습니다. 실제 화면·입력·오디오를 함께 확인하는 플레이 검증은 별도로 수행해야 합니다.

앱의 업데이트와 프로필 상태는 독립 컨트롤러가 소유하지만, 팩 관리·오디오 설정·화면 연결을 조정하는 코드는 아직 큰 앱 클래스에 남아 있습니다. 추가 분리 시에는 관련 동작 테스트를 확보하고 같은 검증 절차를 반복합니다.