Game Design: Mechanics Engineering
Before starting this conversation, let's establish a distinction: game design isn't "coming up with a game idea." Anyone can do that. Game design is engineering a system of rules that, when interacted with by a player, produces a specific emotional and behavioral result. It's an engineering discipline—the compiler is a human brain.
Mechanics: What We Design
Movement and Control
Character controller is the first thing a player touches and the last thing they get used to. Movement feel isn't determined by character speed but by acceleration and deceleration curves. In Unity these are AnimationCurve curves or CharacterController parameters. We don't use linear acceleration: in most genres correct feel comes from ease-in at movement start and sharp braking when releasing the button.
Coyote time (150–200 ms after leaving a platform where jump still registers) and jump buffering (jump registered 100–150 ms before ground contact) aren't "features"—they're platformer standard. Players don't articulate their absence but feel it as "controls feel sluggish."
Inventory
Inventory system looks simple, in practice it's an endless source of edge cases. Stackable/non-stackable items, weight vs. slot limits, drag-and-drop with validation, session persistence, server verification in multiplayer.
We design inventory through data: each item is a ScriptableObject with parameters, inventory slots are containers that accept or reject items by rule set (type, character class, quantity). This lets you add items without code changes.
Combat System: Deep Dive
Combat is where the gap between "looks simple" and "done right" is largest. Let's use melee combat as example.
Hit Detection
Two main approaches: hitbox-based and raycast/spherecast-based.
Hitbox — colliders on weapons and characters, intersection = hit. Works well in slow games. Fast attacks cause tunneling: weapon passes through in one frame without collision registration. Fixed by sweep test or enabling Physics.CCD (Continuous Collision Detection)—expensive on performance.
Raycast/spherecast — each frame during active attack window, cast rays or spheres along weapon trajectory. More precise, framerate-independent, easier zone-of-effect control. We prefer this for most action games.
Attack Windows
Each attack splits into phases:
- Startup — animation windup, character vulnerable, action not yet started
- Active — active hit window, hits register
- Recovery — return animation, character vulnerable, action can't be canceled
These timings aren't just animator numbers. They define combat feel. Long startup creates "heavy" hits. Short recovery enables aggressive playstyle. In Souls-like games, long recovery is the main punishment for mistakes.
In Unity this is Animation Events: animator fires event at specific frame, code activates/deactivates hitbox or enables/disables spherecast loop.
Character State Machine
A combat character is a state machine. In Unity we use Animator Controller as foundation but move business logic to code, not Animator. Animator manages animation transitions, C# manages character state transitions.
Base states: Idle, Moving, Jumping, Falling, Attacking, Hurt, Dead, Blocking, Dodging. Each transition—explicit condition. Transition from Attacking to Hurt only if attack is interruptible (some attacks have iframes or super armor).
Hierarchical state machines (via Override Animator Controller in Unity or custom Hierarchical State Machine) enable nested states: e.g., Moving contains Walking, Running, Crouching substates without duplicating transitions.
Economy: Mathematical Model
This is where game design most often goes "by feel"—and gets broken balance a month post-launch.
Base Progression Model
Most games use one of three mathematical models:
Linear — each level requires same XP. Simple, predictable, boring at high levels.
Exponential — XP(n) = base * multiplier^n. Standard for RPG. multiplier usually 1.5 to 2.0. At 1.5—early levels fast, late ones long. At 2.0—sharp difficulty spike.
Polynomial — XP(n) = a * n^b. Softer growth than exponential. b ranges 1.5 to 2.5 for most games.
We build progression tables in Google Sheets before engine implementation. This lets you check in minutes how many hours players spend per level at different parameters.
Game Economy: Currencies and Flows
Base principle: every currency must have explicit source (tap) and explicit sink (drain). If gold only flows in with nothing valuable to spend on—it devalues, inflation kills economy.
Example simple dual-currency system (typical mobile f2p):
| Soft Currency (Gold) | Hard Currency (Crystals) | |
|---|---|---|
| Source | Quests, enemies, daily rewards | Purchase for money, rare achievements |
| Drain | Consumables, gear upgrades, buildings | Skip time, rare items, premium |
| Conversion | → crystals: no | → gold: yes (but not reverse) |
One-way conversion (hard → soft, not reverse) protects monetization.
Balance Through DPS and TTK
In action games weapon balance is built on two metrics:
DPS (Damage Per Second) — damage per time unit including full attack cycle (including recovery).
TTK (Time To Kill) — time to kill full-health enemy. TTK = HP_enemy / DPS.
Different weapon types should have comparable TTK against standard enemy but different application profiles: pistol quick-draw, sniper rifle high single hit, shotgun close-range effective.
Imbalance is easy to spot: if some weapon TTK is half the others—it's meta, everyone uses only it.
Narrative and Level Design
Narrative doesn't have to be text. Environmental storytelling—object placement, event traces on level, sound design—often beats dialogue.
For dialogue systems we use Ink (narrative language from Inkle) integrated with Unity. Ink lets narrative designers write branching dialogue with variables and conditions in human-readable format without programmer help.
Level design is separate discipline. Base principle: level should teach through gameplay, not text hints. If player doesn't understand what to do—that's design problem, not player problem.
Game Designer Tools in Our Process
| Task | Tool |
|---|---|
| GDD and documentation | Notion, Confluence |
| Balance tables | Google Sheets |
| Mechanic prototyping | Unity (C#), Godot for quick prototypes |
| State machine diagrams | Miro, draw.io |
| Narrative trees | Ink, Twine |
| In-engine configuration | ScriptableObjects (Unity), DataTable (Unreal) |
| Analytics and A/B tests | Firebase Analytics, GameAnalytics |
Iteration and Playtesting
Mechanics don't ship correct first try. First prototype is always awkward—normal. Abnormal is not changing after playtest.
We run internal playtest every two weeks. After playtest—concrete list of changes with priorities. Opinion "something's wrong with combat" isn't a task. Task is "attack startup 400 ms, too long, cut to 250 ms, test again."
Numbers change. Feel gets locked in. Cycle repeats.





