--- from: 개발팀장 to: PM date: 2026-04-17 type: 보고서(초안) status: 진행중 tags: [서버역할정리, 인간개발자지시서, 클라서버경계, PlayFab, 수상한잡화점] related: [C11, C29, C30, P13, P18, P23] depends_on: [PD-#2, PD-#5-B] --- # 인간 서버 개발자 업무 지시서 초안 — 서버 역할 정리 > **목적**: 인간 서버 개발자가 읽고 바로 작업 착수 가능한 **서버 역할 범위·데이터 카테고리·클라/서버 처리 경계 정의서** 초안. 최종 결정은 PD님 몫이며 본 문서는 **초안 + PD 결정 안건** 제시. > > **작성 방법 주석 (C23 정직성)**: 본 세션에서 `Task` 도구로 서버팀장·클라이언트팀장 서브에이전트 호출이 환경 제약으로 불가하여, 개발팀장이 **양쪽 관점을 명시적으로 구분해 단독 분석**. 섹션마다 `[서버 관점]`·`[클라 관점]` 태그로 구분. 서버팀장의 사전 업무공유체계 점검 보고(`공유/소통/개발팀→PM/2026-04-17_업무공유체계_점검_서버팀.md`)는 참조함. --- ## 0. 전제·근거 자료 ### 0-1. PD님 가이드라인 (본 초안의 기본 원칙, 반드시 반영) 1. **재화 사용 시 항상 서버 응답 필수** — 클라 단독 처리 금지 2. **미션 클리어 판단은 클라 재량**. 단 **보상 지급 주체(서버 vs 클라)는 결정 필요**. **보상이 재화 형태가 아니면 서버 처리 어려움** 전제 3. **랭킹 등록은 클라 정보를 서버가 그대로 저장** — 서버는 검증·계산 없이 저장만. **재화 아닌 랭킹 보상은 서버 처리 불가** 전제 ### 0-2. 현 수상한잡화점 실측 결과 | 항목 | 실측 내용 | |------|----------| | **서버 스택** | **PlayFab** (Title API + CloudScript + Leaderboard + Profiles + Mail) | | **인증** | `LoginWithCustomID` (기기 기반 익명 ID) | | **저장 방식** | **하이브리드** — `CryptoUtil.Save`로 **로컬 파일 저장이 1차 소스**, PlayFab CloudScript는 핵심 이벤트만 (로그인 토큰·치트·인게임 시작·가이드 퀘스트·우편) | | **AntiCheat** | `CodeStage.AntiCheat.ObscuredTypes` (ObscuredInt/Long, RandomizeCryptoKey) — **로컬 변조 방어 목적**, 서버 검증은 아님 | | **CloudScript 함수 (현행)** | `ServerSave_LoginToken`, `Get_UserInfo`, `Save_CheatItem`, `Save_IngameStart`, `Save_GuideQuest`, `Get_MailList`, `Get_MailReward`, `Get_AllMail`, `Get_OtherUserInfo`, `Del_TitlePlayer` | | **CloudScript 주석처리 (미구현)** | `Save_StageResult` — 스테이지 완료 시 서버 저장. 현재 비활성 | | **랭킹** | `PlayFabProgressionAPI.GetLeaderboard` / `GetLeaderboardAroundEntity` 사용 중 (단, 등록 경로는 소스에서 미확인 — 추가 분석 필요) | | **인앱 결제** | `InappInfo.cs` **전체 주석처리 상태** (현재 비활성). 재활성 시 `ValidateGooglePlayPurchase` 등 PlayFab 검증 경로 복원 필요 | | **주요 저장 데이터 (`ServerData` 클래스)** | StageData, dic_PC, dic_PC_Awakening, Seal(인장), Equipment, dic_Item(재화/소비), dic_Card, EquipmentTrade, CatGoodsShop, Mission(일일/주간), set_PurchasedPCIDs, show_Scenarios, 출석(RewardAttandanceDay), 고양이 레벨(CatLv/CatExp) | ### 0-3. 미파악·추가 분석 필요 영역 (C23 정직성) - **메타 시스템 SOT 미작성** — 세이브·상점·성장·시즌패스의 공식 설계 문서 부재 (PD #5-B Phase 0-C 미착수) - **랭킹 등록 경로** — `GetLeaderboard` 읽기는 있으나 `UpdatePlayerStatistics`나 CloudScript 등록 호출처가 소스 검색으로 확인 안 됨 - **PlayFab 계속 사용 여부** — PD님 결정 필요 (자체 서버 전환 가능성). 본 초안은 **PlayFab 유지 + CloudScript 확장** 전제로 작성 --- ## A. 서버 관리 데이터 카테고리 (서버 SOT 후보) > **범례**: `[확정]` 현 코드 존재 + 재화성 데이터 / `[추가분석]` 현 코드에 있으나 서버 SOT 전환 검토 필요 / `[신규]` 새로 정의 필요 ### A-1. 재화·자산 `[확정]` — 서버 SOT 필수 (PD 가이드 1) | 도메인 | 필드 예시 | 비고 | |-------|---------|------| | **재화 인벤토리** | `dic_Item[itemid] = amount` (Dictionary) — Gold·Soul·DailyMissionPoint·WeeklyMissionPoint 등 | 사용 시 항상 서버 응답 필수 | | **PC(캐릭터) 보유** | `dic_PC[pcid]` — 레벨·경험치·각성 | 재화로 육성되므로 서버 SOT | | **장비** | `Equipment` (SD_Equipment) + `EquipmentTrade` | 장비 획득·강화·거래 | | **카드** | `dic_Card[cardid]` (SD_Card) | 카드 수집·업그레이드 | | **구매 PC ID 세트** | `set_PurchasedPCIDs` (HashSet) | 현금·패키지 구매 대상 → 결제 검증 후 서버 저장 | ### A-2. 진행도·달성 `[확정]` | 도메인 | 필드 예시 | 비고 | |-------|---------|------| | **스테이지 진행** | `StageData.dic_stagedata[diff].dic_ChapterData[chapter].list_StageData[].Star` | 난이도·챕터·스테이지별 별 수 | | **최고 도달 스테이지** | `Get_ClearMaxStageDatas()` 계산값 | 서버 저장 SOT (현재 로컬 계산) | | **고양이 레벨** | `CatLv`, `CatExp`, `L_CatLvTime` | 메타 성장 지표 | | **시나리오 시청 기록** | `show_Scenarios` (HashSet) | UX — 서버 저장 권장 (기기 변경 시 재시청 방지) | | **미션 진행** | `Mission.dic_Mission[type]` — 일일/주간 카운트·보상 수령 여부 | 보상이 재화이므로 서버 SOT | | **출석** | `RewardAttandanceDay`, `AttandanceDayOfYear` | 보상이 재화이므로 서버 SOT | ### A-3. 랭킹 `[추가분석]` (PD 가이드 3) | 도메인 | 현 구현 | 필요 조치 | |-------|--------|----------| | **리더보드 읽기** | `PlayFabProgressionAPI.GetLeaderboard` 사용 중 | 유지 | | **리더보드 등록** | 호출처 **미확인** (소스 검색 0건) | **인간 개발자가 기존 등록 경로 재구축 or 신규 설계**. PD 가이드 3에 따라 "클라 정보 그대로 저장" 방식 | | **리더보드 종류** | 현재 함수는 `leaderboard` 문자열 파라미터로 동적 | **리더보드 명세 SOT 필요** — 어떤 랭킹 존재? (스테이지 클리어타임? 최고 도달 스테이지? 고양이 레벨?) 기획팀 정의 필요 | | **랭킹 보상** | **현재 없음** | PD 가이드 3 — **재화 보상만 서버 처리 가능**. 비재화(칭호·스킨 등) 시 PD 결정 필요 | ### A-4. 세이브 동기화 `[추가분석]` — **가장 중요한 결정 안건** 현 구조는 **로컬 1차 + 클라우드 보조** 하이브리드. 이를 어디까지 서버 SOT화 할지가 핵심 결정: | 데이터 종류 | 현재 | 권장 방향 | 근거 | |-----------|------|----------|------| | 재화·PC·장비·카드 | 로컬 저장 (ObscuredType 난독화) | **서버 SOT** | PD 가이드 1 "재화 사용 항상 서버 응답" | | 스테이지 진행·별 수 | 로컬 저장 | **서버 SOT** (보상 지급 연결) | PD 가이드 2 보상 연결 | | 시나리오 시청 기록 | 로컬 저장 | **서버 저장** (기기 변경 복원) | UX | | UI 옵션·사운드 볼륨 | 로컬 저장 | **로컬 유지** | 서버 저장 불필요 | ### A-5. 우편 `[확정]` - 현 구현: `Get_MailList`, `Get_MailReward`, `Get_AllMail` CloudScript 존재 - 서버 SOT. 재화 보상 우편 → 서버가 수령 처리 + 인벤토리 반영 응답 ### A-6. 시즌·패스 `[신규]` (메타 시스템 — 추가 분석 필요) - **현 SOT 부재**. 기획팀 메타 시스템 SOT 착수 후 구체화 - 예상 필드: 현 시즌 ID, 시즌 진행 XP, 패스 보유 여부, 단계별 보상 수령 상태 - 시즌 리셋·크로스 시즌 이월은 서버 주도 결정 ### A-7. 상점 `[신규]` (메타 시스템 — 추가 분석 필요) - `CatGoodsShop`(`SD_CatGoodsShop`), `EquipmentTrade`(`SD_EquipmentTrade`) 로컬 구조 존재. **일일 리셋 로직 클라에 있음** (`CheckDailyReset`) - **이슈**: 상점 일일 리셋을 **클라 시간 기반**으로 하면 기기 시간 조작 취약. **서버 시간 기반 리셋 필요** - 현금 상점(패키지·현금 PC 구매)은 A-1의 `set_PurchasedPCIDs`와 연결 ### A-8. 소셜·기타 `[확정 일부]` - **닉네임**: `UpdateUserTitleDisplayName` (PlayFab) — 서버 SOT - **타 유저 정보 조회**: `Get_OtherUserInfo` (CloudScript) — 서버 SOT - **계정 탈퇴**: `Del_TitlePlayer` — 서버 SOT --- ## B. 클라/서버 처리 경계 매트릭스 > **적용 원칙**: PD 가이드 3종을 각 액션에 기계적 적용. 통신 시점·주체·검증 책임 명시. ### B-1. 재화 관련 액션 (PD 가이드 1 적용 — 서버 응답 필수) | 액션 | 클라 역할 | 서버 역할 | 통신 시점 | 비고 | |------|---------|----------|----------|------| | 재화 사용 (예: 카드 업그레이드에 Soul 소비) | 사용 요청 전송 | **잔고 검증·차감·응답** | 요청 즉시 | 서버 거부 시 클라 롤백 | | 재화 획득 (드롭·보상) | 획득 이벤트 통지 | **지급 검증·적립·응답** | 이벤트 발생 즉시 | 스테이지 완료 번들로 묶어 1회 호출 가능 | | 재화 잔고 조회 | UI 표시 | SOT 제공 | 로그인·주요 화면 진입 | 서버 잔고가 정답. 클라 캐시 임시 | | 재화 구매 (현금) | 구매 플로우 실행 | **영수증 검증**(`ValidateGooglePlayPurchase`)·지급 | 영수증 수신 즉시 | InAppInfo 재활성화 필요 | ### B-2. 미션·퀘스트 (PD 가이드 2 적용 — 클라 판단 + 보상 지급 주체 결정 필요) | 액션 | 클라 역할 | 서버 역할 | 통신 시점 | 비고 | |------|---------|----------|----------|------| | 미션 조건 체크 (예: 3회 출석) | **클라 자체 판단** | — | — | 클라가 카운트 누적·달성 판정 | | 미션 완료 통지 | 완료 신호 전송 | 달성 기록 저장 | 완료 즉시 | 단순 기록 | | **미션 보상 (재화)** | 수령 요청 | **지급·응답** | 요청 즉시 | B-1 "재화 획득"과 동일 | | **미션 보상 (비재화)** | **클라 단독 지급** (PC·카드·장비) | 지급 결과만 사후 기록 | 지급 후 통지 | **안건 PD-①** 참조 | ### B-3. 스테이지 진행 (혼합) | 액션 | 클라 역할 | 서버 역할 | 통신 시점 | 비고 | |------|---------|----------|----------|------| | 인게임 시작 | 선택한 맵 전송 | **세션 등록** (`Save_IngameStart` 현 구현) | 전투 시작 시 | 중복 진입 차단·서버 시간 기준 확보 | | 인게임 플레이 | 전 로직 클라 주도 | 개입 없음 | — | 실시간 통신 없음 | | 스테이지 완료 | 결과 전송 (별 수·드롭 아이템·클리어 시간) | **재화 지급 + 진행도 갱신** | 완료 즉시 | `Save_StageResult` 복원·신규 설계 필요 | | 별 보상 수령 (비재화) | 클라 단독 | — | — | B-2 비재화 보상과 동일 | ### B-4. 랭킹 (PD 가이드 3 적용) | 액션 | 클라 역할 | 서버 역할 | 통신 시점 | 비고 | |------|---------|----------|----------|------| | 랭킹 등록 | 점수·메타정보 계산·전송 | **검증 없이 그대로 저장** | 스테이지 완료·시즌 갱신 시 | PD 가이드 3 | | 내 랭킹 조회 | 요청 | `GetLeaderboardAroundEntity` 응답 | 랭킹 UI 진입 | 현 구현 있음 | | 상위 랭킹 조회 | 요청 | `GetLeaderboard` 응답 | 랭킹 UI 진입 | 현 구현 있음 | | **랭킹 보상 (재화)** | 수령 요청 | **지급·응답** | 시즌 종료 시 | B-1과 동일 | | **랭킹 보상 (비재화)** | ? | **서버 처리 불가** | ? | **안건 PD-②** 참조 | ### B-5. 세이브·메타 | 액션 | 클라 역할 | 서버 역할 | 통신 시점 | 비고 | |------|---------|----------|----------|------| | 로그인·최초 데이터 로드 | 요청 | 전체 데이터 응답 | 앱 실행 시 | 현 `Get_UserInfo` 구조 확장 | | 주기 세이브 | 변경분 전송 | 저장 | 주요 결정 직후 (결제·전투 완료·재화 변동) | 빈도 최소화, 이벤트 기반 | | 기기 변경 복원 | 로그인 ID 전송 | 동일 계정 데이터 응답 | 신규 기기 로그인 시 | 계정 연결 정책 별도 필요 | | 일일/주간 리셋 | 리셋 UI 표시 | **서버 시간 기반 판정·리셋 응답** | 로그인·일일 최초 접속 | 현재 클라 `DayOfYear` 비교는 취약 | | 시나리오 시청 기록 | 시청 후 통지 | 기록 저장 | 시청 직후 | 기기 변경 시 복원 | ### B-6. 우편·소셜 | 액션 | 클라 역할 | 서버 역할 | 통신 시점 | 비고 | |------|---------|----------|----------|------| | 우편 조회 | 요청 | 목록 응답 | 우편함 진입 | 현 구현 있음 | | 우편 수령 (재화 포함) | 수령 요청 | **지급·인벤토리 반영·응답** | 요청 즉시 | 현 구현 있음 | | 닉네임 변경 | 입력값 전송 | 중복 검사·저장 | 변경 시 | 현 구현 있음 | --- ## C. 의사결정 필요 항목 (PD님 안건) ### PD-① 미션·스테이지·업적 보상 지급 주체 (PD 가이드 2 연장) **안건**: 비재화 보상(장비·카드·캐릭터 등)의 지급 주체를 어떻게 할 것인가? **현 실측 제약**: - `dic_PC`·`dic_Card`·`Equipment` 등 비재화 자산도 **현재 ServerData 로컬 SOT에 포함** - PlayFab CloudScript는 재화 인벤토리 중심, 장비·카드 지급 로직 미구현 - PD 전제: "재화 아닌 보상은 서버 처리 어려움" **안 2종**: 1. **A안 — 클라 단독 지급 + 사후 서버 동기화** (PD 전제 그대로) - 가) 클라가 보상 지급 + ServerData 로컬 갱신 - 나) 다음 주기 세이브에서 서버 반영 - 다) **리스크**: 지급 직후 앱 강제 종료 시 미반영 — 재지급/유실 판정 정책 필요 2. **B안 — 비재화 자산도 서버 SOT 전환** (PD 전제 초과) - 가) 장비·카드·PC 지급 API 신설 (`Grant_Equipment`·`Grant_Card` CloudScript) - 나) 서버가 유니크 인벤토리 관리 - 다) **비용**: 개발 공수 + PlayFab 인벤토리 모델 재설계 **개발팀장 의견**: A안 기본 + 지급 멱등성 보장용 클라 임시 저널(로컬 큐)로 유실 방지. PD 전제 정합. --- ### PD-② 비재화 랭킹 보상 처리 방안 (PD 가이드 3 연장) **안건**: 랭킹 시즌 종료 시 비재화 보상(칭호·스킨·특수 장비)을 어떻게 지급할 것인가? **현 실측 제약**: - 현재 랭킹 등록 경로 미확인 + 랭킹 보상 시스템 자체 미구현 - PD 전제: "재화 아닌 랭킹 보상은 서버 처리 불가" **안 2종**: 1. **A안 — 재화 우편 보상만 운영** (PD 전제 그대로) - 가) 시즌 종료 시 서버가 순위별 재화 우편 발송 - 나) 칭호·스킨 등 비재화 보상은 설계에서 제외 - 다) **제약**: 랭킹 동기 부여 수단 축소 2. **B안 — 클라 단독 지급 + 서버는 "대상자 여부" 플래그만 관리** - 가) 서버: 시즌 종료 시 순위 확정 → 대상자 플래그 저장 (예: `SeasonReward_S03_Tier1: true`) - 나) 클라: 플래그 확인 후 로컬에서 비재화 보상 해금 - 다) **리스크**: 플래그 조작 시 부정 해금 — AntiCheat로 일부 방어 가능 **개발팀장 의견**: B안 권장. 서버 처리 범위를 "대상자 판정"으로 한정하면 PD 전제("재화 아닌 서버 처리 불가") 정신 유지 + 랭킹 유인 확보. --- ### PD-③ 서버 스택 유지 여부 (PlayFab vs 자체 서버) **안건**: PlayFab을 계속 사용할 것인가, 자체 서버(Node.js + MongoDB 등)로 전환할 것인가? **현 상태**: PlayFab 광범위 의존 (인증·CloudScript·Leaderboard·Profiles·Mail·IAP 검증). `PD 지시 #2`에서 서버 Critical 보안 3건 보류 중. **안 3종**: 1. **A안 — PlayFab 유지 + CloudScript 확장** (현재 기조 유지) 2. **B안 — PlayFab 인증·Leaderboard만 유지 + 게임 로직은 자체 서버** 3. **C안 — 완전 자체 서버 전환** **개발팀장 의견**: 본 안건은 **인간 서버 개발자 배정 후 해당 개발자의 기술 스택 선호·경험과 함께 결정 권장**. 본 초안은 A안(PlayFab 유지) 전제로 작성되었으나, 개발자 배정 시 재검토 필요. --- ### PD-④ 세이브 SOT 전환 범위 **안건**: 현재 **로컬 1차 + 클라우드 보조** 하이브리드를 **서버 1차 SOT**로 전환할 것인가? **안 2종**: 1. **A안 — 현 하이브리드 유지** — 최소 변경. 재화·결제만 서버 검증 2. **B안 — 서버 1차 SOT 전환** — 로컬은 오프라인 캐시로만. 모든 변경 서버 저장 **개발팀장 의견**: **B안이 원칙적으로 옳으나 수상한잡화점 현 시점에는 A안 유지 권장**. 이유: 서버 Critical 3건 보류 중 + 게임 오프라인 플레이 비중 고려. 차기 프로젝트는 B안 기반 설계 (헌법 제1원칙 목표 2 — 코어 프레임워크에 반영 권장). --- ### PD-⑤ 일일/주간 리셋 시간 기준 **안건**: 현재 `DayOfYear` 클라 시간 비교 방식을 서버 시간 기반으로 전환할 것인가? **현 이슈**: 기기 시간 조작으로 일일 출석·일일 상점 어뷰즈 가능. **개발팀장 의견**: **서버 시간 기준 전환 필수**. PD 재검토 불요 수준의 보안 기본. 서버 Critical 보안 3건 재개 시 포함 권장. --- ## D. 인간 서버 개발자 착수 시 선행 작업 (C30·P13·P18 정합) 1. **선행 Read 패키지** (서버팀장 사전 보고 서버 재개 예비 C-1 적용) - 가) 본 문서 - 나) `공유/PD_지시_트래킹/개발팀_PD_지시_로그.md` #2 (서버 Critical 3건) - 다) 현 `ServerClass.cs`·`ServerInfo.cs` 전문 - 라) `memory/org/feedback_*.md` 중 서버·보안 관련 2. **환경 셋업** - 가) PlayFab 계정·TitleId 확인 (현 코드 `Server_Live_ID`·`Server_Dev_ID` 상수 주석 처리 상태) - 나) CloudScript 현 코드 dump 및 버전 관리 편입 - 다) Unity 클라이언트 개발 환경 (수상한잡화점 브랜치 pull) 3. **설계 문서화 의무 (P18)** - 가) 본 초안의 PD 결정 후 **서버 아키텍처 공식 설계 문서** 작성 (`프로젝트/수상한잡화점/서버/01_서버_아키텍처_v1.md` 신규) - 나) API 계약서 작성 (`02_API_계약서_v1.md`) — 엔드포인트·파라미터·응답·에러 코드 - 다) CloudScript 함수 명세 (`03_CloudScript_명세_v1.md`) 4. **P13 공용 인터페이스 변경 사전 공유** - 가) 클라이언트팀(현 개발팀장)과 데이터 포맷 협의 - 나) 기획팀과 재화·미션·랭킹 밸런스 협의 --- ## E. 산출물 요약 | 분류 | 건수 | 긴급도 | |------|------|--------| | A. 데이터 카테고리 | 8개 도메인 (재화·진행도·랭킹·세이브·우편·시즌·상점·소셜) | 정리 완료 | | B. 클라/서버 매트릭스 | 6개 액션군 × 약 25건 | 정리 완료 | | C. PD 결정 안건 | 5건 (보상 지급 주체·비재화 랭킹·서버 스택·SOT 범위·리셋 시간) | PD님 결정 대기 | | D. 선행 작업 | 4단 | 인간 개발자 배정 시 적용 | --- ## F. 기각안 (P24·P27 개정 — 결정·설계 엔트리 필수) 본 초안이 채택하지 않은 대안들: 1. **"서버 처리를 최소화하고 전부 클라 주도로" 안** — PD 가이드 1(재화 서버 필수)과 충돌. 어뷰즈 방어 근거 소멸. 기각 2. **"모든 비재화 자산을 서버 SOT로 전환" 안** — PD 전제("재화 아닌 서버 처리 어려움") 초과. 개발 공수 큼. PD-① B안으로만 옵션 제시하고 초안 본문에서는 비채택 3. **"PlayFab 전면 폐기 + 자체 서버 전면 신규" 안** — 서버 Critical 3건 보류 상태에서 범위 확대는 리스크. PD-③에 옵션으로만 제시하고 본 초안은 PlayFab 유지 전제 4. **"인간 개발자 배정 전 세부 API 스펙까지 확정" 안** — C9(완성도 우선) 정신이나, **배정된 개발자의 기술 선호·경험 반영이 없는 API 스펙은 재작업 리스크**. 본 초안은 원칙·경계·안건까지 정리하고 세부 스펙은 개발자 배정 후 --- ## G. PM 처리 권장 1. **PD님 보고**: 본 초안 + PD-①~⑤ 5건 안건 (C29-3 목표 3 정신 — 결정 요청 최소화된 형태) 2. **PD 결정 수령 시 후속**: 개발팀 PD 지시 로그 #2 재개 트리거 조건 명확화 (서버 Critical 3건 + 본 초안 PD 결정 연계) 3. **인간 개발자 배정 시**: 본 초안 + D-1 선행 Read 패키지 동봉하여 온보딩 4. **차기 프로젝트 코어 프레임워크 반영**: PD-④ B안(서버 1차 SOT), PD-⑤(서버 시간 기준)는 헌법 제1원칙 목표 2 — 차기 프로젝트 프레임워크 기본 탑재 권장 --- **서명**: 개발팀장 (서버팀장·클라이언트팀장 Agent 호출 환경 제약으로 단독 분석, C23 정직성 준수) **검증 권장**: dev-auditor 모드 A 1회 + PM 교차 검토 후 PD 상신