@jarrodmedrano/claude-skills 1.0.2 → 1.0.3
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/skills/game-design-theory/SKILL.md +102 -0
- package/.claude/skills/game-design-theory/design-principles.md +308 -0
- package/.claude/skills/game-design-theory/gameplay-elements.md +213 -0
- package/.claude/skills/game-design-theory/player-psychology.md +175 -0
- package/.claude/skills/game-design-theory/playtesting.md +321 -0
- package/.claude/skills/game-design-theory/storytelling.md +219 -0
- package/.claude/skills/game-feel/SKILL.md +305 -0
- package/.claude/skills/game-feel/references/adsr-tuning.md +271 -0
- package/.claude/skills/game-feel/references/classic-profiles.md +279 -0
- package/.claude/skills/game-feel/references/perception-thresholds.md +160 -0
- package/.claude/skills/game-feel/references/polish-effects.md +246 -0
- package/.claude/skills/game-feel/references/simulation-recipes.md +306 -0
- package/.claude/skills/game-feel/references/six-metrics.md +239 -0
- package/.claude/skills/level-design/SKILL.md +249 -0
- package/.claude/skills/level-design/anticipatory-play.md +223 -0
- package/.claude/skills/level-design/hiding-linearity.md +181 -0
- package/.claude/skills/level-design/indie-practices.md +286 -0
- package/.claude/skills/level-design/open-world-planning.md +294 -0
- package/.claude/skills/level-design/play-personas.md +240 -0
- package/.claude/skills/level-design/procedural-handmade.md +271 -0
- package/.claude/skills/level-design/themed-environments.md +264 -0
- package/package.json +3 -1
- package/scripts/install.js +16 -1
- package/templates/github-actions/README.md +36 -0
- /package/.claude/{commands/design-review → agents}/design-review-agent.md +0 -0
- /package/.claude/{commands/code-review → agents}/pragmatic-code-review-subagent.md +0 -0
- /package/{.claude/commands/code-review → templates/github-actions}/claude-code-review-custom.yml +0 -0
- /package/{.claude/commands/code-review → templates/github-actions}/claude-code-review.yml +0 -0
- /package/{.claude/commands/security-review → templates/github-actions}/security.yml +0 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# ADSR Tuning for Game Feel
|
|
2
|
+
|
|
3
|
+
The ADSR envelope, borrowed from audio synthesis, provides a powerful framework for understanding and tuning game response curves.
|
|
4
|
+
|
|
5
|
+
## The ADSR Model
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Level
|
|
9
|
+
^
|
|
10
|
+
| Decay
|
|
11
|
+
| /‾‾‾‾\
|
|
12
|
+
| / \___________Sustain___________
|
|
13
|
+
| /Attack \
|
|
14
|
+
| / \Release
|
|
15
|
+
|/ \
|
|
16
|
+
+---------------------------------------------> Time
|
|
17
|
+
Input Starts Input Ends
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
| Phase | Definition | Game Example |
|
|
21
|
+
|-------|------------|--------------|
|
|
22
|
+
| **Attack** | Time from input start to peak response | Acceleration from standstill |
|
|
23
|
+
| **Decay** | Time from peak to sustained level | Initial burst settling |
|
|
24
|
+
| **Sustain** | Level maintained while input held | Running at max speed |
|
|
25
|
+
| **Release** | Time from input end to neutral | Deceleration to stop |
|
|
26
|
+
|
|
27
|
+
## Why ADSR Matters for Feel
|
|
28
|
+
|
|
29
|
+
Most "feel" descriptions map directly to ADSR characteristics:
|
|
30
|
+
|
|
31
|
+
| Feel Term | Primary ADSR Factor |
|
|
32
|
+
|-----------|---------------------|
|
|
33
|
+
| Tight | Short Attack + Short Release |
|
|
34
|
+
| Floaty | Long Attack + Long Release |
|
|
35
|
+
| Responsive | Short Attack |
|
|
36
|
+
| Sluggish | Long Attack |
|
|
37
|
+
| Slippery | Long Release |
|
|
38
|
+
| Snappy | Short Attack + Short Release |
|
|
39
|
+
| Weighty | Medium Attack + Medium Release |
|
|
40
|
+
|
|
41
|
+
## Measuring ADSR in Games
|
|
42
|
+
|
|
43
|
+
### Attack Time
|
|
44
|
+
1. Start from neutral (stationary)
|
|
45
|
+
2. Press input
|
|
46
|
+
3. Measure time until maximum response reached
|
|
47
|
+
|
|
48
|
+
**Mario walk attack**: ~0.2 seconds
|
|
49
|
+
**Asteroids thrust attack**: ~0.3 seconds
|
|
50
|
+
**Donkey Kong walk attack**: ~0.03 seconds (nearly instant)
|
|
51
|
+
|
|
52
|
+
### Release Time
|
|
53
|
+
1. From sustained state (full speed)
|
|
54
|
+
2. Release input
|
|
55
|
+
3. Measure time until neutral (stopped)
|
|
56
|
+
|
|
57
|
+
**Mario release**: ~0.3 seconds
|
|
58
|
+
**Asteroids release**: ~4+ seconds
|
|
59
|
+
**Donkey Kong release**: ~0.03 seconds (nearly instant)
|
|
60
|
+
|
|
61
|
+
### Sustain Level
|
|
62
|
+
The maintained response value during continuous input.
|
|
63
|
+
|
|
64
|
+
**Mario walk sustain**: Walk max speed
|
|
65
|
+
**Mario run sustain**: Run max speed (higher)
|
|
66
|
+
**Asteroids sustain**: Max velocity (capped)
|
|
67
|
+
|
|
68
|
+
## Tuning Guidelines
|
|
69
|
+
|
|
70
|
+
### For Platformers (Mario-like)
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
Attack: 0.1 - 0.3 seconds
|
|
74
|
+
Decay: Minimal (go straight to sustain)
|
|
75
|
+
Sustain: Max speed (walk or run)
|
|
76
|
+
Release: 0.2 - 0.4 seconds
|
|
77
|
+
|
|
78
|
+
Jump Attack: Instant (frame 1 response)
|
|
79
|
+
Jump Release: Variable based on button hold
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### For Space Games (Asteroids-like)
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
Attack: 0.2 - 0.5 seconds
|
|
86
|
+
Decay: Minimal
|
|
87
|
+
Sustain: Max thrust speed
|
|
88
|
+
Release: 2 - 5+ seconds (low friction)
|
|
89
|
+
|
|
90
|
+
Rotation Attack: Very short (0.05-0.1s)
|
|
91
|
+
Rotation Release: Instant (no inertia)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### For Racing Games
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Acceleration Attack: 1-3 seconds (car builds speed)
|
|
98
|
+
Acceleration Sustain: Top speed
|
|
99
|
+
Braking Release: 0.5-1 second
|
|
100
|
+
|
|
101
|
+
Steering Attack: 0.1-0.2 seconds (turn-in)
|
|
102
|
+
Steering Release: 0.1-0.2 seconds (self-centering)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### For Fighting Games
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
Normal Attack: 2-5 frames attack (~0.03-0.08s)
|
|
109
|
+
Heavy Attack: 8-15 frames attack (~0.13-0.25s)
|
|
110
|
+
Recovery (Release): 5-20 frames depending on move
|
|
111
|
+
|
|
112
|
+
Movement Attack: Very short (instant response)
|
|
113
|
+
Movement Release: Very short (precise positioning)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Attack Curves
|
|
117
|
+
|
|
118
|
+
Not all attacks are linear. Common curve shapes:
|
|
119
|
+
|
|
120
|
+
### Linear
|
|
121
|
+
```
|
|
122
|
+
Response
|
|
123
|
+
| /
|
|
124
|
+
| /
|
|
125
|
+
| /
|
|
126
|
+
| /
|
|
127
|
+
|/_____ Time
|
|
128
|
+
```
|
|
129
|
+
Steady increase. Feels mechanical.
|
|
130
|
+
|
|
131
|
+
### Ease-In (Slow Start)
|
|
132
|
+
```
|
|
133
|
+
Response
|
|
134
|
+
| _/
|
|
135
|
+
| _/
|
|
136
|
+
| _/
|
|
137
|
+
| /
|
|
138
|
+
|/_____ Time
|
|
139
|
+
```
|
|
140
|
+
Sluggish start, fast finish. Feels heavy.
|
|
141
|
+
|
|
142
|
+
### Ease-Out (Fast Start)
|
|
143
|
+
```
|
|
144
|
+
Response
|
|
145
|
+
| /‾‾‾
|
|
146
|
+
| /
|
|
147
|
+
|/
|
|
148
|
+
|/
|
|
149
|
+
|/_____ Time
|
|
150
|
+
```
|
|
151
|
+
Quick start, gradual finish. Feels responsive.
|
|
152
|
+
|
|
153
|
+
### Ease-In-Out
|
|
154
|
+
```
|
|
155
|
+
Response
|
|
156
|
+
| _--‾
|
|
157
|
+
| _/
|
|
158
|
+
| /
|
|
159
|
+
|/
|
|
160
|
+
|/_____ Time
|
|
161
|
+
```
|
|
162
|
+
Smooth acceleration. Feels natural.
|
|
163
|
+
|
|
164
|
+
## Release Curves
|
|
165
|
+
|
|
166
|
+
### Linear Deceleration
|
|
167
|
+
Constant friction. Feels artificial but predictable.
|
|
168
|
+
|
|
169
|
+
### Exponential Decay
|
|
170
|
+
Fast initial slowdown, gradual final approach to zero.
|
|
171
|
+
Feels more natural, like real friction.
|
|
172
|
+
|
|
173
|
+
### Instant Stop
|
|
174
|
+
No release phase. Feels robotic, but precise.
|
|
175
|
+
|
|
176
|
+
## The Mario Jump ADSR
|
|
177
|
+
|
|
178
|
+
The Mario jump is a special case with modified ADSR:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
Variable Attack (button held)
|
|
182
|
+
|
|
|
183
|
+
v
|
|
184
|
+
Force ____/‾‾‾\
|
|
185
|
+
| \
|
|
186
|
+
| \_ Apex
|
|
187
|
+
| \
|
|
188
|
+
| \ Accelerated Release (3× gravity)
|
|
189
|
+
| \
|
|
190
|
+
____+__________\____
|
|
191
|
+
^ ^
|
|
192
|
+
Button Button
|
|
193
|
+
Pressed Released
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Key Features:
|
|
197
|
+
1. **Attack is instant** (large force applied frame 1)
|
|
198
|
+
2. **Attack extends** while button held (up to max time)
|
|
199
|
+
3. **Early release** artificially caps upward velocity
|
|
200
|
+
4. **Release accelerates** (fall gravity > rise gravity)
|
|
201
|
+
|
|
202
|
+
## Practical Tuning Process
|
|
203
|
+
|
|
204
|
+
### Step 1: Identify Desired Feel
|
|
205
|
+
"I want movement to feel tight but not robotic"
|
|
206
|
+
|
|
207
|
+
### Step 2: Set Target ADSR Values
|
|
208
|
+
- Attack: 0.1s (responsive)
|
|
209
|
+
- Release: 0.15s (not instant, slight slide)
|
|
210
|
+
- Sustain: Based on desired max speed
|
|
211
|
+
|
|
212
|
+
### Step 3: Implement and Test
|
|
213
|
+
Build the basic response, measure actual values
|
|
214
|
+
|
|
215
|
+
### Step 4: Iterate
|
|
216
|
+
- Too floaty? Shorten attack and release
|
|
217
|
+
- Too stiff? Lengthen attack and release
|
|
218
|
+
- Too slippery? Shorten release specifically
|
|
219
|
+
- Too sticky? Shorten attack specifically
|
|
220
|
+
|
|
221
|
+
### Step 5: Test Edge Cases
|
|
222
|
+
- Direction reversal
|
|
223
|
+
- Stop from max speed
|
|
224
|
+
- Start from standstill
|
|
225
|
+
- Interrupting actions
|
|
226
|
+
|
|
227
|
+
## Common ADSR Mistakes
|
|
228
|
+
|
|
229
|
+
### All Values Same
|
|
230
|
+
Everything feels samey. Vary ADSR between actions.
|
|
231
|
+
|
|
232
|
+
### No Attack Phase
|
|
233
|
+
Movement feels robotic, digital, unnatural.
|
|
234
|
+
|
|
235
|
+
### No Release Phase
|
|
236
|
+
Stopping feels abrupt, jarring.
|
|
237
|
+
|
|
238
|
+
### Too Long Attack
|
|
239
|
+
Players feel input is being ignored.
|
|
240
|
+
|
|
241
|
+
### Too Long Release
|
|
242
|
+
Players feel out of control.
|
|
243
|
+
|
|
244
|
+
### Inconsistent Curves
|
|
245
|
+
Different actions feel like different games.
|
|
246
|
+
|
|
247
|
+
## ADSR for Different Actions
|
|
248
|
+
|
|
249
|
+
| Action | Attack | Release | Notes |
|
|
250
|
+
|--------|--------|---------|-------|
|
|
251
|
+
| Walk | 0.1-0.2s | 0.2-0.3s | Moderate both |
|
|
252
|
+
| Run | 0.2-0.4s | 0.3-0.5s | Longer for weight |
|
|
253
|
+
| Jump | Instant | Gravity-driven | Special handling |
|
|
254
|
+
| Turn | 0.05-0.1s | 0.05-0.1s | Needs precision |
|
|
255
|
+
| Shoot | 0-0.03s | 0-0.03s | Near instant |
|
|
256
|
+
| Charge | 0.5-3s | Variable | Long attack is the point |
|
|
257
|
+
| Drift | N/A | 1-3s | Release IS the mechanic |
|
|
258
|
+
|
|
259
|
+
## Testing Tools
|
|
260
|
+
|
|
261
|
+
### Frame-by-Frame Analysis
|
|
262
|
+
Record gameplay at 60fps, step through frames
|
|
263
|
+
Count frames from input to response
|
|
264
|
+
|
|
265
|
+
### Value Visualization
|
|
266
|
+
Graph position/velocity over time
|
|
267
|
+
Look for smooth curves vs jagged transitions
|
|
268
|
+
|
|
269
|
+
### Comparison Recording
|
|
270
|
+
Record same action in reference game
|
|
271
|
+
Match curves to match feel
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# Classic Game Feel Profiles
|
|
2
|
+
|
|
3
|
+
Detailed breakdowns of iconic game feel implementations for reference and study.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Asteroids (1979)
|
|
8
|
+
|
|
9
|
+
**Feel Summary**: Floaty, on-the-edge-of-control, expressive space simulation
|
|
10
|
+
|
|
11
|
+
### Why It Worked
|
|
12
|
+
Asteroids redefined what games could feel like. By separating thrust from rotation, it created a sensation of piloting a craft that was always *almost* out of control—but never actually was.
|
|
13
|
+
|
|
14
|
+
### Input
|
|
15
|
+
- 5 two-state buttons (Rotate L/R, Thrust, Fire, Hyperspace)
|
|
16
|
+
- Two-handed operation required
|
|
17
|
+
- No chorded moves
|
|
18
|
+
- Big, springy, satisfying buttons
|
|
19
|
+
|
|
20
|
+
### Core Mechanic: Separated Thrust/Rotation
|
|
21
|
+
|
|
22
|
+
**Rotation**: Direct, instant
|
|
23
|
+
```
|
|
24
|
+
if (rotateLeft) shipAngle -= rotateSpeed
|
|
25
|
+
if (rotateRight) shipAngle += rotateSpeed
|
|
26
|
+
```
|
|
27
|
+
- Very slight attack (~0.1s ramp)
|
|
28
|
+
- No simulation, no inertia
|
|
29
|
+
- Crisp, precise
|
|
30
|
+
|
|
31
|
+
**Thrust**: Simulated, accumulative
|
|
32
|
+
```
|
|
33
|
+
thrustVector = directionFromAngle(shipAngle) × thrustSpeed
|
|
34
|
+
shipVelocity = shipVelocity + thrustVector // ADD, not overwrite!
|
|
35
|
+
```
|
|
36
|
+
- Floaty 3+ second attack to max speed
|
|
37
|
+
- 4+ second release (very low dampening ~0.99)
|
|
38
|
+
- Creates "spacey" frictionless feel
|
|
39
|
+
|
|
40
|
+
### Critical Insight
|
|
41
|
+
The thrust vector is **added** to ship velocity, not overwriting it. This decouples where you're facing from where you're going—the fundamental Asteroids feel.
|
|
42
|
+
|
|
43
|
+
### Context
|
|
44
|
+
- Screen wrap containment (no escape)
|
|
45
|
+
- Asteroid density provides constant danger
|
|
46
|
+
- Ship moves faster than asteroids but less predictably
|
|
47
|
+
- "Like being an experienced ice skater at a crowded public rink"
|
|
48
|
+
|
|
49
|
+
### Polish
|
|
50
|
+
- Size-pitch correlation: Large asteroid = deep boom, small = high ping
|
|
51
|
+
- Ship disintegrates into component lines on death
|
|
52
|
+
- Thruster visual: flickering vector line
|
|
53
|
+
- Cohesive despite limited hardware
|
|
54
|
+
|
|
55
|
+
### Rules
|
|
56
|
+
- One-hit death (ship feels fragile)
|
|
57
|
+
- Points scale with difficulty (small asteroid = 100, large = 20)
|
|
58
|
+
- Flying saucers: High risk/reward (1000 points for small)
|
|
59
|
+
- Extra life at 10,000 points
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Super Mario Bros (1985)
|
|
64
|
+
|
|
65
|
+
**Feel Summary**: Fluid, expressive, intuitive—the gold standard for platformers
|
|
66
|
+
|
|
67
|
+
### Why It Worked
|
|
68
|
+
Miyamoto understood feel as artistic experience, not simulation accuracy. The result: controls that feel natural despite being highly artificial.
|
|
69
|
+
|
|
70
|
+
### Input
|
|
71
|
+
- NES Controller: D-pad + A (jump) + B (run)
|
|
72
|
+
- Simple Boolean signals
|
|
73
|
+
- B modifies movement parameters, not separate action
|
|
74
|
+
|
|
75
|
+
### Horizontal Movement
|
|
76
|
+
|
|
77
|
+
**Walk**:
|
|
78
|
+
- Acceleration: Moderate
|
|
79
|
+
- Max speed: Capped
|
|
80
|
+
- Deceleration: Moderate slide to stop
|
|
81
|
+
|
|
82
|
+
**Run (B held)**:
|
|
83
|
+
- Acceleration: Higher
|
|
84
|
+
- Max speed: Higher cap
|
|
85
|
+
- Deceleration: Same as walk
|
|
86
|
+
|
|
87
|
+
**Air**:
|
|
88
|
+
- Acceleration: Reduced
|
|
89
|
+
- Same max speed limits apply
|
|
90
|
+
|
|
91
|
+
### Vertical Movement (The Jump)
|
|
92
|
+
|
|
93
|
+
**The Recipe**:
|
|
94
|
+
1. Button press → Instant large upward force
|
|
95
|
+
2. While held → Force continues (up to max time)
|
|
96
|
+
3. Early release → Velocity artificially set to low preset value
|
|
97
|
+
4. Apex detected → Gravity TRIPLES for descent
|
|
98
|
+
5. Terminal velocity caps fall speed
|
|
99
|
+
|
|
100
|
+
**The Critical Hack**:
|
|
101
|
+
When player releases jump early:
|
|
102
|
+
```
|
|
103
|
+
if (velocity.y > reducedJumpVelocity) {
|
|
104
|
+
velocity.y = reducedJumpVelocity // Artificial cap
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
This creates consistent arc shapes regardless of release timing.
|
|
108
|
+
|
|
109
|
+
**Running Jump Boost**:
|
|
110
|
+
If speed > walk max when jumping, slight extra jump force.
|
|
111
|
+
|
|
112
|
+
### Key Parameters
|
|
113
|
+
| Parameter | Approximate Value |
|
|
114
|
+
|-----------|------------------|
|
|
115
|
+
| Walk acceleration | Moderate |
|
|
116
|
+
| Walk max speed | ~3 units/frame |
|
|
117
|
+
| Run acceleration | Higher |
|
|
118
|
+
| Run max speed | ~5 units/frame |
|
|
119
|
+
| Air acceleration | ~30% of ground |
|
|
120
|
+
| Jump force | Large instant burst |
|
|
121
|
+
| Gravity | Moderate |
|
|
122
|
+
| Fall gravity | 3× normal gravity |
|
|
123
|
+
| Max jump time | ~0.4 seconds |
|
|
124
|
+
|
|
125
|
+
### Context
|
|
126
|
+
- Blocks at exact jump heights
|
|
127
|
+
- Gaps at exact run-jump distances
|
|
128
|
+
- Enemies as timing challenges
|
|
129
|
+
- Pipes and hidden areas reward exploration
|
|
130
|
+
|
|
131
|
+
### Polish
|
|
132
|
+
- Slide whistle jump sound (rising pitch)
|
|
133
|
+
- Dust on direction change
|
|
134
|
+
- Squash on landing
|
|
135
|
+
- Simple but coherent
|
|
136
|
+
|
|
137
|
+
### Rules
|
|
138
|
+
- Size changes with powerups (feel different)
|
|
139
|
+
- One-hit death (small) or shrink (big)
|
|
140
|
+
- Coins everywhere (constant small rewards)
|
|
141
|
+
- Time pressure (never truly relaxed)
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Super Mario 64 (1996)
|
|
146
|
+
|
|
147
|
+
**Feel Summary**: Expressive 3D translation with precision special moves
|
|
148
|
+
|
|
149
|
+
### Why It Worked
|
|
150
|
+
Successfully translated 2D Mario feel to 3D through camera-relative controls, multiple jump types, and incline-based physics.
|
|
151
|
+
|
|
152
|
+
### Input
|
|
153
|
+
- N64 controller: Analog stick + A (jump) + B (attack) + Z (crouch)
|
|
154
|
+
- Stick provides continuous direction AND speed
|
|
155
|
+
- Camera controls on C-buttons
|
|
156
|
+
|
|
157
|
+
### Movement System
|
|
158
|
+
|
|
159
|
+
**Thumbstick → World Direction**:
|
|
160
|
+
```
|
|
161
|
+
worldDirection = cameraForward × stick.y + cameraRight × stick.x
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Turn Interpolation**:
|
|
165
|
+
```
|
|
166
|
+
if (speed > 0) {
|
|
167
|
+
currentDirection = lerp(currentDirection, desiredDirection, turnSpeed)
|
|
168
|
+
} else {
|
|
169
|
+
currentDirection = desiredDirection // Instant at standstill
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
Creates carving motion when moving, instant turns when stopped.
|
|
173
|
+
|
|
174
|
+
**Incline Physics**:
|
|
175
|
+
- Steep slopes (>45°) resist climbing
|
|
176
|
+
- Very steep slopes (~75°) trigger slide state
|
|
177
|
+
- Creates soft boundaries without invisible walls
|
|
178
|
+
|
|
179
|
+
### Jump Types
|
|
180
|
+
|
|
181
|
+
| Jump | Trigger | Height | Control |
|
|
182
|
+
|------|---------|--------|---------|
|
|
183
|
+
| Basic | A | Variable (hold) | Full air steering |
|
|
184
|
+
| Continuous | A after landing | Higher, variable | Full air steering |
|
|
185
|
+
| Triple | A after Continuous + speed | Highest, fixed | Air steering |
|
|
186
|
+
| Long | Z+A moving | Low, far, fixed | Air steering |
|
|
187
|
+
| Back Somersault | A while crouching | Very high, fixed | Air steering |
|
|
188
|
+
| Side Somersault | A during direction change | High, fixed | Air steering |
|
|
189
|
+
| Wall Kick | A near wall + away | Fixed | Limited steering |
|
|
190
|
+
|
|
191
|
+
**Variable vs Fixed**:
|
|
192
|
+
- Variable jumps: Expressive, moment-to-moment control
|
|
193
|
+
- Fixed jumps: Predictable, precision platforming
|
|
194
|
+
|
|
195
|
+
### Ground Pound
|
|
196
|
+
```
|
|
197
|
+
if (inAir && Z) {
|
|
198
|
+
velocity.x = 0; velocity.z = 0 // Kill horizontal momentum
|
|
199
|
+
wait(0.1)
|
|
200
|
+
velocity.y = -groundPoundSpeed
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
Provides precision landing by removing horizontal momentum.
|
|
204
|
+
|
|
205
|
+
### Context
|
|
206
|
+
- Levels designed around jump trajectories
|
|
207
|
+
- Landmarks visible from anywhere (aids navigation)
|
|
208
|
+
- Inclines create soft boundaries
|
|
209
|
+
- Open spaces for running, tight spaces for precision
|
|
210
|
+
|
|
211
|
+
### Polish
|
|
212
|
+
- Three-tier impact system (light/medium/heavy)
|
|
213
|
+
- Surface-specific footsteps
|
|
214
|
+
- Mario's vocalizations sync with motion
|
|
215
|
+
- Exaggerated limb scaling on attacks
|
|
216
|
+
|
|
217
|
+
### Control Ambiguity (Flaw)
|
|
218
|
+
Z+A can produce ground pound, backflip, or long jump depending on subtle timing differences. This is acknowledged as a design flaw.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Comparative Analysis
|
|
223
|
+
|
|
224
|
+
### Response Time
|
|
225
|
+
| Game | Attack | Release |
|
|
226
|
+
|------|--------|---------|
|
|
227
|
+
| Asteroids rotation | ~0.1s | Instant |
|
|
228
|
+
| Asteroids thrust | ~3s | ~4s |
|
|
229
|
+
| Mario Bros walk | ~0.2s | ~0.3s |
|
|
230
|
+
| Mario Bros run | ~0.3s | ~0.3s |
|
|
231
|
+
| Mario 64 run | ~0.15s | ~0.1s |
|
|
232
|
+
|
|
233
|
+
### Expressivity
|
|
234
|
+
| Game | Movement States | Jump Variety |
|
|
235
|
+
|------|-----------------|--------------|
|
|
236
|
+
| Asteroids | Continuous velocity | N/A |
|
|
237
|
+
| Mario Bros | Walk/Run | Variable height |
|
|
238
|
+
| Mario 64 | Walk/Run/Slide/Crawl | 7+ jump types |
|
|
239
|
+
|
|
240
|
+
### What They Share
|
|
241
|
+
1. **Separated systems**: Thrust/rotation, horizontal/vertical
|
|
242
|
+
2. **Artificial interventions**: Hacks that feel natural
|
|
243
|
+
3. **Context-mechanic fit**: Levels designed for the controls
|
|
244
|
+
4. **Coherent polish**: Effects reinforce physics
|
|
245
|
+
5. **Responsive input**: <100ms response times
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Modern Applications
|
|
250
|
+
|
|
251
|
+
### When to Use Asteroids-Style Feel
|
|
252
|
+
- Space games
|
|
253
|
+
- Physics toys
|
|
254
|
+
- "Barely in control" experiences
|
|
255
|
+
- Games about mastering momentum
|
|
256
|
+
|
|
257
|
+
### When to Use Mario-Style Feel
|
|
258
|
+
- Platformers
|
|
259
|
+
- Action games
|
|
260
|
+
- Games requiring precise positioning
|
|
261
|
+
- Accessible but deep controls
|
|
262
|
+
|
|
263
|
+
### When to Use Mario 64-Style Feel
|
|
264
|
+
- 3D platformers
|
|
265
|
+
- Exploration games
|
|
266
|
+
- Games with diverse movement options
|
|
267
|
+
- Precision 3D navigation
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Study Recommendations
|
|
272
|
+
|
|
273
|
+
To deeply understand these profiles:
|
|
274
|
+
|
|
275
|
+
1. **Play** the original games extensively
|
|
276
|
+
2. **Analyze** by recording and frame-stepping
|
|
277
|
+
3. **Recreate** the feel in a simple prototype
|
|
278
|
+
4. **Modify** parameters to understand their impact
|
|
279
|
+
5. **Compare** to modern games in the same genre
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Perception Thresholds for Game Feel
|
|
2
|
+
|
|
3
|
+
Understanding human perception limits is essential for creating responsive controls.
|
|
4
|
+
|
|
5
|
+
## The Model Human Processor
|
|
6
|
+
|
|
7
|
+
Card, Moran, and Newell's research established three processors working in sequence:
|
|
8
|
+
|
|
9
|
+
### Processor Cycle Times
|
|
10
|
+
|
|
11
|
+
| Processor | Average | Range | Function |
|
|
12
|
+
|-----------|---------|-------|----------|
|
|
13
|
+
| **Perceptual** | ~100ms | 50-200ms | Takes sensory input, finds patterns |
|
|
14
|
+
| **Cognitive** | ~70ms | 30-100ms | Compares state to intent, decides action |
|
|
15
|
+
| **Motor** | ~70ms | 25-170ms | Translates decision to muscle movement |
|
|
16
|
+
|
|
17
|
+
**Total correction cycle: ~240ms**
|
|
18
|
+
|
|
19
|
+
This is the minimum time for a human to:
|
|
20
|
+
1. See the current state
|
|
21
|
+
2. Think about what to do
|
|
22
|
+
3. Act on that decision
|
|
23
|
+
|
|
24
|
+
## The Correction Cycle in Games
|
|
25
|
+
|
|
26
|
+
When controlling a game, players run continuous correction cycles:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Intent (grab coin)
|
|
30
|
+
→ Perceive (see Mario's position)
|
|
31
|
+
→ Think (too far right)
|
|
32
|
+
→ Act (press left)
|
|
33
|
+
→ Perceive (see Mario move)
|
|
34
|
+
→ Think (almost there)
|
|
35
|
+
→ Act (release, press jump)
|
|
36
|
+
→ ...repeat at ~240ms intervals
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This is identical to reaching for a muffin on your desk—constant micro-adjustments until the goal is achieved.
|
|
40
|
+
|
|
41
|
+
## Critical Thresholds for Game Response
|
|
42
|
+
|
|
43
|
+
### Frame Rate (Impression of Motion)
|
|
44
|
+
|
|
45
|
+
| FPS | Milliseconds | Perception |
|
|
46
|
+
|-----|--------------|------------|
|
|
47
|
+
| 10 | 100ms | Minimum for motion illusion |
|
|
48
|
+
| 20 | 50ms | Acceptable motion |
|
|
49
|
+
| 30 | 33ms | Smooth motion |
|
|
50
|
+
| 60 | 16ms | Very smooth |
|
|
51
|
+
| 120+ | <8ms | Diminishing returns for most |
|
|
52
|
+
|
|
53
|
+
**Why it matters**: Below 10fps, the brain sees discrete images, not motion. The illusion breaks.
|
|
54
|
+
|
|
55
|
+
### Response Time (Input to Visual Feedback)
|
|
56
|
+
|
|
57
|
+
| Response | Feel | Notes |
|
|
58
|
+
|----------|------|-------|
|
|
59
|
+
| <50ms | Instantaneous | "Extension of your body" |
|
|
60
|
+
| 50-100ms | Tight, responsive | Ideal for action games |
|
|
61
|
+
| 100-150ms | Noticeable but acceptable | Strategy games tolerate this |
|
|
62
|
+
| 150-200ms | Sluggish | Players complain |
|
|
63
|
+
| >240ms | Broken | Exceeds correction cycle |
|
|
64
|
+
|
|
65
|
+
**The 50ms rule**: At 50ms or less, cause and effect feel simultaneous due to perceptual fusion.
|
|
66
|
+
|
|
67
|
+
### Continuity (Consistent Response Rate)
|
|
68
|
+
|
|
69
|
+
The game must accept input and provide feedback at **consistent 100ms intervals or less**.
|
|
70
|
+
|
|
71
|
+
Sporadic response is worse than slow response:
|
|
72
|
+
- Consistent 80ms = acceptable
|
|
73
|
+
- Varying 40-200ms = feels broken
|
|
74
|
+
|
|
75
|
+
## Perceptual Fusion
|
|
76
|
+
|
|
77
|
+
When two events occur within the same perceptual cycle (~100ms), they appear fused:
|
|
78
|
+
|
|
79
|
+
- Mario in position A, then position B within 100ms = perceived as motion
|
|
80
|
+
- Button press and character response within 100ms = perceived as cause-and-effect
|
|
81
|
+
|
|
82
|
+
**This is how games create the illusion of direct control.**
|
|
83
|
+
|
|
84
|
+
## Fitt's Law Application
|
|
85
|
+
|
|
86
|
+
The time to reach a target depends on distance and target size:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
MT = a + b × log₂(2D/W)
|
|
90
|
+
|
|
91
|
+
MT = movement time
|
|
92
|
+
a = start/stop time
|
|
93
|
+
b = device speed
|
|
94
|
+
D = distance to target
|
|
95
|
+
W = target width
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Game design implications**:
|
|
99
|
+
- Larger targets = faster to hit
|
|
100
|
+
- Closer targets = faster to hit
|
|
101
|
+
- Menu items at screen edges = effectively infinite width
|
|
102
|
+
- Tiny checkboxes = frustrating
|
|
103
|
+
|
|
104
|
+
## Factors That Affect Perception Speed
|
|
105
|
+
|
|
106
|
+
### Faster Processing
|
|
107
|
+
- High alertness/stress
|
|
108
|
+
- Familiar tasks
|
|
109
|
+
- Clear visual feedback
|
|
110
|
+
- Predictable patterns
|
|
111
|
+
|
|
112
|
+
### Slower Processing
|
|
113
|
+
- Fatigue
|
|
114
|
+
- Distraction
|
|
115
|
+
- Poor visibility
|
|
116
|
+
- Novel situations
|
|
117
|
+
|
|
118
|
+
## Measuring Your Own Response Time
|
|
119
|
+
|
|
120
|
+
Test at humanbenchmark.com/tests/reactiontime
|
|
121
|
+
|
|
122
|
+
Typical results:
|
|
123
|
+
- Average person: 200-250ms
|
|
124
|
+
- Trained gamer: 150-180ms
|
|
125
|
+
- Theoretical minimum: ~150ms
|
|
126
|
+
|
|
127
|
+
This represents perception + cognition + motor response combined.
|
|
128
|
+
|
|
129
|
+
## Practical Guidelines
|
|
130
|
+
|
|
131
|
+
### For Responsive Feel
|
|
132
|
+
1. Target <100ms input-to-display
|
|
133
|
+
2. Maintain consistent frame rate (30+ fps)
|
|
134
|
+
3. Never exceed 240ms response time
|
|
135
|
+
4. Use animation to mask unavoidable delays
|
|
136
|
+
|
|
137
|
+
### Acceptable Delay Contexts
|
|
138
|
+
Delays can be acceptable when:
|
|
139
|
+
- Player chose to trigger a long animation
|
|
140
|
+
- Metaphor supports it (heavy character)
|
|
141
|
+
- Risk/reward tradeoff is clear
|
|
142
|
+
- Delay is consistent and predictable
|
|
143
|
+
|
|
144
|
+
### Breaking Feel Intentionally
|
|
145
|
+
Sometimes you want temporary loss of control:
|
|
146
|
+
- Recovery frames after attacks (fighting games)
|
|
147
|
+
- Stumble animations after hits
|
|
148
|
+
- Charge-up mechanics
|
|
149
|
+
|
|
150
|
+
**Key**: Player must have chosen to enter the vulnerable state.
|
|
151
|
+
|
|
152
|
+
## The Computer's Responsibility
|
|
153
|
+
|
|
154
|
+
Real-time control requires the computer to maintain:
|
|
155
|
+
|
|
156
|
+
1. **Motion threshold**: Display updates at 10+ fps (ideally 30+)
|
|
157
|
+
2. **Response threshold**: Input-to-display in <240ms (ideally <100ms)
|
|
158
|
+
3. **Continuity threshold**: Consistent update rate at 100ms or less
|
|
159
|
+
|
|
160
|
+
If any threshold is violated, the player will notice. If response exceeds 240ms, real-time control is broken entirely.
|