Video Game Design and Coding · PLECK lesson

PLECK lesson 54 · suggested week 11, day 4

Reveal a puzzle through feedback

Objective. Explain failure without giving the whole answer immediately.

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.

Booleans, truth tables, inventory flags and testable conditions

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-L053.

A locked gate should tell the player enough to make a next decision. Distinguish “key missing,” “lever off,” and “alarm active” rather than showing the same vague failure. You may reveal one unmet condition at a time in a documented priority order. Do not punish experimentation with a permanent unwinnable state. Write a hint ladder: a gentle reminder, a more specific clue and an explicit solution available on request. Hints are an accessibility feature, not evidence that the learner failed.

Worked example

A separate practice door might require badge OR helper_present. Test each Boolean combination on paper before using the function to show an Open button. Scaffold C-DIALOGUE — Data-driven branching dialogue without personal data Setup: Create Control root Dialogue with VBoxContainer Box containing Label Line and Buttons A and B. Set Box anchors to full rect; Line autowrap if needed. Attach script to Dialogue. Data keys are fictional scene IDs. All three screens can fit in 640x360. This is a self-contained example; replace story text in the assignment. ```gdscript extends Control var page: String = "start" var story: Dictionary = { "start": {"text": "Two paths enter the archive.", "choices": [["Ask the keeper", "keeper"], ["Read a sign", "sign"]]}, "keeper": {"text": "The keeper offers a map.", "choices": [["Return", "start"]]}, "sign": {"text": "Quiet room to the east.", "choices": [["Return", "start"]]} } func _ready() -> void: $Box/A.pressed.connect(_choose.bind(0)) $Box/B.pressed.connect(_choose.bind(1)) _show() func _show() -> void: var entry: Dictionary = story[page] $Box/Line.text = entry["text"] var buttons: Array[Button] = [$Box/A, $Box/B] for i in range(buttons.size()): buttons[i].visible = i < entry["choices"].size() if buttons[i].visible: buttons[i].text = entry["choices"][i][0] $Box/A.grab_focus() func _choose(index: int) -> void: var choices: Array = story[page]["choices"] if index < 0 or index >= choices.size(): return page = str(choices[index][1]) _show() ``` 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") ```

Data-driven branching dialogue without personal data

GDScript (Godot 4, not Scratch, Python, JavaScript or C#). Scaffold C-DIALOGUE. Copy starts from this text. The desk does not run it.

Scene and node setup

Create Control root Dialogue with VBoxContainer Box containing Label Line and Buttons A and B. Set Box anchors to full rect; Line autowrap if needed. Attach script to Dialogue. Data keys are fictional scene IDs. All three screens can fit in 640x360. This is a self-contained example; replace story text in the assignment.

extends Control
var page: String = "start"
var story: Dictionary = {
    "start": {"text": "Two paths enter the archive.", "choices": [["Ask the keeper", "keeper"], ["Read a sign", "sign"]]},
    "keeper": {"text": "The keeper offers a map.", "choices": [["Return", "start"]]},
    "sign": {"text": "Quiet room to the east.", "choices": [["Return", "start"]]}
}
func _ready() -> void:
    $Box/A.pressed.connect(_choose.bind(0))
    $Box/B.pressed.connect(_choose.bind(1))
    _show()
func _show() -> void:
    var entry: Dictionary = story[page]
    $Box/Line.text = entry["text"]
    var buttons: Array[Button] = [$Box/A, $Box/B]
    for i in range(buttons.size()):
        buttons[i].visible = i < entry["choices"].size()
        if buttons[i].visible:
            buttons[i].text = entry["choices"][i][0]
    $Box/A.grab_focus()
func _choose(index: int) -> void:
    var choices: Array = story[page]["choices"]
    if index < 0 or index >= choices.size():
        return
    page = str(choices[index][1])
    _show()

Checks to run in the editor

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 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

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.

Reveal a puzzle through feedback — evidence task

  1. 1. Implement distinct gate feedback and a three-step hint ladder.
  2. 2. Test each unmet condition and the solved state.

Deliverable. Gate-feedback table, hint text and project.

Acceptance checks

Understanding question. Why avoid a permanently consumed key when the only gate remains locked?

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. Use the C-PUZZLE pure function and a paper truth table before attaching conditions to UI. Start with the first assigned task and re-run its acceptance test before adding the remaining feature.

Optional extra. Find a logically equivalent expression and verify all eight truth-table rows. Document one changed parameter, your prediction, and the observed effect; optional, not required for completion.

Name ____________________ Date ____________________