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.
- package/.claude/agents/nccgs-accessibility-specialist.md +26 -0
- package/.claude/agents/nccgs-adversarial-reviewer.md +26 -0
- package/.claude/agents/nccgs-ai-programmer.md +26 -0
- package/.claude/agents/nccgs-analytics-engineer.md +26 -0
- package/.claude/agents/nccgs-art-direction-lead.md +26 -0
- package/.claude/agents/nccgs-audio-direction-lead.md +26 -0
- package/.claude/agents/nccgs-creative-director.md +26 -0
- package/.claude/agents/nccgs-documentation-manager.md +26 -0
- package/.claude/agents/nccgs-economy-designer.md +26 -0
- package/.claude/agents/nccgs-engine-programmer.md +26 -0
- package/.claude/agents/nccgs-game-design-lead.md +26 -0
- package/.claude/agents/nccgs-game-designer.md +26 -0
- package/.claude/agents/nccgs-gameplay-programmer.md +26 -0
- package/.claude/agents/nccgs-level-designer.md +26 -0
- package/.claude/agents/nccgs-live-ops-designer.md +26 -0
- package/.claude/agents/nccgs-localization-lead.md +26 -0
- package/.claude/agents/nccgs-narrative-lead.md +26 -0
- package/.claude/agents/nccgs-network-programmer.md +26 -0
- package/.claude/agents/nccgs-performance-analyst.md +26 -0
- package/.claude/agents/nccgs-producer.md +26 -0
- package/.claude/agents/nccgs-production-coordinator.md +23 -0
- package/.claude/agents/nccgs-programming-lead.md +26 -0
- package/.claude/agents/nccgs-prototyper.md +26 -0
- package/.claude/agents/nccgs-qa-engineer.md +26 -0
- package/.claude/agents/nccgs-qa-lead.md +26 -0
- package/.claude/agents/nccgs-release-engineer.md +26 -0
- package/.claude/agents/nccgs-release-lead.md +26 -0
- package/.claude/agents/nccgs-security-engineer.md +26 -0
- package/.claude/agents/nccgs-sound-designer.md +26 -0
- package/.claude/agents/nccgs-systems-designer.md +26 -0
- package/.claude/agents/nccgs-technical-architect.md +26 -0
- package/.claude/agents/nccgs-technical-artist.md +26 -0
- package/.claude/agents/nccgs-technical-director.md +26 -0
- package/.claude/agents/nccgs-tools-programmer.md +26 -0
- package/.claude/agents/nccgs-ui-programmer.md +26 -0
- package/.claude/agents/nccgs-unity-build-specialist.md +26 -0
- package/.claude/agents/nccgs-unity-content-specialist.md +26 -0
- package/.claude/agents/nccgs-unity-implementer.md +26 -0
- package/.claude/agents/nccgs-unity-rendering-specialist.md +26 -0
- package/.claude/agents/nccgs-unity-systems-specialist.md +26 -0
- package/.claude/agents/nccgs-unity-ui-specialist.md +26 -0
- package/.claude/agents/nccgs-ux-designer.md +26 -0
- package/.claude/agents/nccgs-verification-engineer.md +26 -0
- package/.claude/agents/nccgs-world-builder.md +26 -0
- package/.claude/agents/nccgs-writer.md +26 -0
- package/.claude/nccgs/THIRD_PARTY_NOTICES.md +13 -0
- package/.claude/nccgs/VERSION +1 -0
- package/.claude/nccgs/constitution.md +131 -0
- package/.claude/nccgs/hooks/agent-audit.mjs +10 -0
- package/.claude/nccgs/hooks/common.mjs +41 -0
- package/.claude/nccgs/hooks/post-compact.mjs +1 -0
- package/.claude/nccgs/hooks/pre-compact.mjs +8 -0
- package/.claude/nccgs/hooks/protect-git.mjs +22 -0
- package/.claude/nccgs/hooks/protect-write.mjs +17 -0
- package/.claude/nccgs/hooks/session-start.mjs +15 -0
- package/.claude/nccgs/hooks/session-stop.mjs +7 -0
- package/.claude/nccgs/protocols/agent-contract.md +34 -0
- package/.claude/nccgs/protocols/context-packets.md +13 -0
- package/.claude/nccgs/protocols/evidence.md +15 -0
- package/.claude/nccgs/protocols/model-routing.md +22 -0
- package/.claude/nccgs/protocols/orchestration.md +26 -0
- package/.claude/nccgs/protocols/unity-boundary.md +11 -0
- package/.claude/nccgs/settings.fragment.json +77 -0
- package/.claude/nccgs/studio.json +347 -0
- package/.claude/nccgs/tools/configure-models.mjs +39 -0
- package/.claude/nccgs/unity-skills-manifest.json +727 -0
- package/.claude/nccgs/workflow-catalog.json +317 -0
- package/.claude/rules/nccgs-canonical-docs.md +19 -0
- package/.claude/rules/nccgs-editor-tools.md +12 -0
- package/.claude/rules/nccgs-localization.md +12 -0
- package/.claude/rules/nccgs-networking.md +13 -0
- package/.claude/rules/nccgs-performance.md +14 -0
- package/.claude/rules/nccgs-rendering.md +16 -0
- package/.claude/rules/nccgs-security.md +13 -0
- package/.claude/rules/nccgs-tests.md +18 -0
- package/.claude/rules/nccgs-ui.md +14 -0
- package/.claude/rules/nccgs-unity-assets.md +21 -0
- package/.claude/rules/nccgs-unity-code.md +22 -0
- package/.claude/skills/accessibility-review/SKILL.md +14 -0
- package/.claude/skills/architecture-decision/SKILL.md +14 -0
- package/.claude/skills/asset-audit/SKILL.md +14 -0
- package/.claude/skills/audit/SKILL.md +16 -0
- package/.claude/skills/audit/references/dimensions.md +46 -0
- package/.claude/skills/balance-review/SKILL.md +14 -0
- package/.claude/skills/bug-triage/SKILL.md +14 -0
- package/.claude/skills/build-live-game/SKILL.md +317 -0
- package/.claude/skills/build-live-game/references/achievements.md +779 -0
- package/.claude/skills/build-live-game/references/apis.md +280 -0
- package/.claude/skills/build-live-game/references/authentication.md +437 -0
- package/.claude/skills/build-live-game/references/battlepass.md +860 -0
- package/.claude/skills/build-live-game/references/cloud-code.md +563 -0
- package/.claude/skills/build-live-game/references/cloud-save.md +474 -0
- package/.claude/skills/build-live-game/references/deployment.md +216 -0
- package/.claude/skills/build-live-game/references/player-account.md +813 -0
- package/.claude/skills/build-live-game/references/remote-config.md +96 -0
- package/.claude/skills/build-live-game/references/tooling.md +431 -0
- package/.claude/skills/closure/SKILL.md +14 -0
- package/.claude/skills/code-review/SKILL.md +14 -0
- package/.claude/skills/compatibility-review/SKILL.md +14 -0
- package/.claude/skills/context-pack/SKILL.md +14 -0
- package/.claude/skills/dependency-review/SKILL.md +14 -0
- package/.claude/skills/design/SKILL.md +20 -0
- package/.claude/skills/design-review/SKILL.md +14 -0
- package/.claude/skills/evidence-review/SKILL.md +14 -0
- package/.claude/skills/hotfix/SKILL.md +14 -0
- package/.claude/skills/implement-in-app-purchases/README.md +233 -0
- package/.claude/skills/implement-in-app-purchases/SKILL.md +158 -0
- package/.claude/skills/implement-in-app-purchases/references/api-notes.md +562 -0
- package/.claude/skills/implement-in-app-purchases/references/codeless-catalog.md +331 -0
- package/.claude/skills/implement-in-app-purchases/references/convert-adapty.md +268 -0
- package/.claude/skills/implement-in-app-purchases/references/convert-essentialkit.md +239 -0
- package/.claude/skills/implement-in-app-purchases/references/convert-revenuecat.md +275 -0
- package/.claude/skills/implement-in-app-purchases/references/convert-unipay.md +145 -0
- package/.claude/skills/implement-in-app-purchases/references/migration-v4-to-v5.md +204 -0
- package/.claude/skills/implement-in-app-purchases/references/path-add-iap-to-new-project.md +198 -0
- package/.claude/skills/implement-in-app-purchases/references/path-convert-native-google-billing.md +356 -0
- package/.claude/skills/implement-in-app-purchases/references/path-convert-native-storekit.md +446 -0
- package/.claude/skills/implement-in-app-purchases/references/path-implement-iap-d2c.md +680 -0
- package/.claude/skills/implement-in-app-purchases/references/platform-notes.md +204 -0
- package/.claude/skills/implement-in-app-purchases/references/pre-check.md +205 -0
- package/.claude/skills/incident-recovery/SKILL.md +14 -0
- package/.claude/skills/initialize-ai-navigation/SKILL.md +95 -0
- package/.claude/skills/initialize-ai-navigation/references/navigation-system.md +794 -0
- package/.claude/skills/levelplay-unity-integration/CHANGELOG.md +57 -0
- package/.claude/skills/levelplay-unity-integration/README.md +74 -0
- package/.claude/skills/levelplay-unity-integration/SKILL.md +1126 -0
- package/.claude/skills/levelplay-unity-integration/references/banner-api.md +920 -0
- package/.claude/skills/levelplay-unity-integration/references/best-practices.md +536 -0
- package/.claude/skills/levelplay-unity-integration/references/ilrd-api.md +337 -0
- package/.claude/skills/levelplay-unity-integration/references/initialization-api.md +630 -0
- package/.claude/skills/levelplay-unity-integration/references/interstitial-api.md +899 -0
- package/.claude/skills/levelplay-unity-integration/references/ios-setup.md +491 -0
- package/.claude/skills/levelplay-unity-integration/references/migration-sdk-9.md +666 -0
- package/.claude/skills/levelplay-unity-integration/references/privacy-settings.md +608 -0
- package/.claude/skills/levelplay-unity-integration/references/rewarded-api.md +902 -0
- package/.claude/skills/localization/SKILL.md +135 -0
- package/.claude/skills/localization/references/api-notes.md +76 -0
- package/.claude/skills/localization/resources/L10nBatchProcessor.cs +69 -0
- package/.claude/skills/localization/resources/LocalizedFontAsset.cs +18 -0
- package/.claude/skills/localize-game/SKILL.md +14 -0
- package/.claude/skills/migrate-project/SKILL.md +21 -0
- package/.claude/skills/migrate-project/references/procedure.md +63 -0
- package/.claude/skills/milestone-review/SKILL.md +14 -0
- package/.claude/skills/new-unity-project/SKILL.md +179 -0
- package/.claude/skills/optimize-audio/SKILL.md +199 -0
- package/.claude/skills/optimize-audio/resources/audio-import-api.md +146 -0
- package/.claude/skills/optimize-audio/resources/platform-settings.md +48 -0
- package/.claude/skills/optimize-text-mesh-pro/SKILL.md +182 -0
- package/.claude/skills/optimize-web/SKILL.md +393 -0
- package/.claude/skills/optimize-web/resources/WebOptimizer.cs +21 -0
- package/.claude/skills/optimize-web/resources/toktx-examples.sh +11 -0
- package/.claude/skills/performance-audit/SKILL.md +14 -0
- package/.claude/skills/physics-3d-collision/SKILL.md +442 -0
- package/.claude/skills/physics-3d-collision/references/troubleshooting.md +41 -0
- package/.claude/skills/physics-3d-collision/resources/CollisionDebugger.cs +33 -0
- package/.claude/skills/plan-feature/SKILL.md +14 -0
- package/.claude/skills/playtest/SKILL.md +14 -0
- package/.claude/skills/project-stage/SKILL.md +14 -0
- package/.claude/skills/prototype-feature/SKILL.md +14 -0
- package/.claude/skills/qa-plan/SKILL.md +14 -0
- package/.claude/skills/release/SKILL.md +18 -0
- package/.claude/skills/release-readiness/SKILL.md +14 -0
- package/.claude/skills/retrospective/SKILL.md +14 -0
- package/.claude/skills/review/SKILL.md +16 -0
- package/.claude/skills/security-audit/SKILL.md +14 -0
- package/.claude/skills/setup-multiplayer-services/SKILL.md +39 -0
- package/.claude/skills/setup-multiplayer-services/references/dgs-entrypoint.md +79 -0
- package/.claude/skills/setup-multiplayer-services/references/entrypoints.md +213 -0
- package/.claude/skills/setup-multiplayer-services/references/examples.md +33 -0
- package/.claude/skills/setup-multiplayer-services/references/implementation-fit.md +30 -0
- package/.claude/skills/setup-multiplayer-services/references/underlying-services.md +11 -0
- package/.claude/skills/setup-multiplayer-services/references/workflows-prerequisites.md +17 -0
- package/.claude/skills/setup-vivox-voice-chat/SKILL.md +118 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/.env.example +6 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/README.md +101 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/promptfooconfig.yaml +32 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/tests/init-and-login.yaml +76 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/tests/text-chat.yaml +65 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/tests/voice-channels.yaml +74 -0
- package/.claude/skills/setup-vivox-voice-chat/references/events-and-participants.md +79 -0
- package/.claude/skills/setup-vivox-voice-chat/references/init-and-login.md +92 -0
- package/.claude/skills/setup-vivox-voice-chat/references/text-chat.md +93 -0
- package/.claude/skills/setup-vivox-voice-chat/references/troubleshooting.md +47 -0
- package/.claude/skills/setup-vivox-voice-chat/references/voice-channels.md +90 -0
- package/.claude/skills/shader-graph-create-custom-node/SKILL.md +25 -0
- package/.claude/skills/shader-graph-create-custom-node/resources/all_hints.hlsl +182 -0
- package/.claude/skills/sprint-plan/SKILL.md +14 -0
- package/.claude/skills/sprite-editor/SKILL.md +66 -0
- package/.claude/skills/sprite-editor/references/api_reference.md +151 -0
- package/.claude/skills/sprite-editor/references/background.md +112 -0
- package/.claude/skills/sprite-editor/references/templates.md +72 -0
- package/.claude/skills/sprite-editor/scripts/AutomaticSliceTexture.cs +40 -0
- package/.claude/skills/sprite-editor/scripts/GenerateNewSpriteRects.cs +200 -0
- package/.claude/skills/sprite-editor/scripts/GetTextureSourceImageSize.cs +32 -0
- package/.claude/skills/sprite-editor/scripts/GetTextureToSlice.cs +55 -0
- package/.claude/skills/sprite-editor/scripts/GridSliceTexture.cs +40 -0
- package/.claude/skills/sprite-editor/scripts/IsometricSliceTexture.cs +141 -0
- package/.claude/skills/sprite-editor/scripts/README.md +134 -0
- package/.claude/skills/sprite-editor/scripts/SetPivotExample.cs +58 -0
- package/.claude/skills/sprite-editor/scripts/SpriteToPng.cs +88 -0
- package/.claude/skills/status/SKILL.md +16 -0
- package/.claude/skills/story-readiness/SKILL.md +14 -0
- package/.claude/skills/test/SKILL.md +16 -0
- package/.claude/skills/ui/SKILL.md +142 -0
- package/.claude/skills/ui-imgui/SKILL.md +186 -0
- package/.claude/skills/ui-imgui/references/gui-elements.md +156 -0
- package/.claude/skills/ui-imgui/references/templates.md +141 -0
- package/.claude/skills/ui-review/SKILL.md +14 -0
- package/.claude/skills/ui-ugui/SKILL.md +282 -0
- package/.claude/skills/ui-ugui/references/scrollview-setup.md +29 -0
- package/.claude/skills/ui-uitk/SKILL.md +235 -0
- package/.claude/skills/ui-uitk/references/common-issues.md +74 -0
- package/.claude/skills/ui-uitk/references/custom-elements.md +241 -0
- package/.claude/skills/ui-uitk/references/painter2d.md +282 -0
- package/.claude/skills/ui-uitk/references/pointermanipulator-guide.md +94 -0
- package/.claude/skills/ui-uitk/references/svg-icons.md +136 -0
- package/.claude/skills/ui-uitk/references/ui-runtime-binding.md +234 -0
- package/.claude/skills/ui-uitk/references/uss-guide.md +138 -0
- package/.claude/skills/unity-cli/CHANGELOG.md +233 -0
- package/.claude/skills/unity-cli/SECURITY.md +22 -0
- package/.claude/skills/unity-cli/SKILL.md +414 -0
- package/.claude/skills/unity-cli/references/auth-license-cloud.md +146 -0
- package/.claude/skills/unity-cli/references/build-run-test.md +349 -0
- package/.claude/skills/unity-cli/references/collaboration.md +472 -0
- package/.claude/skills/unity-cli/references/config-hub.md +103 -0
- package/.claude/skills/unity-cli/references/diagnostics-maintenance.md +326 -0
- package/.claude/skills/unity-cli/references/editors-install.md +327 -0
- package/.claude/skills/unity-cli/references/integration-advanced.md +472 -0
- package/.claude/skills/unity-cli/references/projects-templates.md +574 -0
- package/.claude/skills/unity-package-management/SKILL.md +304 -0
- package/.claude/skills/unity-package-management/references/select-packages.md +108 -0
- package/.claude/skills/urp-postprocessing/SKILL.md +188 -0
- package/.claude/skills/urp-postprocessing/references/code-templates.md +119 -0
- package/.claude/skills/urp-postprocessing/references/effect-reference.md +86 -0
- package/.claude/skills/validate-urp-render-graph-renderer-feature/SKILL.md +269 -0
- package/.claude/skills/work/SKILL.md +36 -0
- package/.claude/skills/work/references/classification.md +41 -0
- package/.claude/skills/work/references/closure.md +50 -0
- package/.claude/skills/work/references/feature-contracts.md +32 -0
- package/.claude/skills/work/references/verification.md +26 -0
- package/CLAUDE.md +6 -0
- package/LICENSE +21 -0
- package/README.md +162 -0
- package/THIRD_PARTY_NOTICES.md +23 -0
- package/UPGRADING.md +32 -0
- package/VERSION +1 -0
- package/docs/ARCHITECTURE.md +73 -0
- package/docs/HUONG-DAN-MIGRATE-VA-SU-DUNG.md +324 -0
- package/docs/MIGRATION-MATRIX.md +23 -0
- package/docs/PROJECT-POLICY.md +67 -0
- package/docs/WORKFLOWS.md +61 -0
- package/package-assets/setup-vivox-voice-chat-evals.gitignore +7 -0
- package/package.json +41 -0
- package/scaffold/.nccgs/bugs/.gitkeep +1 -0
- package/scaffold/.nccgs/closures/.gitkeep +1 -0
- package/scaffold/.nccgs/context/.gitkeep +1 -0
- package/scaffold/.nccgs/decisions/.gitkeep +1 -0
- package/scaffold/.nccgs/evidence/.gitkeep +1 -0
- package/scaffold/.nccgs/features/.gitkeep +1 -0
- package/scaffold/.nccgs/migrations/.gitkeep +1 -0
- package/scaffold/.nccgs/playtests/.gitkeep +1 -0
- package/scaffold/.nccgs/project.yaml +103 -0
- package/scaffold/.nccgs/requirements.yaml +10 -0
- package/scaffold/.nccgs/reviews/.gitkeep +1 -0
- package/scaffold/.nccgs/state.md +40 -0
- package/scaffold/.nccgs/templates/agent-handoff.md +25 -0
- package/scaffold/.nccgs/templates/architecture-decision.md +27 -0
- package/scaffold/.nccgs/templates/closure-record.md +51 -0
- package/scaffold/.nccgs/templates/context-packet.yaml +17 -0
- package/scaffold/.nccgs/templates/evidence-record.md +23 -0
- package/scaffold/.nccgs/templates/feature-contract.md +35 -0
- package/scaffold/.nccgs/templates/migration-plan.md +40 -0
- package/scaffold/.nccgs/templates/waiver.md +11 -0
- package/scripts/cli.mjs +56 -0
- package/scripts/install.mjs +267 -0
- package/scripts/sync-unity-skills.mjs +126 -0
- package/scripts/validate.mjs +205 -0
- package/tests/framework.test.mjs +121 -0
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
# Authentication Reference
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [Anti-Hallucination Reference](#anti-hallucination-reference)
|
|
6
|
+
- [Sign-In Methods](#sign-in-methods)
|
|
7
|
+
- [Key Properties](#key-properties)
|
|
8
|
+
- [Events](#events)
|
|
9
|
+
- [Player Info / Name](#player-info--name)
|
|
10
|
+
- [Link / Unlink Methods](#link--unlink-methods)
|
|
11
|
+
- [Profile Switching](#profile-switching)
|
|
12
|
+
- [Username/Password Constraints](#usernamepassword-constraints)
|
|
13
|
+
- [Options / Types](#options--types)
|
|
14
|
+
- [Identity Providers Quick Reference](#identity-providers-quick-reference)
|
|
15
|
+
- [Code Templates](#code-templates)
|
|
16
|
+
- [Error Handling](#error-handling)
|
|
17
|
+
- [Session Warnings](#session-warnings)
|
|
18
|
+
|
|
19
|
+
Accessed via `AuthenticationService.Instance` (`IAuthenticationService`, namespace `Unity.Services.Authentication`). Assembly: `Unity.Services.Authentication`.
|
|
20
|
+
|
|
21
|
+
Call `UnityServices.InitializeAsync()` from `com.unity.services.core` before using this service.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Anti-Hallucination Reference
|
|
26
|
+
|
|
27
|
+
| Correct | Incorrect (do NOT use) |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `SignOut(bool clearCredentials = false)` -- synchronous void | `SignOutAsync`, `SignOut()` returning Task |
|
|
30
|
+
| `SignInWithSteamAsync(sessionTicket, identity)` -- identity param is required | `SignInWithSteamAsync(sessionTicket)` -- deprecated |
|
|
31
|
+
| `SignInWithOculusAsync(nonce, userId)` -- both params required | `SignInWithOculusAsync(nonce)` -- missing userId |
|
|
32
|
+
| `LinkWithSteamAsync(sessionTicket, identity)` | `LinkWithSteamAsync(sessionTicket)` -- deprecated |
|
|
33
|
+
| `LinkWithOculusAsync(nonce, userId)` | `LinkWithOculusAsync(nonce)` -- missing userId |
|
|
34
|
+
| `SwitchProfile(string)` -- synchronous void | `SwitchProfileAsync` |
|
|
35
|
+
| `ClearSessionToken()` -- synchronous void | `ClearSessionTokenAsync` |
|
|
36
|
+
| No `UnlinkUsernamePasswordAsync` | Username/password cannot be unlinked once linked |
|
|
37
|
+
| No `IsAnonymous` property | Use `PlayerInfo.Identities` to check linked providers |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Sign-In Methods
|
|
42
|
+
|
|
43
|
+
```csharp
|
|
44
|
+
// Anonymous sign-in. Creates a new player if no cached credentials exist.
|
|
45
|
+
Task SignInAnonymouslyAsync(SignInOptions options = default)
|
|
46
|
+
|
|
47
|
+
// Google ID token sign-in.
|
|
48
|
+
Task SignInWithGoogleAsync(string idToken, SignInOptions options = default)
|
|
49
|
+
|
|
50
|
+
// Google Play Games auth code sign-in.
|
|
51
|
+
Task SignInWithGooglePlayGamesAsync(string authCode, SignInOptions options = default)
|
|
52
|
+
|
|
53
|
+
// Apple ID token sign-in.
|
|
54
|
+
Task SignInWithAppleAsync(string idToken, SignInOptions options = default)
|
|
55
|
+
|
|
56
|
+
// Apple Game Center signature sign-in.
|
|
57
|
+
Task SignInWithAppleGameCenterAsync(string signature, string teamPlayerId, string publicKeyURL, string salt, ulong timestamp, SignInOptions options = default)
|
|
58
|
+
|
|
59
|
+
// Facebook access token sign-in.
|
|
60
|
+
Task SignInWithFacebookAsync(string accessToken, SignInOptions options = default)
|
|
61
|
+
|
|
62
|
+
// Steam session ticket sign-in. The identity param is REQUIRED (deprecated overload without it).
|
|
63
|
+
[Obsolete] Task SignInWithSteamAsync(string sessionTicket, SignInOptions options = default)
|
|
64
|
+
Task SignInWithSteamAsync(string sessionTicket, string identity, SignInOptions options = default)
|
|
65
|
+
// For sub-apps (PlayTest, Demo) -- include appId:
|
|
66
|
+
Task SignInWithSteamAsync(string sessionTicket, string identity, string appId, SignInOptions options = default)
|
|
67
|
+
|
|
68
|
+
// Oculus sign-in. Both nonce AND userId are required.
|
|
69
|
+
Task SignInWithOculusAsync(string nonce, string userId, SignInOptions options = default)
|
|
70
|
+
|
|
71
|
+
// OpenID Connect sign-in with a custom provider ID.
|
|
72
|
+
Task SignInWithOpenIdConnectAsync(string idProviderName, string idToken, SignInOptions options = default)
|
|
73
|
+
|
|
74
|
+
// Unity token sign-in.
|
|
75
|
+
Task SignInWithUnityAsync(string token, SignInOptions options = default)
|
|
76
|
+
|
|
77
|
+
// Username/password sign-up (first-time registration).
|
|
78
|
+
Task SignUpWithUsernamePasswordAsync(string username, string password)
|
|
79
|
+
|
|
80
|
+
// Username/password sign-in (no SignInOptions).
|
|
81
|
+
Task SignInWithUsernamePasswordAsync(string username, string password)
|
|
82
|
+
|
|
83
|
+
// Device code flow -- generate code, then poll for sign-in.
|
|
84
|
+
Task<SignInCodeInfo> GenerateSignInCodeAsync(string identifier = default)
|
|
85
|
+
Task SignInWithCodeAsync(bool usePolling = false, CancellationToken cancellationToken = default)
|
|
86
|
+
Task<SignInCodeInfo> GetSignInCodeInfoAsync(string code)
|
|
87
|
+
Task ConfirmCodeAsync(string code, string idProvider = default, string externalToken = default)
|
|
88
|
+
|
|
89
|
+
// Sign out. Synchronous (void), NOT async.
|
|
90
|
+
void SignOut(bool clearCredentials = false)
|
|
91
|
+
|
|
92
|
+
// Permanently delete the current player's account.
|
|
93
|
+
Task DeleteAccountAsync()
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Key Properties
|
|
99
|
+
|
|
100
|
+
| Property | Type | Description |
|
|
101
|
+
|---|---|---|
|
|
102
|
+
| `IsSignedIn` | `bool` | Token exists in memory (player has signed in during this session) |
|
|
103
|
+
| `IsAuthorized` | `bool` | Access token is present AND not expired (player can make API calls) |
|
|
104
|
+
| `IsExpired` | `bool` | Access token has expired but still exists (SDK will try auto-refresh) |
|
|
105
|
+
| `PlayerId` | `string` | Unique player identifier |
|
|
106
|
+
| `PlayerName` | `string` | Player display name |
|
|
107
|
+
| `AccessToken` | `string` | JWT access token for service calls |
|
|
108
|
+
| `Profile` | `string` | Current profile name |
|
|
109
|
+
| `SessionTokenExists` | `bool` | True if a session token is cached |
|
|
110
|
+
|
|
111
|
+
**Key distinction:** `IsSignedIn` means a token exists (even if expired). `IsAuthorized` means the token is currently valid. `IsExpired` means the token expired but still exists -- the SDK will attempt automatic refresh. If refresh fails, `SignInFailed` fires.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Events
|
|
116
|
+
|
|
117
|
+
| Event | Signature | When fired |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| `SignedIn` | `Action` | Sign-in succeeds |
|
|
120
|
+
| `SignedOut` | `Action` | Player signs out |
|
|
121
|
+
| `Expired` | `Action` | Access token expires; SDK auto-attempts refresh. Re-auth only needed if refresh fails (`SignInFailed` fires) |
|
|
122
|
+
| `SignInFailed` | `Action<RequestFailedException>` | Sign-in or token refresh fails |
|
|
123
|
+
| `SignInCodeReceived` | `Action<SignInCodeInfo>` | Device code flow: sign-in code generated |
|
|
124
|
+
| `SignInCodeExpired` | `Action` | Device code flow: sign-in code expired |
|
|
125
|
+
| `PlayerNameChanged` | `Action<string>` | Player name updated (provides new name) |
|
|
126
|
+
| `PlayerIdChanged` | `Action<string>` | Player ID changed (provides new ID) |
|
|
127
|
+
| `PlayerInfoChanged` | `Action<PlayerInfo>` | Player info updated |
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Player Info / Name
|
|
132
|
+
|
|
133
|
+
```csharp
|
|
134
|
+
Task<PlayerInfo> GetPlayerInfoAsync()
|
|
135
|
+
Task<string> GetPlayerNameAsync(bool autoGenerate = true)
|
|
136
|
+
Task<string> UpdatePlayerNameAsync(string name)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### `PlayerInfo` Properties
|
|
140
|
+
|
|
141
|
+
| Property | Type | Description |
|
|
142
|
+
|---|---|---|
|
|
143
|
+
| `Id` | `string` | UGS player ID |
|
|
144
|
+
| `Username` | `string?` | Username (if set) |
|
|
145
|
+
| `Identities` | `List<Identity>` | Linked external providers |
|
|
146
|
+
| `CreatedAt` | `DateTime?` | Account creation time |
|
|
147
|
+
| `LastPasswordUpdate` | `DateTime?` | Last password change |
|
|
148
|
+
|
|
149
|
+
Helper methods: `GetGoogleId()`, `GetAppleId()`, `GetFacebookId()`, `GetSteamId()`, `GetOculusId()`, `GetGooglePlayGamesId()`, `GetAppleGameCenterId()`, `GetUnityId()`, `GetOpenIdConnectId(providerName)`, `GetCustomId()`, `GetOpenIdConnectIdProviders()`.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Link / Unlink Methods
|
|
154
|
+
|
|
155
|
+
All Link methods accept an optional `LinkOptions` parameter (for `ForceLink`).
|
|
156
|
+
|
|
157
|
+
```csharp
|
|
158
|
+
Task LinkWithGoogleAsync(string idToken, LinkOptions options = default)
|
|
159
|
+
Task LinkWithGooglePlayGamesAsync(string authCode, LinkOptions options = default)
|
|
160
|
+
Task LinkWithAppleAsync(string idToken, LinkOptions options = default)
|
|
161
|
+
Task LinkWithAppleGameCenterAsync(string signature, string teamPlayerId, string publicKeyURL, string salt, ulong timestamp, LinkOptions options = default)
|
|
162
|
+
Task LinkWithFacebookAsync(string accessToken, LinkOptions options = default)
|
|
163
|
+
[Obsolete] Task LinkWithSteamAsync(string sessionTicket, LinkOptions options = default)
|
|
164
|
+
Task LinkWithSteamAsync(string sessionTicket, string identity, LinkOptions options = default)
|
|
165
|
+
Task LinkWithSteamAsync(string sessionTicket, string identity, string appId, LinkOptions options = default)
|
|
166
|
+
Task LinkWithOculusAsync(string nonce, string userId, LinkOptions options = default)
|
|
167
|
+
Task LinkWithOpenIdConnectAsync(string idProviderName, string idToken, LinkOptions options = default)
|
|
168
|
+
Task LinkWithUnityAsync(string token, LinkOptions options = default)
|
|
169
|
+
|
|
170
|
+
Task UnlinkGoogleAsync()
|
|
171
|
+
Task UnlinkGooglePlayGamesAsync()
|
|
172
|
+
Task UnlinkAppleAsync()
|
|
173
|
+
Task UnlinkAppleGameCenterAsync()
|
|
174
|
+
Task UnlinkFacebookAsync()
|
|
175
|
+
Task UnlinkSteamAsync()
|
|
176
|
+
Task UnlinkOculusAsync()
|
|
177
|
+
Task UnlinkOpenIdConnectAsync(string idProviderName)
|
|
178
|
+
Task UnlinkUnityAsync()
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Note:** There is no `UnlinkUsernamePasswordAsync`. Username/password credentials cannot be unlinked once linked.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Profile Switching
|
|
186
|
+
|
|
187
|
+
```csharp
|
|
188
|
+
// Switch active profile. Must be called BEFORE sign-in. Synchronous.
|
|
189
|
+
void SwitchProfile(string profile)
|
|
190
|
+
|
|
191
|
+
// Clear cached session token for the active profile.
|
|
192
|
+
void ClearSessionToken()
|
|
193
|
+
|
|
194
|
+
// Process externally-obtained tokens.
|
|
195
|
+
void ProcessAuthenticationTokens(string accessToken, string sessionToken = default)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Use `SwitchProfile(string profile)` before sign-in to store separate cached credentials per-profile (useful for multiple accounts on one device). Must be called BEFORE signing in -- call `SignOut()` first if already signed in.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Username/Password Constraints
|
|
203
|
+
|
|
204
|
+
| Field | Constraint |
|
|
205
|
+
|---|---|
|
|
206
|
+
| Username length | 3-20 characters |
|
|
207
|
+
| Username characters | `A-Z`, `a-z`, `0-9`, `.`, `-`, `@`, `_` |
|
|
208
|
+
| Username case | Case insensitive (stored lowercase) |
|
|
209
|
+
| Password length | 8-30 characters |
|
|
210
|
+
| Password requirements | At least 1 lowercase + 1 uppercase + 1 number + 1 symbol |
|
|
211
|
+
|
|
212
|
+
Username/password credentials **cannot be unlinked** once linked. `UpdatePasswordAsync()` signs out all other devices for this player.
|
|
213
|
+
|
|
214
|
+
Additional username/password management methods:
|
|
215
|
+
|
|
216
|
+
```csharp
|
|
217
|
+
// Add username/password to an existing signed-in account.
|
|
218
|
+
Task AddUsernamePasswordAsync(string username, string password)
|
|
219
|
+
|
|
220
|
+
// Update the password for the currently signed-in account.
|
|
221
|
+
// WARNING: Signs out ALL other devices for this player.
|
|
222
|
+
Task UpdatePasswordAsync(string currentPassword, string newPassword)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Options / Types
|
|
228
|
+
|
|
229
|
+
### `SignInOptions`
|
|
230
|
+
|
|
231
|
+
| Property | Type | Default | Description |
|
|
232
|
+
|---|---|---|---|
|
|
233
|
+
| `CreateAccount` | `bool` | `true` | If false, only sign in if an existing player maps to the credentials |
|
|
234
|
+
|
|
235
|
+
### `LinkOptions`
|
|
236
|
+
|
|
237
|
+
| Property | Type | Default | Description |
|
|
238
|
+
|---|---|---|---|
|
|
239
|
+
| `ForceLink` | `bool` | `false` | If true, removes existing link on another player and reassigns to current |
|
|
240
|
+
|
|
241
|
+
### `SignInCodeInfo`
|
|
242
|
+
|
|
243
|
+
| Property | Type | Description |
|
|
244
|
+
|---|---|---|
|
|
245
|
+
| `SignInCode` | `string` | The code to display to the user |
|
|
246
|
+
| `Identifier` | `string` | Identifier for the code |
|
|
247
|
+
| `Expiration` | `string` | When the code expires |
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Identity Providers Quick Reference
|
|
252
|
+
|
|
253
|
+
| Provider | Dashboard credentials | SDK input | SDK method |
|
|
254
|
+
|---|---|---|---|
|
|
255
|
+
| Anonymous | None | None | `SignInAnonymouslyAsync()` |
|
|
256
|
+
| Google | Client ID, Client Secret | ID token | `SignInWithGoogleAsync(idToken)` |
|
|
257
|
+
| Google Play Games | Client ID, Client Secret | Auth code | `SignInWithGooglePlayGamesAsync(authCode)` |
|
|
258
|
+
| Apple | Client ID, Client Secret | ID token | `SignInWithAppleAsync(idToken)` |
|
|
259
|
+
| Apple Game Center | Client ID, Client Secret | Signature bundle | `SignInWithAppleGameCenterAsync(...)` |
|
|
260
|
+
| Facebook | Client ID, Client Secret | Access token | `SignInWithFacebookAsync(accessToken)` |
|
|
261
|
+
| Steam | Publisher Web API Key | Session ticket + identity | `SignInWithSteamAsync(sessionTicket, identity)` |
|
|
262
|
+
| Oculus | App ID, App Secret | Nonce + user ID | `SignInWithOculusAsync(nonce, userId)` |
|
|
263
|
+
| OpenID Connect | Client ID, Client Secret, Issuer URL | ID token | `SignInWithOpenIdConnectAsync(providerName, idToken)` |
|
|
264
|
+
| Unity Player Accounts | Enable in dashboard | Access token | `SignInWithUnityAsync(token)` |
|
|
265
|
+
| Username / Password | Enable in dashboard | Username + password | `SignInWithUsernamePasswordAsync(u, p)` |
|
|
266
|
+
|
|
267
|
+
All social identity providers are configured in the **Unity Dashboard**: Your project > Products > Authentication > Identity Providers > Add provider.
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Code Templates
|
|
272
|
+
|
|
273
|
+
### Initialize and Sign In Anonymously
|
|
274
|
+
|
|
275
|
+
```csharp
|
|
276
|
+
using Unity.Services.Core;
|
|
277
|
+
using Unity.Services.Authentication;
|
|
278
|
+
|
|
279
|
+
async Task InitAndSignIn()
|
|
280
|
+
{
|
|
281
|
+
await UnityServices.InitializeAsync();
|
|
282
|
+
|
|
283
|
+
// SignInAnonymouslyAsync auto-detects returning vs new players:
|
|
284
|
+
// - If a session token exists, it signs in silently with the cached token
|
|
285
|
+
// - If no token exists, it creates a new anonymous account
|
|
286
|
+
if (!AuthenticationService.Instance.IsSignedIn)
|
|
287
|
+
{
|
|
288
|
+
await AuthenticationService.Instance.SignInAnonymouslyAsync();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
Debug.Log($"Signed in as {AuthenticationService.Instance.PlayerId}");
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Sign In with Steam (with Identity Param)
|
|
296
|
+
|
|
297
|
+
```csharp
|
|
298
|
+
// sessionTicket from SteamUser.GetAuthSessionTicket
|
|
299
|
+
// identity string for security (required -- old overload without it is deprecated)
|
|
300
|
+
await AuthenticationService.Instance.SignInWithSteamAsync(sessionTicket, identity);
|
|
301
|
+
|
|
302
|
+
// For sub-apps (PlayTest, Demo) -- include appId:
|
|
303
|
+
await AuthenticationService.Instance.SignInWithSteamAsync(sessionTicket, identity, appId);
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Username/Password Sign Up then Sign In
|
|
307
|
+
|
|
308
|
+
```csharp
|
|
309
|
+
// First-time registration
|
|
310
|
+
await AuthenticationService.Instance.SignUpWithUsernamePasswordAsync("myUsername", "MyPassword123!");
|
|
311
|
+
|
|
312
|
+
// Subsequent sign-ins
|
|
313
|
+
await AuthenticationService.Instance.SignInWithUsernamePasswordAsync("myUsername", "MyPassword123!");
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Link a Provider
|
|
317
|
+
|
|
318
|
+
```csharp
|
|
319
|
+
// Player is already signed in anonymously; link their Google account
|
|
320
|
+
try
|
|
321
|
+
{
|
|
322
|
+
await AuthenticationService.Instance.LinkWithGoogleAsync(googleIdToken);
|
|
323
|
+
Debug.Log("Google account linked successfully.");
|
|
324
|
+
}
|
|
325
|
+
catch (AuthenticationException ex) when (ex.ErrorCode == AuthenticationErrorCodes.AccountAlreadyLinked)
|
|
326
|
+
{
|
|
327
|
+
Debug.LogWarning("This Google account is already linked to another player.");
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Force-link: removes existing link on another player and reassigns to current
|
|
331
|
+
await AuthenticationService.Instance.LinkWithGoogleAsync(
|
|
332
|
+
idToken,
|
|
333
|
+
new LinkOptions { ForceLink = true });
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Switch Profile
|
|
337
|
+
|
|
338
|
+
```csharp
|
|
339
|
+
// Must sign out first, then switch, then sign in
|
|
340
|
+
AuthenticationService.Instance.SignOut();
|
|
341
|
+
AuthenticationService.Instance.SwitchProfile("ProfileB");
|
|
342
|
+
await AuthenticationService.Instance.SignInAnonymouslyAsync();
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Token Expiry Handling
|
|
346
|
+
|
|
347
|
+
```csharp
|
|
348
|
+
AuthenticationService.Instance.Expired += () =>
|
|
349
|
+
{
|
|
350
|
+
// Token expired - the SDK will attempt to refresh automatically.
|
|
351
|
+
// If refresh fails, you'll get SignInFailed and need to re-authenticate.
|
|
352
|
+
Debug.Log("Token expired, SDK is attempting refresh...");
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
AuthenticationService.Instance.SignInFailed += (ex) =>
|
|
356
|
+
{
|
|
357
|
+
// Refresh failed, prompt user to sign in again
|
|
358
|
+
Debug.LogError($"Sign-in failed: {ex.Message}");
|
|
359
|
+
};
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Error Handling
|
|
363
|
+
|
|
364
|
+
```csharp
|
|
365
|
+
try
|
|
366
|
+
{
|
|
367
|
+
await AuthenticationService.Instance.SignInAnonymouslyAsync();
|
|
368
|
+
}
|
|
369
|
+
catch (AuthenticationException ex)
|
|
370
|
+
{
|
|
371
|
+
// ex.ErrorCode contains the specific error code
|
|
372
|
+
Debug.LogError($"Auth failed: {ex.Message} (code: {ex.ErrorCode})");
|
|
373
|
+
}
|
|
374
|
+
catch (RequestFailedException ex)
|
|
375
|
+
{
|
|
376
|
+
// Network or other service errors
|
|
377
|
+
Debug.LogError($"Request failed: {ex.Message}");
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Account Management (GetPlayerInfo, UpdatePlayerName, DeleteAccount)
|
|
382
|
+
|
|
383
|
+
```csharp
|
|
384
|
+
// Get full player info
|
|
385
|
+
var info = await AuthenticationService.Instance.GetPlayerInfoAsync();
|
|
386
|
+
|
|
387
|
+
// Get or update player name
|
|
388
|
+
var name = await AuthenticationService.Instance.GetPlayerNameAsync();
|
|
389
|
+
var updated = await AuthenticationService.Instance.UpdatePlayerNameAsync("NewName");
|
|
390
|
+
|
|
391
|
+
// Add username/password to existing account
|
|
392
|
+
await AuthenticationService.Instance.AddUsernamePasswordAsync(username, password);
|
|
393
|
+
|
|
394
|
+
// Update password (signs out ALL other devices for this player)
|
|
395
|
+
await AuthenticationService.Instance.UpdatePasswordAsync(currentPassword, newPassword);
|
|
396
|
+
|
|
397
|
+
// Delete account permanently
|
|
398
|
+
await AuthenticationService.Instance.DeleteAccountAsync();
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## Error Handling
|
|
404
|
+
|
|
405
|
+
Throws `AuthenticationException` (extends `RequestFailedException`) on failure. Use `ex.ErrorCode` and compare against `AuthenticationErrorCodes`:
|
|
406
|
+
|
|
407
|
+
| Constant | Value | Meaning |
|
|
408
|
+
|---|---|---|
|
|
409
|
+
| `ClientInvalidUserState` | 10000 | Operation not valid in current state |
|
|
410
|
+
| `ClientNoActiveSession` | 10001 | No active session |
|
|
411
|
+
| `InvalidParameters` | 10002 | Bad input parameters |
|
|
412
|
+
| `AccountAlreadyLinked` | 10003 | External ID already linked to another player |
|
|
413
|
+
| `AccountLinkLimitExceeded` | 10004 | Max linked accounts for this provider type |
|
|
414
|
+
| `ClientUnlinkExternalIdNotFound` | 10005 | External ID not linked |
|
|
415
|
+
| `ClientInvalidProfile` | 10006 | Invalid profile name |
|
|
416
|
+
| `InvalidSessionToken` | 10007 | Session token invalid or expired |
|
|
417
|
+
| `InvalidProvider` | 10008 | Unknown identity provider |
|
|
418
|
+
| `BannedUser` | 10009 | Player has been banned |
|
|
419
|
+
| `EnvironmentMismatch` | 10010 | Session token from a different environment |
|
|
420
|
+
|
|
421
|
+
**Error response format:** Authentication errors follow RFC 7807 (Problem Details). Branch your error handling on `status` and `title` fields, never on `detail` -- the detail message may change without notice.
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## Session Warnings
|
|
426
|
+
|
|
427
|
+
**Console platforms (Xbox, PlayStation, Switch):** Token refresh is NOT automatic. You must manually re-sign in when the token expires.
|
|
428
|
+
|
|
429
|
+
**Anonymous-only accounts:** Calling `ClearSessionToken()` or `SignOut(clearCredentials: true)` on an account that ONLY has anonymous sign-in will **permanently lose** that account. Always link at least one external provider before clearing credentials.
|
|
430
|
+
|
|
431
|
+
**DeleteAccountAsync compliance:** iOS App Store (Guideline 5.1.1) requires apps that support account creation to offer account deletion. `DeleteAccountAsync()` only deletes **Authentication data**. It does NOT automatically clean up data in other UGS services (Cloud Save, Economy, Leaderboards, etc.). You must manually delete data from each service before calling `DeleteAccountAsync()`.
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
## Asset Store Building Blocks
|
|
436
|
+
|
|
437
|
+
- **Player Account Building Block:** Ready-made sign-in UI (anonymous, Unity browser, username/password), Cloud Save integration for player data, and a Cloud Code module for server-authoritative writes. [Asset Store](https://assetstore.unity.com/packages/essentials/tutorial-projects/unity-building-block-player-account-341928)
|