Lesson 13

Sound, pause, and exporting GridFall

The finish line. We add a couple of sound effects, a pause toggle, and export a real build. By the end you have a complete, shippable GridFall.

▸ By the end of this lesson: A pause toggle, sound on lock and clear, and an exported build of the finished game

13.1Add sound effects

  1. Drop two short .wav or .ogg files into the project (a soft 'thud' for lock, a brighter 'ding' for clear). You can grab free CC0 sounds or generate simple ones — any short clip works.
  2. In main.tscn, under Main, add two AudioStreamPlayer nodes named LockSound and ClearSound.
  3. Select each, and in the Inspector drag the matching audio file into the Stream slot.
main.gd (wiring notes)gdscript
@onready var lock_sound: AudioStreamPlayer = $LockSound
@onready var clear_sound: AudioStreamPlayer = $ClearSound

# call lock_sound.play() at the end of _lock_piece(), before spawn_piece():
#   ... board writes ...
#   lock_sound.play()
#   if cleared > 0:
#       _award_score(cleared)
#       clear_sound.play()

Concretely, update _lock_piece():

main.gd (replace _lock_piece)gdscript
func _lock_piece() -> void:
	for cell in active_piece.get_cells():
		board.set_cell(cell.x, cell.y, active_piece.color_id)
	active_piece.queue_free()
	active_piece = null
	lock_sound.play()

	var cleared: int = board.clear_full_rows()
	if cleared > 0:
		_award_score(cleared)
		clear_sound.play()

	_render_board()
	spawn_piece()

Guard against missing streams

If an AudioStreamPlayer has no stream assigned, play() does nothing harmful but logs a warning. Make sure each has a file in its Stream slot, or wrap calls in if lock_sound.stream:.

13.2Pause

  1. In Project Settings → Input Map, add an action pause bound to Esc or P.

Godot has a built-in pause system. Toggle the SceneTree's paused flag. Add to main.gd:

main.gd (replace _input)gdscript
func _input(event: InputEvent) -> void:
	if event.is_action_pressed("pause"):
		get_tree().paused = not get_tree().paused
		return
	if active_piece == null or game_over:
		return
	if event.is_action_pressed("hard_drop"):
		_hard_drop()
	elif event.is_action_pressed("rotate_cw"):
		_try_rotate()

Pause needs a process mode

By default a paused tree freezes every node — including the one reading the pause key. Select Main in the Inspector, find Process → Mode, and set it to Always so Main keeps listening for the unpause key while everything else is frozen.

13.3Export a real build

  1. Project → Export. Click Add... and choose a preset — Windows Desktop, Linux, macOS, or Web.
  2. The first time, Godot prompts to download export templates — click Manage/Download and let it finish.
  3. For a quick shareable build, pick Web: it produces an index.html plus support files can be hosted anywhere (including TeqStudy).
  4. Click Export Project, choose an output folder, and export.

Android target

GridFall's touch-friendliness aside, exporting to Android needs the Android SDK + a debug keystore configured in Editor Settings. That's a larger setup covered by Godot's export docs; desktop and web work out of the box.

You built a complete game

Spawning, gravity, input, rotation with kicks, line clears, scoring, escalation, game over, HUD, preview, juice, sound, pause, and an export. That's GridFall — a full, shippable 2D game built entirely by example.

Checkpoint — expected state