PetAI WBS 2.0 Unity 클라이언트·도메인
목표: 서버와 SLM 없이도 핵심 게임을 완주하고, 결과·관계·방·추억을 손실 없이 저장·복구한다.
기준: Unity 6000.5.4f1, Builder authoritative, local-first
주 책임: Unity Client
협업: Product, Content, Local AI, QA
1. 아키텍처 경계
Presentation
→ Application Use Case
→ Domain Rule / State Transition
→ Persistence Port
Content Bundle → Validator → Event Runner
Local AI → Expression Candidate → Validator → Presentation
Backend → Optional Adapter → Local Cache
- Presentation은 관계·보상·추억을 직접 수정하지 않는다.
- AI 출력은 상태 변경 명령이 아니다.
- Backend 응답은 GameState 전체를 덮어쓰지 않는다.
- scene YAML 수동 변경보다 Builder 생성 경로를 권위로 둔다.
2. 작업분해구조
| WBS |
Work package |
우선 |
선행 |
산출물 |
완료 증거 |
| 2.1.1 |
GameState schema |
P0 |
기능 범위 |
schema·invariant·migration |
round-trip unit test |
| 2.1.2 |
Atomic save |
P0 |
schema |
tmp→parse→backup→replace |
중단·손상 fixture |
| 2.1.3 |
Recovery inspect |
P0 |
persistence port |
read-only health result |
inspect write 0건 |
| 2.1.4 |
Recovery UI |
P0 |
inspect |
restore/export/fresh start |
Player 물리 입력 |
| 2.1.5 |
Migration |
P0 |
schema history |
schema 3→4+ fixture |
과거 값 무소급 |
| 2.2.1 |
Home room |
P0 |
room contract |
walk lane·anchors·sorting |
390×844 capture |
| 2.2.2 |
Input arbitration |
P0 |
home scene |
modal→UI→object→character→walk |
중복 action 0건 |
| 2.2.3 |
Character motion |
P0 |
approved placeholder |
idle/walk/turn/click |
접지·canonical idle |
| 2.2.4 |
Furniture interaction |
P0 |
anchors |
desk/shelf/window command |
art/hit rect 일치 |
| 2.3.1 |
Shared play shell |
P0 |
outcome contract |
entry/pause/complete/abandon |
genre-neutral fixture |
| 2.3.2 |
Result transaction |
P0 |
domain rules |
outcome→claim→room→memory |
atomic integration test |
| 2.3.3 |
Retry and interruption |
P0 |
shell |
retry/home/restart |
중단 시 결과 0건 |
| 2.4.1 |
Event validator |
P1 |
content schema |
duplicate/ref/condition 검사 |
malformed fixture 차단 |
| 2.4.2 |
Event runner |
P1 |
validator |
queue, priority, active step |
중단 재개 test |
| 2.4.3 |
Choice commit |
P1 |
event runner |
once-only transition |
double apply 0건 |
| 2.5.1 |
Memory store |
P0/P1 |
result/event |
create/update/delete/index |
동일 날짜 정책 test |
| 2.5.2 |
Calendar UI |
P1 |
memory store |
month/detail/empty state |
Day 0~7 snapshot |
| 2.6.1 |
Environment resolver |
P1 |
clock/weather ports |
date/period/weather/source |
offline fallback |
| 2.6.2 |
QA clock |
P1 |
resolver |
Day injection |
Production 비활성 |
| 2.7.1 |
Local AI adapter |
P1 |
AI contract |
timeout/validate/fallback |
network 0·fallback 1.5s |
| 2.8.1 |
Optional backend adapter |
P2 |
API spec |
cache/retry/signature |
local path 불간섭 |
3. 상태 불변 조건
- 실패만으로 친밀도가 감소하지 않는다.
- 같은 날짜·content·claim type은 한 번만 지급한다.
- 플레이 완료 전 중단은 결과·보상·추억을 만들지 않는다.
- 같은 날짜의 대표 추억은 정해진 merge policy를 따른다.
- 자정이 플레이 중 지나도 transaction은 시작 시점의 localDate를 사용한다.
- migration은 기존 관계와 추억을 소급 차감하지 않는다.
- 손상 파일은 사용자 동의 없이 삭제·덮어쓰기하지 않는다.
- 로드 실패 상태에서는 gameplay autosave를 중지한다.
- Builder 재생성 뒤에도 승인 scene reference가 유지되어야 한다.
4. Boot·복구 상태표
| Primary |
Backup |
화면 |
허용 action |
금지 |
| healthy |
any |
Home |
정상 플레이 |
불필요한 복구 알림 |
| corrupt |
valid |
Recovery |
restore, export, quit |
implicit overwrite |
| missing |
valid |
Recovery 또는 정책상 restore |
restore, export |
빈 save 자동 생성 |
| valid |
corrupt |
Home + 진단 |
정상 플레이 |
primary 손상 처리 |
| corrupt |
corrupt |
Recovery |
export, fresh start 2-confirm, quit |
자동 초기화 |
| future schema |
any |
Incompatible |
export, update 안내 |
downgrade write |
5. 공동 놀이 공통 contract
장르 모듈은 다음 값만 domain에 전달한다.
{
"contentId": "catalog-id",
"contentVersion": 1,
"status": "completed",
"outcome": "success",
"resultSummary": {},
"startedLocalDate": "YYYY-MM-DD"
}
공통 계층은 상태 enum과 schema를 검증한 뒤 claim·관계·공간·추억 transaction을 처리한다. 리듬게임의 BPM·판정·점수·패턴은 별도 HTMLBook에서 정의하고 adapter로 연결한다.
6. 화면별 최소 상태
| 화면 |
Loading |
Empty |
Error |
Offline |
Recovery |
| Boot |
schema inspect |
신규 save |
future/corrupt |
정상 |
전용 화면 |
| Home |
content resolve |
기본 방 |
asset fallback |
정상 |
진입 금지 |
| Dialogue |
template resolve |
fallback line |
invalid output |
template |
active step 유지 |
| Shared Play |
module load |
not available |
safe exit |
정상 |
결과 미생성 |
| Result |
transaction |
invalid result |
rollback |
정상 |
save 성공 뒤 표시 |
| Calendar |
index build |
날짜 empty |
card fallback |
정상 |
read-only 가능 |
7. 필수 자동 테스트
- save serialize/parse/round-trip
- tmp parse 실패 시 primary 불변
- primary corrupt + backup valid 복구
- both corrupt에서 implicit write 0건
- fresh start 두 번째 확인만 승인
- event duplicate/template/step/condition 오류 차단
- active event step 재개와 choice 중복 방지
- 공동 놀이 success/failure/abandon transaction
- 같은 날짜 claim 중복 방지
- 날짜·시간대·자정·timezone fixture
- canonical idle, 이동 중 frame progression, 이동 종료 frame 0
- Builder regeneration 뒤 scene·resource reference 유지
8. 실제 Player 수용 기준
- 390×844에서 홈·복구·결과·달력 UI 겹침 없음
- desk 상·중·하단과 캐릭터·바닥이 각각 한 action만 실행
- success·failure·restart persistence를 사람 입력 영상으로 증명
- both-corrupt recovery에서 원본 파일 보존
- offline·AI disabled·backend disabled 상태에서 Day 0 완주
- Profiler 기준 심각한 33ms spike와 메모리 누수 없음
9. 연결 문서
10. 2026-07-23 Unity 클라이언트 추가 범위
| WBS |
클라이언트 책임 |
상태/계약 |
수용 기준 |
| 2.10 |
튜토리얼 재개 |
단계·초기 지급 idempotency·권한 요청 시점 |
중단/재시작/계정 연결 뒤 중복 지급 없이 다음 단계 재개 |
| 2.11 |
육성·회복 상태 |
stress 0..100 등 정규화, reward multiplier 하한, 일일 감소 키 |
raw stress 공식을 저장하지 않고 밸런스 config 교체 가능 |
| 2.12 |
아이템 도감 |
acquisition source, limited window, rerun policy, owned/equipped/placed |
획득/미획득 필터와 한정·히든 표시가 저장 복원 뒤 일치 |
| 2.13 |
상점·구매 반영 |
상품 정의, 소유권, 복장/가구 반영, restore/refund hook |
중복 소유·중복 청구 없이 구매/복원/환불 상태를 구분 |
| 2.14 |
날씨·위젯·딥링크 |
last confirmed environment, widget snapshot, notification target |
위젯이 마지막 확정 방/환경과 불일치하지 않고 알림이 올바른 화면으로 이동 |
| 2.15 |
권한 fallback |
위치·알림·건강 권한 off 상태 |
수동 도시/로컬 알림 off/수면 연동 off에서도 게임 핵심 흐름 유지 |
| 2.16 |
친구 화면 |
invite, pending, accepted, blocked, snapshot visibility |
승인 전 방 노출 없음, 차단 후 모든 진입점에서 상호작용 차단 |
10.1 클라이언트 금지 규칙
- 대화 원문, 장기 기억 원문, 건강 원본을 백업·친구·위젯 payload로 내보내지 않는다.
- 위젯에서 재화·관계·구매를 직접 변경하지 않는다.
- 리듬게임의 세부 로직은 별도 명세가 승인되기 전 이 WBS의 필수 완료 조건이 아니다.