@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,396 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: game-binary-vcs-strategy
|
|
3
|
+
description: Git LFS deep dive, Perforce and PlasticSCM comparison, large repo tuning, lock protocols, CI for binary assets, VCS selection guide
|
|
4
|
+
topics: [game-dev, vcs, git-lfs, perforce, binary-assets]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Game development produces enormous volumes of binary assets — textures, meshes, audio, animations, and engine-specific formats — that fundamentally break assumptions baked into distributed version control systems like Git. A single Unreal project can exceed 100 GB of binary data that cannot be diffed, merged, or compressed efficiently. Choosing the right VCS strategy, configuring it correctly, and establishing team protocols around binary file workflows is a prerequisite for any multi-person game project. The wrong choice creates daily friction that compounds into weeks of lost productivity over a production cycle.
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
### The Binary Asset Problem
|
|
12
|
+
|
|
13
|
+
Standard Git was designed for text files. It stores full copies of every version of every file, diffs them line-by-line, and merges them with three-way text merge. Binary files break all three assumptions:
|
|
14
|
+
|
|
15
|
+
- **No meaningful diffs**: A 50 MB texture changed by an artist produces a 50 MB delta that conveys no human-readable information
|
|
16
|
+
- **No merging**: Two artists editing the same Maya file simultaneously will always produce a conflict that cannot be auto-resolved
|
|
17
|
+
- **Repository bloat**: Without special handling, every revision of every binary file lives in the Git object store forever, making clones take hours and disk usage grow without bound
|
|
18
|
+
|
|
19
|
+
### VCS Options for Game Projects
|
|
20
|
+
|
|
21
|
+
Three primary approaches exist, each with distinct tradeoffs:
|
|
22
|
+
|
|
23
|
+
1. **Git + Git LFS** — Uses Git for code and metadata, offloads binary files to a separate LFS server. Best for teams already fluent in Git workflows who need binary support.
|
|
24
|
+
|
|
25
|
+
2. **Perforce (Helix Core)** — Centralized VCS built for binary-heavy workflows from the ground up. Industry standard for AAA studios. Excellent file locking, workspace views, and stream-based branching.
|
|
26
|
+
|
|
27
|
+
3. **PlasticSCM (Unity Version Control)** — Hybrid centralized/distributed VCS with visual merge tools, strong binary handling, and deep Unity integration. Now owned by Unity Technologies.
|
|
28
|
+
|
|
29
|
+
### When to Use Each
|
|
30
|
+
|
|
31
|
+
- **Git LFS**: Teams under 20, binary content under 50 GB, strong Git familiarity, open-source or indie projects, GitHub/GitLab CI pipelines already established
|
|
32
|
+
- **Perforce**: Teams over 20, binary content over 100 GB, AAA/console projects, need exclusive file checkout enforcement, multiple offices with proxy servers
|
|
33
|
+
- **PlasticSCM**: Unity-centric teams, desire for visual diff/merge tools for prefabs and scenes, teams wanting centralized locking with distributed code workflows
|
|
34
|
+
|
|
35
|
+
### Key Decision Factors
|
|
36
|
+
|
|
37
|
+
- **Team size**: Larger teams need stronger locking enforcement — Perforce excels here
|
|
38
|
+
- **Repository size**: Git LFS has practical limits around 50–100 GB before clone/fetch times become painful; Perforce handles terabyte-scale repos routinely
|
|
39
|
+
- **Platform familiarity**: Forcing a Git-native team onto Perforce (or vice versa) creates onboarding friction
|
|
40
|
+
- **CI/CD integration**: Git-based CI (GitHub Actions, GitLab CI) integrates trivially with Git LFS; Perforce requires dedicated CI setup
|
|
41
|
+
- **Cost**: Git LFS is free (server hosting costs apply); Perforce is free for up to 5 users/20 workspaces; PlasticSCM is free for up to 3 users with Unity subscription
|
|
42
|
+
|
|
43
|
+
## Deep Guidance
|
|
44
|
+
|
|
45
|
+
### Git LFS Deep Dive
|
|
46
|
+
|
|
47
|
+
Git LFS replaces large files with lightweight pointer files in the Git repository, storing the actual file content on a separate LFS server (GitHub LFS, GitLab LFS, Azure DevOps, or self-hosted).
|
|
48
|
+
|
|
49
|
+
**How it works:**
|
|
50
|
+
1. `.gitattributes` rules designate which file patterns are LFS-tracked
|
|
51
|
+
2. On `git add`, LFS replaces the file content with a ~130-byte pointer containing the SHA-256 hash
|
|
52
|
+
3. The actual file is stored in `.git/lfs/objects/` locally and uploaded to the LFS server on push
|
|
53
|
+
4. On `git checkout`, LFS downloads the actual file content and replaces the pointer in the working directory
|
|
54
|
+
|
|
55
|
+
**Initial setup for a game project:**
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Initialize LFS in the repository (run once)
|
|
59
|
+
git lfs install
|
|
60
|
+
|
|
61
|
+
# Track binary file types BEFORE adding any binary files
|
|
62
|
+
# This creates/updates .gitattributes
|
|
63
|
+
git lfs track "*.png" "*.jpg" "*.tga" "*.psd" "*.exr"
|
|
64
|
+
git lfs track "*.fbx" "*.blend" "*.mb" "*.ma" "*.obj"
|
|
65
|
+
git lfs track "*.wav" "*.ogg" "*.mp3" "*.flac"
|
|
66
|
+
git lfs track "*.uasset" "*.umap"
|
|
67
|
+
git lfs track "*.unity" "*.prefab" "*.asset"
|
|
68
|
+
git lfs track "*.mp4" "*.mov"
|
|
69
|
+
git lfs track "*.dll" "*.so" "*.dylib"
|
|
70
|
+
|
|
71
|
+
# CRITICAL: Commit .gitattributes FIRST, before adding binary files
|
|
72
|
+
git add .gitattributes
|
|
73
|
+
git commit -m "chore: configure Git LFS tracking for game assets"
|
|
74
|
+
|
|
75
|
+
# Verify tracking
|
|
76
|
+
git lfs track
|
|
77
|
+
# Should list all patterns from .gitattributes
|
|
78
|
+
|
|
79
|
+
# Check LFS status
|
|
80
|
+
git lfs status
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**LFS locking for team workflows:**
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Enable locking on the server (GitHub, GitLab, etc.)
|
|
87
|
+
# Mark file types as lockable in .gitattributes
|
|
88
|
+
# (See game-asset-pipeline knowledge entry for full .gitattributes template)
|
|
89
|
+
|
|
90
|
+
# Lock a file before editing
|
|
91
|
+
git lfs lock "Content/Textures/T_Hero_D.png"
|
|
92
|
+
|
|
93
|
+
# See all current locks
|
|
94
|
+
git lfs locks
|
|
95
|
+
|
|
96
|
+
# See locks held by a specific user
|
|
97
|
+
git lfs locks --user="artist@studio.com"
|
|
98
|
+
|
|
99
|
+
# Unlock after pushing changes
|
|
100
|
+
git lfs unlock "Content/Textures/T_Hero_D.png"
|
|
101
|
+
|
|
102
|
+
# Admin force-unlock (when someone is unavailable)
|
|
103
|
+
git lfs unlock --force "Content/Textures/T_Hero_D.png"
|
|
104
|
+
|
|
105
|
+
# Verify all locks in CI (fail if stale locks exist)
|
|
106
|
+
# stale_locks.sh — run in CI on a schedule
|
|
107
|
+
STALE_THRESHOLD_HOURS=48
|
|
108
|
+
git lfs locks --json | python3 -c "
|
|
109
|
+
import json, sys
|
|
110
|
+
from datetime import datetime, timezone, timedelta
|
|
111
|
+
locks = json.load(sys.stdin)
|
|
112
|
+
threshold = datetime.now(timezone.utc) - timedelta(hours=$STALE_THRESHOLD_HOURS)
|
|
113
|
+
stale = [l for l in locks if datetime.fromisoformat(l['locked_at'].replace('Z','+00:00')) < threshold]
|
|
114
|
+
if stale:
|
|
115
|
+
for l in stale:
|
|
116
|
+
print(f\"STALE LOCK: {l['path']} by {l['owner']['name']} since {l['locked_at']}\")
|
|
117
|
+
sys.exit(1)
|
|
118
|
+
print(f'No stale locks (checked {len(locks)} active locks)')
|
|
119
|
+
"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### LFS Performance Tuning
|
|
123
|
+
|
|
124
|
+
Large repositories with Git LFS require tuning to maintain reasonable performance.
|
|
125
|
+
|
|
126
|
+
**Bandwidth and transfer optimization:**
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Increase concurrent LFS transfers (default is 3)
|
|
130
|
+
git config lfs.concurrenttransfers 8
|
|
131
|
+
|
|
132
|
+
# Enable LFS transfer queue batching
|
|
133
|
+
git config lfs.batch true
|
|
134
|
+
|
|
135
|
+
# Set transfer timeout for large files (seconds)
|
|
136
|
+
git config lfs.activitytimeout 60
|
|
137
|
+
|
|
138
|
+
# Use SSH transfer for better performance on some servers
|
|
139
|
+
git config lfs.url "ssh://git@github.com/org/repo.git"
|
|
140
|
+
|
|
141
|
+
# For partial clones — only download LFS objects you need
|
|
142
|
+
# Clone without downloading ANY LFS objects
|
|
143
|
+
GIT_LFS_SKIP_SMUDGE=1 git clone <repo-url>
|
|
144
|
+
# Then fetch only the LFS objects for your current checkout
|
|
145
|
+
git lfs pull
|
|
146
|
+
|
|
147
|
+
# For CI: only fetch LFS objects that changed in the PR
|
|
148
|
+
git lfs fetch origin main --recent
|
|
149
|
+
git lfs checkout
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Repository maintenance:**
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
# Prune old LFS objects not referenced by recent commits
|
|
156
|
+
git lfs prune
|
|
157
|
+
|
|
158
|
+
# Verify LFS object integrity
|
|
159
|
+
git lfs fsck
|
|
160
|
+
|
|
161
|
+
# Migrate existing binary files into LFS (if LFS was added late)
|
|
162
|
+
# WARNING: This rewrites history — coordinate with the entire team
|
|
163
|
+
git lfs migrate import --include="*.png,*.fbx,*.wav" --everything
|
|
164
|
+
|
|
165
|
+
# Check LFS storage usage
|
|
166
|
+
git lfs ls-files -s | awk '{sum += $1} END {print sum/1024/1024 " MB"}'
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Perforce (Helix Core) for Game Development
|
|
170
|
+
|
|
171
|
+
Perforce is the industry standard for AAA game studios. Its centralized model eliminates the binary merge problem by design — only one person can check out an exclusive file at a time.
|
|
172
|
+
|
|
173
|
+
**Key advantages over Git LFS:**
|
|
174
|
+
- **Native exclusive checkout**: Files marked as exclusive can only be edited by one person at a time, enforced server-side. No need for manual locking discipline.
|
|
175
|
+
- **Workspace views**: Users sync only the files they need. An artist can exclude all code; a programmer can exclude all raw art. Reduces local disk usage dramatically.
|
|
176
|
+
- **Streams**: Branching model designed for game development with mainline, development, and release streams that handle binary assets correctly.
|
|
177
|
+
- **Proxy servers**: Perforce Proxy caches frequently accessed file revisions at remote offices, reducing WAN traffic for distributed teams.
|
|
178
|
+
- **Scale**: Perforce routinely handles repositories with millions of files and terabytes of content. Google's monorepo runs on a Perforce fork (Piper).
|
|
179
|
+
|
|
180
|
+
**Key disadvantages:**
|
|
181
|
+
- **Centralized model**: Requires constant server connectivity for most operations. Offline work is limited.
|
|
182
|
+
- **Learning curve**: Perforce concepts (workspaces, changelists, streams, typemaps) differ significantly from Git. Teams fluent in Git face a ramp-up period.
|
|
183
|
+
- **Cost**: Free for up to 5 users/20 workspaces. Beyond that, per-seat licensing adds up for large teams.
|
|
184
|
+
- **CI complexity**: Most modern CI systems (GitHub Actions, GitLab CI) are Git-native. Perforce integration requires dedicated plugins or custom scripting.
|
|
185
|
+
|
|
186
|
+
**Perforce typemap for game assets:**
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
# Perforce typemap — add to server configuration
|
|
190
|
+
# Controls how file types are stored and locked
|
|
191
|
+
|
|
192
|
+
Typemap:
|
|
193
|
+
binary+lFS4 //depot/....png
|
|
194
|
+
binary+lFS4 //depot/....jpg
|
|
195
|
+
binary+lFS4 //depot/....tga
|
|
196
|
+
binary+lFS4 //depot/....psd
|
|
197
|
+
binary+lFS4 //depot/....exr
|
|
198
|
+
binary+lFS4 //depot/....fbx
|
|
199
|
+
binary+lFS4 //depot/....blend
|
|
200
|
+
binary+lFS4 //depot/....mb
|
|
201
|
+
binary+lFS4 //depot/....ma
|
|
202
|
+
binary+lFS4 //depot/....wav
|
|
203
|
+
binary+lFS4 //depot/....ogg
|
|
204
|
+
binary+lFS4 //depot/....mp3
|
|
205
|
+
binary+lFS4 //depot/....uasset
|
|
206
|
+
binary+lFS4 //depot/....umap
|
|
207
|
+
text //depot/....cs
|
|
208
|
+
text //depot/....cpp
|
|
209
|
+
text //depot/....h
|
|
210
|
+
text //depot/....py
|
|
211
|
+
text //depot/....json
|
|
212
|
+
text //depot/....yaml
|
|
213
|
+
text //depot/....yml
|
|
214
|
+
text //depot/....md
|
|
215
|
+
text //depot/....xml
|
|
216
|
+
|
|
217
|
+
# Flags explanation:
|
|
218
|
+
# l = exclusive lock (only one checkout at a time)
|
|
219
|
+
# F = store full file (no delta compression for binaries)
|
|
220
|
+
# S4 = keep only last 4 revisions server-side (saves storage)
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### PlasticSCM (Unity Version Control)
|
|
224
|
+
|
|
225
|
+
PlasticSCM offers a middle ground — centralized locking like Perforce with distributed branching like Git, plus visual merge tools that understand Unity-specific file formats.
|
|
226
|
+
|
|
227
|
+
**Key advantages:**
|
|
228
|
+
- **Unity integration**: Built-in to Unity Editor. Artists and designers can lock, check out, and commit without leaving Unity.
|
|
229
|
+
- **Visual merge for Unity files**: Can merge `.prefab`, `.unity`, and `.asset` files with a visual tool that understands the YAML serialization format.
|
|
230
|
+
- **Branch explorer**: Visual branch/merge history that is more intuitive than `git log --graph` for non-programmers.
|
|
231
|
+
- **Distributed + centralized**: Developers can work distributed (like Git); artists can work centralized (like Perforce). Same repository, different workflows.
|
|
232
|
+
|
|
233
|
+
**Key disadvantages:**
|
|
234
|
+
- **Unity-centric**: Integration with Unreal or Godot is minimal. Non-Unity projects lose the main selling point.
|
|
235
|
+
- **Smaller ecosystem**: Fewer third-party integrations, tutorials, and community support compared to Git or Perforce.
|
|
236
|
+
- **Ownership uncertainty**: Unity Technologies acquired PlasticSCM; its long-term roadmap is tied to Unity's business decisions.
|
|
237
|
+
|
|
238
|
+
### Hybrid Strategies
|
|
239
|
+
|
|
240
|
+
Many studios use a hybrid approach — Git for code, a separate system for art:
|
|
241
|
+
|
|
242
|
+
**Git (code) + Perforce (art):**
|
|
243
|
+
- Programmers use Git with their existing workflows, branching, and CI
|
|
244
|
+
- Artists use Perforce for binary assets with exclusive checkout
|
|
245
|
+
- A build system assembles both repositories into a single build
|
|
246
|
+
- Complexity: two systems to maintain, two sets of access controls, potential sync issues
|
|
247
|
+
|
|
248
|
+
**Git LFS with strict locking + submodules:**
|
|
249
|
+
- Main repository contains code and metadata
|
|
250
|
+
- Binary assets live in a separate Git LFS repository added as a submodule
|
|
251
|
+
- Allows different clone/fetch strategies per repository
|
|
252
|
+
- CI checks out code repo normally, does a shallow/sparse checkout of the asset repo
|
|
253
|
+
|
|
254
|
+
**Decision framework:**
|
|
255
|
+
|
|
256
|
+
```yaml
|
|
257
|
+
# vcs_decision.yaml — Evaluate and document your VCS choice
|
|
258
|
+
|
|
259
|
+
project:
|
|
260
|
+
team_size: 8
|
|
261
|
+
binary_content_gb: 25
|
|
262
|
+
engine: unity
|
|
263
|
+
ci_platform: github_actions
|
|
264
|
+
distributed_team: false
|
|
265
|
+
|
|
266
|
+
evaluation:
|
|
267
|
+
git_lfs:
|
|
268
|
+
score: 8
|
|
269
|
+
pros:
|
|
270
|
+
- team already knows Git (10 years collective experience)
|
|
271
|
+
- GitHub Actions CI pipeline is established
|
|
272
|
+
- repository size (25 GB) within LFS comfort zone
|
|
273
|
+
- free with GitHub plan
|
|
274
|
+
cons:
|
|
275
|
+
- locking requires discipline (not enforced by default)
|
|
276
|
+
- clone time will grow as asset count increases
|
|
277
|
+
- no partial workspace (must clone entire repo)
|
|
278
|
+
mitigations:
|
|
279
|
+
- pre-commit hook to verify locks before edit
|
|
280
|
+
- CI stale lock detection
|
|
281
|
+
- document LFS partial clone for CI
|
|
282
|
+
|
|
283
|
+
perforce:
|
|
284
|
+
score: 5
|
|
285
|
+
pros:
|
|
286
|
+
- exclusive checkout prevents binary conflicts by design
|
|
287
|
+
- workspace views allow partial sync
|
|
288
|
+
cons:
|
|
289
|
+
- team has zero Perforce experience
|
|
290
|
+
- CI pipeline would need complete rebuild
|
|
291
|
+
- cost for 8 users exceeds git hosting
|
|
292
|
+
- overkill for 25 GB repository
|
|
293
|
+
mitigations:
|
|
294
|
+
- training budget for team onboarding
|
|
295
|
+
- Perforce CI plugins exist for Jenkins
|
|
296
|
+
|
|
297
|
+
plastic_scm:
|
|
298
|
+
score: 7
|
|
299
|
+
pros:
|
|
300
|
+
- Unity integration is excellent
|
|
301
|
+
- visual merge tools for .prefab files
|
|
302
|
+
- locking + distributed hybrid
|
|
303
|
+
cons:
|
|
304
|
+
- CI integration less mature than Git
|
|
305
|
+
- team would need to learn new tool
|
|
306
|
+
mitigations:
|
|
307
|
+
- in-Unity workflow reduces learning curve for artists
|
|
308
|
+
|
|
309
|
+
decision: git_lfs
|
|
310
|
+
rationale: >
|
|
311
|
+
Team Git expertise, existing CI pipeline, and moderate repo size
|
|
312
|
+
make Git LFS the lowest-friction choice. Locking discipline will
|
|
313
|
+
be enforced via hooks and CI checks rather than relying on
|
|
314
|
+
server-side enforcement.
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### CI Integration for Binary Assets
|
|
318
|
+
|
|
319
|
+
Binary assets require CI attention beyond code linting and unit tests.
|
|
320
|
+
|
|
321
|
+
**Pre-commit checks:**
|
|
322
|
+
- Verify no binary files are committed outside LFS tracking (check for large files in the Git object store)
|
|
323
|
+
- Validate file naming conventions
|
|
324
|
+
- Ensure locked files are actually locked by the committer
|
|
325
|
+
|
|
326
|
+
**Build pipeline:**
|
|
327
|
+
- Asset cooking/import validation (textures compressed, meshes within budget)
|
|
328
|
+
- Build size tracking — alert if build size grows by more than 5% in a single PR
|
|
329
|
+
- Orphaned asset detection — find assets not referenced by any scene or prefab
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
#!/usr/bin/env bash
|
|
333
|
+
# ci_binary_checks.sh — Binary asset validation for CI
|
|
334
|
+
|
|
335
|
+
set -euo pipefail
|
|
336
|
+
|
|
337
|
+
echo "=== Checking for binary files outside LFS ==="
|
|
338
|
+
# Find files larger than 1MB that are NOT tracked by LFS
|
|
339
|
+
git diff --cached --name-only --diff-filter=ACM | while read -r file; do
|
|
340
|
+
if [ -f "$file" ]; then
|
|
341
|
+
size=$(wc -c < "$file")
|
|
342
|
+
if [ "$size" -gt 1048576 ]; then # 1 MB
|
|
343
|
+
# Check if file is LFS-tracked
|
|
344
|
+
if ! git lfs ls-files --name-only | grep -qF "$file"; then
|
|
345
|
+
echo "ERROR: $file is ${size} bytes and NOT tracked by LFS"
|
|
346
|
+
echo " Add to .gitattributes: $(basename "$file" | sed 's/.*\./\*./')" \
|
|
347
|
+
"filter=lfs diff=lfs merge=lfs -text"
|
|
348
|
+
exit 1
|
|
349
|
+
fi
|
|
350
|
+
fi
|
|
351
|
+
fi
|
|
352
|
+
done
|
|
353
|
+
|
|
354
|
+
echo "=== Checking LFS pointer integrity ==="
|
|
355
|
+
# Verify all LFS pointers resolve to actual objects
|
|
356
|
+
git lfs ls-files --name-only | head -20 | while read -r lfs_file; do
|
|
357
|
+
if [ -f "$lfs_file" ]; then
|
|
358
|
+
if head -1 "$lfs_file" 2>/dev/null | grep -q "^version https://git-lfs"; then
|
|
359
|
+
echo "WARNING: $lfs_file is still a pointer (LFS content not fetched)"
|
|
360
|
+
fi
|
|
361
|
+
fi
|
|
362
|
+
done
|
|
363
|
+
|
|
364
|
+
echo "=== Checking build size delta ==="
|
|
365
|
+
if [ -f "build_size_baseline.txt" ]; then
|
|
366
|
+
baseline=$(cat build_size_baseline.txt)
|
|
367
|
+
# This would be replaced with actual build size measurement
|
|
368
|
+
echo "Baseline build size: ${baseline} MB"
|
|
369
|
+
fi
|
|
370
|
+
|
|
371
|
+
echo "All binary asset checks passed."
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Large Repository Performance Strategies
|
|
375
|
+
|
|
376
|
+
As game repositories grow, several strategies maintain developer productivity:
|
|
377
|
+
|
|
378
|
+
**Shallow clones for CI:**
|
|
379
|
+
- `git clone --depth=1` reduces clone time dramatically (only latest commit)
|
|
380
|
+
- Combined with `GIT_LFS_SKIP_SMUDGE=1`, avoids downloading any LFS content until explicitly requested
|
|
381
|
+
- CI then fetches only the LFS objects needed for the current build
|
|
382
|
+
|
|
383
|
+
**Sparse checkout:**
|
|
384
|
+
- `git sparse-checkout` lets developers clone only subdirectories they need
|
|
385
|
+
- An artist working on Level 3 does not need Level 1 or Level 2 assets locally
|
|
386
|
+
- Reduces local disk usage from hundreds of GB to the relevant working set
|
|
387
|
+
|
|
388
|
+
**LFS file caching:**
|
|
389
|
+
- Deploy a local LFS cache server (or Perforce Proxy) for studios with multiple developers on a LAN
|
|
390
|
+
- First developer to fetch an LFS object caches it; subsequent developers pull from cache
|
|
391
|
+
- Reduces external bandwidth by 80–90% in office environments
|
|
392
|
+
|
|
393
|
+
**Worktree strategy for binary-heavy repos:**
|
|
394
|
+
- Avoid multiple full clones for parallel work — use `git worktree` to share the object store
|
|
395
|
+
- Each worktree shares the same LFS cache, avoiding duplicate downloads
|
|
396
|
+
- Particularly valuable for code review checkouts alongside active development
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: game-design-document
|
|
3
|
+
description: GDD structure, game pillars, core loop design, mechanics documentation, and progression archetypes
|
|
4
|
+
topics: [game-dev, design, gdd, mechanics, progression]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
A Game Design Document (GDD) is the authoritative source of truth for what a game is, how it plays, and why its systems exist. Unlike traditional software requirements docs, a GDD must capture the feel and fantasy of the experience alongside its mechanical specifications. A well-structured GDD prevents scope creep, aligns the team on creative vision, and serves as the contract between design, engineering, and art.
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
### Game Pillars
|
|
12
|
+
|
|
13
|
+
Game pillars are the 3-5 non-negotiable design principles that guide every decision in development. They are phrased as "X over Y" tradeoffs to force clarity about what the game prioritizes when conflicts arise.
|
|
14
|
+
|
|
15
|
+
**Pillar craft rules:**
|
|
16
|
+
|
|
17
|
+
- Each pillar must be falsifiable — if its opposite is nonsensical, the pillar is too vague
|
|
18
|
+
- Pillars resolve conflicts: when two features compete for resources, the one aligned with more pillars wins
|
|
19
|
+
- Pillars are not features — "multiplayer" is a feature, "social connection over solo mastery" is a pillar
|
|
20
|
+
- Limit to 3-5; more than 5 means nothing is truly prioritized
|
|
21
|
+
- Revisit pillars only at major milestones, never mid-sprint
|
|
22
|
+
|
|
23
|
+
**Example pillar sets:**
|
|
24
|
+
|
|
25
|
+
- Dark Souls: "Challenge over accessibility," "Discovery over instruction," "Atmosphere over narrative"
|
|
26
|
+
- Stardew Valley: "Player expression over optimization," "Relaxation over challenge," "Community over competition"
|
|
27
|
+
- XCOM: "Consequence over convenience," "Tactical depth over action speed," "Emergent stories over scripted narrative"
|
|
28
|
+
|
|
29
|
+
### Core Loop
|
|
30
|
+
|
|
31
|
+
The core loop is the fundamental cycle of actions the player repeats most frequently. Every game has a primary loop (seconds-to-minutes), a secondary loop (minutes-to-hours), and often a tertiary loop (hours-to-sessions). Each loop feeds into the next.
|
|
32
|
+
|
|
33
|
+
**Core loop anatomy:**
|
|
34
|
+
|
|
35
|
+
1. **Input** — What the player does (move, shoot, place, select)
|
|
36
|
+
2. **Rules** — How the system processes the input (physics, damage calc, economy)
|
|
37
|
+
3. **Outcome** — What changes in the game state (enemy dies, resource gained, territory claimed)
|
|
38
|
+
4. **Feedback** — How the player perceives the outcome (animation, sound, UI change, screen shake)
|
|
39
|
+
|
|
40
|
+
A core loop is healthy when: every action has visible feedback within 200ms, outcomes feel proportional to skill/effort, and the loop itself is satisfying even without meta-progression.
|
|
41
|
+
|
|
42
|
+
### Mechanics Documentation
|
|
43
|
+
|
|
44
|
+
Every mechanic in the GDD must be documented with four components: inputs (what the player controls), rules (how the system resolves actions), outputs (what changes), and feedback (how the player perceives the change). Mechanics without all four components are incomplete and will be implemented inconsistently.
|
|
45
|
+
|
|
46
|
+
### Progression Archetypes
|
|
47
|
+
|
|
48
|
+
Games use one or more progression models to structure player advancement:
|
|
49
|
+
|
|
50
|
+
- **Linear** — Fixed sequence of levels/stages (e.g., Mario, Uncharted). Low design cost, high replayability risk.
|
|
51
|
+
- **Branching** — Player choices create divergent paths (e.g., Witcher, Mass Effect). Exponential content cost, high narrative agency.
|
|
52
|
+
- **Open-World** — Player chooses order and pacing (e.g., Breath of the Wild, Elden Ring). Requires careful gating and scaling.
|
|
53
|
+
- **Prestige/Ascension** — Player resets progress for permanent bonuses (e.g., Rogue Legacy, Cookie Clicker). Extends longevity cheaply.
|
|
54
|
+
- **Emergent** — No designed progression; player creates own goals (e.g., Minecraft, Dwarf Fortress). Requires rich systemic depth.
|
|
55
|
+
|
|
56
|
+
## Deep Guidance
|
|
57
|
+
|
|
58
|
+
### GDD Document Structure
|
|
59
|
+
|
|
60
|
+
A complete GDD follows a hierarchical structure that mirrors the game's design from vision down to individual mechanics. The document should be modular — each section can be read independently by the relevant discipline (art reads the aesthetic section, engineering reads the systems section).
|
|
61
|
+
|
|
62
|
+
```markdown
|
|
63
|
+
# [Game Title] — Game Design Document
|
|
64
|
+
|
|
65
|
+
## 1. Vision
|
|
66
|
+
### 1.1 Elevator Pitch
|
|
67
|
+
One paragraph. What is this game? Who is it for? Why will they care?
|
|
68
|
+
|
|
69
|
+
### 1.2 Game Pillars
|
|
70
|
+
- **[Pillar 1 Name]**: [X] over [Y] — [one sentence explanation]
|
|
71
|
+
- **[Pillar 2 Name]**: [X] over [Y] — [one sentence explanation]
|
|
72
|
+
- **[Pillar 3 Name]**: [X] over [Y] — [one sentence explanation]
|
|
73
|
+
|
|
74
|
+
### 1.3 Target Experience
|
|
75
|
+
What emotion or state should the player feel during a typical session?
|
|
76
|
+
Reference games, films, or other media that evoke similar feelings.
|
|
77
|
+
|
|
78
|
+
### 1.4 Unique Selling Proposition
|
|
79
|
+
What makes this game different from competitors? Be specific — not
|
|
80
|
+
"innovative gameplay" but "real-time base building inside turn-based combat."
|
|
81
|
+
|
|
82
|
+
## 2. Core Gameplay
|
|
83
|
+
### 2.1 Core Loop Diagram
|
|
84
|
+
[Visual or textual description of primary, secondary, and tertiary loops]
|
|
85
|
+
|
|
86
|
+
### 2.2 Player Actions
|
|
87
|
+
For each action: input method, rules governing resolution, possible
|
|
88
|
+
outcomes, feedback delivered to the player.
|
|
89
|
+
|
|
90
|
+
### 2.3 Win/Loss Conditions
|
|
91
|
+
How does the player succeed? How do they fail? Are there partial
|
|
92
|
+
success states?
|
|
93
|
+
|
|
94
|
+
## 3. Systems Design
|
|
95
|
+
### 3.1 Economy
|
|
96
|
+
Resources, currencies, sinks, faucets, exchange rates, inflation
|
|
97
|
+
controls.
|
|
98
|
+
|
|
99
|
+
### 3.2 Progression
|
|
100
|
+
Level structure, unlock trees, gating mechanics, difficulty curves.
|
|
101
|
+
|
|
102
|
+
### 3.3 Combat / Interaction
|
|
103
|
+
Damage model, stat interactions, ability system, AI behavior tiers.
|
|
104
|
+
|
|
105
|
+
### 3.4 Social Systems
|
|
106
|
+
Multiplayer modes, matchmaking rules, communication tools, anti-cheat.
|
|
107
|
+
|
|
108
|
+
## 4. Content
|
|
109
|
+
### 4.1 World / Setting
|
|
110
|
+
Lore, geography, factions, timeline.
|
|
111
|
+
|
|
112
|
+
### 4.2 Characters
|
|
113
|
+
Protagonist, antagonist, NPCs — motivations, arcs, gameplay roles.
|
|
114
|
+
|
|
115
|
+
### 4.3 Level / Mission Design
|
|
116
|
+
Level count, pacing chart, difficulty ramp, estimated play time.
|
|
117
|
+
|
|
118
|
+
### 4.4 Narrative Structure
|
|
119
|
+
Story beats, branching points, cutscene inventory.
|
|
120
|
+
|
|
121
|
+
## 5. Aesthetic Direction
|
|
122
|
+
### 5.1 Art Style
|
|
123
|
+
Reference images, color palette, proportions, silhouette rules.
|
|
124
|
+
|
|
125
|
+
### 5.2 Audio Direction
|
|
126
|
+
Music style, adaptive audio triggers, SFX priorities, voice acting scope.
|
|
127
|
+
|
|
128
|
+
### 5.3 UI/UX Philosophy
|
|
129
|
+
HUD philosophy (minimal vs. data-rich), menu flow, accessibility targets.
|
|
130
|
+
|
|
131
|
+
## 6. Technical Constraints
|
|
132
|
+
### 6.1 Target Platforms
|
|
133
|
+
Hardware, OS, minimum specs, performance budgets.
|
|
134
|
+
|
|
135
|
+
### 6.2 Engine & Middleware
|
|
136
|
+
Engine choice rationale, key middleware dependencies.
|
|
137
|
+
|
|
138
|
+
### 6.3 Networking Model
|
|
139
|
+
Client-server vs. P2P, tick rate, rollback vs. lockstep.
|
|
140
|
+
|
|
141
|
+
## 7. Scope & Milestones
|
|
142
|
+
### 7.1 Feature Priority Matrix
|
|
143
|
+
Must-have, should-have, nice-to-have for each milestone.
|
|
144
|
+
|
|
145
|
+
### 7.2 Content Budget
|
|
146
|
+
Asset counts by type, estimated production time per asset category.
|
|
147
|
+
|
|
148
|
+
### 7.3 Risk Register
|
|
149
|
+
Top 5 risks with likelihood, impact, and mitigation strategies.
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Writing Effective Mechanics Specifications
|
|
153
|
+
|
|
154
|
+
Each mechanic should be documented as a self-contained spec that any engineer can implement without ambiguity.
|
|
155
|
+
|
|
156
|
+
**Mechanic spec template:**
|
|
157
|
+
|
|
158
|
+
- **Name**: Clear, consistent label used across all documentation
|
|
159
|
+
- **Purpose**: Why this mechanic exists — which pillar does it serve?
|
|
160
|
+
- **Inputs**: Player actions that trigger this mechanic (button presses, gestures, selections)
|
|
161
|
+
- **Rules**: The exact processing logic
|
|
162
|
+
- Formulas with named variables (e.g., `damage = base_attack * weapon_multiplier - target_armor`)
|
|
163
|
+
- Edge cases explicitly called out (what happens at zero health? at max stack?)
|
|
164
|
+
- Randomness specified with distribution type and range (e.g., "uniform random between 0.8 and 1.2")
|
|
165
|
+
- **Outputs**: State changes that result (HP reduced, item added, flag set)
|
|
166
|
+
- **Feedback**: Exactly what the player sees, hears, and feels
|
|
167
|
+
- Visual: animation name, particle effect, UI indicator
|
|
168
|
+
- Audio: sound effect trigger, music state change
|
|
169
|
+
- Haptic: vibration pattern and duration (if applicable)
|
|
170
|
+
- Camera: shake intensity, zoom, slow-motion duration
|
|
171
|
+
- **Interactions**: How this mechanic combines with or is modified by other mechanics
|
|
172
|
+
- **Tuning Parameters**: Variables designers will tweak post-implementation, with initial values and expected ranges
|
|
173
|
+
|
|
174
|
+
### Core Loop Worksheet
|
|
175
|
+
|
|
176
|
+
When designing a core loop, work through these questions for each loop tier:
|
|
177
|
+
|
|
178
|
+
**Primary loop (moment-to-moment):**
|
|
179
|
+
- What is the single most frequent player action? Can you describe it in 3 words or fewer?
|
|
180
|
+
- Is the action itself satisfying with no rewards attached? (If not, the loop will feel like a grind.)
|
|
181
|
+
- What is the feedback latency? (Target: under 100ms for primary actions.)
|
|
182
|
+
- How many distinct outcomes can a single action produce? (Too few = boring, too many = confusing.)
|
|
183
|
+
|
|
184
|
+
**Secondary loop (session-level):**
|
|
185
|
+
- What goal does the player pursue across multiple primary loop cycles?
|
|
186
|
+
- How does the player measure progress toward this goal?
|
|
187
|
+
- What is the average session length this loop implies? Does that match the target platform? (Mobile: 3-5 min, PC: 30-60 min, console: 20-45 min)
|
|
188
|
+
- What decision does the player make between secondary loop cycles? (Build order, loadout, path choice)
|
|
189
|
+
|
|
190
|
+
**Tertiary loop (meta-progression):**
|
|
191
|
+
- What persists between sessions?
|
|
192
|
+
- What new options does the player unlock over time?
|
|
193
|
+
- Is there a reset/prestige mechanic? At what threshold?
|
|
194
|
+
- How do you prevent power creep from trivializing early content?
|
|
195
|
+
|
|
196
|
+
### Progression Design Patterns
|
|
197
|
+
|
|
198
|
+
**Linear progression pitfalls:**
|
|
199
|
+
- Difficulty spikes from untested level ordering — playtest the sequence, not just individual levels
|
|
200
|
+
- No reason to replay — add scoring systems, time trials, or collectibles
|
|
201
|
+
- Content bottleneck — each level is a unique asset, making this the most expensive progression type per hour of gameplay
|
|
202
|
+
|
|
203
|
+
**Branching progression pitfalls:**
|
|
204
|
+
- Combinatorial explosion — if 3 choices each have 3 outcomes, you have 27 end states by level 3
|
|
205
|
+
- Meaningful choice illusion — if branches reconverge immediately, players feel cheated
|
|
206
|
+
- QA coverage gaps — rare paths get less testing and more bugs
|
|
207
|
+
- Mitigation: use a "wide funnel" — many choices early, converging to fewer late-game states
|
|
208
|
+
|
|
209
|
+
**Open-world progression pitfalls:**
|
|
210
|
+
- Level scaling paradox — if everything scales to the player, progression feels meaningless
|
|
211
|
+
- Content gating — hard gates feel artificial, soft gates (enemies too strong) feel punishing
|
|
212
|
+
- Waypoint fatigue — too many markers overwhelm; too few leave players aimless
|
|
213
|
+
- Mitigation: use "interest curves" — alternate dense and sparse areas, vary encounter types
|
|
214
|
+
|
|
215
|
+
**Prestige progression pitfalls:**
|
|
216
|
+
- The first reset is the hardest sell — the initial run must be long enough to invest, short enough to not resent losing progress
|
|
217
|
+
- Permanent bonuses must feel worth the reset — "+2% damage" is not compelling; "unlock a new character class" is
|
|
218
|
+
- Late-game prestige runs become trivially fast — this is a feature, not a bug (it creates the power fantasy)
|
|
219
|
+
|
|
220
|
+
### GDD Anti-Patterns
|
|
221
|
+
|
|
222
|
+
**The Novel** — A 200-page document that nobody reads. GDDs should be reference documents, not prose. Use tables, bullet points, and diagrams. If a section exceeds 3 pages, split it into a sub-document.
|
|
223
|
+
|
|
224
|
+
**The Wishlist** — Every cool idea makes the cut. A GDD without a "Rejected Ideas" section has no discipline. Document what you chose not to do and why.
|
|
225
|
+
|
|
226
|
+
**The Fossil** — Written once, never updated. A GDD that diverges from the actual game is worse than no GDD — it actively misleads. Assign a GDD owner who updates it weekly.
|
|
227
|
+
|
|
228
|
+
**The Ambiguity** — "Combat should feel satisfying." What does that mean? Every adjective in the GDD must be operationalized: "satisfying" means "hit feedback plays within 50ms, enemies stagger on every hit, damage numbers appear with screen shake proportional to damage dealt."
|
|
229
|
+
|
|
230
|
+
**The Island** — A GDD disconnected from production reality. Include technical constraints, asset budgets, and milestone targets directly in the GDD so design decisions account for production capacity.
|
|
231
|
+
|
|
232
|
+
### Pillar Validation Checklist
|
|
233
|
+
|
|
234
|
+
Use this checklist at every design review to verify features align with declared pillars:
|
|
235
|
+
|
|
236
|
+
1. For each proposed feature, identify which pillar(s) it serves
|
|
237
|
+
2. If a feature serves zero pillars, it does not belong in this game — cut it or revise a pillar
|
|
238
|
+
3. If two features conflict, the one aligned with more pillars wins
|
|
239
|
+
4. If a feature actively contradicts a pillar, it must be reworked or removed
|
|
240
|
+
5. Track pillar coverage: if one pillar has no features serving it, either the pillar is wrong or the feature set is incomplete
|
|
241
|
+
6. During playtesting, ask players to describe their experience — map their words to your pillars; misalignment means the implementation is not delivering on the pillar's promise
|
|
242
|
+
|
|
243
|
+
### Scoping the GDD by Project Size
|
|
244
|
+
|
|
245
|
+
**Game jam (48-72 hours):**
|
|
246
|
+
- Vision + Core Loop only. One page maximum.
|
|
247
|
+
- No progression system — the game is one session long.
|
|
248
|
+
- Pillars: 1-2 at most.
|
|
249
|
+
|
|
250
|
+
**Indie (3-18 months, 1-10 people):**
|
|
251
|
+
- Full GDD but concise. Target 10-20 pages.
|
|
252
|
+
- Focus on core loop and one progression system.
|
|
253
|
+
- Aesthetic direction can be a mood board, not a style guide.
|
|
254
|
+
- Technical constraints section is critical — small teams cannot afford bad tech choices.
|
|
255
|
+
|
|
256
|
+
**AA/AAA (1-5 years, 20-500+ people):**
|
|
257
|
+
- Full GDD becomes a living wiki, not a single document.
|
|
258
|
+
- Each system gets its own detailed design document (combat design doc, economy design doc, etc.).
|
|
259
|
+
- GDD serves as the index and the source of pillars, loops, and high-level vision.
|
|
260
|
+
- Requires a dedicated design owner per major system and a design director maintaining coherence.
|