Week 33 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 33 — Content and alpha
## VGC-L161 — Build the promised content sequence
**Objective:** Arrange a beginning, practice and a concluding challenge.
**Time:** 55 minutes
### Instruction
Expand to the content amount in your proposal: a short route, several waves, six to ten story passages or a small set of resource goals. Use introduce, practice and combine as the sequence. Reuse the same tested mechanics; do not copy entire manager scripts for every room. Each content step needs a purpose and a reachable next step. Keep the target play length realistic. Remove padding that repeats a task without adding a new decision or understanding.
### Worked example
A pacing sequence introduces a rule safely, gives a practice opportunity, then combines it with a familiar challenge. Longer content is not automatically better content.
Scaffold C-STATES — Explicit game states and gated scoring
Setup: Attach to Node root StateLab with child Label Status. This is a standalone demonstrator; call start_round, add_points, finish_round from buttons or Remote Inspector. In a real game the manager owns this state. Additional Player and spawner scripts must also honor the manager’s state, or be disabled when finishing.
```gdscript
extends Node
enum Phase { TITLE, PLAY, WIN, LOSE }
var phase: Phase = Phase.TITLE
var score: int = 0
func _ready() -> void:
_show()
func start_round() -> void:
score = 0
phase = Phase.PLAY
_show()
func add_points(amount: int) -> void:
if phase != Phase.PLAY:
return
score += maxi(amount, 0)
_show()
func finish_round(won: bool) -> void:
if phase != Phase.PLAY:
return
phase = Phase.WIN if won else Phase.LOSE
_show()
func _show() -> void:
$Status.text = "State: %s | Score: %d" % [Phase.keys()[phase], score]
```
### Assignment
1. Build the planned content sequence and label each section’s purpose.
2. Play the route from start to ending without editor intervention.
### Acceptance checks
- Every section leads to a reachable next step.
- The sequence introduces requirements before combining them.
**Submit:** Content-complete checkpoint and pacing map.
**Question:** Why is repeating the same easy task ten times not necessarily useful progression?
**Support:** Add only the amount of content promised in the proposal. Reuse tested systems instead of duplicating new rule code per room. Start with the first assigned task and re-run its acceptance test before adding the remaining feature.
**Optional extension:** Create one optional challenge that does not block the main ending. 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)
---
## VGC-L162 — Replace placeholders with original coherent assets
**Objective:** Improve presentation without destabilizing rules.
**Time:** 55 minutes
### Instruction
Replace only the visuals and sounds needed to make the game understandable. Use original shapes, SVGs, writing and permitted local sounds. Keep physics colliders and authoritative state unchanged unless a mismatch requires an intentional fix. Update the asset-rights table. Compare screenshots before and after to confirm hazards, goals and controls remain readable. More detailed art can reduce clarity if it hides the collision boundary or competes with important feedback.
### Worked example
A pacing sequence introduces a rule safely, gives a practice opportunity, then combines it with a familiar challenge. Longer content is not automatically better content.
Scaffold C-DRAW — Draw an original geometric actor
Setup: Create Node2D root Actor. Attach actor.gd. Save Actor.tscn. A draw command uses coordinates relative to Actor. Set its Position to (200,150) in the Inspector. Change the blue color or white marker to make original art. No imported artwork is needed.
```gdscript
extends Node2D
func _draw() -> void:
draw_circle(Vector2.ZERO, 14.0, Color(0.15, 0.5, 0.9))
draw_line(Vector2(-8, 0), Vector2(8, 0), Color.WHITE, 3.0)
```
Scaffold C-TWEEN — Animate only a visual child
Setup: Create Node2D root Visual under a stationary physics actor, attach this script to Visual and keep its parent collider unchanged. Draw a small circle. A Tween interpolates properties over seconds; this is a visual pulse, not a flashing effect. Use modest scale changes and disable it in a reduced-motion setting.
```gdscript
extends Node2D
var pulse: Tween
func _draw() -> void:
draw_circle(Vector2.ZERO, 10.0, Color.GOLD)
func _ready() -> void:
pulse = create_tween().set_loops()
pulse.tween_property(self, "scale", Vector2(1.08, 1.08), 0.6)
pulse.tween_property(self, "scale", Vector2.ONE, 0.6)
func stop_motion() -> void:
if pulse != null:
pulse.kill()
scale = Vector2.ONE
```
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. Replace at least three meaningful placeholders with original or clearly permitted assets.
2. Audit rights and collision/visual agreement.
### Acceptance checks
- All assets have documented origin.
- New presentation does not obscure the gameplay categories.
**Submit:** Presentation checkpoint, asset credits and comparison screenshots.
**Question:** Why can more detailed artwork make a game harder to use?
**Support:** Add only the amount of content promised in the proposal. Reuse tested systems instead of duplicating new rule code per room. Start with the first assigned task and re-run its acceptance test before adding the remaining feature.
**Optional extension:** Create one optional challenge that does not block the main ending. 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)
---
## VGC-L163 — Finish comfort controls and clear instructions
**Objective:** Deliver tested alternatives rather than unverified claims.
**Time:** 55 minutes
### Instruction
Choose at least two appropriate comfort features such as mute, reduced motion, readable/enlarged text, pause or gentle mode. Keyboard navigation and non-color critical cues remain baseline goals. Test every instruction against actual controls. State unsupported devices or assistive technologies honestly. If an option resets at launch, document that; if it persists, validate the saved field. No player should need to provide personal information to select a setting.
### Worked example
A pacing sequence introduces a rule safely, gives a practice opportunity, then combines it with a familiar challenge. Longer content is not automatically better content.
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-TWEEN — Animate only a visual child
Setup: Create Node2D root Visual under a stationary physics actor, attach this script to Visual and keep its parent collider unchanged. Draw a small circle. A Tween interpolates properties over seconds; this is a visual pulse, not a flashing effect. Use modest scale changes and disable it in a reduced-motion setting.
```gdscript
extends Node2D
var pulse: Tween
func _draw() -> void:
draw_circle(Vector2.ZERO, 10.0, Color.GOLD)
func _ready() -> void:
pulse = create_tween().set_loops()
pulse.tween_property(self, "scale", Vector2(1.08, 1.08), 0.6)
pulse.tween_property(self, "scale", Vector2.ONE, 0.6)
func stop_motion() -> void:
if pulse != null:
pulse.kill()
scale = Vector2.ONE
```
Scaffold C-PAUSE — Pause with an always-processing resume control
Setup: Node2D World root has CanvasLayer HUD with Button Pause, plus normal gameplay children. Set Pause button Process > Mode to Always in Inspector; leave World and gameplay as Inherit/Pausable. Attach script to World; merge into its existing _ready if present. Signal callbacks still work from the always-processing button. Label text starts Pause.
```gdscript
extends Node2D
func _ready() -> void:
$HUD/Pause.pressed.connect(_toggle_pause)
func _toggle_pause() -> void:
get_tree().paused = not get_tree().paused
$HUD/Pause.text = "Resume" if get_tree().paused else "Pause"
```
### Assignment
1. Complete two comfort features and a concise controls/help screen.
2. Test each feature on/off plus a keyboard-only menu path.
### Acceptance checks
- Instructions match current bindings.
- Comfort combinations preserve essential information and completion.
**Submit:** Comfort-complete checkpoint and option matrix.
**Question:** Why should a settings label explain its effect?
**Support:** Add only the amount of content promised in the proposal. Reuse tested systems instead of duplicating new rule code per room. Start with the first assigned task and re-run its acceptance test before adding the remaining feature.
**Optional extension:** Create one optional challenge that does not block the main ending. 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)
---
## VGC-L164 — Freeze the alpha and inventory known issues
**Objective:** Stop adding features and make defects traceable.
**Time:** 55 minutes
### Instruction
Alpha here means the planned minimum and content are present, though bugs may remain. Name the artifact alpha1, restore-test it and freeze new features. Create an issue list with IDs, severity, reproduction and status. Separate blockers from polish. Ideas that arrive now go to a future list, not directly into the build. This reduces the chance that a late untested feature undermines the complete loop. A known issue is not shameful; hiding it prevents effective repair.
### Worked example
A pacing sequence introduces a rule safely, gives a practice opportunity, then combines it with a familiar challenge. Longer content is not automatically better content.
Scaffold C-TESTS — A tiny pure-function test harness
Setup: Attach to Node TestLab. If using command line, create a separate SceneTree harness rather than running this Node script with --script. Run current TestLab scene in editor; assert reports a failed condition in Debugger. No external test framework or package is needed.
```gdscript
extends Node
func bounded_score(old_score: int, change: int) -> int:
return clampi(old_score + change, 0, 999)
func _ready() -> void:
assert(bounded_score(10, 2) == 12)
assert(bounded_score(0, -3) == 0)
assert(bounded_score(998, 9) == 999)
print("3 score checks passed")
```
### Assignment
1. Package alpha1 and create an issue list with at least three observations.
2. Mark feature freeze and future ideas separately.
### Acceptance checks
- The artifact is reproducible and versioned.
- Every blocker has clear steps and expected versus actual behavior.
**Submit:** Alpha source artifact, issue tracker document and future list.
**Question:** Does alpha mean every bug is fixed?
**Support:** Add only the amount of content promised in the proposal. Reuse tested systems instead of duplicating new rule code per room. Start with the first assigned task and re-run its acceptance test before adding the remaining feature.
**Optional extension:** Create one optional challenge that does not block the main ending. 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)
---
## VGC-L165 — Perform a full alpha regression
**Objective:** Check interaction among content, systems and packaging.
**Time:** 55 minutes
### Instruction
Run all twelve acceptance tests plus one test for each content section and comfort option. Use a restored alpha copy. Look for interactions: a longer passage may break layout, a new room may invalidate a saved checkpoint, or a new sound may ignore mute. Record the version for every result. Fix only high-priority defects in a separate beta candidate. Do not alter the frozen alpha artifact so later comparisons remain meaningful.
### Worked example
A pacing sequence introduces a rule safely, gives a practice opportunity, then combines it with a familiar challenge. Longer content is not automatically better content.
Scaffold C-TESTS — A tiny pure-function test harness
Setup: Attach to Node TestLab. If using command line, create a separate SceneTree harness rather than running this Node script with --script. Run current TestLab scene in editor; assert reports a failed condition in Debugger. No external test framework or package is needed.
```gdscript
extends Node
func bounded_score(old_score: int, change: int) -> int:
return clampi(old_score + change, 0, 999)
func _ready() -> void:
assert(bounded_score(10, 2) == 12)
assert(bounded_score(0, -3) == 0)
assert(bounded_score(998, 9) == 999)
print("3 score checks passed")
```
### Assignment
1. Run the full alpha suite and classify failures.
2. Choose the next three fixes by impact and dependency.
### Acceptance checks
- The report distinguishes core, content, comfort and packaging tests.
- Fix priorities cite actual failures.
**Submit:** Alpha regression report and beta repair plan.
**Question:** Why keep the frozen alpha after making a beta?
**Support:** Add only the amount of content promised in the proposal. Reuse tested systems instead of duplicating new rule code per room. Start with the first assigned task and re-run its acceptance test before adding the remaining feature.
**Optional extension:** Create one optional challenge that does not block the main ending. 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)
---
