Week 20 packet
Student instructions, tasks, and checks. The answer key is not in this packet. Links stay as text. This page does not embed a clip or run a file.
# Week 20 — Audio with equivalent visual feedback
## VGC-L096 — Plan purposeful sounds
**Objective:** Map audio cues to events without making audio mandatory.
**Time:** 55 minutes
### Instruction
Audio can confirm an action, signal a change or establish mood. It should not be the only way to know that a required event occurred. Create an event table for collect, damage, checkpoint and completion. For each, specify a short sound and an equivalent visual cue. Silence can be a valid design choice. Avoid continuous loud music or startling peaks. No learner must record their voice; an original tap, simple teacher-provided sound or no-sound version meets the planning goal.
### Worked example
A short original tap sound confirms a collected object while a number changes on screen. Muting the tap leaves all required information visible.
### Assignment
1. Write an audio/visual cue table for four events.
2. Identify which events need priority if sounds overlap.
### Acceptance checks
- Every essential sound has an equivalent visible cue.
- No task requires voice, face or personal recording.
**Submit:** Four-event sound design sheet.
**Question:** Why is a completion chime alone insufficient feedback?
**Support:** Use one short teacher-provided original sound or a privately recorded tap. Keep volume modest and retain text cues. Start with the first assigned task and re-run its acceptance test before adding the remaining feature.
**Optional extension:** Compare two sound choices with the same loudness and explain which better communicates the event. Document one changed parameter, your prediction, and the observed effect; optional, not required for completion.
**Optional free reading:** [Your first 2D game](https://docs.godotengine.org/en/stable/getting_started/first_2d_game/index.html), [Exporting for the Web](https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_web.html)
---
## VGC-L097 — Import a short original audio file
**Objective:** Use a local AudioStreamPlayer with an explicit play action.
**Time:** 55 minutes
### Instruction
Use a short original WAV or OGG provided by a teacher or recorded privately with permission. Put it in audio and assign it to an AudioStreamPlayer named Sound as in C-AUDIO. Turn autoplay off and lower volume before testing. Press Play to trigger the sound. Keep recordings free of conversations, names and background private information. If recording is unavailable, use a teacher-provided original sound; recording equipment is not part of the programming requirement.
### Worked example
A short original tap sound confirms a collected object while a number changes on screen. Muting the tap leaves all required information visible.
Scaffold C-AUDIO — Local audio playback with a reversible mute
Setup: Create Control AudioLab with Button Play and CheckButton Mute. Child AudioStreamPlayer Sound: copy the supplied student-support/audio/course-tap.wav into your project audio folder and assign it (or another short original WAV/OGG), autoplay Off, volume_db -12. Attach script to AudioLab. Recording is optional: a teacher-provided original file is equivalent. No microphone or face recording is required and all recording stays private.
```gdscript
extends Control
func _ready() -> void:
$Play.pressed.connect(_play)
$Mute.toggled.connect(_mute)
func _play() -> void:
if not $Mute.button_pressed:
$Sound.play()
func _mute(enabled: bool) -> void:
if enabled:
$Sound.stop()
```
### Assignment
1. Build the C-AUDIO lab with a short original sound.
2. Record filename, origin and duration in the asset inventory.
### Acceptance checks
- Sound starts after pressing Play, not automatically at launch.
- The imported file is included in the restored project.
**Submit:** Audio lab source and asset inventory update.
**Question:** Why include the actual sound file in the project artifact?
**Support:** Use one short teacher-provided original sound or a privately recorded tap. Keep volume modest and retain text cues. Start with the first assigned task and re-run its acceptance test before adding the remaining feature.
**Optional extension:** Compare two sound choices with the same loudness and explain which better communicates the event. Document one changed parameter, your prediction, and the observed effect; optional, not required for completion.
**Optional free reading:** [Your first 2D game](https://docs.godotengine.org/en/stable/getting_started/first_2d_game/index.html), [Exporting for the Web](https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_web.html)
---
## VGC-L098 — Add mute that really stops playback
**Objective:** Keep audio state separate from button appearance.
**Time:** 55 minutes
### Instruction
C-AUDIO uses a CheckButton to represent mute. Enabling mute stops the current sound and suppresses future Play actions. Merely dimming a speaker icon would not enforce the rule. In your game, route event-sound requests through one helper that checks the setting, rather than remembering to check it in every collision handler. Preserve visual feedback. Test muting during a sound as well as before it begins; these are different cases.
### Worked example
A short original tap sound confirms a collected object while a number changes on screen. Muting the tap leaves all required information visible.
Scaffold C-AUDIO — Local audio playback with a reversible mute
Setup: Create Control AudioLab with Button Play and CheckButton Mute. Child AudioStreamPlayer Sound: copy the supplied student-support/audio/course-tap.wav into your project audio folder and assign it (or another short original WAV/OGG), autoplay Off, volume_db -12. Attach script to AudioLab. Recording is optional: a teacher-provided original file is equivalent. No microphone or face recording is required and all recording stays private.
```gdscript
extends Control
func _ready() -> void:
$Play.pressed.connect(_play)
$Mute.toggled.connect(_mute)
func _play() -> void:
if not $Mute.button_pressed:
$Sound.play()
func _mute(enabled: bool) -> void:
if enabled:
$Sound.stop()
```
### Assignment
1. Add the mute pattern to the game’s event-sound helper.
2. Test mute-before-play, mute-during-play and unmute-then-play.
### Acceptance checks
- Muted state is silent in both timing cases.
- Unmuting restores playback without changing game rules.
**Submit:** Muted game checkpoint and three-case log.
**Question:** Why must mute stop a sound already playing?
**Support:** Use one short teacher-provided original sound or a privately recorded tap. Keep volume modest and retain text cues. Start with the first assigned task and re-run its acceptance test before adding the remaining feature.
**Optional extension:** Compare two sound choices with the same loudness and explain which better communicates the event. Document one changed parameter, your prediction, and the observed effect; optional, not required for completion.
**Optional free reading:** [Your first 2D game](https://docs.godotengine.org/en/stable/getting_started/first_2d_game/index.html), [Exporting for the Web](https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_web.html)
---
## VGC-L099 — Synchronize sound with a validated event
**Objective:** Play a cue after the rule accepts the action.
**Time:** 55 minutes
### Instruction
Play sound after a valid state change, not merely after an attempted input. A denied purchase should not use the same success chime as a completed purchase. For a pickup, the manager can update score and then request the collect cue once. Duplicate collision notifications should still produce one reward and one cue. Use a separate quieter failure cue only if it adds useful information, and keep failure text. Test repeated events and invalid actions rather than listening only to a successful case.
### Worked example
A short original tap sound confirms a collected object while a number changes on screen. Muting the tap leaves all required information visible.
Scaffold C-AUDIO — Local audio playback with a reversible mute
Setup: Create Control AudioLab with Button Play and CheckButton Mute. Child AudioStreamPlayer Sound: copy the supplied student-support/audio/course-tap.wav into your project audio folder and assign it (or another short original WAV/OGG), autoplay Off, volume_db -12. Attach script to AudioLab. Recording is optional: a teacher-provided original file is equivalent. No microphone or face recording is required and all recording stays private.
```gdscript
extends Control
func _ready() -> void:
$Play.pressed.connect(_play)
$Mute.toggled.connect(_mute)
func _play() -> void:
if not $Mute.button_pressed:
$Sound.play()
func _mute(enabled: bool) -> void:
if enabled:
$Sound.stop()
```
Scaffold C-PICKUP — An exactly-once pickup signal
Setup: Create Area2D root Coin, CollisionShape2D Circle radius 10. Layer 3 (bit value 4), mask layer 1 only. Monitoring on. Attach script and save Coin.tscn. In the Node > Groups editor add Player root to group player. Put a Coin instance and Player instance in World. Manager connects each Coin.collected to its score handler (see C-MANAGER). Signal wiring here is code-only: do not also connect body_entered in editor.
```gdscript
extends Area2D
signal collected(points: int)
@export var points: int = 1
var taken: bool = false
func _ready() -> void:
body_entered.connect(_on_body_entered)
func _draw() -> void:
draw_circle(Vector2.ZERO, 10.0, Color.GOLD)
draw_line(Vector2(-5, 0), Vector2(5, 0), Color.BLACK, 2.0)
func _on_body_entered(body: Node2D) -> void:
if taken or not body.is_in_group("player"):
return
taken = true
collected.emit(points)
queue_free()
```
### Assignment
1. Connect one success cue to the accepted state update and one visible equivalent.
2. Test valid, invalid and repeated attempts.
### Acceptance checks
- Invalid attempts do not trigger success audio.
- Exactly-once events do not produce stacked duplicate sounds.
**Submit:** Event-audio implementation and three-attempt evidence.
**Question:** Why is button-pressed not always the correct place for a success sound?
**Support:** Use one short teacher-provided original sound or a privately recorded tap. Keep volume modest and retain text cues. Start with the first assigned task and re-run its acceptance test before adding the remaining feature.
**Optional extension:** Compare two sound choices with the same loudness and explain which better communicates the event. Document one changed parameter, your prediction, and the observed effect; optional, not required for completion.
**Optional free reading:** [Your first 2D game](https://docs.godotengine.org/en/stable/getting_started/first_2d_game/index.html), [Exporting for the Web](https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_web.html)
---
## VGC-L100 — Test audio activation and quiet play
**Objective:** Explain browser restrictions and preserve a local alternative.
**Time:** 55 minutes
### Instruction
Browsers often require a user gesture before playing audio, and a Godot web export has additional constraints. If you test a web build later, start with an explicit Start button rather than assuming autoplay. The required course path remains local editor play, which needs no hosting account. Test the game with audio off and low volume; all required actions and outcomes must remain understandable. Record the tested platform instead of claiming sound works identically everywhere.
### Worked example
A short original tap sound confirms a collected object while a number changes on screen. Muting the tap leaves all required information visible.
Scaffold C-AUDIO — Local audio playback with a reversible mute
Setup: Create Control AudioLab with Button Play and CheckButton Mute. Child AudioStreamPlayer Sound: copy the supplied student-support/audio/course-tap.wav into your project audio folder and assign it (or another short original WAV/OGG), autoplay Off, volume_db -12. Attach script to AudioLab. Recording is optional: a teacher-provided original file is equivalent. No microphone or face recording is required and all recording stays private.
```gdscript
extends Control
func _ready() -> void:
$Play.pressed.connect(_play)
$Mute.toggled.connect(_mute)
func _play() -> void:
if not $Mute.button_pressed:
$Sound.play()
func _mute(enabled: bool) -> void:
if enabled:
$Sound.stop()
```
### Assignment
1. Run a complete muted local round and a low-volume round.
2. Add a Start interaction before audio if a web build is tested.
### Acceptance checks
- Muted play remains completable.
- Platform and known audio limitations are named in the readme.
**Submit:** Audio accessibility report and updated readme.
**Question:** Does successful desktop playback prove browser autoplay will work?
**Support:** Use one short teacher-provided original sound or a privately recorded tap. Keep volume modest and retain text cues. Start with the first assigned task and re-run its acceptance test before adding the remaining feature.
**Optional extension:** Compare two sound choices with the same loudness and explain which better communicates the event. Document one changed parameter, your prediction, and the observed effect; optional, not required for completion.
**Optional free reading:** [Your first 2D game](https://docs.godotengine.org/en/stable/getting_started/first_2d_game/index.html), [Exporting for the Web](https://docs.godotengine.org/en/stable/tutorials/export/exporting_for_web.html)
---
