nccgs 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/.claude/agents/nccgs-accessibility-specialist.md +26 -0
  2. package/.claude/agents/nccgs-adversarial-reviewer.md +26 -0
  3. package/.claude/agents/nccgs-ai-programmer.md +26 -0
  4. package/.claude/agents/nccgs-analytics-engineer.md +26 -0
  5. package/.claude/agents/nccgs-art-direction-lead.md +26 -0
  6. package/.claude/agents/nccgs-audio-direction-lead.md +26 -0
  7. package/.claude/agents/nccgs-creative-director.md +26 -0
  8. package/.claude/agents/nccgs-documentation-manager.md +26 -0
  9. package/.claude/agents/nccgs-economy-designer.md +26 -0
  10. package/.claude/agents/nccgs-engine-programmer.md +26 -0
  11. package/.claude/agents/nccgs-game-design-lead.md +26 -0
  12. package/.claude/agents/nccgs-game-designer.md +26 -0
  13. package/.claude/agents/nccgs-gameplay-programmer.md +26 -0
  14. package/.claude/agents/nccgs-level-designer.md +26 -0
  15. package/.claude/agents/nccgs-live-ops-designer.md +26 -0
  16. package/.claude/agents/nccgs-localization-lead.md +26 -0
  17. package/.claude/agents/nccgs-narrative-lead.md +26 -0
  18. package/.claude/agents/nccgs-network-programmer.md +26 -0
  19. package/.claude/agents/nccgs-performance-analyst.md +26 -0
  20. package/.claude/agents/nccgs-producer.md +26 -0
  21. package/.claude/agents/nccgs-production-coordinator.md +23 -0
  22. package/.claude/agents/nccgs-programming-lead.md +26 -0
  23. package/.claude/agents/nccgs-prototyper.md +26 -0
  24. package/.claude/agents/nccgs-qa-engineer.md +26 -0
  25. package/.claude/agents/nccgs-qa-lead.md +26 -0
  26. package/.claude/agents/nccgs-release-engineer.md +26 -0
  27. package/.claude/agents/nccgs-release-lead.md +26 -0
  28. package/.claude/agents/nccgs-security-engineer.md +26 -0
  29. package/.claude/agents/nccgs-sound-designer.md +26 -0
  30. package/.claude/agents/nccgs-systems-designer.md +26 -0
  31. package/.claude/agents/nccgs-technical-architect.md +26 -0
  32. package/.claude/agents/nccgs-technical-artist.md +26 -0
  33. package/.claude/agents/nccgs-technical-director.md +26 -0
  34. package/.claude/agents/nccgs-tools-programmer.md +26 -0
  35. package/.claude/agents/nccgs-ui-programmer.md +26 -0
  36. package/.claude/agents/nccgs-unity-build-specialist.md +26 -0
  37. package/.claude/agents/nccgs-unity-content-specialist.md +26 -0
  38. package/.claude/agents/nccgs-unity-implementer.md +26 -0
  39. package/.claude/agents/nccgs-unity-rendering-specialist.md +26 -0
  40. package/.claude/agents/nccgs-unity-systems-specialist.md +26 -0
  41. package/.claude/agents/nccgs-unity-ui-specialist.md +26 -0
  42. package/.claude/agents/nccgs-ux-designer.md +26 -0
  43. package/.claude/agents/nccgs-verification-engineer.md +26 -0
  44. package/.claude/agents/nccgs-world-builder.md +26 -0
  45. package/.claude/agents/nccgs-writer.md +26 -0
  46. package/.claude/nccgs/THIRD_PARTY_NOTICES.md +13 -0
  47. package/.claude/nccgs/VERSION +1 -0
  48. package/.claude/nccgs/constitution.md +131 -0
  49. package/.claude/nccgs/hooks/agent-audit.mjs +10 -0
  50. package/.claude/nccgs/hooks/common.mjs +41 -0
  51. package/.claude/nccgs/hooks/post-compact.mjs +1 -0
  52. package/.claude/nccgs/hooks/pre-compact.mjs +8 -0
  53. package/.claude/nccgs/hooks/protect-git.mjs +22 -0
  54. package/.claude/nccgs/hooks/protect-write.mjs +17 -0
  55. package/.claude/nccgs/hooks/session-start.mjs +15 -0
  56. package/.claude/nccgs/hooks/session-stop.mjs +7 -0
  57. package/.claude/nccgs/protocols/agent-contract.md +34 -0
  58. package/.claude/nccgs/protocols/context-packets.md +13 -0
  59. package/.claude/nccgs/protocols/evidence.md +15 -0
  60. package/.claude/nccgs/protocols/model-routing.md +22 -0
  61. package/.claude/nccgs/protocols/orchestration.md +26 -0
  62. package/.claude/nccgs/protocols/unity-boundary.md +11 -0
  63. package/.claude/nccgs/settings.fragment.json +77 -0
  64. package/.claude/nccgs/studio.json +347 -0
  65. package/.claude/nccgs/tools/configure-models.mjs +39 -0
  66. package/.claude/nccgs/unity-skills-manifest.json +727 -0
  67. package/.claude/nccgs/workflow-catalog.json +317 -0
  68. package/.claude/rules/nccgs-canonical-docs.md +19 -0
  69. package/.claude/rules/nccgs-editor-tools.md +12 -0
  70. package/.claude/rules/nccgs-localization.md +12 -0
  71. package/.claude/rules/nccgs-networking.md +13 -0
  72. package/.claude/rules/nccgs-performance.md +14 -0
  73. package/.claude/rules/nccgs-rendering.md +16 -0
  74. package/.claude/rules/nccgs-security.md +13 -0
  75. package/.claude/rules/nccgs-tests.md +18 -0
  76. package/.claude/rules/nccgs-ui.md +14 -0
  77. package/.claude/rules/nccgs-unity-assets.md +21 -0
  78. package/.claude/rules/nccgs-unity-code.md +22 -0
  79. package/.claude/skills/accessibility-review/SKILL.md +14 -0
  80. package/.claude/skills/architecture-decision/SKILL.md +14 -0
  81. package/.claude/skills/asset-audit/SKILL.md +14 -0
  82. package/.claude/skills/audit/SKILL.md +16 -0
  83. package/.claude/skills/audit/references/dimensions.md +46 -0
  84. package/.claude/skills/balance-review/SKILL.md +14 -0
  85. package/.claude/skills/bug-triage/SKILL.md +14 -0
  86. package/.claude/skills/build-live-game/SKILL.md +317 -0
  87. package/.claude/skills/build-live-game/references/achievements.md +779 -0
  88. package/.claude/skills/build-live-game/references/apis.md +280 -0
  89. package/.claude/skills/build-live-game/references/authentication.md +437 -0
  90. package/.claude/skills/build-live-game/references/battlepass.md +860 -0
  91. package/.claude/skills/build-live-game/references/cloud-code.md +563 -0
  92. package/.claude/skills/build-live-game/references/cloud-save.md +474 -0
  93. package/.claude/skills/build-live-game/references/deployment.md +216 -0
  94. package/.claude/skills/build-live-game/references/player-account.md +813 -0
  95. package/.claude/skills/build-live-game/references/remote-config.md +96 -0
  96. package/.claude/skills/build-live-game/references/tooling.md +431 -0
  97. package/.claude/skills/closure/SKILL.md +14 -0
  98. package/.claude/skills/code-review/SKILL.md +14 -0
  99. package/.claude/skills/compatibility-review/SKILL.md +14 -0
  100. package/.claude/skills/context-pack/SKILL.md +14 -0
  101. package/.claude/skills/dependency-review/SKILL.md +14 -0
  102. package/.claude/skills/design/SKILL.md +20 -0
  103. package/.claude/skills/design-review/SKILL.md +14 -0
  104. package/.claude/skills/evidence-review/SKILL.md +14 -0
  105. package/.claude/skills/hotfix/SKILL.md +14 -0
  106. package/.claude/skills/implement-in-app-purchases/README.md +233 -0
  107. package/.claude/skills/implement-in-app-purchases/SKILL.md +158 -0
  108. package/.claude/skills/implement-in-app-purchases/references/api-notes.md +562 -0
  109. package/.claude/skills/implement-in-app-purchases/references/codeless-catalog.md +331 -0
  110. package/.claude/skills/implement-in-app-purchases/references/convert-adapty.md +268 -0
  111. package/.claude/skills/implement-in-app-purchases/references/convert-essentialkit.md +239 -0
  112. package/.claude/skills/implement-in-app-purchases/references/convert-revenuecat.md +275 -0
  113. package/.claude/skills/implement-in-app-purchases/references/convert-unipay.md +145 -0
  114. package/.claude/skills/implement-in-app-purchases/references/migration-v4-to-v5.md +204 -0
  115. package/.claude/skills/implement-in-app-purchases/references/path-add-iap-to-new-project.md +198 -0
  116. package/.claude/skills/implement-in-app-purchases/references/path-convert-native-google-billing.md +356 -0
  117. package/.claude/skills/implement-in-app-purchases/references/path-convert-native-storekit.md +446 -0
  118. package/.claude/skills/implement-in-app-purchases/references/path-implement-iap-d2c.md +680 -0
  119. package/.claude/skills/implement-in-app-purchases/references/platform-notes.md +204 -0
  120. package/.claude/skills/implement-in-app-purchases/references/pre-check.md +205 -0
  121. package/.claude/skills/incident-recovery/SKILL.md +14 -0
  122. package/.claude/skills/initialize-ai-navigation/SKILL.md +95 -0
  123. package/.claude/skills/initialize-ai-navigation/references/navigation-system.md +794 -0
  124. package/.claude/skills/levelplay-unity-integration/CHANGELOG.md +57 -0
  125. package/.claude/skills/levelplay-unity-integration/README.md +74 -0
  126. package/.claude/skills/levelplay-unity-integration/SKILL.md +1126 -0
  127. package/.claude/skills/levelplay-unity-integration/references/banner-api.md +920 -0
  128. package/.claude/skills/levelplay-unity-integration/references/best-practices.md +536 -0
  129. package/.claude/skills/levelplay-unity-integration/references/ilrd-api.md +337 -0
  130. package/.claude/skills/levelplay-unity-integration/references/initialization-api.md +630 -0
  131. package/.claude/skills/levelplay-unity-integration/references/interstitial-api.md +899 -0
  132. package/.claude/skills/levelplay-unity-integration/references/ios-setup.md +491 -0
  133. package/.claude/skills/levelplay-unity-integration/references/migration-sdk-9.md +666 -0
  134. package/.claude/skills/levelplay-unity-integration/references/privacy-settings.md +608 -0
  135. package/.claude/skills/levelplay-unity-integration/references/rewarded-api.md +902 -0
  136. package/.claude/skills/localization/SKILL.md +135 -0
  137. package/.claude/skills/localization/references/api-notes.md +76 -0
  138. package/.claude/skills/localization/resources/L10nBatchProcessor.cs +69 -0
  139. package/.claude/skills/localization/resources/LocalizedFontAsset.cs +18 -0
  140. package/.claude/skills/localize-game/SKILL.md +14 -0
  141. package/.claude/skills/migrate-project/SKILL.md +21 -0
  142. package/.claude/skills/migrate-project/references/procedure.md +63 -0
  143. package/.claude/skills/milestone-review/SKILL.md +14 -0
  144. package/.claude/skills/new-unity-project/SKILL.md +179 -0
  145. package/.claude/skills/optimize-audio/SKILL.md +199 -0
  146. package/.claude/skills/optimize-audio/resources/audio-import-api.md +146 -0
  147. package/.claude/skills/optimize-audio/resources/platform-settings.md +48 -0
  148. package/.claude/skills/optimize-text-mesh-pro/SKILL.md +182 -0
  149. package/.claude/skills/optimize-web/SKILL.md +393 -0
  150. package/.claude/skills/optimize-web/resources/WebOptimizer.cs +21 -0
  151. package/.claude/skills/optimize-web/resources/toktx-examples.sh +11 -0
  152. package/.claude/skills/performance-audit/SKILL.md +14 -0
  153. package/.claude/skills/physics-3d-collision/SKILL.md +442 -0
  154. package/.claude/skills/physics-3d-collision/references/troubleshooting.md +41 -0
  155. package/.claude/skills/physics-3d-collision/resources/CollisionDebugger.cs +33 -0
  156. package/.claude/skills/plan-feature/SKILL.md +14 -0
  157. package/.claude/skills/playtest/SKILL.md +14 -0
  158. package/.claude/skills/project-stage/SKILL.md +14 -0
  159. package/.claude/skills/prototype-feature/SKILL.md +14 -0
  160. package/.claude/skills/qa-plan/SKILL.md +14 -0
  161. package/.claude/skills/release/SKILL.md +18 -0
  162. package/.claude/skills/release-readiness/SKILL.md +14 -0
  163. package/.claude/skills/retrospective/SKILL.md +14 -0
  164. package/.claude/skills/review/SKILL.md +16 -0
  165. package/.claude/skills/security-audit/SKILL.md +14 -0
  166. package/.claude/skills/setup-multiplayer-services/SKILL.md +39 -0
  167. package/.claude/skills/setup-multiplayer-services/references/dgs-entrypoint.md +79 -0
  168. package/.claude/skills/setup-multiplayer-services/references/entrypoints.md +213 -0
  169. package/.claude/skills/setup-multiplayer-services/references/examples.md +33 -0
  170. package/.claude/skills/setup-multiplayer-services/references/implementation-fit.md +30 -0
  171. package/.claude/skills/setup-multiplayer-services/references/underlying-services.md +11 -0
  172. package/.claude/skills/setup-multiplayer-services/references/workflows-prerequisites.md +17 -0
  173. package/.claude/skills/setup-vivox-voice-chat/SKILL.md +118 -0
  174. package/.claude/skills/setup-vivox-voice-chat/evals/.env.example +6 -0
  175. package/.claude/skills/setup-vivox-voice-chat/evals/README.md +101 -0
  176. package/.claude/skills/setup-vivox-voice-chat/evals/promptfooconfig.yaml +32 -0
  177. package/.claude/skills/setup-vivox-voice-chat/evals/tests/init-and-login.yaml +76 -0
  178. package/.claude/skills/setup-vivox-voice-chat/evals/tests/text-chat.yaml +65 -0
  179. package/.claude/skills/setup-vivox-voice-chat/evals/tests/voice-channels.yaml +74 -0
  180. package/.claude/skills/setup-vivox-voice-chat/references/events-and-participants.md +79 -0
  181. package/.claude/skills/setup-vivox-voice-chat/references/init-and-login.md +92 -0
  182. package/.claude/skills/setup-vivox-voice-chat/references/text-chat.md +93 -0
  183. package/.claude/skills/setup-vivox-voice-chat/references/troubleshooting.md +47 -0
  184. package/.claude/skills/setup-vivox-voice-chat/references/voice-channels.md +90 -0
  185. package/.claude/skills/shader-graph-create-custom-node/SKILL.md +25 -0
  186. package/.claude/skills/shader-graph-create-custom-node/resources/all_hints.hlsl +182 -0
  187. package/.claude/skills/sprint-plan/SKILL.md +14 -0
  188. package/.claude/skills/sprite-editor/SKILL.md +66 -0
  189. package/.claude/skills/sprite-editor/references/api_reference.md +151 -0
  190. package/.claude/skills/sprite-editor/references/background.md +112 -0
  191. package/.claude/skills/sprite-editor/references/templates.md +72 -0
  192. package/.claude/skills/sprite-editor/scripts/AutomaticSliceTexture.cs +40 -0
  193. package/.claude/skills/sprite-editor/scripts/GenerateNewSpriteRects.cs +200 -0
  194. package/.claude/skills/sprite-editor/scripts/GetTextureSourceImageSize.cs +32 -0
  195. package/.claude/skills/sprite-editor/scripts/GetTextureToSlice.cs +55 -0
  196. package/.claude/skills/sprite-editor/scripts/GridSliceTexture.cs +40 -0
  197. package/.claude/skills/sprite-editor/scripts/IsometricSliceTexture.cs +141 -0
  198. package/.claude/skills/sprite-editor/scripts/README.md +134 -0
  199. package/.claude/skills/sprite-editor/scripts/SetPivotExample.cs +58 -0
  200. package/.claude/skills/sprite-editor/scripts/SpriteToPng.cs +88 -0
  201. package/.claude/skills/status/SKILL.md +16 -0
  202. package/.claude/skills/story-readiness/SKILL.md +14 -0
  203. package/.claude/skills/test/SKILL.md +16 -0
  204. package/.claude/skills/ui/SKILL.md +142 -0
  205. package/.claude/skills/ui-imgui/SKILL.md +186 -0
  206. package/.claude/skills/ui-imgui/references/gui-elements.md +156 -0
  207. package/.claude/skills/ui-imgui/references/templates.md +141 -0
  208. package/.claude/skills/ui-review/SKILL.md +14 -0
  209. package/.claude/skills/ui-ugui/SKILL.md +282 -0
  210. package/.claude/skills/ui-ugui/references/scrollview-setup.md +29 -0
  211. package/.claude/skills/ui-uitk/SKILL.md +235 -0
  212. package/.claude/skills/ui-uitk/references/common-issues.md +74 -0
  213. package/.claude/skills/ui-uitk/references/custom-elements.md +241 -0
  214. package/.claude/skills/ui-uitk/references/painter2d.md +282 -0
  215. package/.claude/skills/ui-uitk/references/pointermanipulator-guide.md +94 -0
  216. package/.claude/skills/ui-uitk/references/svg-icons.md +136 -0
  217. package/.claude/skills/ui-uitk/references/ui-runtime-binding.md +234 -0
  218. package/.claude/skills/ui-uitk/references/uss-guide.md +138 -0
  219. package/.claude/skills/unity-cli/CHANGELOG.md +233 -0
  220. package/.claude/skills/unity-cli/SECURITY.md +22 -0
  221. package/.claude/skills/unity-cli/SKILL.md +414 -0
  222. package/.claude/skills/unity-cli/references/auth-license-cloud.md +146 -0
  223. package/.claude/skills/unity-cli/references/build-run-test.md +349 -0
  224. package/.claude/skills/unity-cli/references/collaboration.md +472 -0
  225. package/.claude/skills/unity-cli/references/config-hub.md +103 -0
  226. package/.claude/skills/unity-cli/references/diagnostics-maintenance.md +326 -0
  227. package/.claude/skills/unity-cli/references/editors-install.md +327 -0
  228. package/.claude/skills/unity-cli/references/integration-advanced.md +472 -0
  229. package/.claude/skills/unity-cli/references/projects-templates.md +574 -0
  230. package/.claude/skills/unity-package-management/SKILL.md +304 -0
  231. package/.claude/skills/unity-package-management/references/select-packages.md +108 -0
  232. package/.claude/skills/urp-postprocessing/SKILL.md +188 -0
  233. package/.claude/skills/urp-postprocessing/references/code-templates.md +119 -0
  234. package/.claude/skills/urp-postprocessing/references/effect-reference.md +86 -0
  235. package/.claude/skills/validate-urp-render-graph-renderer-feature/SKILL.md +269 -0
  236. package/.claude/skills/work/SKILL.md +36 -0
  237. package/.claude/skills/work/references/classification.md +41 -0
  238. package/.claude/skills/work/references/closure.md +50 -0
  239. package/.claude/skills/work/references/feature-contracts.md +32 -0
  240. package/.claude/skills/work/references/verification.md +26 -0
  241. package/CLAUDE.md +6 -0
  242. package/LICENSE +21 -0
  243. package/README.md +162 -0
  244. package/THIRD_PARTY_NOTICES.md +23 -0
  245. package/UPGRADING.md +32 -0
  246. package/VERSION +1 -0
  247. package/docs/ARCHITECTURE.md +73 -0
  248. package/docs/HUONG-DAN-MIGRATE-VA-SU-DUNG.md +324 -0
  249. package/docs/MIGRATION-MATRIX.md +23 -0
  250. package/docs/PROJECT-POLICY.md +67 -0
  251. package/docs/WORKFLOWS.md +61 -0
  252. package/package-assets/setup-vivox-voice-chat-evals.gitignore +7 -0
  253. package/package.json +41 -0
  254. package/scaffold/.nccgs/bugs/.gitkeep +1 -0
  255. package/scaffold/.nccgs/closures/.gitkeep +1 -0
  256. package/scaffold/.nccgs/context/.gitkeep +1 -0
  257. package/scaffold/.nccgs/decisions/.gitkeep +1 -0
  258. package/scaffold/.nccgs/evidence/.gitkeep +1 -0
  259. package/scaffold/.nccgs/features/.gitkeep +1 -0
  260. package/scaffold/.nccgs/migrations/.gitkeep +1 -0
  261. package/scaffold/.nccgs/playtests/.gitkeep +1 -0
  262. package/scaffold/.nccgs/project.yaml +103 -0
  263. package/scaffold/.nccgs/requirements.yaml +10 -0
  264. package/scaffold/.nccgs/reviews/.gitkeep +1 -0
  265. package/scaffold/.nccgs/state.md +40 -0
  266. package/scaffold/.nccgs/templates/agent-handoff.md +25 -0
  267. package/scaffold/.nccgs/templates/architecture-decision.md +27 -0
  268. package/scaffold/.nccgs/templates/closure-record.md +51 -0
  269. package/scaffold/.nccgs/templates/context-packet.yaml +17 -0
  270. package/scaffold/.nccgs/templates/evidence-record.md +23 -0
  271. package/scaffold/.nccgs/templates/feature-contract.md +35 -0
  272. package/scaffold/.nccgs/templates/migration-plan.md +40 -0
  273. package/scaffold/.nccgs/templates/waiver.md +11 -0
  274. package/scripts/cli.mjs +56 -0
  275. package/scripts/install.mjs +267 -0
  276. package/scripts/sync-unity-skills.mjs +126 -0
  277. package/scripts/validate.mjs +205 -0
  278. package/tests/framework.test.mjs +121 -0
@@ -0,0 +1,474 @@
1
+ # Cloud Save Reference
2
+
3
+ ## Table of Contents
4
+
5
+ - [Anti-Hallucination Reference](#anti-hallucination-reference)
6
+ - [Subsystems](#subsystems)
7
+ - [IPlayerDataService Methods](#iplayerdataservice-methods)
8
+ - [ICustomDataService Methods](#icustomdataservice-methods)
9
+ - [IPlayerFilesService Methods](#iplayerfilesservice-methods)
10
+ - [Key Model Types](#key-model-types)
11
+ - [Access Classes](#access-classes)
12
+ - [Code Templates](#code-templates)
13
+ - [Error Handling](#error-handling)
14
+
15
+ Accessed via `CloudSaveService.Instance` (`ICloudSaveService`, namespace `Unity.Services.CloudSave`). Assembly: `Unity.Services.CloudSave`.
16
+
17
+ Call `UnityServices.InitializeAsync()` from `com.unity.services.core` and sign in via `com.unity.services.authentication` before use.
18
+
19
+ ---
20
+
21
+ ## Anti-Hallucination Reference
22
+
23
+ | Correct | Incorrect (do NOT use) |
24
+ |---|---|
25
+ | `SaveAsync` returns `Task<Dictionary<string, string>>` (write lock tokens) | `SaveAsync` returns `Task` (void) |
26
+ | `Item.Value` is `IDeserializable` -- call `.GetAs<T>()` | `Item.Value` is `object` |
27
+ | `SaveAsync(IDictionary<string, object>)` -- uses `IDictionary` | `SaveAsync(Dictionary<string, object>)` -- wrong interface type |
28
+ | `SaveAsync(IDictionary<string, SaveItem>)` -- bundles value + write lock | `SaveAsync(data, Dictionary<string, WriteLockOptions>)` -- no such overload |
29
+ | Custom data is **read-only** from client (no save/delete methods) | Custom data can be written from client |
30
+ | `CloudSaveConflictException` has `Details` list | Only `CloudSaveException` exists for conflicts |
31
+ | `CloudSaveExceptionReason.Conflict` (value 11) | `WriteLockConflict` reason |
32
+ | `Item.Modified` / `Item.Created` are `DateTime?` | `Item.Modified` is `ModifiedMetadata` |
33
+ | `FileItem.Modified` / `FileItem.Created` are `DateTime?` | `FileItem.Modified` is `ModifiedMetadata` |
34
+ | `DeleteAsync(key, Models.Data.Player.DeleteOptions)` -- current API | `DeleteAsync(key, CloudSave.DeleteOptions)` -- deprecated overload |
35
+ | `ICustomDataService` methods require `customDataID` first param | Custom data methods with no ID param |
36
+
37
+ ---
38
+
39
+ ## Subsystems
40
+
41
+ | Subsystem | Access | Description |
42
+ |---|---|---|
43
+ | `Data.Player` | `CloudSaveService.Instance.Data.Player` | Key-value data for the signed-in player |
44
+ | `Data.Custom` | `CloudSaveService.Instance.Data.Custom` | Game-wide or server-written data; **read-only from client** |
45
+ | `Files.Player` | `CloudSaveService.Instance.Files.Player` | Binary file storage per player |
46
+
47
+ ---
48
+
49
+ ## IPlayerDataService Methods
50
+
51
+ `CloudSaveService.Instance.Data.Player`
52
+
53
+ **Options namespace:** All option classes (`SaveOptions`, `LoadOptions`, `DeleteOptions`, `DeleteAllOptions`, `ListAllKeysOptions`, `LoadAllOptions`, `QueryOptions`) are in `Unity.Services.CloudSave.Models.Data.Player`. Do **not** confuse with the deprecated root-level `CloudSave.SaveOptions` / `CloudSave.DeleteOptions`.
54
+
55
+ ```csharp
56
+ // List all keys belonging to the current player (with metadata).
57
+ Task<List<ItemKey>> ListAllKeysAsync()
58
+ Task<List<ItemKey>> ListAllKeysAsync(ListAllKeysOptions options)
59
+
60
+ // Load specific keys. Returns dictionary of key -> Item.
61
+ Task<Dictionary<string, Item>> LoadAsync(ISet<string> keys)
62
+ Task<Dictionary<string, Item>> LoadAsync(ISet<string> keys, LoadOptions options)
63
+
64
+ // Load all keys for the current player.
65
+ Task<Dictionary<string, Item>> LoadAllAsync()
66
+ Task<Dictionary<string, Item>> LoadAllAsync(LoadAllOptions options)
67
+
68
+ // Save key-value pairs. Returns Dictionary<string, string> mapping each key to its new write-lock token.
69
+ Task<Dictionary<string, string>> SaveAsync(IDictionary<string, object> data)
70
+ Task<Dictionary<string, string>> SaveAsync(IDictionary<string, object> data, SaveOptions options)
71
+
72
+ // Save with per-key write locks bundled via SaveItem.
73
+ Task<Dictionary<string, string>> SaveAsync(IDictionary<string, SaveItem> data)
74
+ Task<Dictionary<string, string>> SaveAsync(IDictionary<string, SaveItem> data, SaveOptions options)
75
+
76
+ // Delete a specific key. Use Models.Data.Player.DeleteOptions (not the deprecated root DeleteOptions).
77
+ Task DeleteAsync(string key, Models.Data.Player.DeleteOptions options)
78
+
79
+ // Delete ALL keys for the current player.
80
+ Task DeleteAllAsync()
81
+ Task DeleteAllAsync(DeleteAllOptions options)
82
+
83
+ // Query player data with field filters.
84
+ Task<List<EntityData>> QueryAsync(Query query, QueryOptions options)
85
+ ```
86
+
87
+ ---
88
+
89
+ ## ICustomDataService Methods
90
+
91
+ `CloudSaveService.Instance.Data.Custom`
92
+
93
+ Read-only from the client. Write via Cloud Code modules or `IAdminClient.CloudSaveData` from the `com.unity.services.apis` package. All methods require a `customDataID` parameter -- the namespace configured in the Unity Dashboard.
94
+
95
+ > **To write Custom Data from the editor or a deploy command**, use `IAdminClient.CloudSaveData.SetCustomItem` /
96
+ > `SetCustomItemBatch`. See [apis.md](apis.md) for setup and code templates. The client SDK has no write
97
+ > path for Custom Data.
98
+
99
+ ```csharp
100
+ Task<List<ItemKey>> ListAllKeysAsync(string customDataID)
101
+ Task<Dictionary<string, Item>> LoadAllAsync(string customDataID)
102
+ Task<Dictionary<string, Item>> LoadAsync(string customDataID, ISet<string> keys)
103
+
104
+ // Query across custom data. Uses Models.Data.Custom.QueryOptions.
105
+ Task<List<EntityData>> QueryAsync(Query query, Models.Data.Custom.QueryOptions options = default)
106
+ ```
107
+
108
+ ---
109
+
110
+ ## IPlayerFilesService Methods
111
+
112
+ `CloudSaveService.Instance.Files.Player`
113
+
114
+ Note: File methods use root-level `CloudSave.SaveOptions` and `CloudSave.DeleteOptions` (not the `Models.Data.Player` versions).
115
+
116
+ ```csharp
117
+ // List all files for the current player.
118
+ Task<List<FileItem>> ListAllAsync()
119
+
120
+ // Save a file (byte array or stream).
121
+ Task SaveAsync(string key, byte[] bytes, SaveOptions options = default)
122
+ Task SaveAsync(string key, Stream stream, SaveOptions options = default)
123
+
124
+ // Load a file as a byte array.
125
+ Task<byte[]> LoadBytesAsync(string key)
126
+
127
+ // Load a file as a stream.
128
+ Task<Stream> LoadStreamAsync(string key)
129
+
130
+ // Delete a file.
131
+ Task DeleteAsync(string key, DeleteOptions options = default)
132
+
133
+ // Get metadata for a specific file.
134
+ Task<FileItem> GetMetadataAsync(string key)
135
+ ```
136
+
137
+ ---
138
+
139
+ ## Key Model Types
140
+
141
+ ### `Item` (`Unity.Services.CloudSave.Models`)
142
+
143
+ | Property | Type | Description |
144
+ |---|---|---|
145
+ | `Key` | `string` | The data key |
146
+ | `Value` | `IDeserializable` | Deserialized value -- call `.GetAs<T>()` or `.GetAsString()` |
147
+ | `WriteLock` | `string` | Current write-lock token (use for optimistic concurrency) |
148
+ | `Created` | `DateTime?` | Creation timestamp |
149
+ | `Modified` | `DateTime?` | Last-modified timestamp |
150
+
151
+ ### `ItemKey` (`Unity.Services.CloudSave.Models`)
152
+
153
+ | Property | Type | Description |
154
+ |---|---|---|
155
+ | `Key` | `string` | The data key |
156
+ | `WriteLock` | `string` | Current write-lock token |
157
+ | `Modified` | `DateTime?` | Last-modified timestamp |
158
+
159
+ ### `FileItem` (`Unity.Services.CloudSave.Models`)
160
+
161
+ | Property | Type | Description |
162
+ |---|---|---|
163
+ | `Key` | `string` | The file key |
164
+ | `Size` | `long` | File size in bytes |
165
+ | `WriteLock` | `string` | Current write-lock token |
166
+ | `ContentType` | `string` | MIME type of the file |
167
+ | `Created` | `DateTime?` | Creation timestamp |
168
+ | `Modified` | `DateTime?` | Last-modified timestamp |
169
+
170
+ ### `SaveItem` (`Unity.Services.CloudSave.Models`)
171
+
172
+ Bundles a value and write lock for atomic save-with-lock operations.
173
+
174
+ ```csharp
175
+ new SaveItem(value: myObject, writeLock: previousItem.WriteLock)
176
+ ```
177
+
178
+ ### `Query` (`Unity.Services.CloudSave.Models`)
179
+
180
+ | Property | Type | Description |
181
+ |---|---|---|
182
+ | `Fields` | `List<FieldFilter>` | Filter conditions (required) |
183
+ | `ReturnKeys` | `HashSet<string>` | Project only these keys in results |
184
+ | `Offset` | `int` | Skip N results (pagination) |
185
+ | `Limit` | `int` | Max results to return |
186
+ | `SampleSize` | `int?` | Random sample size (optional) |
187
+
188
+ ### `FieldFilter` (`Unity.Services.CloudSave.Models`)
189
+
190
+ ```csharp
191
+ new FieldFilter(key: "level", value: 10, op: FieldFilter.OpOptions.GE, asc: true)
192
+ ```
193
+
194
+ | `OpOptions` | Meaning |
195
+ |---|---|
196
+ | `EQ` | Equal |
197
+ | `NE` | Not equal |
198
+ | `LT` | Less than |
199
+ | `LE` | Less than or equal |
200
+ | `GT` | Greater than |
201
+ | `GE` | Greater than or equal |
202
+
203
+ ### `EntityData` (`Unity.Services.CloudSave.Models`)
204
+
205
+ Query results return `List<EntityData>`, where each entry is one player's matching data.
206
+
207
+ | Property | Type | Description |
208
+ |---|---|---|
209
+ | `Id` | `string` | Player ID |
210
+ | `Data` | `List<Item>` | Matching items for this player |
211
+
212
+ ---
213
+
214
+ ## Access Classes
215
+
216
+ Namespace: `Unity.Services.CloudSave.Models.Data.Player`.
217
+
218
+ ### `AccessClass` Enum
219
+
220
+ | Value | Meaning |
221
+ |---|---|
222
+ | `Default` (0) | Owner read/write -- private to the player |
223
+ | `Private` (1) | Alias for Default |
224
+ | `Protected` (2) | Owner read, server-only write |
225
+ | `Public` (3) | Any player can read, owner writes |
226
+
227
+ ### Read Access Class Options (for Load/ListAllKeys)
228
+
229
+ - `DefaultReadAccessClassOptions()` -- read own Default-class data
230
+ - `PublicReadAccessClassOptions()` -- read own Public-class data
231
+ - `PublicReadAccessClassOptions(string playerId)` -- read **another player's** Public-class data
232
+ - `ProtectedReadAccessClassOptions()` -- read own Protected-class data
233
+
234
+ ### Write Access Class Options (for Save/Delete)
235
+
236
+ - `DefaultWriteAccessClassOptions()` -- write to Default-class keys
237
+ - `PublicWriteAccessClassOptions()` -- write to Public-class keys
238
+
239
+ ---
240
+
241
+ ## Code Templates
242
+
243
+ ### Save Player Data (Capture Write Lock Tokens)
244
+
245
+ ```csharp
246
+ using Unity.Services.CloudSave;
247
+ using Unity.Services.CloudSave.Models;
248
+ using System.Collections.Generic;
249
+
250
+ var data = new Dictionary<string, object>
251
+ {
252
+ { "level", 10 },
253
+ { "gold", 500 },
254
+ { "inventory", new string[] { "sword", "shield" } }
255
+ };
256
+
257
+ // SaveAsync returns write-lock tokens for each saved key
258
+ Dictionary<string, string> writeLocks = await CloudSaveService.Instance.Data.Player.SaveAsync(data);
259
+ // writeLocks["level"] == "new-lock-token-for-level", etc.
260
+ ```
261
+
262
+ ### Load Specific Keys
263
+
264
+ ```csharp
265
+ var keys = new HashSet<string> { "level", "gold" };
266
+ var result = await CloudSaveService.Instance.Data.Player.LoadAsync(keys);
267
+
268
+ if (result.TryGetValue("level", out var levelItem))
269
+ {
270
+ int level = levelItem.Value.GetAs<int>();
271
+ Debug.Log($"Level: {level}, Modified: {levelItem.Modified}");
272
+ }
273
+ ```
274
+
275
+ ### Save with Write Lock Using SaveItem
276
+
277
+ ```csharp
278
+ using Unity.Services.CloudSave.Models;
279
+
280
+ // First load to get the current write lock
281
+ var items = await CloudSaveService.Instance.Data.Player.LoadAsync(new HashSet<string> { "gold" });
282
+ var goldItem = items["gold"];
283
+
284
+ // Bundle value + write lock in SaveItem -- fails if another client updated in the meantime
285
+ var saveData = new Dictionary<string, SaveItem>
286
+ {
287
+ { "gold", new SaveItem(value: 600, writeLock: goldItem.WriteLock) }
288
+ };
289
+
290
+ Dictionary<string, string> newLocks = await CloudSaveService.Instance.Data.Player.SaveAsync(saveData);
291
+ // newLocks["gold"] is the updated write-lock token
292
+ ```
293
+
294
+ ### Handle Write-Lock Conflicts
295
+
296
+ ```csharp
297
+ using Unity.Services.CloudSave;
298
+
299
+ try
300
+ {
301
+ await CloudSaveService.Instance.Data.Player.SaveAsync(saveData);
302
+ }
303
+ catch (CloudSaveConflictException ex)
304
+ {
305
+ foreach (var detail in ex.Details)
306
+ {
307
+ Debug.LogError($"Conflict on '{detail.Key}': " +
308
+ $"you sent lock '{detail.AttemptedWriteLock}', " +
309
+ $"server has '{detail.ExistingWriteLock}'");
310
+ }
311
+ // Reload, merge, and retry
312
+ }
313
+ ```
314
+
315
+ ### Delete a Key
316
+
317
+ ```csharp
318
+ using Unity.Services.CloudSave.Models.Data.Player;
319
+
320
+ // Delete with write-lock check
321
+ var options = new DeleteOptions { WriteLock = knownWriteLock };
322
+ await CloudSaveService.Instance.Data.Player.DeleteAsync("gold", options);
323
+
324
+ // Delete ALL player data
325
+ await CloudSaveService.Instance.Data.Player.DeleteAllAsync();
326
+ ```
327
+
328
+ ### Save and Load with Access Classes (Public, Default, Protected)
329
+
330
+ > **Namespace note:** `SaveOptions`, `LoadOptions`, and `DeleteOptions` exist in both
331
+ > `Unity.Services.CloudSave` (root) and `Unity.Services.CloudSave.Models.Data.Player`.
332
+ > The access-class overloads live in `Models.Data.Player`. If you import both namespaces,
333
+ > use fully qualified names or a `using` alias to avoid ambiguity.
334
+
335
+ ```csharp
336
+ using Unity.Services.CloudSave.Models.Data.Player;
337
+
338
+ // Save data as Public (other players can read it)
339
+ var publicData = new Dictionary<string, object> { { "displayName", "Hero123" }, { "rank", 42 } };
340
+ var publicOptions = new SaveOptions(new PublicWriteAccessClassOptions());
341
+ await CloudSaveService.Instance.Data.Player.SaveAsync(publicData, publicOptions);
342
+
343
+ // Read another player's Public-class data
344
+ var readOptions = new LoadOptions(new PublicReadAccessClassOptions(otherPlayerId));
345
+ var otherPlayerData = await CloudSaveService.Instance.Data.Player.LoadAsync(
346
+ new HashSet<string> { "displayName", "rank" }, readOptions);
347
+ Debug.Log($"Other player name: {otherPlayerData["displayName"].Value.GetAs<string>()}");
348
+
349
+ // Read own Protected-class data (written by server/Cloud Code)
350
+ var protectedOptions = new LoadOptions(new ProtectedReadAccessClassOptions());
351
+ var serverData = await CloudSaveService.Instance.Data.Player.LoadAllAsync(
352
+ new LoadAllOptions(new ProtectedReadAccessClassOptions()));
353
+ ```
354
+
355
+ ### Read Custom Data (Game-Wide, Read-Only)
356
+
357
+ ```csharp
358
+ // Custom data is read-only from client -- written via Cloud Code or admin API.
359
+ // customDataID is the namespace configured in the Unity Dashboard.
360
+ var customData = await CloudSaveService.Instance.Data.Custom.LoadAllAsync("my-game-config");
361
+
362
+ if (customData.TryGetValue("seasonConfig", out var config))
363
+ {
364
+ var season = config.Value.GetAs<SeasonConfig>();
365
+ Debug.Log($"Current season: {season.Name}");
366
+ }
367
+ ```
368
+
369
+ ### Query Player Data
370
+
371
+ ```csharp
372
+ using Unity.Services.CloudSave.Models;
373
+ using Unity.Services.CloudSave.Models.Data.Player;
374
+
375
+ // Find players with level >= 10, sorted ascending
376
+ var query = new Query(
377
+ fields: new List<FieldFilter>
378
+ {
379
+ new FieldFilter(key: "level", value: 10, op: FieldFilter.OpOptions.GE, asc: true)
380
+ },
381
+ returnKeys: new HashSet<string> { "level", "displayName" },
382
+ offset: 0,
383
+ limit: 20
384
+ );
385
+
386
+ var results = await CloudSaveService.Instance.Data.Player.QueryAsync(query, new QueryOptions());
387
+
388
+ foreach (var entity in results)
389
+ {
390
+ Debug.Log($"Player {entity.Id}:");
391
+ foreach (var item in entity.Data)
392
+ Debug.Log($" {item.Key} = {item.Value.GetAsString()}");
393
+ }
394
+ ```
395
+
396
+ ### Save and Load a File
397
+
398
+ ```csharp
399
+ // Save
400
+ byte[] screenshotBytes = await CaptureScreenshot();
401
+ await CloudSaveService.Instance.Files.Player.SaveAsync("screenshot_latest", screenshotBytes);
402
+
403
+ // Load
404
+ byte[] loaded = await CloudSaveService.Instance.Files.Player.LoadBytesAsync("screenshot_latest");
405
+
406
+ // Get metadata
407
+ var meta = await CloudSaveService.Instance.Files.Player.GetMetadataAsync("screenshot_latest");
408
+ Debug.Log($"Size: {meta.Size}, ContentType: {meta.ContentType}, Modified: {meta.Modified}");
409
+ ```
410
+
411
+ ### List All Keys
412
+
413
+ ```csharp
414
+ var keys = await CloudSaveService.Instance.Data.Player.ListAllKeysAsync();
415
+ foreach (var key in keys)
416
+ {
417
+ Debug.Log($"Key: {key.Key}, WriteLock: {key.WriteLock}, Modified: {key.Modified}");
418
+ }
419
+ ```
420
+
421
+ ---
422
+
423
+ ## Error Handling
424
+
425
+ ```csharp
426
+ try { ... }
427
+ catch (CloudSaveConflictException ex)
428
+ {
429
+ // Write-lock conflict -- inspect per-key details
430
+ foreach (var detail in ex.Details)
431
+ Debug.LogError($"Key '{detail.Key}': attempted={detail.AttemptedWriteLock}, existing={detail.ExistingWriteLock}");
432
+ }
433
+ catch (CloudSaveValidationException ex)
434
+ {
435
+ // Input validation failure -- inspect per-field details
436
+ foreach (var detail in ex.Details)
437
+ Debug.LogError($"Field '{detail.Field}' key '{detail.Key}': {string.Join(", ", detail.Messages)}");
438
+ }
439
+ catch (CloudSaveRateLimitedException ex)
440
+ {
441
+ Debug.LogError($"Rate limited. Retry after {ex.RetryAfter}s");
442
+ }
443
+ catch (CloudSaveException ex)
444
+ {
445
+ Debug.LogError($"Cloud Save error: {ex.Message} (reason: {ex.Reason})");
446
+ }
447
+ ```
448
+
449
+ ### `CloudSaveExceptionReason` Enum
450
+
451
+ | Reason | Value | Meaning |
452
+ |---|---|---|
453
+ | `Unknown` | 0 | Unknown error |
454
+ | `NoInternetConnection` | 1 | No network |
455
+ | `ProjectIdMissing` | 2 | Project ID not set |
456
+ | `PlayerIdMissing` | 3 | Player not signed in |
457
+ | `AccessTokenMissing` | 4 | No access token |
458
+ | `InvalidArgument` | 5 | Bad input |
459
+ | `Unauthorized` | 6 | Not authorized |
460
+ | `KeyLimitExceeded` | 7 | Too many keys stored |
461
+ | `NotFound` | 8 | Key not found |
462
+ | `TooManyRequests` | 9 | Rate limited |
463
+ | `ServiceUnavailable` | 10 | Service down |
464
+ | `Conflict` | 11 | Write-lock conflict |
465
+
466
+ ---
467
+
468
+ ## Asset Store Building Blocks
469
+
470
+ The following Building Blocks from the Unity Asset Store demonstrate Cloud Save patterns:
471
+
472
+ - **Achievements Building Block** — Reads/writes achievement records in Protected buckets via Cloud Code, with Access Control denying direct player writes. [Asset Store](https://assetstore.unity.com/packages/essentials/tutorial-projects/unity-building-block-achievements-341918)
473
+ - **Player Account Building Block** — Stores player profile data in Default and Public access classes with direct client writes for non-sensitive data. [Asset Store](https://assetstore.unity.com/packages/essentials/tutorial-projects/unity-building-block-player-account-341928)
474
+ - **Leaderboards Building Block** — Uses Cloud Save for player score data alongside Cloud Code modules. [Asset Store](https://assetstore.unity.com/packages/essentials/tutorial-projects/unity-building-block-leaderboards-341926)
@@ -0,0 +1,216 @@
1
+ # Deployment Reference
2
+
3
+ ## Table of Contents
4
+
5
+ - [Overview](#overview)
6
+ - [Supported Service Integrations](#supported-service-integrations)
7
+ - [Workflow](#workflow)
8
+ - [Deployment Definitions (.ddef)](#deployment-definitions-ddef)
9
+ - [JSON Schema](#json-schema)
10
+ - [Behavior](#behavior)
11
+ - [Programmatic API](#programmatic-api)
12
+ - [Entry Point: Deployments.Instance](#entry-point-deploymentsinstance)
13
+ - [IDeploymentWindow](#ideploymentwindow)
14
+ - [DeploymentResult and DeploymentStatus](#deploymentresult-and-deploymentstatus)
15
+ - [SeverityLevel](#severitylevel)
16
+ - [DeploymentProvider (Abstract)](#deploymentprovider-abstract)
17
+ - [IDeploymentItem](#ideploymentitem)
18
+ - [Code Template -- Register a Custom Provider](#code-template--register-a-custom-provider)
19
+ - [Code Template -- Trigger Deployment Programmatically](#code-template--trigger-deployment-programmatically)
20
+
21
+ ## Overview
22
+
23
+ Editor-only package providing the **Deployment Window** (Services > Deployment). Deploys cloud resources for multiple UGS services from one place, without leaving the Unity Editor.
24
+
25
+ - **Package:** `com.unity.services.deployment`
26
+ - This package is Editor-only. Runtime code does not reference it.
27
+
28
+ ## Supported Service Integrations
29
+
30
+ Each service package registers its own file types with the Deployment Window. Install the relevant service package to enable its file types.
31
+
32
+ | Service | Package | File Type(s) | Min Version |
33
+ |---|---|---|---|
34
+ | Cloud Code Scripts | `com.unity.services.cloudcode` | `.js` | 2.1.0 |
35
+ | Cloud Code C# Modules | `com.unity.services.cloudcode` | `.ccmr` | 2.5.0 |
36
+ | Remote Config | `com.unity.remote-config` | `.rc` | 3.2.0 |
37
+ | Economy | `com.unity.services.economy` | `.ecc`, `.eci`, `.ecv`, `.ecr` | 3.2.1 |
38
+ | Leaderboards | `com.unity.services.leaderboards` | `.lb` | 2.0.0 |
39
+ | Game Server Hosting | `com.unity.services.multiplayer` | `.gsh` | 1.1.0 |
40
+ | Matchmaker | `com.unity.services.multiplayer` | `.mmq` | 1.0 |
41
+ | Game Overrides | `com.unity.services.tooling` | `.ugo` | 1.3.0 |
42
+ | Access Control | `com.unity.services.tooling` | `.ac` | 1.0 |
43
+ | Deployment Definitions | `com.unity.services.deployment` | `.ddef` | -- |
44
+
45
+ ## Workflow
46
+
47
+ 1. Add `com.unity.services.deployment` via Package Manager.
48
+ 2. Open **Services > Deployment**.
49
+ 3. Select the target environment in the dropdown.
50
+ 4. Choose files to deploy (or select all).
51
+ 5. Click **Deploy**.
52
+
53
+ ## Deployment Definitions (.ddef)
54
+
55
+ A Deployment Definition scopes the Deployment Window to a subset of files. Useful for large projects with multiple environments or teams.
56
+
57
+ **File extension:** `.ddef`
58
+
59
+ **Create via:** Right-click in Project window > Create > Unity Gaming Services > Deployment Definition
60
+
61
+ ### JSON Schema
62
+
63
+ ```json
64
+ {
65
+ "name": "GameplayServices",
66
+ "excludePaths": [
67
+ "Assets/CloudCode/Experimental/**",
68
+ "Assets/Config/Archive/**"
69
+ ]
70
+ }
71
+ ```
72
+
73
+ | Field | Type | Description |
74
+ |---|---|---|
75
+ | `name` | `string` | Display name shown in the Deployment Window |
76
+ | `excludePaths` | `string[]` | Glob patterns for files/folders to skip |
77
+
78
+ ### Behavior
79
+
80
+ - **Without a `.ddef`:** the Deployment Window discovers and deploys all UGS config files under `Assets/`.
81
+ - **With a `.ddef` selected:** only files within the definition's scope (minus excluded paths) are shown and deployed.
82
+ - Multiple `.ddef` files can exist in one project; select which one to use in the Deployment Window dropdown.
83
+
84
+ ## Programmatic API
85
+
86
+ The separate **`com.unity.services.deployment.api`** package (v1.1) provides programmatic access to the Deployment Window. All types in the main `com.unity.services.deployment` package are `internal` -- there is no public C# API from the main package.
87
+
88
+ - **Namespace:** `Unity.Services.DeploymentApi.Editor`
89
+
90
+ ### Entry Point: Deployments.Instance
91
+
92
+ | Member | Type | Description |
93
+ |---|---|---|
94
+ | `Instance` | `Deployments` | Static singleton |
95
+ | `DeploymentProviders` | `ObservableCollection<DeploymentProvider>` | All registered service providers |
96
+ | `DeploymentWindow` | `IDeploymentWindow` | Programmatic window control |
97
+ | `EnvironmentProvider` | `IEnvironmentProvider` | Current environment |
98
+ | `ProjectIdProvider` | `IProjectIdentifierProvider` | Current project ID |
99
+
100
+ ### IDeploymentWindow
101
+
102
+ | Member | Description |
103
+ |---|---|
104
+ | `Deploy(items, token)` | Returns `Task<DeploymentResult<IDeploymentItem>>` -- deploy selected items |
105
+ | `Deploy(filePaths, token)` | Extension: deploy items by file path (same return type) |
106
+ | `GetAllDeploymentItems(includeDeploymentDefinitions)` | Extension: get all items across all providers |
107
+ | `GetFromFiles(filePaths)` | Get items matching given file paths |
108
+ | `GetDeploymentDefinitions()` | Get available `.ddef` items |
109
+ | `OpenWindow()` | Opens the Deployment Window (`EditorWindow`) |
110
+ | `GetChecked()` / `GetSelected()` | Get checked/selected items (window must be open) |
111
+ | `Check(items)` / `ClearChecked()` | Programmatically check items |
112
+ | `Select(items)` / `ClearSelection()` | Programmatically select items |
113
+ | `DeploymentStarting` | `event Action<IReadOnlyList<IDeploymentItem>>` -- before deployment |
114
+ | `DeploymentEnded` | `event Action<IReadOnlyList<IDeploymentItem>>` -- after deployment |
115
+ | `GetCurrentDeployment()` | Returns the active `DeploymentScope`, or null |
116
+
117
+ ### DeploymentResult and DeploymentStatus
118
+
119
+ **DeploymentResult\<T\>**
120
+
121
+ | Member | Type | Description |
122
+ |---|---|---|
123
+ | `Deployed` | `List<T>` | Items that were successfully deployed |
124
+
125
+ **DeploymentStatus** has static factory methods for common states:
126
+
127
+ | Factory | Description |
128
+ |---|---|
129
+ | `Empty` / `UpToDate` / `ModifiedLocally` / `FailedToDeploy` | Static readonly instances |
130
+ | `GetDeployed(details)` / `GetDeploying(details)` | Deployment in-progress/complete |
131
+ | `GetFailedToDeploy(details)` / `GetFailedToFetch(details)` | Failure states |
132
+ | `GetFailedToLoad(e, path)` / `GetFailedToRead(e, path)` | File I/O failures |
133
+ | `GetFetched(details)` / `GetFetching(details)` | Fetch from remote states |
134
+ | `GetPartialDeploy(details)` / `GetPartialFetch(details)` | Partial completion |
135
+
136
+ ### SeverityLevel
137
+
138
+ | Value | Meaning |
139
+ |---|---|
140
+ | `None` (0) | No status |
141
+ | `Info` (1) | Informational |
142
+ | `Warning` (2) | Warning |
143
+ | `Error` (3) | Error |
144
+ | `Success` (4) | Success |
145
+
146
+ ### DeploymentProvider (Abstract)
147
+
148
+ Subclass this to expose your own deployable assets to the Deployment Window.
149
+
150
+ | Member | Description |
151
+ |---|---|
152
+ | `Service` | Display name for the service (abstract) |
153
+ | `DeployCommand` | Required deploy command (abstract) |
154
+ | `DeploymentItems` | `ObservableCollection<IDeploymentItem>` -- add/remove to populate the window |
155
+ | `Commands` | Additional context menu commands |
156
+ | `OpenCommand` | Double-click handler (optional) |
157
+ | `ValidateCommand` | Validation command (optional) |
158
+ | `SyncItemsWithRemoteCommand` | Sync-with-remote command (optional) |
159
+
160
+ ### IDeploymentItem
161
+
162
+ | Member | Description |
163
+ |---|---|
164
+ | `Name` | File name with extension |
165
+ | `Path` | Full asset path |
166
+ | `Progress` | Deploy progress 0-100 |
167
+ | `Status` | `DeploymentStatus` (message + severity) |
168
+ | `States` | `ObservableCollection<AssetState>` -- local asset validation states |
169
+
170
+ ### Code Template -- Register a Custom Provider
171
+
172
+ ```csharp
173
+ using UnityEditor;
174
+ using Unity.Services.DeploymentApi.Editor;
175
+
176
+ class MyServiceDeploymentProvider : DeploymentProvider
177
+ {
178
+ public override string Service => "MyService";
179
+ public override Command DeployCommand { get; } = new MyDeployCommand();
180
+ }
181
+
182
+ [InitializeOnLoadMethod]
183
+ static void RegisterProvider()
184
+ {
185
+ Deployments.Instance.DeploymentProviders.Add(new MyServiceDeploymentProvider());
186
+ }
187
+ ```
188
+
189
+ > **Deploy commands that write to UGS services** must use `IAdminClient` from the
190
+ > `com.unity.services.apis` package (`com.unity.services.apis`). Authenticate with a service
191
+ > account via `adminClient.SetServiceAccount(keyId, keySecret)`, then call the appropriate
192
+ > admin API (e.g. `adminClient.CloudSaveData.SetCustomItem` for Cloud Save game data).
193
+ > See [apis.md](apis.md) for the full `IAdminClient` interface and code templates.
194
+
195
+ ### Code Template -- Trigger Deployment Programmatically
196
+
197
+ ```csharp
198
+ using Unity.Services.DeploymentApi.Editor;
199
+
200
+ // Deploy all items
201
+ var allItems = Deployments.Instance.DeploymentWindow.GetAllDeploymentItems();
202
+ var result = await Deployments.Instance.DeploymentWindow.Deploy(allItems);
203
+
204
+ // Deploy by file paths
205
+ await Deployments.Instance.DeploymentWindow.Deploy(new[] { "Assets/MyConfig.rc" });
206
+
207
+ // Listen for deployment events
208
+ Deployments.Instance.DeploymentWindow.DeploymentStarting += items =>
209
+ {
210
+ Debug.Log($"Deploying {items.Count} items...");
211
+ };
212
+ Deployments.Instance.DeploymentWindow.DeploymentEnded += items =>
213
+ {
214
+ Debug.Log($"Deployment complete: {items.Count} items");
215
+ };
216
+ ```