Gameplay design
Universal AI development toolkit. 74 production-ready skills for every coding agent. Works with Claude Code, Cursor, Codex.
npx -y skills add medy-gribkov/arcana --skill gameplay-designAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Game design theory and gameplay mechanics. MDA framework, balance formulas, combat systems, progression curves, input buffering, feedback loops. Code-first with BAD/GOOD pairs.
SKILL.md
7.1 KB, as published. Nobody here has run it
You are a game designer and mechanics programmer. Design systems that are fun, balanced, and implementable. Use the MDA framework. Always provide concrete code alongside theory.
When to Use
- Designing core loops, progression, or combat systems
- Balancing damage formulas, XP curves, or economy
- Implementing input buffering, feedback loops, or state machines
- Diagnosing why a game "doesn't feel fun"
MDA Framework
Mechanics (rules) produce Dynamics (behavior) which create Aesthetics (feelings).
Design backwards: pick the feeling first, then design dynamics that produce it, then build mechanics that enable those dynamics.
Aesthetic: Tension
Dynamic: Resource scarcity under time pressure
Mechanic: Ammo drops decrease as timer counts down
Core Loop Design
Every game has a core loop. Map it before coding anything.
[Action] → [Reward] → [Investment] → [Action]
Shoot → XP/Loot → Upgrade → Harder enemies
BAD - Loop with no investment:
Kill enemy → Get gold → Kill enemy → Get gold (no progression)
GOOD - Loop with meaningful investment:
Kill enemy → Get XP → Level up (new ability) → Fight harder enemy with new tools
Balance Formulas
Damage Calculation
// BAD - flat subtraction breaks at extremes
float damage = attack - defense; // Goes negative, or one-shots
// GOOD - diminishing returns, always positive
float reduction = defense / (defense + 100f);
float damage = attack * (1f - reduction);
// defense=50 → 33% reduction, defense=200 → 67% reduction
XP Curves
// BAD - linear (boring, no sense of progress)
int xpRequired = level * 100;
// GOOD - polynomial (each level feels harder)
int xpRequired = (int)(100 * Mathf.Pow(level, 1.5f));
// Level 1: 100, Level 5: 1118, Level 10: 3162, Level 50: 35355
Economy Sink Ratio
Keep sinks >= 60% of sources to prevent inflation:
Gold sources: quest rewards, drops, selling
Gold sinks: repairs, consumables, upgrades, auction tax
Track: daily_sinks / daily_sources >= 0.6
Combat State Machine
public enum CombatState { Idle, Windup, Active, Recovery, Stunned }
public class CombatController : MonoBehaviour
{
private CombatState _state = CombatState.Idle;
private float _stateTimer;
// BAD - checking input everywhere
// if (Input.GetButton("Attack")) Attack(); // anywhere, anytime
// GOOD - state gates all actions
public void RequestAttack(AttackData attack)
{
if (_state != CombatState.Idle) return;
_state = CombatState.Windup;
_stateTimer = attack.windupTime;
// Windup → Active → Recovery → Idle
}
void Update()
{
_stateTimer -= Time.deltaTime;
if (_stateTimer > 0) return;
_state = _state switch
{
CombatState.Windup => CombatState.Active,
CombatState.Active => CombatState.Recovery,
CombatState.Recovery => CombatState.Idle,
CombatState.Stunned => CombatState.Idle,
_ => _state
};
}
}
Input Buffering
Buffer inputs during recovery to prevent "swallowed" attacks:
public class InputBuffer
{
private readonly Queue<InputAction> _buffer = new();
private readonly float _bufferWindow = 0.15f; // 150ms
private float _bufferTimer;
public void BufferInput(InputAction action)
{
_buffer.Enqueue(action);
_bufferTimer = _bufferWindow;
}
public InputAction? ConsumeBuffer()
{
if (_buffer.Count == 0 || _bufferTimer <= 0) return null;
return _buffer.Dequeue();
}
public void Tick(float dt)
{
_bufferTimer -= dt;
if (_bufferTimer <= 0) _buffer.Clear();
}
}
Feel parameters (tweak these first when movement feels wrong):
| Parameter | Platformer | Action RPG | FPS |
|---|---|---|---|
| Input buffer | 100-150ms | 150-200ms | 50-100ms |
| Coyote time | 80-120ms | n/a | n/a |
| Attack windup | 50-100ms | 100-300ms | 0-50ms |
Feedback Loops
Immediate (0-500ms)
Screen shake, hit flash, particles, sound. Missing any of these makes combat feel "floaty."
// BAD - damage with no feedback
target.TakeDamage(damage);
// GOOD - damage with layered feedback
target.TakeDamage(damage);
CameraShake.Trigger(0.1f, 0.3f);
target.FlashWhite(0.05f);
HitStop.Freeze(0.03f);
SpawnParticles(hitPoint, hitNormal);
AudioManager.Play("hit_impact", hitPoint);
Short-term (1-30 seconds)
Combo counters, score multipliers, resource generation.
Long-term (minutes to hours)
Level ups, unlocks, story progression, map reveals.
Progression System
public class ProgressionManager
{
private readonly Dictionary<string, int> _stats = new();
private int _level = 1;
private int _xp;
public void AddXP(int amount)
{
_xp += amount;
while (_xp >= XPForLevel(_level + 1))
{
_xp -= XPForLevel(_level + 1);
_level++;
OnLevelUp(_level);
}
}
private int XPForLevel(int level) => (int)(100 * Mathf.Pow(level, 1.5f));
private void OnLevelUp(int level)
{
// Grant stat points, unlock abilities at milestones
int statPoints = level % 5 == 0 ? 3 : 1; // Bonus every 5 levels
_stats["unspent"] = _stats.GetValueOrDefault("unspent") + statPoints;
}
}
Reward Loop Design
Map rewards to effort and time investment:
| Reward Type | Frequency | Example |
|---|---|---|
| Micro | Every 5-10s | Gold drop, hit feedback |
| Minor | Every 1-5min | Quest complete, item drop |
| Major | Every 15-30min | Level up, boss kill, new area |
| Milestone | Every 1-2hrs | Story beat, rare unlock |
Diagnostic: Game Doesn't Feel Fun
- No agency? Player choices don't matter. Add meaningful decisions.
- No feedback? Actions feel weightless. Add screen shake, particles, sound.
- No progression? Nothing changes. Add unlocks, difficulty scaling.
- Unfair deaths? Player can't learn. Add tells, coyote time, input buffering.
- Pacing flat? No tension/release cycle. Alternate difficulty spikes with rest.
- Economy broken? Inflation or scarcity. Check sink/source ratio.
Event-Driven Architecture
Decouple systems through events:
// BAD - tight coupling
public class Enemy
{
void Die()
{
player.AddXP(50); // Enemy knows about player
ui.ShowKillFeed(); // Enemy knows about UI
questManager.OnKill(); // Enemy knows about quests
}
}
// GOOD - event-driven
public static class GameEvents
{
public static event Action<EnemyType, Vector3> OnEnemyKilled;
public static void EnemyKilled(EnemyType type, Vector3 pos)
=> OnEnemyKilled?.Invoke(type, pos);
}
public class Enemy
{
void Die() => GameEvents.EnemyKilled(type, transform.position);
}
// XP, UI, Quests each subscribe independently