Video Game Design and Coding · PLECK lesson
PLECK lesson 152 · suggested week 31, day 2
Complete the central rule set
Objective. Implement every required rule without adding optional mechanics.
Godot Engine Standard desktop editor 4.7.2-stable, GDScript (Godot 4), Compatibility renderer. Headless Godot 4.7.2.stable.official.ed1daf0bf passed 106 assertions on the supplied scaffolds, including malformed JSON saves. Audio used the Dummy driver and a synthetic WAV, not a speaker. The visual editor, browser export, and signed-in submission were not tested. The desk still does not run a student's own upload.
About 55 minutes. The due date is chosen by a parent.
Input robustness, rule completion, challenge and progress
Suggested pace: Recall and predict 5 min; Read instruction and scaffold 12 min; Build or design the assigned artifact 25 min; Run acceptance tests 8 min; Explain and checkpoint 5 min.
Materials: Godot Standard 4.7.2 desktop editor (GDScript, Compatibility renderer), Local course folder and prior checkpoint, No paid assets or public account required.
Comes after VGC-L151.
List the minimum rules from your contract and compare them with actual code. Finish the missing one with the highest dependency impact. For a multi-resource rule, validate all costs before mutation; for collection, enforce once-only rewards; for narrative, validate target IDs; for an arcade game, gate events by phase. Add a pure helper where the decision can be tested independently. Keep the rule’s authoritative data in the owner named by your architecture.
Worked example
A repeat-input test might press a one-time choice rapidly. The accepted event happens once, while later calls observe the changed state and do nothing. Scaffold C-PUZZLE — A testable gate rule Setup: Create Node root GateLab and attach this script. The pure gate_open function does not read input or change a scene. A level can call it with its inventory and lever state. Assertions run on start. For the assignment write additional tests before changing the rule. ```gdscript extends Node func gate_open(has_key: bool, lever_on: bool, alarm_on: bool) -> bool: return has_key and lever_on and not alarm_on func _ready() -> void: assert(gate_open(true, true, false)) assert(not gate_open(false, true, false)) assert(not gate_open(true, false, false)) assert(not gate_open(true, true, true)) print("Gate checks passed") ``` Scaffold C-INVENTORY — Dictionary inventory with guarded spending Setup: Attach to Node InventoryLab for standalone testing. In a real level put the same functions on its inventory node and update UI after successful calls. Item IDs are short fixed strings, never a player’s name. A key represents one item type and its integer value is the quantity. ```gdscript extends Node var items: Dictionary = {"seed": 0, "water": 0} func add_item(id: String, amount: int = 1) -> bool: if not items.has(id) or amount <= 0: return false items[id] = int(items[id]) + amount return true func spend(id: String, amount: int = 1) -> bool: if not items.has(id) or amount <= 0 or int(items[id]) < amount: return false items[id] = int(items[id]) - amount return true func _ready() -> void: assert(add_item("seed", 2)) assert(spend("seed", 1)) assert(not spend("seed", 2)) assert(items["seed"] == 1) ``` 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") ```
A testable gate rule
GDScript (Godot 4, not Scratch, Python, JavaScript or C#). Scaffold C-PUZZLE. Copy starts from this text. The desk does not run it.
Scene and node setup
Create Node root GateLab and attach this script. The pure gate_open function does not read input or change a scene. A level can call it with its inventory and lever state. Assertions run on start. For the assignment write additional tests before changing the rule.
extends Node
func gate_open(has_key: bool, lever_on: bool, alarm_on: bool) -> bool:
return has_key and lever_on and not alarm_on
func _ready() -> void:
assert(gate_open(true, true, false))
assert(not gate_open(false, true, false))
assert(not gate_open(true, false, false))
assert(not gate_open(true, true, true))
print("Gate checks passed")
Checks to run in the editor
- Four supplied assertions pass.
- A complete truth table contains eight input combinations.
Native Godot 4.7.2.stable.official.ed1daf0bf headless compile and representative node-tree/runtime tests passed; see native-qa-results.json. Visual UI, audible output, exports and website submission still need separate checks.
Dictionary inventory with guarded spending
GDScript (Godot 4, not Scratch, Python, JavaScript or C#). Scaffold C-INVENTORY. Copy starts from this text. The desk does not run it.
Scene and node setup
Attach to Node InventoryLab for standalone testing. In a real level put the same functions on its inventory node and update UI after successful calls. Item IDs are short fixed strings, never a player’s name. A key represents one item type and its integer value is the quantity.
extends Node
var items: Dictionary = {"seed": 0, "water": 0}
func add_item(id: String, amount: int = 1) -> bool:
if not items.has(id) or amount <= 0:
return false
items[id] = int(items[id]) + amount
return true
func spend(id: String, amount: int = 1) -> bool:
if not items.has(id) or amount <= 0 or int(items[id]) < amount:
return false
items[id] = int(items[id]) - amount
return true
func _ready() -> void:
assert(add_item("seed", 2))
assert(spend("seed", 1))
assert(not spend("seed", 2))
assert(items["seed"] == 1)
Checks to run in the editor
- Spending more than owned returns false and does not change inventory.
- Unknown IDs and nonpositive amounts are rejected.
Native Godot 4.7.2.stable.official.ed1daf0bf headless compile and representative node-tree/runtime tests passed; see native-qa-results.json. Visual UI, audible output, exports and website submission still need separate checks.
A tiny pure-function test harness
GDScript (Godot 4, not Scratch, Python, JavaScript or C#). Scaffold C-TESTS. Copy starts from this text. The desk does not run it.
Scene and node 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.
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")
Checks to run in the editor
- All three assertions pass.
- Intentionally change expected 12 to 13 and observe a failure, then restore.
Native Godot 4.7.2.stable.official.ed1daf0bf headless compile and representative node-tree/runtime tests passed; see native-qa-results.json. Visual UI, audible output, exports and website submission still need separate checks.
Complete the central rule set — evidence task
- 1. Finish the central rule and add three focused tests.
- 2. Update the rule-to-code map with actual function names.
Deliverable. Rule-complete checkpoint and rule/code/test map.
Acceptance checks
- VGC-L152-T1. Each required rule has a code location and test.
- VGC-L152-T2. No rule is enforced only by label text or visual button state.
Understanding question. What is the risk of enforcing a rule only in the interface?
Include a downloadable project ZIP with project.godot, .tscn, .gd and original asset files when code changes. A private, teacher-accessible download link to that ZIP is equivalent. Screenshots or a playthrough do not replace editable source.
If this is still shaky. Work on one task-board item at a time and checkpoint after each passing test. Do not expand the room count yet. Start with the first assigned task and re-run its acceptance test before adding the remaining feature.
Optional extra. Add a harmless alternate input or optional route after required mechanics pass. Document one changed parameter, your prediction, and the observed effect; optional, not required for completion.
- Your first 2D game
Free public tutorial; no account; external asset download is optional, not used by this course.
· Opening this link does not submit the lesson.
Name ____________________ Date ____________________