@zigrivers/scaffold 3.4.1 → 3.5.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/README.md +91 -0
- package/content/knowledge/game/game-accessibility.md +328 -0
- package/content/knowledge/game/game-ai-patterns.md +542 -0
- package/content/knowledge/game/game-asset-pipeline.md +359 -0
- package/content/knowledge/game/game-audio-design.md +342 -0
- package/content/knowledge/game/game-binary-vcs-strategy.md +396 -0
- package/content/knowledge/game/game-design-document.md +260 -0
- package/content/knowledge/game/game-domain-patterns.md +297 -0
- package/content/knowledge/game/game-economy-design.md +355 -0
- package/content/knowledge/game/game-engine-selection.md +242 -0
- package/content/knowledge/game/game-input-systems.md +357 -0
- package/content/knowledge/game/game-level-content-design.md +455 -0
- package/content/knowledge/game/game-liveops-analytics.md +280 -0
- package/content/knowledge/game/game-localization.md +323 -0
- package/content/knowledge/game/game-milestone-definitions.md +337 -0
- package/content/knowledge/game/game-modding-ugc.md +390 -0
- package/content/knowledge/game/game-narrative-design.md +404 -0
- package/content/knowledge/game/game-networking.md +391 -0
- package/content/knowledge/game/game-performance-budgeting.md +378 -0
- package/content/knowledge/game/game-platform-certification.md +417 -0
- package/content/knowledge/game/game-project-structure.md +360 -0
- package/content/knowledge/game/game-save-systems.md +452 -0
- package/content/knowledge/game/game-testing-strategy.md +470 -0
- package/content/knowledge/game/game-ui-patterns.md +475 -0
- package/content/knowledge/game/game-vr-ar-design.md +313 -0
- package/content/knowledge/review/review-art-bible.md +305 -0
- package/content/knowledge/review/review-game-design.md +303 -0
- package/content/knowledge/review/review-game-economy.md +272 -0
- package/content/knowledge/review/review-netcode.md +280 -0
- package/content/knowledge/review/review-platform-cert.md +341 -0
- package/content/methodology/custom-defaults.yml +25 -0
- package/content/methodology/deep.yml +25 -0
- package/content/methodology/game-overlay.yml +145 -0
- package/content/methodology/mvp.yml +25 -0
- package/content/pipeline/architecture/ai-behavior-design.md +87 -0
- package/content/pipeline/architecture/netcode-spec.md +86 -0
- package/content/pipeline/architecture/review-netcode.md +78 -0
- package/content/pipeline/foundation/performance-budgets.md +91 -0
- package/content/pipeline/modeling/narrative-bible.md +84 -0
- package/content/pipeline/pre/game-design-document.md +89 -0
- package/content/pipeline/pre/review-gdd.md +74 -0
- package/content/pipeline/quality/analytics-telemetry.md +98 -0
- package/content/pipeline/quality/live-ops-plan.md +99 -0
- package/content/pipeline/quality/platform-cert-prep.md +129 -0
- package/content/pipeline/quality/playtest-plan.md +83 -0
- package/content/pipeline/specification/art-bible.md +87 -0
- package/content/pipeline/specification/audio-design.md +96 -0
- package/content/pipeline/specification/content-structure-design.md +141 -0
- package/content/pipeline/specification/economy-design.md +104 -0
- package/content/pipeline/specification/game-accessibility.md +82 -0
- package/content/pipeline/specification/game-ui-spec.md +97 -0
- package/content/pipeline/specification/input-controls-spec.md +81 -0
- package/content/pipeline/specification/localization-plan.md +113 -0
- package/content/pipeline/specification/modding-ugc-spec.md +116 -0
- package/content/pipeline/specification/online-services-spec.md +104 -0
- package/content/pipeline/specification/review-economy.md +87 -0
- package/content/pipeline/specification/review-game-ui.md +73 -0
- package/content/pipeline/specification/save-system-spec.md +116 -0
- package/dist/cli/commands/adopt.d.ts.map +1 -1
- package/dist/cli/commands/adopt.js +25 -0
- package/dist/cli/commands/adopt.js.map +1 -1
- package/dist/cli/commands/adopt.test.js +28 -1
- package/dist/cli/commands/adopt.test.js.map +1 -1
- package/dist/cli/commands/build.test.js +3 -0
- package/dist/cli/commands/build.test.js.map +1 -1
- package/dist/cli/commands/init.d.ts +1 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +6 -0
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/init.test.js +12 -1
- package/dist/cli/commands/init.test.js.map +1 -1
- package/dist/cli/commands/knowledge.test.js +8 -0
- package/dist/cli/commands/knowledge.test.js.map +1 -1
- package/dist/cli/commands/next.d.ts.map +1 -1
- package/dist/cli/commands/next.js +19 -5
- package/dist/cli/commands/next.js.map +1 -1
- package/dist/cli/commands/next.test.js +56 -0
- package/dist/cli/commands/next.test.js.map +1 -1
- package/dist/cli/commands/rework.d.ts.map +1 -1
- package/dist/cli/commands/rework.js +11 -2
- package/dist/cli/commands/rework.js.map +1 -1
- package/dist/cli/commands/rework.test.js +5 -0
- package/dist/cli/commands/rework.test.js.map +1 -1
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +54 -4
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/run.test.js +384 -0
- package/dist/cli/commands/run.test.js.map +1 -1
- package/dist/cli/commands/skip.test.js +3 -0
- package/dist/cli/commands/skip.test.js.map +1 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +16 -3
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/status.test.js +55 -0
- package/dist/cli/commands/status.test.js.map +1 -1
- package/dist/cli/output/auto.d.ts +3 -0
- package/dist/cli/output/auto.d.ts.map +1 -1
- package/dist/cli/output/auto.js +9 -0
- package/dist/cli/output/auto.js.map +1 -1
- package/dist/cli/output/context.d.ts +6 -0
- package/dist/cli/output/context.d.ts.map +1 -1
- package/dist/cli/output/context.js.map +1 -1
- package/dist/cli/output/context.test.js +87 -0
- package/dist/cli/output/context.test.js.map +1 -1
- package/dist/cli/output/error-display.test.js +3 -0
- package/dist/cli/output/error-display.test.js.map +1 -1
- package/dist/cli/output/interactive.d.ts +3 -0
- package/dist/cli/output/interactive.d.ts.map +1 -1
- package/dist/cli/output/interactive.js +76 -0
- package/dist/cli/output/interactive.js.map +1 -1
- package/dist/cli/output/json.d.ts +3 -0
- package/dist/cli/output/json.d.ts.map +1 -1
- package/dist/cli/output/json.js +9 -0
- package/dist/cli/output/json.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +3 -2
- package/dist/config/loader.js.map +1 -1
- package/dist/config/schema.d.ts +641 -15
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +26 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/config/schema.test.js +192 -1
- package/dist/config/schema.test.js.map +1 -1
- package/dist/core/assembly/overlay-loader.d.ts +24 -0
- package/dist/core/assembly/overlay-loader.d.ts.map +1 -0
- package/dist/core/assembly/overlay-loader.js +190 -0
- package/dist/core/assembly/overlay-loader.js.map +1 -0
- package/dist/core/assembly/overlay-loader.test.d.ts +2 -0
- package/dist/core/assembly/overlay-loader.test.d.ts.map +1 -0
- package/dist/core/assembly/overlay-loader.test.js +106 -0
- package/dist/core/assembly/overlay-loader.test.js.map +1 -0
- package/dist/core/assembly/overlay-resolver.d.ts +15 -0
- package/dist/core/assembly/overlay-resolver.d.ts.map +1 -0
- package/dist/core/assembly/overlay-resolver.js +58 -0
- package/dist/core/assembly/overlay-resolver.js.map +1 -0
- package/dist/core/assembly/overlay-resolver.test.d.ts +2 -0
- package/dist/core/assembly/overlay-resolver.test.d.ts.map +1 -0
- package/dist/core/assembly/overlay-resolver.test.js +246 -0
- package/dist/core/assembly/overlay-resolver.test.js.map +1 -0
- package/dist/core/assembly/overlay-state-resolver.d.ts +26 -0
- package/dist/core/assembly/overlay-state-resolver.d.ts.map +1 -0
- package/dist/core/assembly/overlay-state-resolver.js +63 -0
- package/dist/core/assembly/overlay-state-resolver.js.map +1 -0
- package/dist/core/assembly/overlay-state-resolver.test.d.ts +2 -0
- package/dist/core/assembly/overlay-state-resolver.test.d.ts.map +1 -0
- package/dist/core/assembly/overlay-state-resolver.test.js +256 -0
- package/dist/core/assembly/overlay-state-resolver.test.js.map +1 -0
- package/dist/core/assembly/preset-loader.d.ts +1 -0
- package/dist/core/assembly/preset-loader.d.ts.map +1 -1
- package/dist/core/assembly/preset-loader.js +2 -0
- package/dist/core/assembly/preset-loader.js.map +1 -1
- package/dist/core/dependency/eligibility.test.js +3 -0
- package/dist/core/dependency/eligibility.test.js.map +1 -1
- package/dist/e2e/game-pipeline.test.d.ts +10 -0
- package/dist/e2e/game-pipeline.test.d.ts.map +1 -0
- package/dist/e2e/game-pipeline.test.js +298 -0
- package/dist/e2e/game-pipeline.test.js.map +1 -0
- package/dist/e2e/init.test.js +3 -0
- package/dist/e2e/init.test.js.map +1 -1
- package/dist/project/adopt.d.ts +3 -1
- package/dist/project/adopt.d.ts.map +1 -1
- package/dist/project/adopt.js +29 -1
- package/dist/project/adopt.js.map +1 -1
- package/dist/project/adopt.test.js +51 -1
- package/dist/project/adopt.test.js.map +1 -1
- package/dist/types/config.d.ts +50 -4
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.test.d.ts +2 -0
- package/dist/types/config.test.d.ts.map +1 -0
- package/dist/types/config.test.js +97 -0
- package/dist/types/config.test.js.map +1 -0
- package/dist/utils/eligible.d.ts +3 -2
- package/dist/utils/eligible.d.ts.map +1 -1
- package/dist/utils/eligible.js +18 -4
- package/dist/utils/eligible.js.map +1 -1
- package/dist/utils/errors.d.ts +4 -0
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +31 -0
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/errors.test.js +4 -1
- package/dist/utils/errors.test.js.map +1 -1
- package/dist/wizard/questions.d.ts +4 -0
- package/dist/wizard/questions.d.ts.map +1 -1
- package/dist/wizard/questions.js +59 -1
- package/dist/wizard/questions.js.map +1 -1
- package/dist/wizard/questions.test.js +178 -4
- package/dist/wizard/questions.test.js.map +1 -1
- package/dist/wizard/wizard.d.ts +1 -0
- package/dist/wizard/wizard.d.ts.map +1 -1
- package/dist/wizard/wizard.js +4 -1
- package/dist/wizard/wizard.js.map +1 -1
- package/dist/wizard/wizard.test.js +102 -4
- package/dist/wizard/wizard.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: game-platform-certification
|
|
3
|
+
description: Sony TRC, Microsoft XR, Nintendo Lotcheck, mobile store guidelines, Steam Deck compatibility review, and common failure points
|
|
4
|
+
topics: [game-dev, certification, trc, tcr, xr, lotcheck, app-store]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Platform certification is the gatekeeping process each platform holder uses to ensure games meet minimum technical and policy standards before release. Every platform has its own requirements document, submission process, and failure criteria. Failing certification delays launch by days to weeks per resubmission, and each failure costs time, money, and morale. Understanding common failure points and building pre-check routines into your development process is far cheaper than discovering issues during formal submission.
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
### Platform Overview
|
|
12
|
+
|
|
13
|
+
**Sony PlayStation — Technical Requirements Checklist (TRC):**
|
|
14
|
+
Sony's TRC is the most detailed console certification. Requirements cover system features (trophies, Activity Cards, PS5-specific features), save data handling, network behavior, error handling, and performance. Sony reviews builds in their QA lab, typically taking 5-10 business days. A single critical failure ("A-rank" issue) triggers a full resubmission with the same timeline.
|
|
15
|
+
|
|
16
|
+
**Microsoft Xbox — Xbox Requirements (XR):**
|
|
17
|
+
Microsoft's requirements are called Xbox Requirements (XR), not "TCR" (an older term). XR covers Xbox Live integration, achievement implementation, suspend/resume behavior, Quick Resume support, smart delivery, and accessibility. Microsoft's certification process is faster than Sony's (often 3-5 business days) but they enforce Xbox Live integration requirements strictly.
|
|
18
|
+
|
|
19
|
+
**Nintendo — Lotcheck:**
|
|
20
|
+
Nintendo's Lotcheck process is the most opaque. Nintendo does not publish a full requirements document externally — developers receive guidelines under NDA when onboarded. Lotcheck is known for strict requirements around controller handling (Joy-Con detachment, handheld/docked transitions), save data, and user interface standards. Lotcheck turnaround varies from 5-15 business days.
|
|
21
|
+
|
|
22
|
+
**Apple App Store / Google Play:**
|
|
23
|
+
Mobile store reviews focus on content policy, privacy (App Tracking Transparency, data safety), and user experience. Apple's review is more subjective and can reject for UI/UX reasons. Google's review is more automated but stricter on policy violations. Both have appeal processes. Review time is typically 1-3 days for updates, longer for initial submissions.
|
|
24
|
+
|
|
25
|
+
**Steam Deck — Compatibility Review:**
|
|
26
|
+
Valve's Steam Deck process is a compatibility review, not a certification. Valve explicitly uses this language. Games are categorized as Verified, Playable, Unsupported, or Unknown based on controller support, display compatibility, seamless experience (no external launchers), and system support (Proton/Linux compatibility). There is no submission process — Valve tests games proactively, and developers can request a review or update their status.
|
|
27
|
+
|
|
28
|
+
### Certification Timelines
|
|
29
|
+
|
|
30
|
+
```yaml
|
|
31
|
+
# Typical certification timelines (plan these into your release schedule)
|
|
32
|
+
certification_timelines:
|
|
33
|
+
sony_playstation:
|
|
34
|
+
initial_submission: "5-10 business days"
|
|
35
|
+
resubmission: "5-10 business days (full re-review)"
|
|
36
|
+
patch_submission: "3-5 business days"
|
|
37
|
+
pre_check_available: true
|
|
38
|
+
notes: "Book slots early — queue backs up before major holidays"
|
|
39
|
+
|
|
40
|
+
microsoft_xbox:
|
|
41
|
+
initial_submission: "3-5 business days"
|
|
42
|
+
resubmission: "3-5 business days"
|
|
43
|
+
patch_submission: "1-3 business days"
|
|
44
|
+
pre_check_available: true
|
|
45
|
+
notes: "Pre-cert tool catches many XR issues before submission"
|
|
46
|
+
|
|
47
|
+
nintendo_switch:
|
|
48
|
+
initial_submission: "5-15 business days"
|
|
49
|
+
resubmission: "5-15 business days"
|
|
50
|
+
patch_submission: "5-10 business days"
|
|
51
|
+
pre_check_available: false
|
|
52
|
+
notes: "Most variable timeline — plan conservatively"
|
|
53
|
+
|
|
54
|
+
apple_app_store:
|
|
55
|
+
initial_submission: "1-7 days (highly variable)"
|
|
56
|
+
update: "1-3 days"
|
|
57
|
+
expedited_review: "Available for critical fixes"
|
|
58
|
+
notes: "Rejections can be subjective — prepare for appeals"
|
|
59
|
+
|
|
60
|
+
google_play:
|
|
61
|
+
initial_submission: "1-3 days"
|
|
62
|
+
update: "Hours to 2 days"
|
|
63
|
+
notes: "Mostly automated; policy violations may trigger manual review"
|
|
64
|
+
|
|
65
|
+
steam_deck:
|
|
66
|
+
compatibility_review: "Valve-initiated, no fixed timeline"
|
|
67
|
+
developer_request: "Submit via Steamworks partner site"
|
|
68
|
+
notes: "Not a certification — Valve calls it 'compatibility review'"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Deep Guidance
|
|
72
|
+
|
|
73
|
+
### Sony TRC Common Requirements and Failure Points
|
|
74
|
+
|
|
75
|
+
Sony's TRC document is extensive (hundreds of requirements). The following are the most common failure points based on industry experience:
|
|
76
|
+
|
|
77
|
+
**Save data handling (TRC R4050-series):**
|
|
78
|
+
- Save data must be stored using the platform's save API, not raw filesystem writes
|
|
79
|
+
- Games must handle corrupt save data gracefully — detect, inform the player, offer to create new save
|
|
80
|
+
- Save icons and descriptions must be set correctly
|
|
81
|
+
- Auto-save must display a save indicator and prevent power-off during write
|
|
82
|
+
- Save data size must be within declared limits
|
|
83
|
+
|
|
84
|
+
**Trophy implementation (TRC R5000-series):**
|
|
85
|
+
- Every game must have a Platinum trophy (awarded for earning all other trophies)
|
|
86
|
+
- Trophy descriptions must not contain spoilers for the first half of the game
|
|
87
|
+
- Trophies must be earnable — no trophy can be made permanently inaccessible through normal gameplay
|
|
88
|
+
- Trophy unlock must use the correct API calls and display the system notification
|
|
89
|
+
- Trophy images must meet resolution and content guidelines
|
|
90
|
+
|
|
91
|
+
**PS5-specific features:**
|
|
92
|
+
- Activity Cards must accurately reflect game progress and state
|
|
93
|
+
- Haptic feedback and adaptive triggers should be implemented (strongly recommended, not always required)
|
|
94
|
+
- Game Help integration for Activity Cards (recommended for major first-party, less enforced for indie)
|
|
95
|
+
- SSD performance: loading screens under 2 seconds for fast-travel and respawn (target, not always enforced)
|
|
96
|
+
|
|
97
|
+
**Network and error handling:**
|
|
98
|
+
- Games must handle network disconnection gracefully at every point
|
|
99
|
+
- PSN sign-in/sign-out during gameplay must not crash
|
|
100
|
+
- Error messages must use platform-standard error codes where applicable
|
|
101
|
+
- Online features must check PS Plus subscription status where required
|
|
102
|
+
|
|
103
|
+
**Common failure pattern:** The single most common TRC failure is improper suspend/resume behavior. The game must correctly handle being suspended (rest mode) and resumed at any point in the game flow — including during loading screens, cutscenes, save operations, and network transactions.
|
|
104
|
+
|
|
105
|
+
### Microsoft Xbox Requirements (XR)
|
|
106
|
+
|
|
107
|
+
Microsoft's Xbox Requirements document uses the XR naming convention. Key areas:
|
|
108
|
+
|
|
109
|
+
**Xbox Live integration:**
|
|
110
|
+
- Games using Xbox Live must integrate Xbox Identity (sign-in)
|
|
111
|
+
- Achievements must be implemented according to XR specs: meaningful achievements, no trivially awarded achievements, achievement art meets guidelines
|
|
112
|
+
- Rich Presence strings must accurately reflect current game activity
|
|
113
|
+
- Xbox Live multiplayer must use the platform matchmaking and session management APIs
|
|
114
|
+
|
|
115
|
+
**Quick Resume:**
|
|
116
|
+
- Games must support Quick Resume (suspend to SSD, resume in seconds)
|
|
117
|
+
- Game state must be preserved and restored correctly
|
|
118
|
+
- Network connections must be re-established transparently after resume
|
|
119
|
+
- If Quick Resume is technically impossible for the game, a waiver must be requested
|
|
120
|
+
|
|
121
|
+
**Smart Delivery:**
|
|
122
|
+
- Games targeting both Xbox One and Xbox Series X|S must use Smart Delivery
|
|
123
|
+
- Players who purchase the game get the correct version for their console automatically
|
|
124
|
+
- This is largely handled by packaging and build configuration in the Xbox partner tools
|
|
125
|
+
|
|
126
|
+
**Accessibility:**
|
|
127
|
+
- XR includes accessibility requirements (drawn from XAG) — text size minimums, subtitle support
|
|
128
|
+
- These requirements are evolving and becoming stricter over time
|
|
129
|
+
- Meeting XAG guidelines is not required for certification, but specific XR items drawn from XAG are
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
// Pre-certification checklist automation
|
|
133
|
+
// Run this as part of your CI/CD pipeline before submission builds
|
|
134
|
+
|
|
135
|
+
interface CertCheckResult {
|
|
136
|
+
platform: string;
|
|
137
|
+
category: string;
|
|
138
|
+
requirement: string;
|
|
139
|
+
status: "pass" | "fail" | "warn" | "skip";
|
|
140
|
+
details: string;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function runPreCertChecks(platform: Platform): CertCheckResult[] {
|
|
144
|
+
const results: CertCheckResult[] = [];
|
|
145
|
+
|
|
146
|
+
// Common cross-platform checks
|
|
147
|
+
results.push(checkSaveDataIntegrity());
|
|
148
|
+
results.push(checkCrashOnSuspendResume());
|
|
149
|
+
results.push(checkNetworkDisconnectHandling());
|
|
150
|
+
results.push(checkErrorMessageCompliance(platform));
|
|
151
|
+
results.push(checkMinimumTextSize(platform));
|
|
152
|
+
results.push(checkSubtitleImplementation());
|
|
153
|
+
results.push(checkControllerDisconnectHandling(platform));
|
|
154
|
+
|
|
155
|
+
// Platform-specific checks
|
|
156
|
+
switch (platform) {
|
|
157
|
+
case "playstation":
|
|
158
|
+
results.push(checkTrophyImplementation());
|
|
159
|
+
results.push(checkActivityCards());
|
|
160
|
+
results.push(checkPSNSignInOutFlow());
|
|
161
|
+
results.push(checkSaveDataAPI("orbis")); // PS platform save API
|
|
162
|
+
break;
|
|
163
|
+
|
|
164
|
+
case "xbox":
|
|
165
|
+
results.push(checkAchievementImplementation());
|
|
166
|
+
results.push(checkQuickResumeSupport());
|
|
167
|
+
results.push(checkRichPresenceStrings());
|
|
168
|
+
results.push(checkXboxLiveIntegration());
|
|
169
|
+
results.push(checkSmartDeliveryConfig());
|
|
170
|
+
break;
|
|
171
|
+
|
|
172
|
+
case "nintendo":
|
|
173
|
+
results.push(checkJoyConHandling());
|
|
174
|
+
results.push(checkDockedHandheldTransition());
|
|
175
|
+
results.push(checkNintendoAccountIntegration());
|
|
176
|
+
results.push(checkSaveDataSize());
|
|
177
|
+
break;
|
|
178
|
+
|
|
179
|
+
case "ios":
|
|
180
|
+
results.push(checkAppTrackingTransparency());
|
|
181
|
+
results.push(checkInAppPurchaseImplementation());
|
|
182
|
+
results.push(checkPrivacyNutritionLabels());
|
|
183
|
+
results.push(checkIPv6Networking());
|
|
184
|
+
break;
|
|
185
|
+
|
|
186
|
+
case "android":
|
|
187
|
+
results.push(checkDataSafetySection());
|
|
188
|
+
results.push(checkTargetAPILevel());
|
|
189
|
+
results.push(checkPlayBillingLibrary());
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return results;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
type Platform = "playstation" | "xbox" | "nintendo" | "ios" | "android" | "steam_deck";
|
|
197
|
+
|
|
198
|
+
// Stub check functions — replace with actual implementation
|
|
199
|
+
function checkSaveDataIntegrity(): CertCheckResult {
|
|
200
|
+
return { platform: "all", category: "save", requirement: "Save data integrity", status: "pass", details: "" };
|
|
201
|
+
}
|
|
202
|
+
function checkCrashOnSuspendResume(): CertCheckResult {
|
|
203
|
+
return { platform: "all", category: "lifecycle", requirement: "Suspend/resume stability", status: "pass", details: "" };
|
|
204
|
+
}
|
|
205
|
+
function checkNetworkDisconnectHandling(): CertCheckResult {
|
|
206
|
+
return { platform: "all", category: "network", requirement: "Disconnect handling", status: "pass", details: "" };
|
|
207
|
+
}
|
|
208
|
+
function checkErrorMessageCompliance(p: Platform): CertCheckResult {
|
|
209
|
+
return { platform: p, category: "ux", requirement: "Error message compliance", status: "pass", details: "" };
|
|
210
|
+
}
|
|
211
|
+
function checkMinimumTextSize(p: Platform): CertCheckResult {
|
|
212
|
+
return { platform: p, category: "accessibility", requirement: "Minimum text size", status: "pass", details: "" };
|
|
213
|
+
}
|
|
214
|
+
function checkSubtitleImplementation(): CertCheckResult {
|
|
215
|
+
return { platform: "all", category: "accessibility", requirement: "Subtitle options", status: "pass", details: "" };
|
|
216
|
+
}
|
|
217
|
+
function checkControllerDisconnectHandling(p: Platform): CertCheckResult {
|
|
218
|
+
return { platform: p, category: "input", requirement: "Controller disconnect", status: "pass", details: "" };
|
|
219
|
+
}
|
|
220
|
+
function checkTrophyImplementation(): CertCheckResult {
|
|
221
|
+
return { platform: "playstation", category: "trc", requirement: "Trophy implementation", status: "pass", details: "" };
|
|
222
|
+
}
|
|
223
|
+
function checkActivityCards(): CertCheckResult {
|
|
224
|
+
return { platform: "playstation", category: "trc", requirement: "Activity Cards", status: "pass", details: "" };
|
|
225
|
+
}
|
|
226
|
+
function checkPSNSignInOutFlow(): CertCheckResult {
|
|
227
|
+
return { platform: "playstation", category: "trc", requirement: "PSN sign-in/out", status: "pass", details: "" };
|
|
228
|
+
}
|
|
229
|
+
function checkSaveDataAPI(api: string): CertCheckResult {
|
|
230
|
+
return { platform: "playstation", category: "trc", requirement: `Save API (${api})`, status: "pass", details: "" };
|
|
231
|
+
}
|
|
232
|
+
function checkAchievementImplementation(): CertCheckResult {
|
|
233
|
+
return { platform: "xbox", category: "xr", requirement: "Achievements", status: "pass", details: "" };
|
|
234
|
+
}
|
|
235
|
+
function checkQuickResumeSupport(): CertCheckResult {
|
|
236
|
+
return { platform: "xbox", category: "xr", requirement: "Quick Resume", status: "pass", details: "" };
|
|
237
|
+
}
|
|
238
|
+
function checkRichPresenceStrings(): CertCheckResult {
|
|
239
|
+
return { platform: "xbox", category: "xr", requirement: "Rich Presence", status: "pass", details: "" };
|
|
240
|
+
}
|
|
241
|
+
function checkXboxLiveIntegration(): CertCheckResult {
|
|
242
|
+
return { platform: "xbox", category: "xr", requirement: "Xbox Live integration", status: "pass", details: "" };
|
|
243
|
+
}
|
|
244
|
+
function checkSmartDeliveryConfig(): CertCheckResult {
|
|
245
|
+
return { platform: "xbox", category: "xr", requirement: "Smart Delivery", status: "pass", details: "" };
|
|
246
|
+
}
|
|
247
|
+
function checkJoyConHandling(): CertCheckResult {
|
|
248
|
+
return { platform: "nintendo", category: "lotcheck", requirement: "Joy-Con handling", status: "pass", details: "" };
|
|
249
|
+
}
|
|
250
|
+
function checkDockedHandheldTransition(): CertCheckResult {
|
|
251
|
+
return { platform: "nintendo", category: "lotcheck", requirement: "Docked/handheld transition", status: "pass", details: "" };
|
|
252
|
+
}
|
|
253
|
+
function checkNintendoAccountIntegration(): CertCheckResult {
|
|
254
|
+
return { platform: "nintendo", category: "lotcheck", requirement: "Nintendo Account", status: "pass", details: "" };
|
|
255
|
+
}
|
|
256
|
+
function checkSaveDataSize(): CertCheckResult {
|
|
257
|
+
return { platform: "nintendo", category: "lotcheck", requirement: "Save data size", status: "pass", details: "" };
|
|
258
|
+
}
|
|
259
|
+
function checkAppTrackingTransparency(): CertCheckResult {
|
|
260
|
+
return { platform: "ios", category: "appstore", requirement: "ATT prompt", status: "pass", details: "" };
|
|
261
|
+
}
|
|
262
|
+
function checkInAppPurchaseImplementation(): CertCheckResult {
|
|
263
|
+
return { platform: "ios", category: "appstore", requirement: "IAP implementation", status: "pass", details: "" };
|
|
264
|
+
}
|
|
265
|
+
function checkPrivacyNutritionLabels(): CertCheckResult {
|
|
266
|
+
return { platform: "ios", category: "appstore", requirement: "Privacy labels", status: "pass", details: "" };
|
|
267
|
+
}
|
|
268
|
+
function checkIPv6Networking(): CertCheckResult {
|
|
269
|
+
return { platform: "ios", category: "appstore", requirement: "IPv6 networking", status: "pass", details: "" };
|
|
270
|
+
}
|
|
271
|
+
function checkDataSafetySection(): CertCheckResult {
|
|
272
|
+
return { platform: "android", category: "playstore", requirement: "Data safety section", status: "pass", details: "" };
|
|
273
|
+
}
|
|
274
|
+
function checkTargetAPILevel(): CertCheckResult {
|
|
275
|
+
return { platform: "android", category: "playstore", requirement: "Target API level", status: "pass", details: "" };
|
|
276
|
+
}
|
|
277
|
+
function checkPlayBillingLibrary(): CertCheckResult {
|
|
278
|
+
return { platform: "android", category: "playstore", requirement: "Play Billing Library", status: "pass", details: "" };
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Nintendo Lotcheck
|
|
283
|
+
|
|
284
|
+
Lotcheck is less documented than Sony/Microsoft certification due to NDA constraints. Known common failure areas:
|
|
285
|
+
|
|
286
|
+
**Controller handling:**
|
|
287
|
+
- Games must handle Joy-Con detachment and reattachment during gameplay without crashing
|
|
288
|
+
- Docked-to-handheld and handheld-to-docked transitions must work seamlessly
|
|
289
|
+
- If the game supports single Joy-Con play, all required actions must be mappable to the reduced button set
|
|
290
|
+
- Pro Controller, Joy-Con grip, handheld mode, and tabletop mode must all be supported (or the game must clearly indicate which modes are supported)
|
|
291
|
+
|
|
292
|
+
**Performance:**
|
|
293
|
+
- Frame rate must not drop below playable thresholds during normal gameplay
|
|
294
|
+
- Memory usage must stay within Switch limits (especially problematic for cross-platform ports)
|
|
295
|
+
- Load times should be reasonable — excessively long loads can trigger Lotcheck concerns
|
|
296
|
+
|
|
297
|
+
**User experience:**
|
|
298
|
+
- Nintendo has specific requirements for how system UI interacts with the game
|
|
299
|
+
- Home button must be responsive at all times
|
|
300
|
+
- Sleep mode and wake must work correctly with no data loss
|
|
301
|
+
|
|
302
|
+
### Apple App Store and Google Play
|
|
303
|
+
|
|
304
|
+
**Apple-specific concerns:**
|
|
305
|
+
- **App Tracking Transparency (ATT)**: Games that track users across apps must display the ATT prompt. Using any third-party analytics or ad SDK likely triggers this requirement.
|
|
306
|
+
- **In-App Purchase**: All digital goods must use Apple's IAP system. No linking to external payment methods for digital content. Physical goods and services are exempt.
|
|
307
|
+
- **IPv6**: All networking must work on IPv6-only networks. Apple tests this. Hardcoded IPv4 addresses will be rejected.
|
|
308
|
+
- **Design guidelines**: Apple rejects apps for UI/UX issues: non-standard navigation, confusing layouts, or "minimal functionality."
|
|
309
|
+
|
|
310
|
+
**Google-specific concerns:**
|
|
311
|
+
- **Target API level**: Google requires targeting a recent Android API level. Falling behind triggers removal from the store.
|
|
312
|
+
- **Play Billing Library**: Must use the current version of Google's billing library for in-app purchases.
|
|
313
|
+
- **Data Safety section**: Accurate declaration of all data collected and how it is used. Inaccuracies lead to enforcement actions.
|
|
314
|
+
- **Families Policy**: Games targeting children face additional restrictions (no personalized ads, limited data collection).
|
|
315
|
+
|
|
316
|
+
### Steam Deck Compatibility Review
|
|
317
|
+
|
|
318
|
+
Valve evaluates games for Steam Deck compatibility using four categories:
|
|
319
|
+
|
|
320
|
+
- **Verified**: The game works perfectly on Steam Deck with no modifications. Full controller support, no launchers, readable text, correct display resolution.
|
|
321
|
+
- **Playable**: The game works but may require manual configuration (community controller layout, launcher interaction, text readability issues).
|
|
322
|
+
- **Unsupported**: The game does not work on Steam Deck (anti-cheat incompatibility, hardware requirements, missing controller support).
|
|
323
|
+
- **Unknown**: Valve has not reviewed the game yet.
|
|
324
|
+
|
|
325
|
+
**Key criteria for Verified status:**
|
|
326
|
+
- Full controller support with appropriate glyphs (show Steam Deck button icons, not Xbox or keyboard)
|
|
327
|
+
- No external launcher that interrupts the experience (this is the most common reason for "Playable" instead of "Verified")
|
|
328
|
+
- Text readable at Steam Deck's 7-inch 1280x800 display
|
|
329
|
+
- Default configuration works without user intervention
|
|
330
|
+
- Game runs at acceptable performance on Steam Deck hardware
|
|
331
|
+
|
|
332
|
+
### Waiver Best Practices
|
|
333
|
+
|
|
334
|
+
Sometimes a certification requirement cannot be met. Platforms allow waivers for specific requirements when justified.
|
|
335
|
+
|
|
336
|
+
**When to request a waiver:**
|
|
337
|
+
- A technical limitation of the game engine or middleware makes compliance impossible
|
|
338
|
+
- The requirement conflicts with the game's core design (e.g., a VR game cannot implement certain controller handling requirements)
|
|
339
|
+
- The feature is planned for a post-launch patch with a specific date
|
|
340
|
+
|
|
341
|
+
**How to write a successful waiver:**
|
|
342
|
+
- Identify the exact requirement number being waived
|
|
343
|
+
- Explain why compliance is not possible (technical detail, not excuses)
|
|
344
|
+
- Describe the user impact and any mitigations in place
|
|
345
|
+
- Provide a timeline for future compliance if applicable
|
|
346
|
+
- Be specific — vague waiver requests are denied
|
|
347
|
+
|
|
348
|
+
### Common Failure Points by Category
|
|
349
|
+
|
|
350
|
+
```yaml
|
|
351
|
+
# Most common certification failures across all platforms
|
|
352
|
+
common_failures:
|
|
353
|
+
lifecycle_management:
|
|
354
|
+
frequency: "Very High"
|
|
355
|
+
examples:
|
|
356
|
+
- "Game crashes when suspended during loading screen"
|
|
357
|
+
- "Network session not restored after Quick Resume"
|
|
358
|
+
- "Save data corrupted when power lost during write"
|
|
359
|
+
- "Game hangs when user signs out of platform account mid-game"
|
|
360
|
+
prevention: "Test suspend/resume at every game state, including loading and saving"
|
|
361
|
+
|
|
362
|
+
controller_handling:
|
|
363
|
+
frequency: "High"
|
|
364
|
+
examples:
|
|
365
|
+
- "Game does not respond to controller reconnection"
|
|
366
|
+
- "Joy-Con detachment causes crash"
|
|
367
|
+
- "Button prompts show wrong glyphs for current input device"
|
|
368
|
+
- "No controller disconnect notification shown to player"
|
|
369
|
+
prevention: "Implement controller hot-swap handling early; test disconnect at every screen"
|
|
370
|
+
|
|
371
|
+
save_data:
|
|
372
|
+
frequency: "High"
|
|
373
|
+
examples:
|
|
374
|
+
- "Corrupt save data crashes game instead of recovery prompt"
|
|
375
|
+
- "Save data exceeds declared size limits"
|
|
376
|
+
- "Auto-save does not show save indicator"
|
|
377
|
+
- "Platform save API not used (raw file I/O instead)"
|
|
378
|
+
prevention: "Use platform save APIs exclusively; test with corrupted save files"
|
|
379
|
+
|
|
380
|
+
network_resilience:
|
|
381
|
+
frequency: "Medium-High"
|
|
382
|
+
examples:
|
|
383
|
+
- "Game hangs when network drops during matchmaking"
|
|
384
|
+
- "Error message does not use platform error codes"
|
|
385
|
+
- "No timeout on network requests — game waits indefinitely"
|
|
386
|
+
- "Online features accessible without required subscription check"
|
|
387
|
+
prevention: "Test every network call with simulated disconnects and timeouts"
|
|
388
|
+
|
|
389
|
+
text_and_localization:
|
|
390
|
+
frequency: "Medium"
|
|
391
|
+
examples:
|
|
392
|
+
- "Text truncated or overlapping in non-English languages"
|
|
393
|
+
- "Minimum text size requirements not met"
|
|
394
|
+
- "Placeholder text visible in shipped build"
|
|
395
|
+
- "Legal text or EULA not displayed per platform requirements"
|
|
396
|
+
prevention: "Test all supported languages; verify text size at target display distances"
|
|
397
|
+
|
|
398
|
+
age_rating_and_content:
|
|
399
|
+
frequency: "Low-Medium"
|
|
400
|
+
examples:
|
|
401
|
+
- "ESRB/PEGI rating does not match actual content"
|
|
402
|
+
- "User-generated content not properly filtered"
|
|
403
|
+
- "Content descriptors incomplete or inaccurate"
|
|
404
|
+
prevention: "Complete rating questionnaires after content lock; re-rate if content changes"
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Certification in Your Release Schedule
|
|
408
|
+
|
|
409
|
+
Build certification into your timeline from day one:
|
|
410
|
+
|
|
411
|
+
- **Content lock → Cert submission**: Allow 1-2 weeks for internal pre-check and build preparation
|
|
412
|
+
- **First submission → Response**: Allow the full platform timeline (worst case for each platform)
|
|
413
|
+
- **Fix and resubmit**: Budget for at least one resubmission cycle per platform
|
|
414
|
+
- **Total cert buffer**: 4-6 weeks minimum from content lock to release-ready
|
|
415
|
+
- **Multi-platform simultaneous launch**: All platforms must pass cert before any can launch (unless the publisher accepts staggered launch)
|
|
416
|
+
|
|
417
|
+
Never schedule a release date that does not include certification buffer. A failed certification with no schedule margin means a delayed launch.
|