> ## Documentation Index
> Fetch the complete documentation index at: https://docs.summerengine.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Design mechanic skill for AI agents

> Design one mechanic in detail (input, feedback, failure modes, tunables) as a doc plus a script stub. A Summer Engine skill for AI agents.

`design-mechanic` is a skill from the [Summer skill library](/mcp/skills): a guide your AI agent reads when the task matches, so it builds the good version on the first try. Design one mechanic in detail (input, feedback, failure modes, tunables) as a doc plus a script stub.

| | |
| - | - |
| Status | Stable |
| Domains | Gameplay, Game design |
| Version | `1.0.2` |
| Engine version | `>=4.6` |
| Recommended set | Yes, installed by `--recommended` |

## When your agent uses it

* Designing one specific game mechanic in detail — input, response, feedback, failure modes, depth, tunables
* Add a grappling hook, dash, double jump, wall run, or parry

## Install

`summer setup` installs every skill for your agent. To add only this one:

```bash theme={null}
npx -y summer-engine@latest skills install design-mechanic --agent claude-code
```

Swap `claude-code` for your agent, such as `codex` or `cursor`. See [Skills](/mcp/skills#quick-start) for every option.

## The skill

## Overview

A "mechanic" is a verb the player performs that produces a meaningful response from the world. Not a system. Not a feature. A verb with feedback. This skill walks the five layers of a real mechanic: **input → response → feedback → failure modes → depth** — then drops a node-graph sketch + GDScript stub into the project so the next session can implement it.

**Core principle:** a mechanic is only as good as its weakest feedback layer. A perfect parry with no audio cue is broken. A great audio cue with floaty input is broken. Walk all five layers before scaffolding.

## Steps

### 1. Pin which mechanic

Ask exactly one question and wait:

> Which mechanic? (e.g., "double-jump", "parry", "stamina-dash", "pickup", "lock-on", "crafting-recipe-craft").

If the user gives a system name ("inventory", "combat"), push back:

> Inventory is a system, not a mechanic. The mechanics inside it are: pickup, equip, drop, use, swap. Which one?

### 2. Read context if available

If `.summer/GameSoul.md` exists, read it. The mechanic should fit the game brief, not exist in isolation.

```
Read .summer/GameSoul.md
```

Quote the relevant constraint back at the user:

> Brief says core loop is "see obstacle, attempt, fail, learn, retry". A double-jump only matters if it changes which obstacles are reachable. Confirm that's what we're solving.

### 3. Walk the five layers — one at a time

**Layer 1: Input.** Exactly what does the player press, hold, release, time?

State a candidate, ask for refinement:

> Input candidate: tap Space mid-air. Or: hold-and-release for variable height? Or: requires direction + Space? Pick one.

**Layer 2: Response.** What changes in the world the moment the input fires?

State the deltas. For double-jump:

> Response: vertical velocity set to (jump\_velocity \* 0.85). `_can_double_jump` flag flips false. Visual rig plays "jump\_2" anim. Audio cue. Particle burst at feet.

**Layer 3: Feedback** — and this is where most amateur designs collapse. Three sub-channels, all required:

| Channel | Question to answer | Bad example | Good example |
| - | - | - | - |
| Visual | Can a player who can't hear tell it worked? | "It just jumps." | "GPUParticles3D burst at feet, 0.1s slow-mo on apex, after-image trail behind." |
| Audio | Can a player who can't see tell it worked? | "Plays jump.wav." | "Layered: short whoosh on input, ambient pitch-up while airborne, soft thud on second jump start." |
| Mechanical | Does the input feel different from a single-jump? | "Same jump, just twice." | "Second jump has tighter air control, slightly lower height, different particle color." |

Force the user to answer all three. If they hand-wave one, name it:

> You named visual and audio. Mechanical-feel is missing — what makes the second jump feel different from the first beyond just being a second one?

**Layer 4: Failure modes.** What happens when the input fires but conditions aren't met?

For double-jump:

* Already used? → no input registered? Or denied with a UI shake? Or a small audio cue?
* During wall-slide? → does it count as airborne or grounded?
* During cutscene? → is input gated entirely?
* Spammed input? → buffered or ignored?

State the rules, ask:

> Failure rules: (a) already-used → silent ignore. (b) during wall-slide → counts as airborne, can double-jump off wall. (c) cutscene → input fully gated. (d) spam → input buffer of 0.1s. OK?

**Layer 5: Depth.** What makes this mechanic interesting after 5 minutes of play?

This is the hardest layer. State the depth-vector explicitly:

> Depth: double-jump becomes interesting when level design forces a *choice* — jump now to clear obstacle A, or save it to escape enemy B coming at you. Without that choice, it's just a longer jump. The level-design implication: every double-jump gap should pair with a near-future threat that also wants the resource.

If the user can't articulate depth, the mechanic might not be needed. Say it:

> If the only purpose is "can reach higher platforms", that's just a higher-jumping single-jump. Either change the input shape (give it a cost), or cut it.

### 4. List the tunables

Every mechanic has 3-7 numbers a designer will tweak. Name them. For double-jump:

```
@export var double_jump_velocity: float = 4.0      # vertical speed of second jump
@export var double_jump_air_control: float = 0.7   # multiplier vs ground control
@export var input_buffer_time: float = 0.1         # window to register early input
@export var ground_grace_period: float = 0.05      # coyote time before lockout
@export var slow_mo_on_apex: float = 0.0           # 0 = off, 0.05 = brief
```

These become `@export` vars in the stub. The user tunes in the inspector, no recompile.

### 5. Sketch the node graph

Describe what nodes the mechanic touches in the existing scene. Don't add yet — sketch first.

```
World/Player (CharacterBody3D)               # existing
├── CollisionShape3D                          # existing
├── Camera3D                                  # existing
├── DoubleJumpFX (GPUParticles3D)             # NEW — particles on second jump
├── JumpAudio (AudioStreamPlayer3D)           # NEW — input + apex cues
└── (script: player_controller.gd, modify)    # MODIFY — add _can_double_jump state
```

Show this to the user. Ask:

> Node-graph plan above. May I add `DoubleJumpFX` and `JumpAudio` to `./World/Player`, and modify `player_controller.gd` to add the double-jump logic?

### 6. Scaffold via MCP

**Preferred (Summer MCP):**

```
summer_get_scene_tree()                     # confirm Player exists where expected
summer_add_node(scenePath="res://main.tscn", parent="./World/Player", type="GPUParticles3D", name="DoubleJumpFX")
summer_set_prop(scenePath="res://main.tscn", path="./World/Player/DoubleJumpFX", key="emitting", value="false")
summer_add_node(scenePath="res://main.tscn", parent="./World/Player", type="AudioStreamPlayer3D", name="JumpAudio")
summer_input_map_bind(name="jump", events=[{"type": "key", "key": "Space"}])   # idempotent
summer_save_scene(scenePath="res://main.tscn")
summer_get_script_errors(path="res://scripts/player_controller.gd")
```

Argument notes, all of which the tool schema enforces:

* `scenePath` is required on `summer_add_node`, `summer_set_prop` and
  `summer_save_scene`. It names the exact `res://` scene; there is no
  "current scene" default.
* `summer_set_prop` takes named `path` / `key` / `value` — not positional.
* `summer_input_map_bind` events are dicts. `{"type": "key", "key": "Space"}`
  works; key names go through the engine's keycode table, so `W`, `Space`, `Shift`,
  `Escape` resolve and typos silently produce no event.
* `summer_get_script_errors` checks one file and requires `path`. Use
  `summer_get_diagnostics()` (no args) for a project-wide check.

**Fallback (no MCP):** Print the `.tscn` snippet for the user to paste:

```
[node name="DoubleJumpFX" type="GPUParticles3D" parent="Player"]
emitting = false
amount = 16
lifetime = 0.4

[node name="JumpAudio" type="AudioStreamPlayer3D" parent="Player"]
```

### 7. Write the GDScript stub

Stub only — implementation is the next session. Typed GDScript throughout (see `gdscript-patterns`). For double-jump:

```gdscript theme={null}
class_name PlayerController
extends CharacterBody3D

# Tunables
@export var jump_velocity: float = 4.5
@export var double_jump_velocity: float = 4.0
@export var double_jump_air_control: float = 0.7
@export var input_buffer_time: float = 0.1

# State
var _can_double_jump: bool = false
var _input_buffer_t: float = 0.0

@onready var fx: GPUParticles3D = $DoubleJumpFX
@onready var audio: AudioStreamPlayer3D = $JumpAudio

signal jumped
signal double_jumped

func _physics_process(delta: float) -> void:
    _input_buffer_t = max(0.0, _input_buffer_t - delta)

    if Input.is_action_just_pressed("jump"):
        _input_buffer_t = input_buffer_time

    if _input_buffer_t > 0.0:
        if is_on_floor():
            velocity.y = jump_velocity
            _can_double_jump = true
            _input_buffer_t = 0.0
            jumped.emit()
        elif _can_double_jump:
            velocity.y = double_jump_velocity
            _can_double_jump = false
            _input_buffer_t = 0.0
            fx.emitting = true
            audio.play()
            double_jumped.emit()

    move_and_slide()
```

Ask:

> May I write `scripts/player_controller.gd` (or merge into the existing script if one is attached)?

### 8. Save the design doc

Always write the design doc — it's the artifact the next session reads. Path: `.summer/mechanics/<mechanic-name>.md`.

```markdown theme={null}
# Mechanic: Double-Jump

**Input:** Tap Space mid-air. Buffered 0.1s before ground.
**Response:** velocity.y = double_jump_velocity. `_can_double_jump` flag false.
**Feedback:**
- Visual: GPUParticles3D burst, 0.1s slow-mo on apex
- Audio: short whoosh on input
- Mechanical: 70% air control on second jump
**Failure modes:**
- Already used → silent ignore
- During wall-slide → counts as airborne
- Cutscene → input gated
- Spam → buffered (0.1s window)
**Depth:**
- Resource the player chooses when to spend
- Level design pairs every gap with a near-future threat
**Tunables:** see @export vars in player_controller.gd
**Open questions:** <list any the user couldn't answer>
```

Ask:

> May I create `.summer/mechanics/double-jump.md` with this design doc?

## Common mistakes

| Mistake | Fix |
| - | - |
| Designing the system, not the verb | "Combat" is a system. "Parry" is a mechanic. Pick the verb. |
| Skipping mechanical-feel in feedback | Visual + audio alone produce hollow mechanics. Mechanical difference is required. |
| No failure modes | Players spam, edge into states you didn't plan for, and find the hole. Plan the failure cases up front. |
| Hand-wave depth | "Players will use it strategically" is not depth. Name the choice the player makes. |
| Tunables hard-coded as `const` | Use `@export` so designers tune in the inspector. |
| Adding the mechanic without the FX/audio nodes | Without nodes for feedback, the mechanic ships feeling cheap. Scaffold the nodes alongside the script. |
| Setting `position` for movement instead of `velocity` | Physics objects use `velocity` in `_physics_process`. |
| Calling SetResourceProperty before the property holds a resource | Explicit `resource is null` error, not a silent drop. Assign the resource first (`summer_set_prop key="mesh" value="BoxMesh"`), then set its sub-properties. Scene-embedded sub\_resources are fully supported targets. |

## Collaborative protocol

This skill writes scene nodes and one or more files (`.gd`, `.summer/mechanics/<name>.md`). Group writes into one ask per phase.

## Want a working starter?

For full character mechanics in a runnable starter:

* FPS variant → `summer create 3d-fps-old-school`
* Platformer → `summer create 3d-third-person-controller` (jump-capable character; no dedicated 3D platformer template yet)

This skill is a workflow that designs and scaffolds — the templates are runnable bases the mechanic plugs into.

## See also

* `brainstorm-game` — produces `.summer/GameSoul.md` this skill reads
* `design-level` — design the levels that exercise the mechanic
* `fps-controller` — FPS movement scaffolding
* `gdscript-patterns` — state machines and other script patterns for complex mechanics
* `audio-direction` — defines the SFX vocabulary the mechanic draws from

## From a shell

No Summer MCP tools in this session? Run each one as a command; when `summer --version` is missing or below 4.0, use `npx -y summer-engine@latest` in place of `summer`. Fields are flags in kebab-case (`--scene-path res://main.tscn`) or one `--input '<json>'`, and `summer ops describe <op>` prints the exact input. The `summer-cli` skill has the rest.

| In this skill | Command |
| - | - |
| `summer_add_node` | `summer engine add-node` |
| `summer_get_diagnostics` | `summer engine get-diagnostics` |
| `summer_get_scene_tree` | `summer engine get-scene-tree` |
| `summer_get_script_errors` | `summer engine get-script-errors` |
| `summer_input_map_bind` | `summer engine input-map-bind` |
| `summer_inspect_node` | `summer engine inspect-node` |
| `summer_save_scene` | `summer engine save-scene` |
| `summer_set_prop` | `summer engine set-prop` |

## Related skills

* [`audio-direction`](/skills/audio-direction): Define the game's sound (music style, SFX vocabulary, dynamic music) as .summer/audio-bible.md.
* [`fps-controller`](/skills/fps-controller): First-person controller: WASD, mouse look, jump, coyote time, jump buffering, air control.
* [`design-level`](/skills/design-level): Design one level (layout, pacing, encounters, secrets) as a design doc plus a node-tree skeleton.
* [`brainstorm-game`](/skills/brainstorm-game): Turn a vague game idea into a 1-page brief (genre, scope, core loop, mechanics) in .summer/GameSoul.md.
* [`gdscript-patterns`](/skills/gdscript-patterns): GDScript conventions: type hints, signals, exports, onready, lifecycle methods, node paths, naming.

***

Source: [`library/skills/design-mechanic/SKILL.md`](https://github.com/SummerEngine/summer/blob/main/library/skills/design-mechanic/SKILL.md), rendered from `summer-engine@4.3.0` on npm.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.