Complete persistence boundaries and free-play supply with device verification

This commit is contained in:
NINI
2026-10-05 11:30:12 +09:00
parent a651e5ca7f
commit e84eb1a35e
21 changed files with 1786 additions and 95 deletions
+24
View File
@@ -0,0 +1,24 @@
# 저장·진행·자유놀이
JSON v1은 앱 전용 `progress.json`에 확정 상태만 기록한다. 각 단계의 미완료 상태는 독립적으로 하나씩 보관하고, 최근 자유놀이는 전역 하나다. 완료 기록은 누적되며, 재도전 미완료와 같은 단계의 완료 기록이 함께 존재할 수 있다. 성공 시 완료 추가·해당 미완료 제거·최근 자유놀이 교체가 한 번의 저장 호출로 일어난다. 자동으로 다음 단계로 이동하지 않는다.
카탈로그는 현재 1·2·6·10·14다. 2번은 실제 `[1,1] → [2]` 계수 퍼즐이며 1번 완료 뒤 해금된다. 6·10·14는 정상 순차 잠금 규칙을 유지한다. 전체 30단계와 첫 시범은 후속 콘텐츠 범위다. `HasSeenTutorial` / `MarkTutorialSeen`는 `merge`·`split`만 한 번씩 저장하며, 이 단계에서 시범 자체를 추가하지 않는다.
성공한 구의 ID·위치·소속·카메라를 유지한 자유놀이에서 합체·분리·이동한다. **하나 꺼내기**는 현재 ID와 충돌하지 않는 구 하나를 기존과 같은 크기로 만든다. 화면 안에서 친구·배경과 겹치지 않는 공간을 검사하며 구 합계 10에서 추가를 거부한다. **친구 반납**은 탭한 친구의 모든 구를 반납한다. 일부만 반납하려면 먼저 분리한다. 빈 보드도 저장하고 다시 꺼낼 수 있다. 자유놀이 조작은 완료 기록을 취소하지 않는다.
확정 이동·합체·분리·계수·공급·반납, 카메라 조작 종료, 화면 이동, 일시정지에서 저장한다. 미확정 드래그와 선택·접촉 표시를 저장하지 않는다. 저장 실패는 현재 화면에 짧은 한국어 안내를 보여주고 실제 파일 오류를 개발 로그에 남긴다. 다음 저장 성공 시 안내를 비운다. 복원은 Home에서 시작하며 이전 계수나 성공 음성을 반복하지 않는다. 같은 보드의 자유놀이 조작 중에는 마지막 숫자 대기열을 보존하고 화면 이동·일시정지는 음성을 정리한다.
임시 파일을 디스크에 flush한 뒤 primary를 교체한다. 유효 primary를 backup으로 보존하며 불완전 `.tmp`는 읽지 않는다. 손상 primary는 유효 backup 전체로 복구한다. 다음 저장 전에 손상 원본을 `.damaged-*`로 복사하며, 손상 primary를 유효 backup 위에 덮어쓰지 않는다. 둘 다 손상되면 정상 초기 상태와 안내를 표시하고 원본 증거를 보존한다.
검증 명령:
```powershell
pwsh -NoProfile -File tools/verify.ps1 -Phase EditMode -Milestone Persistence
pwsh -NoProfile -File tools/verify.ps1 -Phase PlayMode -Milestone Persistence
pwsh -NoProfile -File tools/verify.ps1 -Phase AndroidBuild -Milestone Persistence
pwsh -NoProfile -File tools/verify.ps1 -Phase AndroidSmoke -Milestone Persistence
```
`artifacts/verification/Persistence/`의 XML, 실제 명령과 종료 코드, APK SHA256, AVD serial, PNG, JSON 전후 쌍과 런타임 로그가 근거다. `red/`는 잠긴 임시 파일과 저장 안내·공급 UI 부재의 실제 실패 증거다. Android 검사는 실제 터치로 1/2 양수 부분 계수를 만들고 일시정지·force-stop·재시작한다. test-only 완료 진행 fixture는 대표 6 접근에만 사용하며 부분 계수 ID·위치를 주입하지 않는다. 실제 이동한 6번 미완료, 실제 완료한 1번 자유놀이와 번갈아 전체 필드를 비교한다. 공급 10개 제한·친구 전체 반납·빈 보드 재공급·쓰기 실패·backup 전체 복구·두 파일 손상을 검사한다. 에뮬레이터 검사는 실제 모바일 하드웨어 성능 판정이 아니다.
Stage02의 `count_02`는 이미 연결된 초안 음성을 사용하며 사람 청취 승인은 별도다. 승인된 `count_01`·`guide_collect`·`guide_count` WAV를 변경하지 않는다. SFX/BGM은 [요청표](audio-requests.md)를 유지하며 사용자 요청대로 나중에 추가한다.