[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CBNAC22XCGFNWK6B3JWRV0":3,"skill-same:01M6CBNAC22XCGFNWK6B3JWRV0":59},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":27,"linkOnly":28,"markdownContent":29,"markdownBody":30,"frontMatter":31,"refName":32,"commitSha":33,"skillDirectory":34,"forksCount":14,"repositoryHtmlUrl":35,"repositoryHomepageUrl":6,"ownerHtmlUrl":36,"ownerBlogUrl":6,"ownerDescription":37,"updatedAt":38,"install":39,"resources":52},"01M6CBNAC22XCGFNWK6B3JWRV0","game-message-storage",null,"Use this skill when implementing or refactoring GameMessageStorage and SaveData JSON codec flow for message.stats in MobilePackage.","devwinsoft\u002Fdevian","devwinsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F22570160?v=4","01M6C6RR8W05NH8NPKQNCE3Q72","maoshy","01M6C6RRDJ5TJJCZXRTY801YDH",0,"MIT","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian-unity\u002F50-mobile-package\u002F45-game-message-system\u002F14-game-message-storage\u002FSKILL.md",[],[19,20,21,22,23,24,25,26],"storage","game","game message storage","stats","flow","refactoring","json","use","2026-11-10 10:12:30",false,"---\nname: game-message-storage\ndescription: Use this skill when implementing or refactoring GameMessageStorage and SaveData JSON codec flow for message.stats in MobilePackage.\n---\n\n# 14-game-message-storage\n\nStatus: ACTIVE\nAppliesTo: v10\nType: Design \u002F SSOT\n\n## Purpose\n\n`GameMessageStorage`의 저장 모델과 payload 규약 정본이다.\n\n---\n\n## Implementation Location (3-path mirror)\n\n- UPM (정본): `framework-cs\u002Fupm\u002Fcom.devian.foundation\u002FSamples~\u002FMobilePackage\u002FRuntime\u002FGameMessage\u002FGameMessageStorage.cs`\n- UPM Codec: `framework-cs\u002Fupm\u002Fcom.devian.foundation\u002FSamples~\u002FMobilePackage\u002FRuntime\u002FSaveData\u002FJsonCodec\u002FSaveDataJsonCodecMessage.cs`\n- Packages (sync): `framework-cs\u002Fapps\u002FUnityExample\u002FPackages\u002Fcom.devian.foundation\u002FSamples~\u002FMobilePackage\u002FRuntime\u002FGameMessage\u002FGameMessageStorage.cs`\n- Packages Codec (sync): `framework-cs\u002Fapps\u002FUnityExample\u002FPackages\u002Fcom.devian.foundation\u002FSamples~\u002FMobilePackage\u002FRuntime\u002FSaveData\u002FJsonCodec\u002FSaveDataJsonCodecMessage.cs`\n- Assets\u002FSamples (import): `framework-cs\u002Fapps\u002FUnityExample\u002FAssets\u002FSamples\u002FDevian Samples\u002F{version}\u002FMobilePackage\u002FRuntime\u002FGameMessage\u002FGameMessageStorage.cs`\n- Assets Codec (import): `framework-cs\u002Fapps\u002FUnityExample\u002FAssets\u002FSamples\u002FDevian Samples\u002F{version}\u002FMobilePackage\u002FRuntime\u002FSaveData\u002FJsonCodec\u002FSaveDataJsonCodecMessage.cs`\n\n---\n\n## Ownership\n\n- `GameMessageManager`가 `GameMessageStorage`를 소유한다.\n- stat 저장 접근 정본: `GameMessageManager.Storage`\n\n---\n\n## Storage Model\n\n`GameMessageStorage` 필드:\n- `schemaVersion`\n- `stats: Dictionary\u003Cstring, CBigInt>`\n\n규칙:\n- key는 반드시 `message_id` string\n- value는 `MESSAGE.saveType` 규약에 따라 누적된 값\n- `Clear()`는 schema 기본값 복원 + 컬렉션 초기화\n\n---\n\n## SaveData Payload\n\n루트 payload에서 message 섹션은 `message` 키를 사용한다.\n\n```json\n{\n  \"version\": 13,\n  \"message\": {\n    \"schemaVersion\": 1,\n    \"stats\": { \"\u003Cmessage_id>\": { \"base\": 0, \"pow\": 0 } }\n  }\n}\n```\n\n핵심 규칙:\n- `mission.stats`는 더 이상 write하지 않는다.\n- mission\u002Fachieve runtime은 `message_id` 필드를 사용한다.\n\n---\n\n## Migration Rules\n\n- v12 이하 payload load 시:\n  - legacy `mission.stats`를 `message.stats`로 이동한다.\n  - runtime의 legacy 필드 `missionStatId`는 `message_id` fallback으로 읽는다.\n- v13 write 시:\n  - `message.stats`만 기록한다.\n\n---\n\n## Related\n\n- [03-ssot](..\u002F03-ssot\u002FSKILL.md)\n- [10-game-message-manager](..\u002F10-game-message-manager\u002FSKILL.md)\n- [21-savedata-system\u002F43-savedata-json-codec](..\u002F..\u002F21-savedata-system\u002F43-savedata-json-codec\u002FSKILL.md)\n- [48-mission-system\u002F12-mission-storage](..\u002F..\u002F48-mission-system\u002F12-mission-storage\u002FSKILL.md)\n","# 14-game-message-storage\n\nStatus: ACTIVE\nAppliesTo: v10\nType: Design \u002F SSOT\n\n## Purpose\n\n`GameMessageStorage`의 저장 모델과 payload 규약 정본이다.\n\n---\n\n## Implementation Location (3-path mirror)\n\n- UPM (정본): `framework-cs\u002Fupm\u002Fcom.devian.foundation\u002FSamples~\u002FMobilePackage\u002FRuntime\u002FGameMessage\u002FGameMessageStorage.cs`\n- UPM Codec: `framework-cs\u002Fupm\u002Fcom.devian.foundation\u002FSamples~\u002FMobilePackage\u002FRuntime\u002FSaveData\u002FJsonCodec\u002FSaveDataJsonCodecMessage.cs`\n- Packages (sync): `framework-cs\u002Fapps\u002FUnityExample\u002FPackages\u002Fcom.devian.foundation\u002FSamples~\u002FMobilePackage\u002FRuntime\u002FGameMessage\u002FGameMessageStorage.cs`\n- Packages Codec (sync): `framework-cs\u002Fapps\u002FUnityExample\u002FPackages\u002Fcom.devian.foundation\u002FSamples~\u002FMobilePackage\u002FRuntime\u002FSaveData\u002FJsonCodec\u002FSaveDataJsonCodecMessage.cs`\n- Assets\u002FSamples (import): `framework-cs\u002Fapps\u002FUnityExample\u002FAssets\u002FSamples\u002FDevian Samples\u002F{version}\u002FMobilePackage\u002FRuntime\u002FGameMessage\u002FGameMessageStorage.cs`\n- Assets Codec (import): `framework-cs\u002Fapps\u002FUnityExample\u002FAssets\u002FSamples\u002FDevian Samples\u002F{version}\u002FMobilePackage\u002FRuntime\u002FSaveData\u002FJsonCodec\u002FSaveDataJsonCodecMessage.cs`\n\n---\n\n## Ownership\n\n- `GameMessageManager`가 `GameMessageStorage`를 소유한다.\n- stat 저장 접근 정본: `GameMessageManager.Storage`\n\n---\n\n## Storage Model\n\n`GameMessageStorage` 필드:\n- `schemaVersion`\n- `stats: Dictionary\u003Cstring, CBigInt>`\n\n규칙:\n- key는 반드시 `message_id` string\n- value는 `MESSAGE.saveType` 규약에 따라 누적된 값\n- `Clear()`는 schema 기본값 복원 + 컬렉션 초기화\n\n---\n\n## SaveData Payload\n\n루트 payload에서 message 섹션은 `message` 키를 사용한다.\n\n```json\n{\n  \"version\": 13,\n  \"message\": {\n    \"schemaVersion\": 1,\n    \"stats\": { \"\u003Cmessage_id>\": { \"base\": 0, \"pow\": 0 } }\n  }\n}\n```\n\n핵심 규칙:\n- `mission.stats`는 더 이상 write하지 않는다.\n- mission\u002Fachieve runtime은 `message_id` 필드를 사용한다.\n\n---\n\n## Migration Rules\n\n- v12 이하 payload load 시:\n  - legacy `mission.stats`를 `message.stats`로 이동한다.\n  - runtime의 legacy 필드 `missionStatId`는 `message_id` fallback으로 읽는다.\n- v13 write 시:\n  - `message.stats`만 기록한다.\n\n---\n\n## Related\n\n- [03-ssot](..\u002F03-ssot\u002FSKILL.md)\n- [10-game-message-manager](..\u002F10-game-message-manager\u002FSKILL.md)\n- [21-savedata-system\u002F43-savedata-json-codec](..\u002F..\u002F21-savedata-system\u002F43-savedata-json-codec\u002FSKILL.md)\n- [48-mission-system\u002F12-mission-storage](..\u002F..\u002F48-mission-system\u002F12-mission-storage\u002FSKILL.md)\n",{"name":5,"description":7},"main","8cb5bd877a3a7004867d2f55697cb9e4ff2f1734","skills\u002Fdevian-unity\u002F50-mobile-package\u002F45-game-message-system\u002F14-game-message-storage","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian","https:\u002F\u002Fgithub.com\u002Fdevwinsoft","Kim Hyong Joon","2026-04-12 18:44:10",{"source":8,"skillName":5,"commands":40,"prompt":50,"zipAvailable":51},[41,44,47],{"tool":42,"command":43},"npx","npx skills add devwinsoft\u002Fdevian --skill game-message-storage",{"tool":45,"command":46},"bunx","bunx skills add devwinsoft\u002Fdevian --skill game-message-storage",{"tool":48,"command":49},"pnpm","pnpm dlx skills add devwinsoft\u002Fdevian --skill game-message-storage","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian-unity\u002F50-mobile-package\u002F45-game-message-system\u002F14-game-message-storage\u002FSKILL.md",true,[53],{"path":54,"resourceType":55,"resourceTypeDesc":56,"sizeBytes":57,"sourceHtmlUrl":58},"agents\u002Fopenai.yaml","REFERENCE","参考文档",111,"https:\u002F\u002Fgithub.com\u002Fmalinskibeniamin\u002Fskills\u002Fblob\u002Fmain\u002Fcodex-skills\u002Fdomain-modeling\u002Fagents\u002Fopenai.yaml",[60,66,74,82,91,98],{"skillNo":61,"name":62,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":65,"publishedAt":27},"01M6CBX3K2JJV38ANHVGCAT8A0","devian","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002FSKILL.md",[],[62],{"skillNo":67,"name":68,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":69,"categories":70,"keywords":71,"publishedAt":27},"01M6CBX210BFMM8AMN770J9WY8","90-project-archive","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F90-project-archive\u002FSKILL.md",[],[72,73],"archive","90 project archive",{"skillNo":75,"name":76,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":77,"categories":78,"keywords":79,"publishedAt":27},"01M6CBWZSGRR9R3YJZB3177667","30-env-management","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F30-env-management\u002FSKILL.md",[],[80,81],"management","30 env management",{"skillNo":83,"name":84,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":87,"publishedAt":27},"01M6CBWYD3TGWBQV7V35551THF","19-page-push-send","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F19-page-push-send\u002FSKILL.md",[],[88,89,90],"push","page","19 page push send",{"skillNo":92,"name":93,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":94,"categories":95,"keywords":96,"publishedAt":27},"01M6CBWWRQ05A7604GHJKTPJTF","18-page-savedata","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F18-page-savedata\u002FSKILL.md",[],[89,97],"18 page savedata",{"skillNo":99,"name":100,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":101,"categories":102,"keywords":103,"publishedAt":27},"01M6CBWVH4S2VF1V7B2GBTESCT","17-page-deobfuscate","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F17-page-deobfuscate\u002FSKILL.md",[],[89,104],"17 page deobfuscate"]