AGENT SKILL
43-savedata-json-codec
暂无简介
- License 许可
- MIT
- 最近更新
- 2026-04-12
- Stars
- ★ 0
- Forks
- 0
02 资源文件 1
- 参考文档agents/openai.yaml103 B
03 SKILL.md 正文
43-savedata-json-codec — SaveDataJsonCodec
Status: ACTIVE AppliesTo: v10 Type: Design / SSOT
Purpose
SaveDataManager가 local/cloud payload에 저장할 게임 상태 JSON의 직렬화/역직렬화 규약을 정의한다.
- JSON 직렬화/역직렬화의 유일한 진입점은 SaveDataManager 이다.
AccountManager,InventoryManager,PurchaseManager,GameMessageManager,MissionManager,AchieveManager,LeaderboardManager,AttendManager,TreasureManager는 각자 자신의Storage를 소유한다.- JSON 구현은
SaveDataJsonCodecroot codec + section codec으로 분리한다.
Ownership
AccountManager소유:AccountStorageInventoryManager소유:InventoryStoragePurchaseManager소유:PurchaseStorageGameMessageManager소유:GameMessageStorageMissionManager소유:MissionStorageAchieveManager소유:AchieveStorageLeaderboardManager소유:LeaderboardSeasonRewardStorageAttendManager소유:AttendStorageInventoryStorage내부:TreasureCurrent,TreasureCounts(treasure 상태)SaveDataManager책임:- 위 storage를 수집
- primary save binding(local filename + cloud slot) 관리
- JSON serialize/deserialize 호출
- payload encrypt/decrypt
- local/cloud save, load, sync, conflict
중요:
GameStorageManager는 삭제되었다.- 각 manager는 자신의 storage를 직접 소유하며, SaveDataManager가 이를 묶어 저장한다.
Class Boundary
SaveDataManager : CompoSingleton<SaveDataManager>
│
├── ToJson()
│ └── SaveDataJsonCodec.Serialize(inventory, purchase, shop, account, message, mission, achieve, leaderboardReward, attend, treasure)
│
├── LoadFromJson(json)
│ └── SaveDataJsonCodec.DeserializeInto(json, inventory, purchase, shop, account, message, mission, achieve, leaderboardReward, attend, treasure)
│
├── LoadFromPayload(payload)
│ └── ComplexUtil.Decrypt_Base64(payload) -> LoadFromJson(json)
│
└── ClearGameState()
├── AccountManager.Instance.Storage.Clear()
├── InventoryManager.Instance.Storage.Clear()
├── PurchaseManager.Instance.Storage.ClearAll()
├── GameMessageManager.Instance.Storage.Clear()
├── MissionManager.Instance.Storage.Clear()
├── AchieveManager.Instance.Storage.Clear()
├── LeaderboardManager.Instance.Storage.Clear()
├── AttendManager.Instance.Storage.Clear()
└── TreasureManager.Instance.Storage.Clear()
- root orchestration:
SaveDataJsonCodec - inventory section:
SaveDataJsonCodecInventory - purchase section:
SaveDataJsonCodecPurchase - account section:
SaveDataJsonCodecAccount - message section:
SaveDataJsonCodecMessage - mission section:
SaveDataJsonCodecMission - achieve section:
SaveDataJsonCodecAchieve - leaderboard reward section:
SaveDataJsonCodecLeaderboardReward - attend section:
SaveDataJsonCodecAttend - treasure section:
SaveDataJsonCodecTreasure
section codec은 manager를 직접 알지 않고, Storage 타입만 다룬다.
역직렬화 실패는 throw 대신 CommonResult.Failure(...)로 root caller에 전달한다.
Error Model
- save/load는 대표적인 boundary다. parse/version/restore 실패는
CommonResult로 반환한다. - root caller(
SaveDataManager)가 clear/retry/fallback 정책을 선택한다. - section codec은 malformed JSON, lookup miss, restore failure를 조용히 무시하지 않는다.
- private helper에서만 이미 정규화된 내부 invariant 위반 예외를 제한적으로 허용할 수 있다.
- 단, helper 예외가 codec boundary를 넘어 public API 기본 모델이 되지 않게 한다.
Primary Save Rule
- public save API는 멀티 슬롯을 노출하지 않는다.
SaveDataManager는 단일 primary save binding만 가진다.- codec은 binding을 모르고, 순수하게 게임 상태 JSON만 다룬다.
Root JSON Schema
{
"version": 20,
"inventory": {},
"purchase": {},
"shop": {},
"account": {},
"message": {},
"mission": {},
"achieve": {},
"leaderboardReward": {},
"attend": {},
"treasure": {}
}
version: root schema versioninventory:InventoryStorage섹션purchase:PurchaseStorage섹션shop:ShopStorage섹션account:AccountStorage섹션message:GameMessageStorage섹션mission:MissionStorage섹션achieve:AchieveStorage섹션leaderboardReward:LeaderboardSeasonRewardStorage섹션attend:AttendStorage섹션treasure:InventoryStoragetreasure 섹션
payload wrapper(SaveLocalPayload, SaveCloudPayload)의 account 메타는 유지한다.
이 메타는 sync 초기 판정과 account mirror 용도이며, root JSON의 account 섹션과 별개로 존재할 수 있다.
Section Sourcing
serialize 시 source:
AccountManager.Instance.StorageInventoryManager.Instance.StoragePurchaseManager.Instance.StorageGameMessageManager.Instance.StorageMissionManager.Instance.StorageAchieveManager.Instance.StorageLeaderboardManager.Instance.StorageAttendManager.Instance.StorageTreasureManager.Instance.Storage
deserialize 시 target:
AccountManager.Instance.StorageInventoryManager.Instance.StoragePurchaseManager.Instance.StorageGameMessageManager.Instance.StorageMissionManager.Instance.StorageAchieveManager.Instance.StorageLeaderboardManager.Instance.StorageAttendManager.Instance.StorageTreasureManager.Instance.Storage
로드 직후 런타임 재적용:
AccountManager.ApplyStorage(AccountManager.Instance.Storage)InventoryStorage.Rentals/Passes는 payload(local/cloud)에 저장/복원되며, 로그인/복원 시PurchaseManager.SyncEntitlementsAsync()가 서버 entitlements 값으로 재동기화한다.- Mission은
MissionManager가 자신의MissionStorage를 기준으로 runtime state를 재구성한다 - Mission/Achieve/SeasonReward claim 상태 변경 직후에는
SaveDataManager.SaveGameStorageAsync(true, ct)로 root payload 저장을 즉시 시도해야 한다 - 이 local save가 실패하면 mission 시스템은 플레이 불가능 상태로 처리한다(TODO)
Version / Migration Rules
- schema 변경 시 root
version을 증가시킨다. - 하위호환이 필요하면 root codec에서 version 분기 처리한다.
- section codec은 자신이 담당하는 섹션의 레거시 필드만 복구한다.
- 지원하지 않는 version이면 조용히 부분 로드하지 말고, 명시적인 fallback 정책을 문서에 기록한다.
- malformed JSON / section restore failure는
CommonResult.Failure(...)로 반환하고 상위 caller가 전체 상태를 정리한다. - save payload/section 오류를 public API에서
throw기본 모델로 바꾸지 않는다.
Hard Rules
- manager가 자신의 storage를 소유하더라도, payload JSON 직렬화 진입점은 SaveDataManager 하나만 유지한다.
InventoryStorage,PurchaseStorage,AccountStorage,GameMessageStorage,MissionStorage,AchieveStorage,LeaderboardSeasonRewardStorage,AttendStorage에ToJson()/FromJson()을 다시 추가하지 않는다.- codec은 domain rule을 가지지 않는다. domain mutation은 각 manager가 담당한다.
- inventory item save는 generic
statsblob를 생성 정본으로 쓰지 않는다. item 생성은item_id/itemUid/item_level과 table lookup으로 복원하고, mutable 상태는amount/equips같은 explicit field로 저장/복원한다. - equip owner는 별도 field로 저장하지 않는다. hero equip ownership의 저장/복원 SSOT는
heroes[*].equips다. - save JSON에서 enum은 숫자 ordinal로 저장하지 않는다. enum key/value가 필요하면 반드시 enum name 문자열을 사용한다.
- legacy 숫자 enum 파싱은 load 호환용으로만 유지한다. 새 serialize 경로는 숫자 enum을 쓰지 않는다.
- 새 저장 섹션 추가 시:
- root codec 수정
- section codec 추가
- SaveDataManager sourcing 연결
- 관련 manager skill 문서 갱신
- save/load 전용 신규 에러 코드는
COMMON_ERRORappend-only 규칙 안에서만 추가한다.
Implementation Location (3-path mirror)
- UPM (정본):
framework-cs/upm/com.devian.foundation/Samples~/MobilePackage/Runtime/SaveData/JsonCodec/SaveDataJsonCodec.csframework-cs/upm/com.devian.foundation/Samples~/MobilePackage/Runtime/SaveData/JsonCodec/SaveDataJsonCodecInventory.csframework-cs/upm/com.devian.foundation/Samples~/MobilePackage/Runtime/SaveData/JsonCodec/SaveDataJsonCodecPurchase.csframework-cs/upm/com.devian.foundation/Samples~/MobilePackage/Runtime/SaveData/JsonCodec/SaveDataJsonCodecAccount.csframework-cs/upm/com.devian.foundation/Samples~/MobilePackage/Runtime/SaveData/JsonCodec/SaveDataJsonCodecMessage.csframework-cs/upm/com.devian.foundation/Samples~/MobilePackage/Runtime/SaveData/JsonCodec/SaveDataJsonCodecMission.csframework-cs/upm/com.devian.foundation/Samples~/MobilePackage/Runtime/SaveData/JsonCodec/SaveDataJsonCodecAchieve.csframework-cs/upm/com.devian.foundation/Samples~/MobilePackage/Runtime/SaveData/JsonCodec/SaveDataJsonCodecLeaderboardReward.csframework-cs/upm/com.devian.foundation/Samples~/MobilePackage/Runtime/SaveData/JsonCodec/SaveDataJsonCodecAttend.csframework-cs/upm/com.devian.foundation/Samples~/MobilePackage/Runtime/SaveData/JsonCodec/SaveDataJsonCodecTreasure.cs
- Packages (sync):
framework-cs/apps/UnityExample/Packages/com.devian.foundation/Samples~/MobilePackage/Runtime/SaveData/JsonCodec/...
- Assets/Samples (import):
framework-cs/apps/UnityExample/Assets/Samples/Devian Samples/{version}/MobilePackage/Runtime/SaveData/JsonCodec/...
Related
- 10-savedata-manager — SaveDataManager 진입점
- 41-savedata-savelocal — Local payload 저장
- 42-savedata-savecloud — Cloud payload 저장
- 33-account-manager — AccountStorage 소유자
- 10-inventory-manager — InventoryStorage 소유자
- 33-purchase-storage — PurchaseStorage 규약
- 45-game-message-system/14-game-message-storage — GameMessageStorage 규약
- 48-mission-system/12-mission-storage — MissionStorage 규약
- 46-achieve-system/14-achieve-storage — AchieveStorage 규약
- 50-leaderboard/14-leaderboard-season-reward-storage — 시즌 보상 저장 규약
- 27-attend-system/11-attend-storage — AttendStorage 규약
- 51-treasure-system/03-ssot — Treasure 시스템 SSOT