<!-- skill: Godot Indie | version: 1.0.0 | description: Build 2D/3D indie games in Godot 4 with GDScript | category: Games -->
## Instructions
- Use Godot 4.x GDScript with typed vars, `@export`, `@onready`; prefer composition over deep inheritance.
- Structure scenes as reusable units: Player.tscn, Enemy.tscn, HUD.tscn; instance via `preload().instantiate()`.
- Use signals for decoupled communication (`signal health_changed(hp)` + `emit_signal` / `.connect()`); avoid direct node path coupling.
- Configure Input Map in Project Settings for move/jump/attack/ui; never hardcode `Input.is_key_pressed` in gameplay.
- For 2D platformers use CharacterBody2D + `move_and_slide()`, `floor_snap`, coyote time 0.1s, jump buffer 0.12s.
- Build TileMaps with TileSet physics + navigation layers; use TileMapLayer nodes in 4.3+ (one layer per collision/decor).
- Store globals in Autoloads (GameState, AudioManager, SaveSystem); keep autoloads lean and testable.
- Manage UI with Control anchors + CanvasLayer; use `get_viewport().get_visible_rect()` for responsive layouts.
- Export with presets: PC (Win/Linux), Android (SDK + keystore), Web (GL Compatibility renderer, thread-safe export).
- Profile with Debugger + Profiler; fix physics tick at 60Hz, use object pooling for bullets/particles.
- Save via ConfigFile or JSON in `user://saves/`; version save schema and migrate on load.
- Package dialogue/quests as Resources (`.tres`) for data-driven design and easy balancing.
## Examples
- Example 1 — Top-down movement: set Input Map `move_up/down/left/right`, CharacterBody2D reads `Input.get_vector()`, speed 220, acceleration lerp 12.
- Example 2 — Signal health: `player.health_changed.connect(hud._on_health_changed)`; HUD updates ProgressBar without polling.
- Example 3 — TileMap platformer: TileSet with 16px grid, physics layer 0, player with OneWayPlatform check + `floor_max_angle 0.78`.
## Workflows
1. Scaffold: create project (GL Compatibility if targeting Web), set viewport 1280x720, stretch mode `canvas_items`, aspect `expand`.
2. Prototype: Player scene + input map + one TileMap level + Camera2D limits; playtest movement feel in 30 min loop.
3. Systems: add autoloads (Game, Save), HUD signals, enemy instancing, audio buses; add pause menu with `get_tree().paused`.
4. Polish: particles, screen shake, tweened UI, export presets test (run PC build, install APK, host Web zip locally).
5. Ship: bump version, export release templates, notarize/sign as needed, upload to itch.io with Web + PC builds.
## Templates
### GDScript 2D Player (CharacterBody2D)
```gdscript
extends CharacterBody2D
@export var speed := 220.0
@export var jump_velocity := -420.0
var gravity: float = ProjectSettings.get_setting("physics/2d/default_gravity")
signal health_changed(hp: int, max_hp: int)
var hp := 100
var max_hp := 100
var coyote := 0.0
func _physics_process(delta: float) -> void:
  var dir := Input.get_vector("move_left","move_right","move_up","move_down")
  velocity.x = lerp(velocity.x, dir.x * speed, 12.0 * delta)
  velocity.y = lerp(velocity.y, dir.y * speed, 12.0 * delta)
  if is_on_floor():
    coyote = 0.1
  else:
    coyote -= delta
    velocity.y += gravity * delta * 0.4
  move_and_slide()
func take_damage(amount: int) -> void:
  hp = maxi(0, hp - amount)
  health_changed.emit(hp, max_hp)
```
### Instancing + Autoload Save
```gdscript
# spawn enemy
var EnemyScene := preload("res://enemies/slime.tscn")
func spawn(pos: Vector2) -> void:
  var e = EnemyScene.instantiate()
  e.position = pos
  $Enemies.add_child(e)
# autoload SaveSystem
func save_game(slot: int) -> void:
  var cfg := ConfigFile.new()
  cfg.set_value("slot","level", GameState.level)
  cfg.set_value("slot","score", GameState.score)
  cfg.save("user://saves/slot_%d.cfg" % slot)
```
### Export Presets (export_presets.cfg excerpt)
```ini
[preset.0]
name="PC-Windows"
platform="Windows Desktop"
runnable=true
export_path="builds/pc/game.exe"
[preset.1]
name="Android"
platform="Android"
export_path="builds/android/game.apk"
[preset.2]
name="Web"
platform="Web"
export_path="builds/web/index.html"
```
## Tools
- Godot 4.x editor + GDScript LSP, Debugger Profiler, AnimationPlayer/Tween, GPUParticles2D.
- Export templates, Android SDK/cmdline-tools, itch.io Butler for uploads, Git + git-lfs for assets.
- Aseprite/Tiled importers, Kenney assets for prototyping, Freesound for SFX buses.
## Advanced
- Use state machines (NodeState pattern) for player/enemy AI; use NavigationAgent2D for pathfinding on TileMap.
- Optimize draw calls: atlas textures, VisibilityNotifier, occluders; keep physics bodies <200 active, pool projectiles.
- Web export: set renderer GL Compatibility, disable threads if hosting without COOP/COEP, compress to <30MB.
## Documentation
- https://docs.godotengine.org/en/stable/
- https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html
- https://docs.godotengine.org/en/stable/tutorials/export/exporting_projects.html
- https://kidscancode.org/godot_recipes/4.x/
