EngineGodot 4.2 or newer
LanguageGDScript
NodeCharacterBody2D with Sprite2D + CollisionShape2D
Time to run~3 minutes
LevelBeginner
OutputOne file (~50 lines)
DependenciesNone. No plugins.

The prompt

Open a fresh chat at claude.ai/new, paste, and send.

$ Build me a Godot 4.2+ top-down player controller as a single GDScript.

# shape
- One script, file player.gd, attached to a CharacterBody2D.
- Assumes a Sprite2D child and a CollisionShape2D child.
- No plugins, no autoloads.

# movement
- 8-direction movement read with Input.get_vector("move_left","move_right","move_up","move_down").
- Normalized so diagonals are not faster.
- Acceleration toward the target velocity and friction back to zero when no input, both @export floats.
- Speed @export float, default 160. Acceleration default 1200. Friction default 1000.
- Apply movement with move_and_slide().

# sprite
- Flip the Sprite2D horizontally based on the last non-zero horizontal input.
- Do not flip when the player is only moving vertically.

# constraints
- Use the built-in InputMap action names above. If they do not exist, add a one-line comment telling me to create them in Project Settings > Input Map.
- No magic numbers. Everything tunable is @export.
- Godot 4 API only (velocity is a property, move_and_slide takes no arguments).

# return format
- One file. No prose before or after the code.
- Brief comments only on the accel/friction lerp, since that is the non-obvious bit.
Open in Claude ▸ Run · 3 min

What this gets you

A controller that already feels right: the character eases up to speed and coasts to a stop instead of teleporting on and off at full velocity. That accel/friction pair is the difference between "programmer movement" and something you would actually ship.

It is deliberately one file on a CharacterBody2D so you can read the whole thing in one screen and bolt anything else onto it later, an animation tree, a dash, a state machine.

Why it matters

Normalized diagonals

The single most common top-down bug: hold up and right and the player scoots off 40% faster than they move straight. Input.get_vector returns a normalized vector, so this is handled, but only if you actually use it instead of reading four booleans by hand.

Acceleration and friction

Instant velocity feels robotic. Lerping velocity toward a target (accel) and back toward zero (friction) gives movement weight in about four lines. Exposed as @export so you can dial "floaty" vs "tight" without touching code.

Godot 4, not Godot 3

Half the tutorials online are Godot 3, where move_and_slide took the velocity as an argument. In Godot 4 velocity is a property and move_and_slide takes nothing. This prompt pins the version so Claude does not mix them.

What good output looks like

How to wire it up

  1. Create a CharacterBody2D node. Add a Sprite2D and a CollisionShape2D as children.
  2. Save the output as player.gd and attach it to the CharacterBody2D.
  3. Open Project Settings › Input Map and add four actions: move_left, move_right, move_up, move_down. Bind WASD and/or the arrow keys.
  4. Run the scene. The character should move in 8 directions and ease to a stop.

Common gotchas

The player does not move at all

Almost always the Input Map actions do not exist yet. Godot does not create them for you. Add move_left/right/up/down in Project Settings › Input Map.

Diagonal movement is faster

You are probably reading input as a raw Vector2 without normalizing, or building it from four booleans. Use Input.get_vector, which normalizes for you.

The sprite flips while walking straight up

The flip should only update when horizontal input is non-zero. Guard it with if direction.x != 0: so vertical-only movement leaves the facing alone.

Where to go next

  1. Animations. Add an AnimationPlayer and swap idle/walk based on whether velocity is near zero.
  2. Dash. A timed velocity override on a key press. Reuse the @export pattern for dash speed and duration.
  3. State machine. Once you have idle / walk / dash / attack, port to the FSM structure so states stop fighting each other.

Use it however you want

The prompt is CC0, paste it, modify it, ship a game with it. The output Claude gives you is yours. A link back to pixeldex.dev in your project's README helps the next solo dev find this stuff.