@aqian0/dsh-unity 0.0.0-stage → 0.1.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 (360) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/LICENSE-UNITY-COMPANION.md +122 -0
  3. package/LICENSE.md +31 -0
  4. package/NOTICE.md +90 -0
  5. package/README.md +273 -2
  6. package/cordis.patch.yml +22 -0
  7. package/docs/design.md +297 -0
  8. package/icon.svg +16 -0
  9. package/lib/frontmatter.js +392 -0
  10. package/lib/gating.js +105 -0
  11. package/lib/harness.js +16 -0
  12. package/lib/index.js +171 -0
  13. package/lib/project.js +210 -0
  14. package/lib/registry.js +268 -0
  15. package/lib/requirements.js +214 -0
  16. package/lib/skills.js +191 -0
  17. package/lib/types/frontmatter.d.ts +84 -0
  18. package/lib/types/gating.d.ts +80 -0
  19. package/lib/types/harness.d.ts +152 -0
  20. package/lib/types/index.d.ts +75 -0
  21. package/lib/types/project.d.ts +93 -0
  22. package/lib/types/registry.d.ts +96 -0
  23. package/lib/types/requirements.d.ts +67 -0
  24. package/lib/types/skills.d.ts +54 -0
  25. package/lib/types/watch.d.ts +34 -0
  26. package/lib/watch.js +84 -0
  27. package/locale/en.json +6 -0
  28. package/locale/zh.json +6 -0
  29. package/package.json +70 -4
  30. package/skills/2d-pixel-perfect/SKILL.md +208 -0
  31. package/skills/2d-pixel-perfect/references/api-reference.md +81 -0
  32. package/skills/2d-pixel-perfect/references/camera-setup-builtin.cs +40 -0
  33. package/skills/2d-pixel-perfect/references/camera-setup-urp.cs +49 -0
  34. package/skills/2d-pixel-perfect/references/pipeline-detection.cs +50 -0
  35. package/skills/2d-pixel-perfect/references/sprite-settings.cs +37 -0
  36. package/skills/asset-transformer-toolkit/SECURITY.md +15 -0
  37. package/skills/asset-transformer-toolkit/SKILL.md +39 -0
  38. package/skills/asset-transformer-toolkit/references/create-importer.md +121 -0
  39. package/skills/asset-transformer-toolkit/references/lods.md +61 -0
  40. package/skills/asset-transformer-toolkit/references/rule-api.md +154 -0
  41. package/skills/asset-transformer-toolkit/references/ruleblock-api.md +37 -0
  42. package/skills/asset-transformer-toolkit/references/ruleset-api.md +138 -0
  43. package/skills/asset-transformer-toolkit/references/rulesets-and-actions.md +227 -0
  44. package/skills/audio-setup-mixers/SECURITY.md +16 -0
  45. package/skills/audio-setup-mixers/SKILL.md +127 -0
  46. package/skills/audio-setup-mixers/references/api.md +162 -0
  47. package/skills/build-gtk/SECURITY.md +16 -0
  48. package/skills/build-gtk/SKILL.md +200 -0
  49. package/skills/build-gtk/references/api-reference.md +33 -0
  50. package/skills/build-gtk/references/graph-api-gaps.md +96 -0
  51. package/skills/build-gtk/references/runtime-and-visualization.md +191 -0
  52. package/skills/build-gtk/references/state-machine-api.md +270 -0
  53. package/skills/build-gtk/references/where-the-docs-stop.md +49 -0
  54. package/skills/build-live-game/SKILL.md +159 -0
  55. package/skills/build-live-game/references/achievements.md +757 -0
  56. package/skills/build-live-game/references/apis.md +271 -0
  57. package/skills/build-live-game/references/authentication.md +431 -0
  58. package/skills/build-live-game/references/battlepass.md +904 -0
  59. package/skills/build-live-game/references/blueprints-and-samples.md +75 -0
  60. package/skills/build-live-game/references/cloud-code-cloudbehaviours.md +1111 -0
  61. package/skills/build-live-game/references/cloud-code-modules.md +1276 -0
  62. package/skills/build-live-game/references/cloud-code.md +58 -0
  63. package/skills/build-live-game/references/cloud-save.md +464 -0
  64. package/skills/build-live-game/references/deployment.md +231 -0
  65. package/skills/build-live-game/references/orientation.md +30 -0
  66. package/skills/build-live-game/references/player-account.md +821 -0
  67. package/skills/build-live-game/references/remote-config.md +96 -0
  68. package/skills/build-live-game/references/services-overview.md +76 -0
  69. package/skills/build-live-game/references/tooling.md +375 -0
  70. package/skills/build-live-game/references/ugs-cli.md +86 -0
  71. package/skills/craft-game-floors/SECURITY.md +23 -0
  72. package/skills/craft-game-floors/SKILL.md +134 -0
  73. package/skills/craft-game-floors/references/art-direction.md +85 -0
  74. package/skills/craft-game-floors/references/camera-rigs.md +51 -0
  75. package/skills/craft-game-floors/references/character-motion.md +35 -0
  76. package/skills/craft-game-floors/references/game-audio.md +47 -0
  77. package/skills/craft-game-floors/references/game-feel.md +68 -0
  78. package/skills/craft-game-floors/references/game-shell.md +45 -0
  79. package/skills/craft-game-floors/references/live-floor.md +35 -0
  80. package/skills/craft-game-floors/references/placeholder-assets.md +35 -0
  81. package/skills/craft-game-floors/references/scene-lighting.md +52 -0
  82. package/skills/craft-game-floors/references/toon-shading.md +34 -0
  83. package/skills/craft-game-floors/references/vfx.md +40 -0
  84. package/skills/craft-game-floors/references/visual-scorecard.md +43 -0
  85. package/skills/create-2d-physics/SECURITY.md +16 -0
  86. package/skills/create-2d-physics/SKILL.md +128 -0
  87. package/skills/create-2d-physics/references/2d-physics-core.md +155 -0
  88. package/skills/create-2d-physics/references/legacy-2d-physics.md +45 -0
  89. package/skills/create-tile-palette-or-rule-tiles/SKILL.md +95 -0
  90. package/skills/create-tile-palette-or-rule-tiles/references/hexagonalruletile.md +71 -0
  91. package/skills/create-tile-palette-or-rule-tiles/references/palette-create.md +38 -0
  92. package/skills/create-tile-palette-or-rule-tiles/references/ruletile-createempty.md +37 -0
  93. package/skills/create-tile-palette-or-rule-tiles/references/ruletile-createfromsegment.md +219 -0
  94. package/skills/create-tile-palette-or-rule-tiles/references/ruletile.md +95 -0
  95. package/skills/create-tile-palette-or-rule-tiles/scripts/CreatePaletteTemplate.cs +148 -0
  96. package/skills/create-tile-palette-or-rule-tiles/scripts/ManualWorkflowExample.cs +63 -0
  97. package/skills/create-tile-palette-or-rule-tiles/scripts/RuleTileGenerator.cs +61 -0
  98. package/skills/create-tile-palette-or-rule-tiles/scripts/TilemapRuleTileCreateFromSegment.cs +225 -0
  99. package/skills/fix-3d-physics-collisions/SECURITY.md +17 -0
  100. package/skills/fix-3d-physics-collisions/SKILL.md +139 -0
  101. package/skills/fix-3d-physics-collisions/references/collision-checklist.md +80 -0
  102. package/skills/fix-3d-physics-collisions/references/collision-debugger.md +18 -0
  103. package/skills/fix-3d-physics-collisions/references/console-errors-table.md +9 -0
  104. package/skills/fix-3d-physics-collisions/references/kinematic-trigger-facts.md +18 -0
  105. package/skills/fix-3d-physics-collisions/references/other-symptoms.md +29 -0
  106. package/skills/fix-3d-physics-collisions/references/raycast-checklist.md +8 -0
  107. package/skills/fix-3d-physics-collisions/references/topic-map.md +42 -0
  108. package/skills/fix-3d-physics-collisions/references/trigger-checklist.md +9 -0
  109. package/skills/fix-3d-physics-collisions/scripts/CollisionDebugger.cs +561 -0
  110. package/skills/generate-editor-search-query/SECURITY.md +17 -0
  111. package/skills/generate-editor-search-query/SKILL.md +117 -0
  112. package/skills/generate-editor-search-query/references/open-search-window.md +70 -0
  113. package/skills/generate-editor-search-query/references/query-patterns.md +124 -0
  114. package/skills/implement-in-app-purchases/SKILL.md +82 -0
  115. package/skills/implement-in-app-purchases/references/api-details.md +41 -0
  116. package/skills/implement-in-app-purchases/references/api-notes.md +105 -0
  117. package/skills/implement-in-app-purchases/references/codeless-catalog.md +197 -0
  118. package/skills/implement-in-app-purchases/references/convert-adapty.md +270 -0
  119. package/skills/implement-in-app-purchases/references/convert-essentialkit.md +239 -0
  120. package/skills/implement-in-app-purchases/references/convert-revenuecat.md +277 -0
  121. package/skills/implement-in-app-purchases/references/convert-unipay.md +145 -0
  122. package/skills/implement-in-app-purchases/references/migration-v4-to-v5.md +46 -0
  123. package/skills/implement-in-app-purchases/references/path-add-iap-to-new-project.md +197 -0
  124. package/skills/implement-in-app-purchases/references/path-convert-native-google-billing.md +302 -0
  125. package/skills/implement-in-app-purchases/references/path-convert-native-storekit.md +357 -0
  126. package/skills/implement-in-app-purchases/references/path-implement-iap-d2c.md +253 -0
  127. package/skills/implement-in-app-purchases/references/platform-notes.md +55 -0
  128. package/skills/implement-in-app-purchases/references/pre-check.md +207 -0
  129. package/skills/implement-in-app-purchases/references/topic-map.md +46 -0
  130. package/skills/initialize-ai-navigation/SKILL.md +109 -0
  131. package/skills/initialize-ai-navigation/references/navigation-system.md +793 -0
  132. package/skills/initialize-ai-navigation/references/topic-map.md +66 -0
  133. package/skills/levelplay-unity-integration/SKILL.md +122 -0
  134. package/skills/levelplay-unity-integration/references/adding-more-ad-formats.md +15 -0
  135. package/skills/levelplay-unity-integration/references/banner-api.md +927 -0
  136. package/skills/levelplay-unity-integration/references/best-practices.md +604 -0
  137. package/skills/levelplay-unity-integration/references/dependency-resolution.md +94 -0
  138. package/skills/levelplay-unity-integration/references/examples.md +10 -0
  139. package/skills/levelplay-unity-integration/references/ilrd-api.md +337 -0
  140. package/skills/levelplay-unity-integration/references/initialization-api.md +851 -0
  141. package/skills/levelplay-unity-integration/references/interstitial-api.md +907 -0
  142. package/skills/levelplay-unity-integration/references/ios-setup.md +463 -0
  143. package/skills/levelplay-unity-integration/references/migration-sdk-9.md +666 -0
  144. package/skills/levelplay-unity-integration/references/privacy-settings.md +593 -0
  145. package/skills/levelplay-unity-integration/references/production-release-checklist.md +22 -0
  146. package/skills/levelplay-unity-integration/references/rewarded-api.md +918 -0
  147. package/skills/levelplay-unity-integration/references/step-0-new-or-migration.md +8 -0
  148. package/skills/levelplay-unity-integration/references/step-1-verify-environment.md +4 -0
  149. package/skills/levelplay-unity-integration/references/step-10-testing.md +15 -0
  150. package/skills/levelplay-unity-integration/references/step-2-business-goals.md +12 -0
  151. package/skills/levelplay-unity-integration/references/step-3-install-sdk.md +55 -0
  152. package/skills/levelplay-unity-integration/references/step-4-native-dependencies.md +22 -0
  153. package/skills/levelplay-unity-integration/references/step-5-app-key-and-ad-units.md +18 -0
  154. package/skills/levelplay-unity-integration/references/step-6-5-privacy-and-regulation.md +51 -0
  155. package/skills/levelplay-unity-integration/references/step-6-admob-keys.md +16 -0
  156. package/skills/levelplay-unity-integration/references/step-7-initialize.md +50 -0
  157. package/skills/levelplay-unity-integration/references/step-8-ad-unit-strategy.md +16 -0
  158. package/skills/levelplay-unity-integration/references/step-9-implement-ad-units.md +66 -0
  159. package/skills/levelplay-unity-integration/references/testing-and-validation.md +222 -0
  160. package/skills/levelplay-unity-integration/references/troubleshooting.md +99 -0
  161. package/skills/localize-unity-project/SKILL.md +159 -0
  162. package/skills/localize-unity-project/references/api-notes.md +15 -0
  163. package/skills/localize-unity-project/references/cjk-fonts.md +83 -0
  164. package/skills/localize-unity-project/references/docs-map.md +42 -0
  165. package/skills/localize-unity-project/references/documentation-lookup.md +33 -0
  166. package/skills/localize-unity-project/references/locale-switching.md +17 -0
  167. package/skills/localize-unity-project/references/table-completeness-check.md +47 -0
  168. package/skills/localize-unity-project/references/translating-existing-project.md +47 -0
  169. package/skills/localize-unity-project/references/translation-strategy.md +41 -0
  170. package/skills/localize-unity-project/references/troubleshooting.md +12 -0
  171. package/skills/localize-unity-project/scripts/L10nBatchProcessor.cs +191 -0
  172. package/skills/localize-unity-project/scripts/LocalizedFontAsset.cs +18 -0
  173. package/skills/manage-sprite-atlas/SKILL.md +202 -0
  174. package/skills/manage-sprite-atlas/references/addressables-delivery.md +58 -0
  175. package/skills/manage-sprite-atlas/references/advanced-manual-authoring.md +19 -0
  176. package/skills/manage-sprite-atlas/references/api.md +382 -0
  177. package/skills/manage-sprite-atlas/references/best-practices.md +183 -0
  178. package/skills/manage-sprite-atlas/references/common-errors.md +123 -0
  179. package/skills/manage-sprite-atlas/references/complete-workflow.md +61 -0
  180. package/skills/manage-sprite-atlas/references/custom-packing.md +147 -0
  181. package/skills/manage-sprite-atlas/references/delivery-mechanism.md +30 -0
  182. package/skills/manage-sprite-atlas/references/key-requirements.md +21 -0
  183. package/skills/manage-sprite-atlas/references/manual-authoring.md +39 -0
  184. package/skills/manage-sprite-atlas/references/namespaces.md +15 -0
  185. package/skills/manage-sprite-atlas/references/v2-architecture.md +21 -0
  186. package/skills/manage-sprite-atlas/resources/authoringvsruntime.cs +176 -0
  187. package/skills/manage-sprite-atlas/resources/buildaddressablespostprocess.cs +59 -0
  188. package/skills/manage-sprite-atlas/resources/cacheloadedatlases.cs +145 -0
  189. package/skills/manage-sprite-atlas/resources/cleanupbatchoperations.cs +119 -0
  190. package/skills/manage-sprite-atlas/resources/createandconfiguremasteratlas.cs +57 -0
  191. package/skills/manage-sprite-atlas/resources/custompackersetup.cs +88 -0
  192. package/skills/manage-sprite-atlas/resources/deprecatedmethods.cs +142 -0
  193. package/skills/manage-sprite-atlas/resources/dontmodifywithoutsaving.cs +120 -0
  194. package/skills/manage-sprite-atlas/resources/dontpackinruntimebuilds.cs +190 -0
  195. package/skills/manage-sprite-atlas/resources/dontscriptspriteatlasineditor.cs +114 -0
  196. package/skills/manage-sprite-atlas/resources/editorconfiguration.cs +95 -0
  197. package/skills/manage-sprite-atlas/resources/enablespritepacking.cs +172 -0
  198. package/skills/manage-sprite-atlas/resources/gridspritepacker.cs +50 -0
  199. package/skills/manage-sprite-atlas/resources/handlelatebinding.cs +147 -0
  200. package/skills/manage-sprite-atlas/resources/handlenullcases.cs +141 -0
  201. package/skills/manage-sprite-atlas/resources/migratev1tov2.cs +335 -0
  202. package/skills/manage-sprite-atlas/resources/multipagepacker.cs +80 -0
  203. package/skills/manage-sprite-atlas/resources/optimizetexturesettings.cs +191 -0
  204. package/skills/manage-sprite-atlas/resources/packerdebugging.cs +158 -0
  205. package/skills/manage-sprite-atlas/resources/packtransform.cs +51 -0
  206. package/skills/manage-sprite-atlas/resources/platformnames.cs +127 -0
  207. package/skills/manage-sprite-atlas/resources/queryspritesefficiently.cs +222 -0
  208. package/skills/manage-sprite-atlas/resources/registercallbacks.cs +152 -0
  209. package/skills/manage-sprite-atlas/resources/runtimeatlasloader.cs +15 -0
  210. package/skills/manage-sprite-atlas/resources/runtimespriteaccess.cs +19 -0
  211. package/skills/manage-sprite-atlas/resources/savespriteatlasasset.cs +107 -0
  212. package/skills/manage-sprite-atlas/resources/scriptablepacker.cs +81 -0
  213. package/skills/manage-sprite-atlas/resources/setincludeinbuild.cs +164 -0
  214. package/skills/manage-sprite-atlas/resources/sizeoptimizedpacker.cs +88 -0
  215. package/skills/manage-sprite-atlas/resources/spriteatlaslatebinding.cs +123 -0
  216. package/skills/manage-sprite-atlas/resources/spriteatlasprebuildgenerator.cs +219 -0
  217. package/skills/manage-sprite-atlas/resources/spritedata.cs +35 -0
  218. package/skills/manage-sprite-atlas/resources/spritepack.cs +39 -0
  219. package/skills/manage-sprite-atlas/resources/texturedata.cs +15 -0
  220. package/skills/manage-sprite-atlas/resources/updatebuildscripts.cs +357 -0
  221. package/skills/manage-sprite-atlas/resources/updatesettingsconfiguration.cs +135 -0
  222. package/skills/manage-sprite-atlas/resources/usevariantswisely.cs +179 -0
  223. package/skills/manage-sprite-atlas/resources/variantatlas.cs +39 -0
  224. package/skills/migrate-birp-to-urp/SECURITY.md +16 -0
  225. package/skills/migrate-birp-to-urp/SKILL.md +167 -0
  226. package/skills/migrate-birp-to-urp/references/capturing-the-editor.md +66 -0
  227. package/skills/migrate-birp-to-urp/references/complex-shader-situations.md +272 -0
  228. package/skills/migrate-birp-to-urp/references/conversion-and-rendering-triage.md +113 -0
  229. package/skills/migrate-birp-to-urp/references/custom-shader-triage.md +123 -0
  230. package/skills/migrate-birp-to-urp/references/implementation-patterns.md +529 -0
  231. package/skills/migrate-birp-to-urp/references/migration-workflow.md +265 -0
  232. package/skills/migrate-birp-to-urp/references/parity-validation-and-troubleshooting.md +114 -0
  233. package/skills/migrate-birp-to-urp/references/preflight-and-urp-setup.md +195 -0
  234. package/skills/migrate-birp-to-urp/references/quality-settings-map.md +69 -0
  235. package/skills/new-unity-project/SECURITY.md +26 -0
  236. package/skills/new-unity-project/SKILL.md +171 -0
  237. package/skills/new-unity-project/references/checklist.md +18 -0
  238. package/skills/new-unity-project/references/common-mistakes.md +15 -0
  239. package/skills/new-unity-project/references/skill-setup.md +66 -0
  240. package/skills/new-unity-project/references/step-1-concept.md +13 -0
  241. package/skills/new-unity-project/references/step-2-platforms-and-create.md +31 -0
  242. package/skills/new-unity-project/references/step-3-join-and-reconcile.md +16 -0
  243. package/skills/new-unity-project/references/step-4-source-control.md +9 -0
  244. package/skills/new-unity-project/references/step-5-packages.md +18 -0
  245. package/skills/new-unity-project/references/step-6-identity-and-floors.md +20 -0
  246. package/skills/new-unity-project/references/step-7-visual-baseline.md +75 -0
  247. package/skills/new-unity-project/references/step-8-first-commit.md +21 -0
  248. package/skills/new-unity-project/references/step-9-handoff.md +23 -0
  249. package/skills/optimize-audio/SECURITY.md +16 -0
  250. package/skills/optimize-audio/SKILL.md +120 -0
  251. package/skills/optimize-audio/references/diagnostics.md +42 -0
  252. package/skills/optimize-audio/references/troubleshooting.md +41 -0
  253. package/skills/optimize-audio/resources/audio-import-api.md +149 -0
  254. package/skills/optimize-audio/resources/platform-settings.md +48 -0
  255. package/skills/optimize-text-mesh-pro/SKILL.md +181 -0
  256. package/skills/optimize-text-mesh-pro/references/dynamic-atlas-and-profiling.md +28 -0
  257. package/skills/optimize-text-mesh-pro/references/topic-map.md +36 -0
  258. package/skills/optimize-web/SECURITY.md +16 -0
  259. package/skills/optimize-web/SKILL.md +157 -0
  260. package/skills/optimize-web/references/editor-csharp.md +120 -0
  261. package/skills/optimize-web/references/topic-map.md +49 -0
  262. package/skills/optimize-web/references/troubleshooting.md +45 -0
  263. package/skills/optimize-web/references/understand-request.md +19 -0
  264. package/skills/optimize-web/references/web-assets-quality.md +59 -0
  265. package/skills/optimize-web/references/web-player-settings.md +39 -0
  266. package/skills/optimize-web/references/web-profiling-memory.md +71 -0
  267. package/skills/optimize-web/scripts/WebOptimizer.cs +46 -0
  268. package/skills/optimize-web/scripts/toktx-examples.sh +11 -0
  269. package/skills/setup-multiplayer-services/SKILL.md +36 -0
  270. package/skills/setup-multiplayer-services/references/dgs-entrypoint.md +79 -0
  271. package/skills/setup-multiplayer-services/references/entrypoints.md +213 -0
  272. package/skills/setup-multiplayer-services/references/examples.md +33 -0
  273. package/skills/setup-multiplayer-services/references/implementation-fit.md +30 -0
  274. package/skills/setup-multiplayer-services/references/underlying-services.md +11 -0
  275. package/skills/setup-multiplayer-services/references/workflows-prerequisites.md +17 -0
  276. package/skills/setup-vivox-voice-chat/SECURITY.md +16 -0
  277. package/skills/setup-vivox-voice-chat/SKILL.md +166 -0
  278. package/skills/setup-vivox-voice-chat/references/api-reference-lookup.md +28 -0
  279. package/skills/setup-vivox-voice-chat/references/docs-topic-map.md +13 -0
  280. package/skills/setup-vivox-voice-chat/references/events-and-participants.md +79 -0
  281. package/skills/setup-vivox-voice-chat/references/init-and-login.md +92 -0
  282. package/skills/setup-vivox-voice-chat/references/text-chat.md +93 -0
  283. package/skills/setup-vivox-voice-chat/references/troubleshooting.md +47 -0
  284. package/skills/setup-vivox-voice-chat/references/voice-channels.md +92 -0
  285. package/skills/shader-graph-create-custom-node/SKILL.md +25 -0
  286. package/skills/shader-graph-create-custom-node/resources/all_hints.hlsl +182 -0
  287. package/skills/sprite-editor/SECURITY.md +16 -0
  288. package/skills/sprite-editor/SKILL.md +66 -0
  289. package/skills/sprite-editor/references/api_reference.md +151 -0
  290. package/skills/sprite-editor/references/background.md +112 -0
  291. package/skills/sprite-editor/references/templates.md +72 -0
  292. package/skills/sprite-editor/scripts/AutomaticSliceTexture.cs +40 -0
  293. package/skills/sprite-editor/scripts/GenerateNewSpriteRects.cs +200 -0
  294. package/skills/sprite-editor/scripts/GetTextureSourceImageSize.cs +32 -0
  295. package/skills/sprite-editor/scripts/GetTextureToSlice.cs +55 -0
  296. package/skills/sprite-editor/scripts/GridSliceTexture.cs +40 -0
  297. package/skills/sprite-editor/scripts/IsometricSliceTexture.cs +141 -0
  298. package/skills/sprite-editor/scripts/README.md +134 -0
  299. package/skills/sprite-editor/scripts/SetPivotExample.cs +58 -0
  300. package/skills/sprite-editor/scripts/SpriteToPng.cs +88 -0
  301. package/skills/sprite-segment-3x3grid/SKILL.md +177 -0
  302. package/skills/sprite-segment-3x3grid/references/topic-map.md +37 -0
  303. package/skills/sprite-segment-3x3grid/scripts/SpriteGridAnalysis.cs +119 -0
  304. package/skills/ui/SKILL.md +142 -0
  305. package/skills/ui-imgui/SKILL.md +180 -0
  306. package/skills/ui-imgui/references/gui-elements.md +156 -0
  307. package/skills/ui-imgui/references/templates.md +141 -0
  308. package/skills/ui-ugui/SKILL.md +217 -0
  309. package/skills/ui-ugui/references/layout-and-anchors.md +61 -0
  310. package/skills/ui-ugui/references/scrollview-setup.md +29 -0
  311. package/skills/ui-uitk/SKILL.md +229 -0
  312. package/skills/ui-uitk/references/common-issues.md +74 -0
  313. package/skills/ui-uitk/references/custom-elements.md +241 -0
  314. package/skills/ui-uitk/references/painter2d.md +282 -0
  315. package/skills/ui-uitk/references/pointermanipulator-guide.md +94 -0
  316. package/skills/ui-uitk/references/svg-icons.md +136 -0
  317. package/skills/ui-uitk/references/ui-runtime-binding.md +234 -0
  318. package/skills/ui-uitk/references/uss-guide.md +138 -0
  319. package/skills/unity-cli/CHANGELOG.md +524 -0
  320. package/skills/unity-cli/SECURITY.md +68 -0
  321. package/skills/unity-cli/SKILL.md +160 -0
  322. package/skills/unity-cli/references/auth-license-cloud.md +318 -0
  323. package/skills/unity-cli/references/bootstrap-project.md +177 -0
  324. package/skills/unity-cli/references/build-run-test.md +555 -0
  325. package/skills/unity-cli/references/catalog-plugins.md +86 -0
  326. package/skills/unity-cli/references/ci-recipes.md +76 -0
  327. package/skills/unity-cli/references/cloud-automation.md +819 -0
  328. package/skills/unity-cli/references/cloud-workflows.md +19 -0
  329. package/skills/unity-cli/references/collaboration.md +533 -0
  330. package/skills/unity-cli/references/config-hub.md +239 -0
  331. package/skills/unity-cli/references/diagnostics-maintenance.md +718 -0
  332. package/skills/unity-cli/references/docs-workflow.md +179 -0
  333. package/skills/unity-cli/references/editor-targeting.md +29 -0
  334. package/skills/unity-cli/references/editors-install.md +490 -0
  335. package/skills/unity-cli/references/environment-variables.md +42 -0
  336. package/skills/unity-cli/references/exit-codes.md +47 -0
  337. package/skills/unity-cli/references/global-flags.md +32 -0
  338. package/skills/unity-cli/references/integration-advanced.md +1130 -0
  339. package/skills/unity-cli/references/notes.md +20 -0
  340. package/skills/unity-cli/references/notifications.md +39 -0
  341. package/skills/unity-cli/references/playmode-verification-loop.md +279 -0
  342. package/skills/unity-cli/references/projects-templates.md +997 -0
  343. package/skills/unity-cli/references/scene-editing-preflight.md +25 -0
  344. package/skills/unity-cli/references/setup-and-help.md +54 -0
  345. package/skills/unity-cli/references/version-control.md +612 -0
  346. package/skills/unity-package-management/SKILL.md +169 -0
  347. package/skills/unity-package-management/references/discovering-packages.md +66 -0
  348. package/skills/unity-package-management/references/headless-run.md +31 -0
  349. package/skills/unity-package-management/references/installer-script.md +92 -0
  350. package/skills/unity-package-management/references/select-packages.md +126 -0
  351. package/skills/unity-pipeline/SECURITY.md +17 -0
  352. package/skills/unity-pipeline/SKILL.md +205 -0
  353. package/skills/unity-pipeline/references/csharp-eval.md +23 -0
  354. package/skills/unity-pipeline/references/multiplayer-play-mode.md +103 -0
  355. package/skills/urp-postprocessing/SECURITY.md +16 -0
  356. package/skills/urp-postprocessing/SKILL.md +188 -0
  357. package/skills/urp-postprocessing/references/code-templates.md +150 -0
  358. package/skills/urp-postprocessing/references/effect-reference.md +86 -0
  359. package/skills/validate-urp-render-graph-renderer-feature/SKILL.md +92 -0
  360. package/skills/validate-urp-render-graph-renderer-feature/references/validation-checklist.md +179 -0
@@ -0,0 +1,821 @@
1
+ # Player Account Reference
2
+
3
+ ## Table of Contents
4
+
5
+ - [Architecture Overview](#architecture-overview)
6
+ - [Access Classes](#access-classes)
7
+ - [Assembly References](#assembly-references)
8
+ - [Package Setup](#package-setup)
9
+ - [Sign-In: Anonymous](#sign-in-anonymous)
10
+ - [Sign-In: Unity (Browser)](#sign-in-unity-browser)
11
+ - [PlayerAccountService API](#playeraccountservice-api)
12
+ - [Sign-In: Username/Password](#sign-in-usernamepassword)
13
+ - [Username/Password Constraints](#usernamepassword-constraints)
14
+ - [Player Identity](#player-identity)
15
+ - [Cloud Save Operations](#cloud-save-operations)
16
+ - [Namespace Aliases](#namespace-aliases)
17
+ - [Save Default Data](#save-default-data-private-to-player)
18
+ - [Save Public Data](#save-public-data-visible-to-other-players)
19
+ - [Load Default Data](#load-default-data)
20
+ - [Load Public Data](#load-public-data-own)
21
+ - [Load Public Data (Other Player)](#load-public-data-another-player)
22
+ - [Load All Keys](#load-all-keys)
23
+ - [Server-Authoritative Writes via Cloud Code (Optional)](#server-authoritative-writes-via-cloud-code-optional)
24
+ - [Reading Protected Data](#reading-protected-data-client-side)
25
+ - [Writing Protected/Custom Data](#writing-protectedcustom-data-server-side)
26
+ - [Full Client Implementation](#full-client-implementation)
27
+ - [PlayerAccountTester](#playeraccounttester)
28
+ - [Assembly Definition](#assembly-definition)
29
+ - [Error Handling](#error-handling)
30
+ - [AuthenticationException](#authenticationexception)
31
+ - [PlayerAccountsException](#playeraccountsexception)
32
+ - [CloudSaveException](#cloudsaveexception)
33
+ - [Validation](#validation)
34
+
35
+ ---
36
+
37
+ ## Architecture Overview
38
+
39
+ | Concern | Service | API |
40
+ |---|---|---|
41
+ | Sign in (anonymous) | Authentication | `SignInAnonymouslyAsync()` |
42
+ | Sign in (Unity browser) | PlayerAccounts then Authentication | `StartSignInAsync()` then `SignInWithUnityAsync(AccessToken)` |
43
+ | Sign in (username/password) | Authentication | `SignUpWithUsernamePasswordAsync` / `SignInWithUsernamePasswordAsync` |
44
+ | Player identity | Authentication | `PlayerId`, `PlayerName`, `UpdatePlayerNameAsync` |
45
+ | Per-player data | Cloud Save | `CloudSaveService.Instance.Data.Player` |
46
+
47
+ ```
48
+ UnityServices.InitializeAsync()
49
+ |
50
+ v
51
+ AuthenticationService.Instance
52
+ |
53
+ +--------+-----------+
54
+ | | |
55
+ v v v
56
+ Anon Unity/PA Password
57
+ | (browser) |
58
+ | | |
59
+ | PlayerAccountService.Instance
60
+ | .StartSignInAsync()
61
+ | |
62
+ | SignedIn event fires
63
+ | |
64
+ | SignInWithUnityAsync(AccessToken)
65
+ | | |
66
+ +--------+-----------+
67
+ |
68
+ v
69
+ PlayerId / PlayerName
70
+ |
71
+ v
72
+ CloudSaveService.Instance.Data.Player
73
+ | | |
74
+ v v v
75
+ Default Public Protected
76
+ (owner (anyone (owner read,
77
+ read+write) read, server-only
78
+ owner write)
79
+ write)
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Access Classes
85
+
86
+ Cloud Save player data supports three access classes. The access class used when saving determines which access class must be used when loading.
87
+
88
+ | Access Class | Read | Write | Use Case |
89
+ |---|---|---|---|
90
+ | Default | Owner only | Owner only | Private settings, preferences, game progress |
91
+ | Public | Any player | Owner only | Display names, public profiles, shared stats |
92
+ | Protected | Owner only | Server only (Cloud Code) | Anti-cheat data, server-awarded state |
93
+
94
+ ---
95
+
96
+ ## Assembly References
97
+
98
+ Your `.asmdef` must reference all four assemblies. `Unity.Services.Authentication.PlayerAccounts` is a **separate assembly** from `Unity.Services.Authentication`, even though both ship inside the `com.unity.services.authentication` package.
99
+
100
+ | Assembly Name | Package | Purpose |
101
+ |---|---|---|
102
+ | `Unity.Services.Core` | `com.unity.services.core` | `UnityServices.InitializeAsync()` |
103
+ | `Unity.Services.Authentication` | `com.unity.services.authentication` | `AuthenticationService.Instance`, sign-in methods, player identity |
104
+ | `Unity.Services.Authentication.PlayerAccounts` | `com.unity.services.authentication` (separate assembly in same package) | `PlayerAccountService.Instance`, browser-based Unity sign-in |
105
+ | `Unity.Services.CloudSave` | `com.unity.services.cloudsave` | `CloudSaveService.Instance.Data.Player`, save/load operations |
106
+
107
+ ---
108
+
109
+ ## Package Setup
110
+
111
+ Ensure the following packages are listed in `Packages/manifest.json`:
112
+
113
+ ```json
114
+ {
115
+ "dependencies": {
116
+ "com.unity.services.authentication": "3.6.1",
117
+ "com.unity.services.cloudsave": "3.4.0",
118
+ "com.unity.services.core": "1.16.0"
119
+ }
120
+ }
121
+ ```
122
+
123
+ **Optional** — add `com.unity.services.cloudcode` if using Protected player data or Custom (shared) data:
124
+
125
+ ```json
126
+ "com.unity.services.cloudcode": "3.0.0"
127
+ ```
128
+
129
+ > `com.unity.services.cloudcode` **`3.0.0`** is the native-authoring line, which the `.ccmu` module
130
+ > below requires — see the Requirements section of `references/cloud-code-modules.md`. The `2.10.x` line
131
+ > deploys legacy `.ccmr` modules only; use it when maintaining one, not for new work.
132
+
133
+ ---
134
+
135
+ ## Sign-In: Anonymous
136
+
137
+ ```csharp
138
+ using Unity.Services.Core;
139
+ using Unity.Services.Authentication;
140
+ using UnityEngine;
141
+
142
+ async Task SignInAnonymouslyAsync()
143
+ {
144
+ await UnityServices.InitializeAsync();
145
+
146
+ if (!AuthenticationService.Instance.IsSignedIn)
147
+ {
148
+ await AuthenticationService.Instance.SignInAnonymouslyAsync();
149
+ }
150
+
151
+ Debug.Log($"Signed in as {AuthenticationService.Instance.PlayerId}");
152
+ }
153
+ ```
154
+
155
+ `SignInAnonymouslyAsync` handles both new and returning players. If a session token is cached from a previous session, it signs in silently with the cached token. If no token exists, it creates a new anonymous account. Always check `IsSignedIn` before calling to avoid double sign-in errors.
156
+
157
+ ---
158
+
159
+ ## Sign-In: Unity (Browser)
160
+
161
+ Uses `PlayerAccountService` to open a system browser for Unity account sign-in. After the user signs in via the browser, the `SignedIn` event fires and provides an `AccessToken` that is passed to `AuthenticationService.Instance.SignInWithUnityAsync`.
162
+
163
+ **Important:** The `Task` returned by `StartSignInAsync` completes when the browser **opens**, NOT when sign-in finishes. You must subscribe to the `SignedIn` event to know when authentication is complete.
164
+
165
+ ```csharp
166
+ using Unity.Services.Core;
167
+ using Unity.Services.Authentication;
168
+ using Unity.Services.Authentication.PlayerAccounts;
169
+ using UnityEngine;
170
+
171
+ void Start()
172
+ {
173
+ // Wire the event BEFORE calling StartSignInAsync
174
+ PlayerAccountService.Instance.SignedIn += OnPlayerAccountSignedIn;
175
+ }
176
+
177
+ async Task StartSignInWithUnityAsync()
178
+ {
179
+ await UnityServices.InitializeAsync();
180
+
181
+ if (PlayerAccountService.Instance.IsSignedIn)
182
+ {
183
+ // Already signed in to Player Accounts -- go straight to Authentication
184
+ OnPlayerAccountSignedIn();
185
+ return;
186
+ }
187
+
188
+ // Opens the system browser. Task completes when browser opens, NOT when sign-in finishes.
189
+ await PlayerAccountService.Instance.StartSignInAsync();
190
+ }
191
+
192
+ async void OnPlayerAccountSignedIn()
193
+ {
194
+ try
195
+ {
196
+ await AuthenticationService.Instance.SignInWithUnityAsync(
197
+ PlayerAccountService.Instance.AccessToken);
198
+ Debug.Log($"Signed in as {AuthenticationService.Instance.PlayerId}");
199
+ }
200
+ catch (AuthenticationException ex)
201
+ {
202
+ Debug.LogError($"Unity sign-in failed: {ex.Message}");
203
+ }
204
+ catch (RequestFailedException ex)
205
+ {
206
+ Debug.LogError($"Request failed: {ex.Message}");
207
+ }
208
+ }
209
+ ```
210
+
211
+ Namespace: `Unity.Services.Authentication.PlayerAccounts`. Access via `PlayerAccountService.Instance` (`IPlayerAccountService`).
212
+
213
+ If using any authentication other than anonymous, it requires the Unity identity provider to be enabled in **Project Settings > Services > Authentication > Identity Providers**.
214
+
215
+ ### PlayerAccountService API
216
+
217
+ | Member | Type | Description |
218
+ |---|---|---|
219
+ | `StartSignInAsync(bool isSigningUp = false)` | `Task` | Opens browser for sign-in (or sign-up if `true`). Task completes when browser opens. |
220
+ | `SignOut()` | `void` | Signs out of Player Accounts and revokes the access token. Synchronous. |
221
+ | `RefreshTokenAsync()` | `Task` | Refreshes the current access token using the refresh token. |
222
+ | `AccessToken` | `string` | Access token obtained during sign-in. Pass this to `SignInWithUnityAsync`. |
223
+ | `IdToken` | `string` | ID token obtained during sign-in. |
224
+ | `IdTokenClaims` | `IdToken` | Parsed claims from the ID token (email, subject, etc.). |
225
+ | `IsSignedIn` | `bool` | Whether the player is signed in to Player Accounts. |
226
+ | `AccountPortalUrl` | `string` | URL to the Unity Player Account portal. |
227
+ | `SignedIn` | `event Action` | Fires when browser sign-in completes successfully. |
228
+ | `SignedOut` | `event Action` | Fires when the player signs out. |
229
+ | `SignInFailed` | `event Action<RequestFailedException>` | Fires when sign-in fails. |
230
+
231
+ ---
232
+
233
+ ## Sign-In: Username/Password
234
+
235
+ Two separate methods: `SignUpWithUsernamePasswordAsync` for first-time registration, `SignInWithUsernamePasswordAsync` for subsequent sign-ins.
236
+
237
+ ```csharp
238
+ using Unity.Services.Core;
239
+ using Unity.Services.Authentication;
240
+ using UnityEngine;
241
+
242
+ async Task SignUpWithPasswordAsync(string username, string password)
243
+ {
244
+ await UnityServices.InitializeAsync();
245
+
246
+ try
247
+ {
248
+ await AuthenticationService.Instance.SignUpWithUsernamePasswordAsync(username, password);
249
+ Debug.Log($"Signed up and signed in as {AuthenticationService.Instance.PlayerId}");
250
+ }
251
+ catch (AuthenticationException ex) when (ex.ErrorCode == AuthenticationErrorCodes.AccountAlreadyLinked)
252
+ {
253
+ // Error code 10003: username already exists. Sign in instead.
254
+ Debug.LogWarning("Username already exists, signing in instead.");
255
+ await AuthenticationService.Instance.SignInWithUsernamePasswordAsync(username, password);
256
+ }
257
+ catch (AuthenticationException ex)
258
+ {
259
+ Debug.LogError($"Sign-up failed: {ex.Message} (code: {ex.ErrorCode})");
260
+ }
261
+ }
262
+
263
+ async Task SignInWithPasswordAsync(string username, string password)
264
+ {
265
+ await UnityServices.InitializeAsync();
266
+
267
+ try
268
+ {
269
+ await AuthenticationService.Instance.SignInWithUsernamePasswordAsync(username, password);
270
+ Debug.Log($"Signed in as {AuthenticationService.Instance.PlayerId}");
271
+ }
272
+ catch (AuthenticationException ex)
273
+ {
274
+ Debug.LogError($"Sign-in failed: {ex.Message} (code: {ex.ErrorCode})");
275
+ }
276
+ }
277
+ ```
278
+
279
+ Requires the username/password identity provider in **Project Settings > Services > Authentication > Identity Providers**.
280
+
281
+ ### Username/Password Constraints
282
+
283
+ | Field | Constraint |
284
+ |---|---|
285
+ | Username length | 3-20 characters |
286
+ | Username characters | `A-Z`, `a-z`, `0-9`, `.`, `-`, `@`, `_` |
287
+ | Username case | Case insensitive (stored lowercase) |
288
+ | Password length | 8-30 characters |
289
+ | Password requirements | At least 1 lowercase + 1 uppercase + 1 number + 1 symbol |
290
+
291
+ ---
292
+
293
+ ## Player Identity
294
+
295
+ After any successful sign-in, the following properties and methods are available on `AuthenticationService.Instance`:
296
+
297
+ | Member | Type | Description |
298
+ |---|---|---|
299
+ | `PlayerId` | `string` | Unique player identifier, available immediately after sign-in |
300
+ | `PlayerName` | `string` | Player display name (may be null until fetched) |
301
+ | `IsSignedIn` | `bool` | True if a token exists in memory |
302
+ | `IsAnonymous` | `bool` | True if signed in anonymously |
303
+ | `SignedIn` | `event Action` | Fires on successful sign-in |
304
+ | `SignedOut` | `event Action` | Fires on sign-out |
305
+ | `Expired` | `event Action` | Fires when access token expires; SDK auto-attempts refresh |
306
+
307
+ ```csharp
308
+ // Get player name. autoGenerate: true creates a random name if none exists.
309
+ string name = await AuthenticationService.Instance.GetPlayerNameAsync(autoGenerate: true);
310
+
311
+ // Update player name.
312
+ string updatedName = await AuthenticationService.Instance.UpdatePlayerNameAsync("NewDisplayName");
313
+
314
+ // Sign out. Synchronous (void), NOT async.
315
+ AuthenticationService.Instance.SignOut();
316
+ // Optionally clear cached credentials:
317
+ // AuthenticationService.Instance.SignOut(clearCredentials: true);
318
+ ```
319
+
320
+ **Warning:** `SignOut` is synchronous (`void`). There is no `SignOutAsync` method.
321
+
322
+ ---
323
+
324
+ ## Cloud Save Operations
325
+
326
+ ### Namespace Aliases
327
+
328
+ Use namespace aliases to avoid ambiguity between root-level and `Models.Data.Player` option classes:
329
+
330
+ ```csharp
331
+ using Unity.Services.CloudSave;
332
+ using Unity.Services.CloudSave.Models;
333
+ using Unity.Services.CloudSave.Models.Data.Player;
334
+ using PlayerLoadOptions = Unity.Services.CloudSave.Models.Data.Player.LoadOptions;
335
+ using PlayerLoadAllOptions = Unity.Services.CloudSave.Models.Data.Player.LoadAllOptions;
336
+ using PlayerSaveOptions = Unity.Services.CloudSave.Models.Data.Player.SaveOptions;
337
+ ```
338
+
339
+ > **Namespace collision:** `SaveOptions` and `LoadOptions` exist in both `Unity.Services.CloudSave`
340
+ > and `Unity.Services.CloudSave.Models.Data.Player`. Always use the `using` aliases to avoid
341
+ > ambiguity errors.
342
+
343
+ ### Save Default Data (Private to Player)
344
+
345
+ ```csharp
346
+ var data = new Dictionary<string, object>
347
+ {
348
+ { "settings_volume", 0.8f },
349
+ { "settings_difficulty", "hard" },
350
+ { "last_login", DateTime.UtcNow.ToString("o") }
351
+ };
352
+
353
+ await CloudSaveService.Instance.Data.Player.SaveAsync(data);
354
+ ```
355
+
356
+ ### Save Public Data (Visible to Other Players)
357
+
358
+ ```csharp
359
+ var publicData = new Dictionary<string, object>
360
+ {
361
+ { "display_name", "Hero123" },
362
+ { "avatar_id", 42 }
363
+ };
364
+
365
+ var publicSaveOptions = new PlayerSaveOptions(new PublicWriteAccessClassOptions());
366
+ await CloudSaveService.Instance.Data.Player.SaveAsync(publicData, publicSaveOptions);
367
+ ```
368
+
369
+ ### Load Default Data
370
+
371
+ ```csharp
372
+ var keys = new HashSet<string> { "settings_volume", "settings_difficulty" };
373
+ var result = await CloudSaveService.Instance.Data.Player.LoadAsync(keys);
374
+
375
+ if (result.TryGetValue("settings_volume", out var volumeItem))
376
+ {
377
+ float volume = volumeItem.Value.GetAs<float>();
378
+ }
379
+ ```
380
+
381
+ For string values saved via `Dictionary<string, object>`, `GetAsString()` returns the plain string. For complex objects, `GetAsString()` returns the JSON; use `item.Value.GetAs<T>()` to deserialize.
382
+
383
+ ### Load Public Data (Own)
384
+
385
+ ```csharp
386
+ var publicLoadOptions = new PlayerLoadOptions(new PublicReadAccessClassOptions());
387
+ var publicResult = await CloudSaveService.Instance.Data.Player.LoadAsync(
388
+ new HashSet<string> { "display_name", "avatar_id" }, publicLoadOptions);
389
+ ```
390
+
391
+ ### Load Public Data (Another Player)
392
+
393
+ ```csharp
394
+ var otherPlayerOptions = new PlayerLoadOptions(new PublicReadAccessClassOptions(otherPlayerId));
395
+ var otherResult = await CloudSaveService.Instance.Data.Player.LoadAsync(
396
+ new HashSet<string> { "display_name", "avatar_id" }, otherPlayerOptions);
397
+ ```
398
+
399
+ ### Load All Keys
400
+
401
+ ```csharp
402
+ using Unity.Services.CloudSave.Models.Data.Player;
403
+ using PlayerLoadAllOptions = Unity.Services.CloudSave.Models.Data.Player.LoadAllOptions;
404
+
405
+ var allItems = await CloudSaveService.Instance.Data.Player.LoadAllAsync(
406
+ new PlayerLoadAllOptions(new DefaultReadAccessClassOptions()));
407
+
408
+ foreach (var kv in allItems)
409
+ Debug.Log($"{kv.Key}: {kv.Value.Value.GetAsString()}");
410
+ ```
411
+
412
+ **Access class matching rule:** Data saved with `PublicWriteAccessClassOptions` must be loaded with `PublicReadAccessClassOptions`. Data saved with no options (Default) must be loaded with `DefaultReadAccessClassOptions` or no options. Mismatched access classes return empty results without error.
413
+
414
+ ---
415
+
416
+ ## Server-Authoritative Writes via Cloud Code (Optional)
417
+
418
+ The Default and Public access classes above are client-writable — suitable for preferences, display names, and non-sensitive data. Two scenarios require routing writes through a Cloud Code module instead:
419
+
420
+ - **Non-player shared data** (guild info, level configs, global state) — no single player owns this data, so it must be written via Cloud Code to the **Custom** bucket using `IGameApiClient`.
421
+ - **Tamper-proof player data** — if the game design requires anti-cheat protection for specific player state (e.g. XP, currency, unlocked items), write to the **Protected** bucket via Cloud Code. This is a game-design decision, not a requirement.
422
+
423
+ ### Reading Protected Data (Client-Side)
424
+
425
+ ```csharp
426
+ var result = await CloudSaveService.Instance.Data.Player.LoadAsync(
427
+ new HashSet<string> { "player_level", "currency" },
428
+ new PlayerLoadOptions(new ProtectedReadAccessClassOptions()));
429
+
430
+ if (result.TryGetValue("player_level", out var item))
431
+ {
432
+ int level = item.Value.GetAs<int>();
433
+ }
434
+ ```
435
+
436
+ > **Common mistake:** Using default `LoadOptions` instead of `ProtectedReadAccessClassOptions`
437
+ > returns no data, because the keys were written to the Protected bucket by Cloud Code.
438
+
439
+ ### Writing Protected/Custom Data (Server-Side)
440
+
441
+ Writes to Protected and Custom buckets must go through a Cloud Code module. The module uses `IGameApiClient` with the service token to call Cloud Save server-side APIs.
442
+
443
+ Create it with the Editor rather than by hand: right-click a folder under `Assets/` →
444
+ **Create > Services > Cloud Code Module Script** and name it `PlayerAccountModule`. See
445
+ the Creating a Cloud Code Module section of `references/cloud-code-modules.md`.
446
+ The Editor generates the following — use the list to check what you got, not as files to type out. There is
447
+ no `.sln`, `.csproj`, `.pubxml` or test project.
448
+
449
+ - [ ] `Assets/CloudCode/PlayerAccountModule/PlayerAccountModule.ccmu` (holds the two asmdef GUIDs)
450
+ - [ ] `Cloud/PlayerAccountModule.asmdef` — Editor-only, `noEngineReferences`, `autoReferenced: false`
451
+ - [ ] `Cloud/PlayerAccountModule.cs` — rename/replace with the `[CloudCodeFunction]` endpoints
452
+ - [ ] `Client/PlayerAccountModuleClient.asmdef` — references the cloud assembly
453
+ - [ ] `Client/PlayerAccountModuleClient.cs` — `[CloudModuleClient(typeof(PlayerAccountModule))]` partial
454
+
455
+ One file the Editor does **not** generate, which this module needs because its endpoints inject
456
+ `IGameApiClient`:
457
+
458
+ - [ ] `Cloud/CloudSetup.cs` — an `ICloudCodeSetup` calling `config.AddGameApiClient()`
459
+
460
+ The deployed module name is the **cloud asmdef's name** (`PlayerAccountModule`), not the `.ccmu` filename.
461
+
462
+ ---
463
+
464
+ ## Full Client Implementation
465
+
466
+ A complete `MonoBehaviour` covering all three sign-in methods, player identity, and Cloud Save operations.
467
+
468
+ ```csharp
469
+ using System;
470
+ using System.Collections.Generic;
471
+ using System.Threading.Tasks;
472
+ using Unity.Services.Authentication;
473
+ using Unity.Services.Authentication.PlayerAccounts;
474
+ using Unity.Services.CloudSave;
475
+ using Unity.Services.CloudSave.Models.Data.Player;
476
+ using Unity.Services.Core;
477
+ using UnityEngine;
478
+ using PlayerLoadOptions = Unity.Services.CloudSave.Models.Data.Player.LoadOptions;
479
+ using PlayerLoadAllOptions = Unity.Services.CloudSave.Models.Data.Player.LoadAllOptions;
480
+ using PlayerSaveOptions = Unity.Services.CloudSave.Models.Data.Player.SaveOptions;
481
+
482
+ public class PlayerAccountManager : MonoBehaviour
483
+ {
484
+ public string PlayerId => AuthenticationService.Instance.PlayerId;
485
+ public string PlayerName => AuthenticationService.Instance.PlayerName;
486
+ public bool IsSignedIn => AuthenticationService.Instance.IsSignedIn;
487
+
488
+ public event Action SignedIn;
489
+
490
+ async void Start()
491
+ {
492
+ await UnityServices.InitializeAsync();
493
+
494
+ AuthenticationService.Instance.SignedIn += () =>
495
+ {
496
+ Debug.Log($"Signed in: {AuthenticationService.Instance.PlayerId}");
497
+ SignedIn?.Invoke();
498
+ };
499
+
500
+ // Wire PlayerAccountService event BEFORE any StartSignInAsync call
501
+ PlayerAccountService.Instance.SignedIn += OnPlayerAccountSignedIn;
502
+ }
503
+
504
+ // --- Sign-In Methods ---
505
+
506
+ public async Task SignInAnonymouslyAsync()
507
+ {
508
+ if (AuthenticationService.Instance.IsSignedIn) return;
509
+ await AuthenticationService.Instance.SignInAnonymouslyAsync();
510
+ }
511
+
512
+ /// <summary>
513
+ /// Starts the browser-based Unity sign-in flow.
514
+ /// The returned Task completes when the browser opens, NOT when sign-in finishes.
515
+ /// Subscribe to SignedIn to know when authentication is complete.
516
+ /// </summary>
517
+ public async Task StartSignInWithUnity()
518
+ {
519
+ if (PlayerAccountService.Instance.IsSignedIn)
520
+ {
521
+ OnPlayerAccountSignedIn();
522
+ return;
523
+ }
524
+
525
+ await PlayerAccountService.Instance.StartSignInAsync();
526
+ }
527
+
528
+ async void OnPlayerAccountSignedIn()
529
+ {
530
+ try
531
+ {
532
+ await AuthenticationService.Instance.SignInWithUnityAsync(
533
+ PlayerAccountService.Instance.AccessToken);
534
+ }
535
+ catch (AuthenticationException ex)
536
+ {
537
+ Debug.LogError($"Unity sign-in failed: {ex.Message}");
538
+ }
539
+ catch (RequestFailedException ex)
540
+ {
541
+ Debug.LogError($"Request failed: {ex.Message}");
542
+ }
543
+ }
544
+
545
+ public async Task SignUpWithPasswordAsync(string username, string password)
546
+ {
547
+ try
548
+ {
549
+ await AuthenticationService.Instance.SignUpWithUsernamePasswordAsync(username, password);
550
+ }
551
+ catch (AuthenticationException ex) when (ex.ErrorCode == AuthenticationErrorCodes.AccountAlreadyLinked)
552
+ {
553
+ // Error code 10003: username already exists
554
+ Debug.LogWarning("Username already exists. Use SignInWithPasswordAsync instead.");
555
+ throw;
556
+ }
557
+ }
558
+
559
+ public async Task SignInWithPasswordAsync(string username, string password)
560
+ {
561
+ await AuthenticationService.Instance.SignInWithUsernamePasswordAsync(username, password);
562
+ }
563
+
564
+ public void SignOut()
565
+ {
566
+ AuthenticationService.Instance.SignOut();
567
+ // Optionally also sign out of Player Accounts:
568
+ // PlayerAccountService.Instance.SignOut();
569
+ }
570
+
571
+ // --- Player Identity ---
572
+
573
+ public async Task<string> GetPlayerNameAsync()
574
+ {
575
+ return await AuthenticationService.Instance.GetPlayerNameAsync(autoGenerate: true);
576
+ }
577
+
578
+ public async Task<string> UpdatePlayerNameAsync(string newName)
579
+ {
580
+ return await AuthenticationService.Instance.UpdatePlayerNameAsync(newName);
581
+ }
582
+
583
+ // --- Cloud Save: Default (Private) ---
584
+
585
+ public async Task SaveDefaultAsync(string key, object value)
586
+ {
587
+ await CloudSaveService.Instance.Data.Player.SaveAsync(
588
+ new Dictionary<string, object> { { key, value } });
589
+ }
590
+
591
+ public async Task<string> LoadDefaultAsync(string key)
592
+ {
593
+ var result = await CloudSaveService.Instance.Data.Player.LoadAsync(
594
+ new HashSet<string> { key });
595
+ return result.TryGetValue(key, out var item) ? item.Value.GetAsString() : null;
596
+ }
597
+
598
+ // --- Cloud Save: Public ---
599
+
600
+ public async Task SavePublicAsync(string key, object value)
601
+ {
602
+ var options = new PlayerSaveOptions(new PublicWriteAccessClassOptions());
603
+ await CloudSaveService.Instance.Data.Player.SaveAsync(
604
+ new Dictionary<string, object> { { key, value } }, options);
605
+ }
606
+
607
+ public async Task<string> LoadPublicAsync(string key)
608
+ {
609
+ var options = new PlayerLoadOptions(new PublicReadAccessClassOptions());
610
+ var result = await CloudSaveService.Instance.Data.Player.LoadAsync(
611
+ new HashSet<string> { key }, options);
612
+ return result.TryGetValue(key, out var item) ? item.Value.GetAsString() : null;
613
+ }
614
+
615
+ // --- Cloud Save: All Keys ---
616
+
617
+ public async Task<List<string>> LoadAllDefaultKeysAsync()
618
+ {
619
+ var result = await CloudSaveService.Instance.Data.Player.LoadAllAsync(
620
+ new PlayerLoadAllOptions(new DefaultReadAccessClassOptions()));
621
+ return new List<string>(result.Keys);
622
+ }
623
+ }
624
+ ```
625
+
626
+ ---
627
+
628
+ ## PlayerAccountTester
629
+
630
+ Attach alongside `PlayerAccountManager` on the same GameObject. Signs in anonymously, logs identity, then exercises a Cloud Save round-trip and lists all Default keys.
631
+
632
+ ```csharp
633
+ using System.Collections.Generic;
634
+ using System.Text;
635
+ using System.Threading.Tasks;
636
+ using UnityEngine;
637
+
638
+ /// <summary>
639
+ /// Attach alongside PlayerAccountManager to run a quick in-Editor smoke test.
640
+ /// On start: signs in anonymously and logs player identity.
641
+ /// After sign-in: saves a probe value to the Default bucket, loads it back,
642
+ /// and logs all Default keys visible for this player.
643
+ /// </summary>
644
+ public class PlayerAccountTester : MonoBehaviour
645
+ {
646
+ [SerializeField] PlayerAccountManager m_Manager;
647
+
648
+ async void Start()
649
+ {
650
+ if (m_Manager == null)
651
+ m_Manager = GetComponent<PlayerAccountManager>();
652
+
653
+ m_Manager.SignedIn += OnSignedIn;
654
+ await m_Manager.SignInAnonymouslyAsync();
655
+ }
656
+
657
+ async void OnSignedIn()
658
+ {
659
+ LogIdentity("Signed in");
660
+
661
+ await Task.Delay(2000);
662
+
663
+ // Fetch the server-side player name — may be null after anonymous sign-in.
664
+ await m_Manager.GetPlayerNameAsync();
665
+ LogIdentity("After name fetch");
666
+
667
+ // Round-trip a probe value through the Default Cloud Save bucket.
668
+ const string key = "tester_probe";
669
+ const string expected = "ok";
670
+ await m_Manager.SaveDefaultAsync(key, expected);
671
+ var loaded = await m_Manager.LoadDefaultAsync(key);
672
+
673
+ var match = loaded == expected ? "OK" : $"MISMATCH (got '{loaded}')";
674
+ Debug.Log($"[PlayerAccountTester] Save→Load round-trip: {match}");
675
+
676
+ // List all keys in the Default bucket for this player.
677
+ var keys = await m_Manager.LoadAllDefaultKeysAsync();
678
+ LogKeys(keys);
679
+ }
680
+
681
+ void LogIdentity(string label)
682
+ {
683
+ var sb = new StringBuilder();
684
+ sb.AppendLine($"[PlayerAccountTester] {label}:");
685
+ sb.AppendLine($" PlayerId : {m_Manager.PlayerId ?? "<null>"}");
686
+ sb.AppendLine($" PlayerName : {(string.IsNullOrEmpty(m_Manager.PlayerName) ? "<none>" : m_Manager.PlayerName)}");
687
+ sb.AppendLine($" IsSignedIn : {m_Manager.IsSignedIn}");
688
+ Debug.Log(sb.ToString());
689
+ }
690
+
691
+ void LogKeys(List<string> keys)
692
+ {
693
+ var sb = new StringBuilder();
694
+ sb.AppendLine($"[PlayerAccountTester] Default bucket keys ({keys.Count}):");
695
+ foreach (var k in keys)
696
+ sb.AppendLine($" {k}");
697
+ Debug.Log(sb.ToString());
698
+ }
699
+ }
700
+ ```
701
+
702
+ ---
703
+
704
+ ## Assembly Definition
705
+
706
+ Your `.asmdef` must reference both `Unity.Services.Authentication` and `Unity.Services.Authentication.PlayerAccounts`. These are **separate assemblies** within the same package (`com.unity.services.authentication`). Missing the PlayerAccounts reference causes `PlayerAccountService` to be unresolvable. `Unity.Services.CloudCode` is only needed if using Protected or Custom data writes.
707
+
708
+ ```json
709
+ {
710
+ "name": "MyGame.PlayerAccount",
711
+ "rootNamespace": "",
712
+ "references": [
713
+ "Unity.Services.Core",
714
+ "Unity.Services.Authentication",
715
+ "Unity.Services.Authentication.PlayerAccounts",
716
+ "Unity.Services.CloudSave",
717
+ "Unity.Services.CloudCode"
718
+ ],
719
+ "includePlatforms": [],
720
+ "excludePlatforms": [],
721
+ "allowUnsafeCode": false,
722
+ "overrideReferences": false,
723
+ "precompiledReferences": [],
724
+ "autoReferenced": true,
725
+ "defineConstraints": [],
726
+ "versionDefines": [],
727
+ "noEngineReferences": false
728
+ }
729
+ ```
730
+
731
+ ---
732
+
733
+ ## Error Handling
734
+
735
+ ### AuthenticationException
736
+
737
+ Thrown by all `AuthenticationService` methods. Extends `RequestFailedException`.
738
+
739
+ ```csharp
740
+ try
741
+ {
742
+ await AuthenticationService.Instance.SignInAnonymouslyAsync();
743
+ }
744
+ catch (AuthenticationException ex)
745
+ {
746
+ // ex.ErrorCode contains a numeric error code from AuthenticationErrorCodes
747
+ Debug.LogError($"Auth failed: {ex.Message} (code: {ex.ErrorCode})");
748
+ }
749
+ catch (RequestFailedException ex)
750
+ {
751
+ // Network or other service errors
752
+ Debug.LogError($"Request failed: {ex.Message}");
753
+ }
754
+ ```
755
+
756
+ Key error codes:
757
+
758
+ | Constant | Value | Meaning | Fix |
759
+ |---|---|---| :-- |
760
+ | `AccountAlreadyLinked` | 10003 | Username already exists (on sign-up) or external ID already linked | Sign in instead on sign-up, or link with `ForceLink` only after the player confirms |
761
+ | `InvalidParameters` | 10002 | Bad input parameters | Validate the input before the call |
762
+ | `ClientInvalidUserState` | 10000 | Operation not valid in current state | Check the player's sign-in state before the call |
763
+
764
+ ### PlayerAccountsException
765
+
766
+ Thrown by `PlayerAccountService` methods. Also extends `RequestFailedException`.
767
+
768
+ ```csharp
769
+ try
770
+ {
771
+ await PlayerAccountService.Instance.StartSignInAsync();
772
+ }
773
+ catch (PlayerAccountsException ex)
774
+ {
775
+ Debug.LogError($"Player Accounts error: {ex.Message} (code: {ex.ErrorCode})");
776
+ }
777
+ ```
778
+
779
+ Key error codes (from `PlayerAccountsErrorCodes`):
780
+
781
+ | Constant | Value | Meaning | Fix |
782
+ |---|---|---| :-- |
783
+ | `InvalidState` | 10101 | Player is already signed in | Check `PlayerAccountService.Instance.IsSignedIn` before `StartSignInAsync` |
784
+ | `MissingClientId` | 10102 | Client ID not configured in Unity Dashboard | Configure the Unity identity provider's client ID in the Unity Dashboard |
785
+
786
+ ### CloudSaveException
787
+
788
+ Thrown by Cloud Save operations.
789
+
790
+ ```csharp
791
+ try
792
+ {
793
+ await CloudSaveService.Instance.Data.Player.SaveAsync(data);
794
+ }
795
+ catch (CloudSaveValidationException ex)
796
+ {
797
+ foreach (var detail in ex.Details)
798
+ Debug.LogError($"Validation: {detail.Field} {string.Join(", ", detail.Messages)}");
799
+ }
800
+ catch (CloudSaveRateLimitedException ex)
801
+ {
802
+ Debug.LogError($"Rate limited. Retry after {ex.RetryAfter}s");
803
+ }
804
+ catch (CloudSaveException ex)
805
+ {
806
+ Debug.LogError($"Cloud Save error: {ex.Message} (reason: {ex.Reason})");
807
+ }
808
+ ```
809
+
810
+ ---
811
+
812
+ ## Validation
813
+
814
+ After implementing a player account feature, verify:
815
+
816
+ 1. **Compile check:** The project compiles without errors. All namespaces (`Unity.Services.Core`, `Unity.Services.Authentication`, `Unity.Services.Authentication.PlayerAccounts`, `Unity.Services.CloudSave`) resolve correctly.
817
+ 2. **Initialization order:** `UnityServices.InitializeAsync()` is called before any sign-in method. Service singletons (`AuthenticationService.Instance`, `PlayerAccountService.Instance`, `CloudSaveService.Instance`) are accessed only after initialization.
818
+ 3. **Assembly references:** The `.asmdef` references **both** `Unity.Services.Authentication` and `Unity.Services.Authentication.PlayerAccounts`. These are separate assemblies in the same package; omitting the PlayerAccounts reference makes `PlayerAccountService` unresolvable.
819
+ 4. **SignedIn event wiring:** `PlayerAccountService.Instance.SignedIn` is subscribed **before** calling `StartSignInAsync()`. The `StartSignInAsync` Task completes when the browser opens, not when sign-in finishes.
820
+ 5. **Access class matching:** Data saved with `PublicWriteAccessClassOptions` is loaded with `PublicReadAccessClassOptions`. Data saved with no options (Default) is loaded with `DefaultReadAccessClassOptions` or no options. Mismatched access classes return empty results without error.
821
+ 6. **SignOut is synchronous:** `AuthenticationService.Instance.SignOut()` and `PlayerAccountService.Instance.SignOut()` are both `void` methods. Do not `await` them.