#!/usr/bin/env python3 """Materialize 32 original in-session Codex-authored games; no model/API call. This is authorship tooling, not a claim of executed Godot validation. Admission requires the separate Linux engine import and full 60-second runtime check. """ import hashlib import json from pathlib import Path import sys ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT / "src")) from vibegame.project import parse_project, project_sha256 PROJECT = '''config_version=5 [application] config/name="%s" run/main_scene="res://main.tscn" [display] window/size/viewport_width=960 window/size/viewport_height=640 [rendering] renderer/rendering_method="gl_compatibility" environment/defaults/default_clear_color=Color(0.035, 0.047, 0.09, 1) ''' SCENE = '''[gd_scene load_steps=2 format=3] [ext_resource type="Script" path="res://main.gd" id="1"] [node name="Game" type="Node2D"] script = ExtResource("1") ''' HELPERS = ''' func text_at(s: String, p: Vector2, size: int = 22, color: Color = Color.WHITE) -> void: \tdraw_string(ThemeDB.fallback_font, p, s, HORIZONTAL_ALIGNMENT_LEFT, -1, size, color) func backdrop(title: String, controls: String) -> void: \tdraw_rect(Rect2(0, 0, 960, 88), Color("121d35")) \ttext_at(title, Vector2(24, 35), 27, Color("5ef2d0")) \ttext_at(controls, Vector2(24, 68), 17, Color("c1cfe8")) ''' GAMES = {} GAMES[21] = ("Four Floor Courier", '''extends Node2D var people: Array[Dictionary] = [] var cabin: float = 520.0 var remaining: float = 100.0 var delivered: int = 0 var outcome: String = "" func _ready() -> void: reset() func reset() -> void: people.clear() for i in range(8): people.append({"floor": i % 4, "dest": (i % 4 + 1 + i / 4) % 4, "state": 0}) cabin = 520.0 remaining = 100.0 delivered = 0 outcome = "" func _process(dt: float) -> void: if Input.is_physical_key_pressed(KEY_R): reset() if outcome == "": remaining -= dt cabin = clampf(cabin + Input.get_axis("ui_up", "ui_down") * 170.0 * dt, 160, 520) for floor in range(4): if absf(cabin - (520.0 - floor * 120.0)) < 9.0: for p in people: if p["state"] == 1 and p["dest"] == floor: p["state"] = 2 delivered += 1 var onboard: int = 0 for p in people: if p["state"] == 1: onboard += 1 for p in people: if p["state"] == 0 and p["floor"] == floor and onboard < 2: p["state"] = 1 onboard += 1 if delivered == 8: outcome = "All eight passengers delivered! R: new shift" elif remaining <= 0: outcome = "Shift ended before all deliveries. R: retry" queue_redraw() func _draw() -> void: backdrop("FOUR FLOOR COURIER", "Up / Down: elevator | Automatic pickup and drop-off | Capacity 2 | R: restart") for floor in range(4): var y: float = 520.0 - floor * 120.0 draw_line(Vector2(90, y + 22), Vector2(750, y + 22), Color("46617d"), 3) text_at("FLOOR %d" % (floor + 1), Vector2(760, y), 20) draw_rect(Rect2(447, 115, 86, 452), Color("30455f"), false, 3) draw_rect(Rect2(452, cabin - 44, 76, 66), Color("5ef2d0"), false, 4) var seat: int = 0 for i in range(people.size()): var p: Dictionary = people[i] if p["state"] == 2: continue var pos: Vector2 = Vector2(180 + (i / 4) * 75, 520 - int(p["floor"]) * 120) if p["state"] == 1: pos = Vector2(468 + seat * 32, cabin) seat += 1 draw_circle(pos, 12, Color("ffcd6b")) text_at(str(int(p["dest"]) + 1), pos + Vector2(-6, -20), 20) text_at("Delivered %d / 8 Time %d" % [delivered, ceili(remaining)], Vector2(28, 606)) if outcome != "": text_at(outcome, Vector2(170, 110), 23) ''') GAMES[22] = ("Counterweight", '''extends Node2D var balls: Array[float] = [-100.0, 0.0, 100.0] var speeds: Array[float] = [10.0, -14.0, 6.0] var weight: float = 0.0 var angle: float = 0.0 var spin: float = 0.0 var timer: float = 30.0 var outcome: String = "" func _ready() -> void: reset() func reset() -> void: balls = [-100.0, 0.0, 100.0] speeds = [10.0, -14.0, 6.0] weight = 0.0 angle = 0.0 spin = 0.0 timer = 30.0 outcome = "" func _process(dt: float) -> void: if Input.is_physical_key_pressed(KEY_R): reset() if outcome == "": timer -= dt weight = clampf(weight + Input.get_axis("ui_left", "ui_right") * 160.0 * dt, -195, 195) var torque: float = (balls[0] + balls[1] + balls[2] + weight * 3.0) * 0.0007 spin += (torque - angle * 0.5 - spin * 1.5) * dt angle = clampf(angle + spin * dt, -0.6, 0.6) for i in range(3): speeds[i] += (sin(angle) * 220.0 - speeds[i] * 0.08) * dt balls[i] += speeds[i] * dt if absf(balls[i]) > 220: outcome = "A ball fell! Move the counterweight earlier. R: retry" if timer <= 0 and outcome == "": outcome = "Balanced for thirty seconds! R: play again" queue_redraw() func point(x: float, y: float = 0.0) -> Vector2: return Vector2(480, 350) + Vector2(x, y).rotated(angle) func _draw() -> void: backdrop("COUNTERWEIGHT", "Left / Right: move the gold weight | Keep all three balls aboard for 30 seconds | R: restart") draw_colored_polygon(PackedVector2Array([Vector2(450, 460), Vector2(510, 460), Vector2(480, 350)]), Color("46617d")) draw_line(point(-230), point(230), Color("c1cfe8"), 12) for i in range(3): draw_circle(point(balls[i], -20), 14, Color.from_hsv(i * 0.2 + 0.45, 0.7, 1.0)) draw_circle(point(weight, 28), 18, Color("ffcd6b")) text_at("Time left %.1f Plank tilt %.1f degrees" % [maxf(timer, 0), rad_to_deg(angle)], Vector2(180, 530)) if outcome != "": text_at(outcome, Vector2(130, 580), 23) ''') GAMES[23] = ("Two Pan Kitchen", '''extends Node2D var heat: Array[float] = [0.0, 0.0] var cooking: Array[bool] = [false, false] var plates: int = 0 var mistakes: int = 0 var time_left: float = 60.0 var message: String = "Click a cold pan to begin. Click again to serve." var outcome: String = "" func pan_rect(i: int) -> Rect2: return Rect2(190 + i * 340, 170, 220, 230) func reset() -> void: heat = [0.0, 0.0] cooking = [false, false] plates = 0 mistakes = 0 time_left = 60.0 outcome = "" message = "Click a cold pan to begin. Click again to serve." func _input(event: InputEvent) -> void: if event is InputEventKey and event.pressed and event.keycode == KEY_R: reset() if outcome != "": return if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT: for i in range(2): if pan_rect(i).has_point(event.position): if not cooking[i]: cooking[i] = true elif heat[i] >= 65 and heat[i] <= 85: plates += 1 message = "Perfectly served!" cooking[i] = false heat[i] = 0 else: mistakes += 1 message = "Too cold or too hot!" cooking[i] = false heat[i] = 0 func _process(dt: float) -> void: if outcome == "": time_left -= dt for i in range(2): if cooking[i]: heat[i] += (20.0 + i * 7.0) * dt if heat[i] >= 100: mistakes += 1 cooking[i] = false heat[i] = 0 message = "Burned!" if plates >= 6: outcome = "Six plates served. Kitchen complete!" elif mistakes >= 3 or time_left <= 0: outcome = "Kitchen closed. R: try another shift" queue_redraw() func _draw() -> void: backdrop("TWO PAN KITCHEN", "Click pan: start / serve | Serve between 65 and 85 degrees | Six plates, fewer than 3 mistakes | R: restart") for i in range(2): var r: Rect2 = pan_rect(i) draw_rect(r, Color("23344c")) draw_circle(r.position + Vector2(110, 90), 67, Color("ff875b") if cooking[i] else Color("718199")) text_at("PAN %d" % (i + 1), r.position + Vector2(65, 95)) draw_rect(Rect2(r.position + Vector2(10, 174), Vector2(200, 26)), Color("142037")) draw_rect(Rect2(r.position + Vector2(140, 174), Vector2(40, 26)), Color("25855f")) draw_line(r.position + Vector2(10 + heat[i] * 2, 170), r.position + Vector2(10 + heat[i] * 2, 205), Color.WHITE, 4) text_at("%.0f degrees" % heat[i], r.position + Vector2(43, 225)) text_at("Plates %d / 6 Mistakes %d / 3 Time %d" % [plates, mistakes, ceili(maxf(0, time_left))], Vector2(220, 470)) text_at(message, Vector2(180, 520)) text_at(outcome, Vector2(170, 575), 25, Color("ffcd6b")) ''') GAMES[24] = ("Echo Pads", '''extends Node2D var sequence: Array[int] = [0, 2] var showing: bool = true var show_clock: float = -0.8 var response: int = 0 var flash: int = -1 var flash_time: float = 0.0 var outcome: String = "" func reset() -> void: sequence = [0, 2] showing = true show_clock = -0.8 response = 0 flash = -1 outcome = "" func pad(i: int) -> Rect2: return Rect2(200 + (i % 2) * 300, 160 + (i / 2) * 175, 260, 145) func press(i: int) -> void: if showing or outcome != "": return flash = i flash_time = 0.25 if i != sequence[response]: outcome = "Wrong pad. R: listen to a new round" return response += 1 if response == sequence.size(): if sequence.size() == 8: outcome = "Eight-note sequence remembered! R: replay" else: sequence.append(randi_range(0, 3)) showing = true show_clock = -1.0 response = 0 func _input(event: InputEvent) -> void: if event is InputEventKey and event.pressed and not event.echo: if event.keycode == KEY_R: reset() for i in range(4): if event.keycode == KEY_1 + i: press(i) if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT: for i in range(4): if pad(i).has_point(event.position): press(i) func _process(dt: float) -> void: if outcome == "" and showing: show_clock += dt var index: int = floori(show_clock / 0.8) flash = -1 if index >= sequence.size(): showing = false elif index >= 0 and fmod(show_clock, 0.8) < 0.5: flash = sequence[index] elif not showing: flash_time -= dt if flash_time <= 0: flash = -1 queue_redraw() func _draw() -> void: backdrop("ECHO PADS", "Watch the flashes, then repeat at any speed | Click pads or press 1 / 2 / 3 / 4 | R: restart") for i in range(4): draw_rect(pad(i), Color.from_hsv(i * 0.23, 0.7, 1.0 if flash == i else 0.35)) text_at(str(i + 1), pad(i).position + Vector2(116, 90), 46) text_at("WATCH" if showing else "YOUR TURN - no timing requirement", Vector2(230, 125), 25) text_at("Sequence length %d / 8 Entered %d" % [sequence.size(), response], Vector2(240, 555)) text_at(outcome, Vector2(180, 610), 23, Color("ffcd6b")) ''') GAMES[25] = ("Crane Stack", '''extends Node2D var stack: Array[Rect2] = [] var crane: float = 180.0 var direction: float = 1.0 var falling: bool = false var package_pos: Vector2 = Vector2.ZERO var velocity: float = 0.0 var outcome: String = "" func reset() -> void: stack.clear() crane = 180 direction = 1 falling = false outcome = "" func _input(event: InputEvent) -> void: if event is InputEventKey and event.pressed and not event.echo: if event.keycode == KEY_R: reset() if event.keycode == KEY_SPACE and not falling and outcome == "": falling = true package_pos = Vector2(crane - 58, 130) velocity = 0 func _process(dt: float) -> void: if outcome == "": if not falling: crane += direction * (190 + stack.size() * 23) * dt if crane < 120 or crane > 840: direction *= -1 crane = clampf(crane, 120, 840) else: velocity += 570 * dt package_pos.y += velocity * dt var target: float = 550 - stack.size() * 52 if package_pos.y + 52 >= target: package_pos.y = target - 52 var overlap: float = 116 if not stack.is_empty(): overlap = minf(package_pos.x + 116, stack[-1].end.x) - maxf(package_pos.x, stack[-1].position.x) if package_pos.x < 350 or package_pos.x + 116 > 610 or overlap < 78: outcome = "Unstable placement! Stay inside the outline and overlap. R: retry" else: stack.append(Rect2(package_pos, Vector2(116, 52))) if stack.size() == 6: outcome = "Six stable packages! Tower complete. R: replay" falling = false queue_redraw() func _draw() -> void: backdrop("CRANE STACK", "Space: release package | Stay inside the tower and overlap the previous box | R: restart") draw_rect(Rect2(350, 208, 260, 344), Color("5ef2d0"), false, 3) draw_line(Vector2(80, 550), Vector2(880, 550), Color("c1cfe8"), 4) draw_line(Vector2(100, 115), Vector2(860, 115), Color("46617d"), 5) for i in range(stack.size()): draw_rect(stack[i], Color.from_hsv(i * 0.1, 0.6, 0.95)) draw_rect(stack[i], Color.WHITE, false, 2) if outcome == "": var pos: Vector2 = package_pos if falling else Vector2(crane - 58, 130) draw_rect(Rect2(pos, Vector2(116, 52)), Color("ffcd6b")) if not falling: draw_line(Vector2(crane, 115), Vector2(crane, 130), Color.WHITE, 3) text_at("Stable placements %d / 6" % stack.size(), Vector2(310, 590)) text_at(outcome, Vector2(75, 625), 20) ''') GAMES[26] = ("Trail Territory", '''extends Node2D const W: int = 14 const H: int = 10 const STEP: int = 38 var owned: Dictionary = {} var trail: Array[Vector2i] = [] var player: Vector2i = Vector2i(2, 5) var enemy: Vector2i = Vector2i(11, 5) var move_clock: float = 0.0 var enemy_clock: float = 0.0 var time_left: float = 90.0 var outcome: String = "" func _ready() -> void: reset() func reset() -> void: owned.clear() trail.clear() for y in range(H): for x in range(3): owned[Vector2i(x, y)] = true player = Vector2i(2, 5) enemy = Vector2i(11, 5) move_clock = 0 enemy_clock = 0 time_left = 90 outcome = "" func inside(p: Vector2i) -> bool: return p.x >= 0 and p.y >= 0 and p.x < W and p.y < H func reconnect() -> void: for p in trail: owned[p] = true trail.clear() var reached: Dictionary = {enemy: true} var queue: Array[Vector2i] = [enemy] var cursor: int = 0 while cursor < queue.size(): var cell: Vector2i = queue[cursor] cursor += 1 for direction in [Vector2i.LEFT, Vector2i.RIGHT, Vector2i.UP, Vector2i.DOWN]: var next: Vector2i = cell + direction if inside(next) and not owned.has(next) and not reached.has(next): reached[next] = true queue.append(next) for y in range(H): for x in range(W): var cell: Vector2i = Vector2i(x, y) if not reached.has(cell): owned[cell] = true if owned.size() >= 92: outcome = "Territory secured! R: another expedition" func _process(dt: float) -> void: if Input.is_physical_key_pressed(KEY_R): reset() if outcome == "": time_left -= dt move_clock -= dt var direction: Vector2i = Vector2i.ZERO if Input.is_action_pressed("ui_left"): direction = Vector2i.LEFT elif Input.is_action_pressed("ui_right"): direction = Vector2i.RIGHT elif Input.is_action_pressed("ui_up"): direction = Vector2i.UP elif Input.is_action_pressed("ui_down"): direction = Vector2i.DOWN if move_clock <= 0 and direction != Vector2i.ZERO: move_clock = 0.13 var next: Vector2i = player + direction if inside(next): if trail.has(next): outcome = "You crossed your own trail. R: retry" else: player = next if owned.has(player): if not trail.is_empty(): reconnect() else: trail.append(player) enemy_clock -= dt if enemy_clock <= 0: enemy_clock = 0.22 var directions: Array[Vector2i] = [Vector2i.LEFT, Vector2i.RIGHT, Vector2i.UP, Vector2i.DOWN] var next: Vector2i = enemy + directions[randi_range(0, 3)] if inside(next) and not owned.has(next): enemy = next if trail.has(enemy): outcome = "Enemy cut the active trail! R: retry" elif time_left <= 0: outcome = "Time expired. R: retry" queue_redraw() func center(p: Vector2i) -> Vector2: return Vector2(215, 155) + Vector2(p) * STEP + Vector2.ONE * STEP * 0.5 func _draw() -> void: backdrop("TRAIL TERRITORY", "Arrows: step | Leave blue safety, draw a loop, reconnect | Avoid the red enemy | R: restart") for y in range(H): for x in range(W): var p: Vector2i = Vector2i(x, y) var color: Color = Color("287a94") if owned.has(p) else Color("182439") if trail.has(p): color = Color("ffcd6b") draw_rect(Rect2(center(p) - Vector2.ONE * 18, Vector2(36, 36)), color) draw_circle(center(enemy), 13, Color("ff6176")) draw_circle(center(player), 11, Color.WHITE) text_at("Claim %d / 92 tiles Time %d" % [owned.size(), ceili(maxf(0, time_left))], Vector2(240, 575)) text_at(outcome, Vector2(220, 620), 23) ''') GAMES[27] = ("Charge Duel", '''extends Node2D var hp: int = 5 var foe_hp: int = 5 var energy: int = 2 var foe_energy: int = 2 var rounds: int = 0 var report: String = "Choose an action. The opponent commits without seeing your choice." var outcome: String = "" var names: Array[String] = ["ATTACK", "BLOCK", "CHARGE"] func reset() -> void: hp = 5 foe_hp = 5 energy = 2 foe_energy = 2 rounds = 0 report = "Attack costs 1 energy. Block defeats attack. Charge restores 1." outcome = "" func button(i: int) -> Rect2: return Rect2(150 + i * 230, 420, 200, 72) func choose(action: int) -> void: if outcome != "": return if action == 0 and energy == 0: report = "No energy: block or charge first." return var rival: int = 2 if foe_energy == 0 else randi_range(0, 2) rounds += 1 if action == 0: energy -= 1 if rival == 0: foe_energy -= 1 if action == 2: energy = mini(energy + 1, 4) if rival == 2: foe_energy = mini(foe_energy + 1, 4) if action == 0: if rival == 1: hp -= 1 else: foe_hp -= 1 if rival == 0: if action == 1: foe_hp -= 1 else: hp -= 1 report = "You: %s Rival: %s Round %d" % [names[action], names[rival], rounds] if hp <= 0 and foe_hp <= 0: outcome = "Mutual knockout! R: rematch" elif foe_hp <= 0: outcome = "You win the duel! R: rematch" elif hp <= 0: outcome = "Rival wins. R: rematch" func _input(event: InputEvent) -> void: if event is InputEventKey and event.pressed and not event.echo: if event.keycode == KEY_R: reset() for i in range(3): if event.keycode == KEY_1 + i: choose(i) if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT: for i in range(3): if button(i).has_point(event.position): choose(i) queue_redraw() func _draw() -> void: backdrop("CHARGE DUEL", "Click an action or press 1 / 2 / 3 | Attack beats charge; block counters attack | R: restart") draw_circle(Vector2(280, 235), 70, Color("5ef2d0")) draw_circle(Vector2(690, 235), 70, Color("ff6176")) text_at("YOU", Vector2(252, 244), 25, Color("121d35")) text_at("RIVAL", Vector2(650, 244), 25) text_at("HP %d Energy %d / 4" % [hp, energy], Vector2(180, 345)) text_at("HP %d Energy %d / 4" % [foe_hp, foe_energy], Vector2(570, 345)) for i in range(3): draw_rect(button(i), Color("334966")) text_at("%d: %s" % [i + 1, names[i]], button(i).position + Vector2(18, 45)) text_at(report, Vector2(70, 550), 20) text_at(outcome, Vector2(280, 610), 26, Color("ffcd6b")) ''') GAMES[28] = ("Binary Wires", '''extends Node2D var lamps: int = 0 var target: int = 5 var masks: Array[int] = [3, 6, 7] var moves: int = 0 var puzzles: int = 0 var outcome: String = "" func reset() -> void: lamps = 0 target = 5 moves = 0 puzzles = 0 outcome = "" func toggle(i: int) -> void: if outcome != "": return lamps = lamps ^ masks[i] moves += 1 if lamps == target: puzzles += 1 if puzzles == 4: outcome = "Four circuits repaired! R: restart" else: lamps = target target = (target + 3) % 8 moves = 0 elif moves >= 6: outcome = "Six moves used. Circuit locked! R: retry" func switch_rect(i: int) -> Rect2: return Rect2(150 + 240 * i, 390, 180, 75) func _input(event: InputEvent) -> void: if event is InputEventKey and event.pressed and not event.echo: if event.keycode == KEY_R: reset() for i in range(3): if event.keycode == KEY_1 + i: toggle(i) if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT: for i in range(3): if switch_rect(i).has_point(event.position): toggle(i) queue_redraw() func _draw() -> void: backdrop("BINARY WIRES", "Click switches or press 1 / 2 / 3 | Match the target in at most six toggles | R: restart") text_at("TARGET", Vector2(45, 174), 22) text_at("LAMPS", Vector2(45, 278), 22) for j in range(3): var x: float = 240 + 240 * j draw_circle(Vector2(x, 165), 24, Color("5ef2d0") if target & (1 << j) else Color("26394e")) text_at(str((target >> j) & 1), Vector2(x - 6, 172), 21, Color.WHITE) draw_circle(Vector2(x, 265), 35, Color("ffcd6b") if lamps & (1 << j) else Color("26394e")) text_at(str((lamps >> j) & 1), Vector2(x - 7, 273), 24, Color.WHITE) for i in range(3): for j in range(3): if masks[i] & (1 << j): draw_line(Vector2(240 + 240 * i, 390), Vector2(240 + 240 * j, 305), Color.from_hsv(i * 0.24, 0.5, 0.6), 2) draw_rect(switch_rect(i), Color("334966")) text_at("SWITCH %d" % (i + 1), switch_rect(i).position + Vector2(23, 45)) text_at("Repairs %d / 4 Moves %d / 6 Wires show affected lamps" % [puzzles, moves], Vector2(140, 535)) text_at(outcome, Vector2(250, 600), 25) ''') GAMES[29] = ("Water Gates", '''extends Node2D var opened: Array[bool] = [false, false] var levels: Array[int] = [0, 0] var drops: Array[Dictionary] = [] var spawn_clock: float = 0.0 var time_left: float = 65.0 var outcome: String = "" const TARGET: int = 20 func reset() -> void: opened = [false, false] levels = [0, 0] drops.clear() spawn_clock = 0 time_left = 65 outcome = "" func gate(i: int) -> Rect2: return Rect2(270 + i * 320, 210, 100, 55) func _input(event: InputEvent) -> void: if event is InputEventKey and event.pressed and event.keycode == KEY_R: reset() if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT and outcome == "": for i in range(2): if gate(i).has_point(event.position): opened[i] = not opened[i] func _process(dt: float) -> void: if outcome == "": time_left -= dt spawn_clock -= dt if spawn_clock <= 0: spawn_clock = 0.25 for i in range(2): if opened[i]: drops.append({"p": Vector2(320 + i * 320, 265), "v": 0.0, "tank": i}) for k in range(drops.size() - 1, -1, -1): var d: Dictionary = drops[k] d["v"] += 440.0 * dt d["p"] += Vector2(0, float(d["v"]) * dt) var i: int = d["tank"] if d["p"].y >= 555 - levels[i] * 8: levels[i] += 1 drops.remove_at(k) if levels[i] > TARGET: outcome = "A tank overflowed its marked level! R: retry" if levels[0] == TARGET and levels[1] == TARGET and drops.is_empty() and not opened[0] and not opened[1]: outcome = "Both tanks precisely filled! R: another run" elif time_left <= 0 and outcome == "": outcome = "Water service timed out. R: retry" queue_redraw() func _draw() -> void: backdrop("WATER GATES", "Click gates: open / close | Fill BOTH tanks to 20 drops | Close early: falling drops still count | R: restart") draw_rect(Rect2(250, 112, 460, 65), Color("2588b5")) text_at("WATER SOURCE", Vector2(380, 155)) for i in range(2): var x: float = 320 + i * 320 draw_line(Vector2(x, 177), Vector2(x, 210), Color("6fbde8"), 12) draw_rect(gate(i), Color("287b65") if opened[i] else Color("9e5263")) text_at("OPEN" if opened[i] else "CLOSED", gate(i).position + Vector2(7, 36), 20) draw_rect(Rect2(x - 100, 330, 200, 225), Color("182f49"), false, 4) draw_rect(Rect2(x - 95, 555 - levels[i] * 8, 190, levels[i] * 8), Color("329fd2")) draw_line(Vector2(x - 105, 395), Vector2(x + 105, 395), Color("ffcd6b"), 3) text_at("%d / 20" % levels[i], Vector2(x - 35, 590)) for d in drops: draw_circle(d["p"], 7, Color("79d7ff")) text_at("Time %d" % ceili(maxf(0, time_left)), Vector2(25, 120), 20) text_at(outcome, Vector2(190, 626), 23) ''') GAMES[30] = ("Shuttle Platforms", '''extends Node2D var player: Vector2 = Vector2(60, 465) var vy: float = 0.0 var platforms: Array[Rect2] = [] var grounded: int = -2 var clock: float = 0.0 var carrying: bool = true var lives: int = 3 var outcome: String = "" func _ready() -> void: reset() func reset() -> void: player = Vector2(60, 465) vy = 0 clock = 0 carrying = true lives = 3 grounded = -2 outcome = "" platforms = [Rect2(230, 430, 100, 16), Rect2(425, 360, 100, 16), Rect2(620, 430, 100, 16)] func _physics_process(dt: float) -> void: if Input.is_physical_key_pressed(KEY_R): reset() if outcome == "": clock += dt for i in range(3): var previous_x: float = platforms[i].position.x platforms[i].position.x = 230 + i * 195 + sin(clock * 1.2 + i * 1.8) * 38 if grounded == i: player.x += platforms[i].position.x - previous_x if Input.is_action_just_pressed("ui_accept") and grounded != -1: vy = -445 grounded = -1 player.x = clampf(player.x + Input.get_axis("ui_left", "ui_right") * 235 * dt, 0, 935) var old_bottom: float = player.y + 35 vy += 900 * dt player.y += vy * dt grounded = -1 var surfaces: Array[Rect2] = platforms.duplicate() surfaces.append(Rect2(0, 500, 155, 30)) surfaces.append(Rect2(815, 500, 145, 30)) if vy >= 0: for i in range(surfaces.size()): var r: Rect2 = surfaces[i] if old_bottom <= r.position.y + 3 and player.y + 35 >= r.position.y and player.x + 25 > r.position.x and player.x < r.end.x: player.y = r.position.y - 35 vy = 0 grounded = i if i < 3 else -2 if player.y > 650: lives -= 1 player = Vector2(60 if carrying else 875, 465) vy = 0 grounded = -2 if lives == 0: outcome = "Three falls. R: try the delivery again" if carrying and player.x > 870 and grounded == -2: carrying = false if not carrying and player.x < 85 and grounded == -2: outcome = "Delivered and returned safely! R: new route" queue_redraw() func _draw() -> void: backdrop("SHUTTLE PLATFORMS", "Left / Right: move | Space: jump | Deliver the box at right, then return left | R: restart") draw_rect(Rect2(0, 500, 155, 140), Color("334966")) draw_rect(Rect2(815, 500, 145, 140), Color("334966")) for p in platforms: draw_rect(p, Color("5ef2d0")) draw_rect(Rect2(player, Vector2(25, 35)), Color("79bbff")) if carrying: draw_rect(Rect2(player + Vector2(3, -20), Vector2(20, 20)), Color("ffcd6b")) else: draw_rect(Rect2(898, 472, 28, 28), Color("ffcd6b")) text_at("HOME", Vector2(35, 555), 20) text_at("DEPOT", Vector2(845, 555), 20) text_at("Lives %d | %s" % [lives, "Carry box to depot" if carrying else "Box delivered - return HOME"], Vector2(230, 125)) text_at(outcome, Vector2(260, 605), 24) ''') GAMES[31] = ("Driveway Plow", '''extends Node2D const W: int = 10 const H: int = 7 const CELL: int = 56 var snow: Dictionary = {} var piles: Dictionary = {} var player: Vector2i = Vector2i(4, 6) var moves: int = 0 var outcome: String = "" func _ready() -> void: reset() func reset() -> void: snow.clear() piles.clear() for y in range(1, 6): piles[Vector2i(0, y)] = 0 piles[Vector2i(9, y)] = 0 for x in [2, 3, 6, 7]: snow[Vector2i(x, y)] = true player = Vector2i(4, 6) moves = 0 outcome = "" func inside(p: Vector2i) -> bool: return p.x >= 0 and p.y >= 0 and p.x < W and p.y < H func step(direction: Vector2i) -> void: if outcome != "": return var next: Vector2i = player + direction if not inside(next) or piles.has(next): return if snow.has(next): var chain: Array[Vector2i] = [] var end: Vector2i = next while snow.has(end): chain.append(end) end += direction if not inside(end): return if (end.y == 0 or end.y == 6) and (end.x == 4 or end.x == 5): outcome = "Snow blocked the garage exit corridor. R: retry" return for i in range(chain.size() - 1, -1, -1): var dest: Vector2i = chain[i] + direction snow.erase(chain[i]) if piles.has(dest): piles[dest] += 1 else: snow[dest] = true player = next moves += 1 if snow.is_empty(): outcome = "Every driveway tile cleared; exit remains open! R: restart" func _input(event: InputEvent) -> void: if event is InputEventKey and event.pressed and not event.echo: if event.keycode == KEY_R: reset() elif event.keycode == KEY_LEFT: step(Vector2i.LEFT) elif event.keycode == KEY_RIGHT: step(Vector2i.RIGHT) elif event.keycode == KEY_UP: step(Vector2i.UP) elif event.keycode == KEY_DOWN: step(Vector2i.DOWN) queue_redraw() func center(p: Vector2i) -> Vector2: return Vector2(200, 155) + Vector2(p) * CELL + Vector2.ONE * 28 func _draw() -> void: backdrop("DRIVEWAY PLOW", "Tap arrows: move and push snow | Push into green side piles | Keep the yellow exit open | R: restart") for y in range(H): for x in range(W): var p: Vector2i = Vector2i(x, y) var color: Color = Color("28394e") if piles.has(p): color = Color("26785e") elif (y == 0 or y == 6) and (x == 4 or x == 5): color = Color("827035") draw_rect(Rect2(center(p) - Vector2.ONE * 27, Vector2(54, 54)), color) if snow.has(p): draw_circle(center(p), 21, Color("d5ebff")) if piles.has(p): text_at(str(piles[p]), center(p) + Vector2(-6, 7), 19) draw_rect(Rect2(center(player) - Vector2(17, 17), Vector2(34, 34)), Color("ff955b")) text_at("Snow tiles left %d / 20 Moves %d" % [snow.size(), moves], Vector2(270, 585)) text_at(outcome, Vector2(145, 625), 21) ''') GAMES[32] = ("Shepherd Gate", '''extends Node2D var sheep: Array[Vector2] = [] var secured: Array[bool] = [] var shepherd: Vector2 = Vector2(160, 340) var time_left: float = 90.0 var outcome: String = "" func _ready() -> void: reset() func reset() -> void: sheep = [Vector2(240, 235), Vector2(360, 295), Vector2(270, 415), Vector2(410, 440), Vector2(460, 215)] secured = [false, false, false, false, false] shepherd = Vector2(160, 340) time_left = 90 outcome = "" func _process(dt: float) -> void: if Input.is_physical_key_pressed(KEY_R): reset() if outcome == "": time_left -= dt shepherd = get_global_mouse_position() shepherd.x = clampf(shepherd.x, 35, 660) shepherd.y = clampf(shepherd.y, 125, 575) # The marked entrance is reserved for sheep: shepherd stays outside it. if shepherd.x > 595 and shepherd.y > 265 and shepherd.y < 415: shepherd.x = 595 for i in range(sheep.size()): if secured[i]: continue var velocity: Vector2 = Vector2.ZERO var away: Vector2 = sheep[i] - shepherd if away.length() < 145: velocity += away.normalized() * (145 - away.length()) * 1.1 for j in range(sheep.size()): if i != j and not secured[j]: var separation: Vector2 = sheep[i] - sheep[j] if separation.length() < 38: velocity += separation.normalized() * 35 var next: Vector2 = sheep[i] + velocity.limit_length(110) * dt next.y = clampf(next.y, 140, 555) next.x = maxf(next.x, 50) if next.x > 680 and (next.y < 285 or next.y > 395): next.x = 680 if next.x >= 690 and next.y >= 285 and next.y <= 395: secured[i] = true next = Vector2(750 + (i % 2) * 85, 230 + (i / 2) * 80) sheep[i] = next var count: int = 0 for done in secured: if done: count += 1 if count == sheep.size(): outcome = "Every sheep penned; gate corridor clear! R: replay" elif time_left <= 0: outcome = "Time ran out. Approach from behind each sheep. R: retry" queue_redraw() func _draw() -> void: backdrop("SHEPHERD GATE", "Mouse: shepherd repels nearby sheep | Herd them through the right-side gate | Keep corridor clear | R: restart") draw_rect(Rect2(30, 120, 650, 465), Color("1a3b37")) draw_rect(Rect2(700, 160, 220, 380), Color("285746")) draw_rect(Rect2(595, 285, 105, 110), Color("746532")) draw_line(Vector2(690, 120), Vector2(690, 278), Color("c1cfe8"), 8) draw_line(Vector2(690, 402), Vector2(690, 585), Color("c1cfe8"), 8) text_at("PEN", Vector2(775, 145)) var count: int = 0 for i in range(sheep.size()): draw_circle(sheep[i], 16, Color.WHITE) draw_circle(sheep[i] + Vector2(10, 0), 7, Color("68798b")) if secured[i]: count += 1 draw_circle(shepherd, 15, Color("ff9568")) draw_arc(shepherd, 145, 0, TAU, 48, Color(1, 0.7, 0.4, 0.18), 1) text_at("Penned %d / 5 Time %d" % [count, ceili(maxf(time_left, 0))], Vector2(220, 610)) text_at(outcome, Vector2(120, 108), 22) ''') def main(): # Access only the explicitly assigned training prompt IDs; no blind file read. wanted = {f"vg8b-teacher-v1-{i:03d}" for i in list(range(21, 33)) + list(range(65, 85))} prompts = {} with (ROOT / "data/teacher_prompts.jsonl").open() as handle: for line in handle: row = json.loads(line) if row["id"] in wanted: prompts[row["id"]] = row["instruction"] if set(prompts) != wanted: raise RuntimeError("Missing assigned training prompts") rows, provenance = [], [] for number, (title, source) in sorted(GAMES.items()): identity = f"vg8b-teacher-v1-{number:03d}" files = {"project.godot": PROJECT % title, "main.tscn": SCENE, "main.gd": source + HELPERS} output = json.dumps({"files": files}, ensure_ascii=False, separators=(",", ":")) parse_project(output) rows.append({"instruction": prompts[identity], "output": output}) provenance.append({"prompt_id": identity, "title": title, "project_sha256": project_sha256(files), "output_sha256": hashlib.sha256(output.encode()).hexdigest(), "gdscript_characters": len(files["main.gd"]), "static_contract_pass": True}) output_path = ROOT / "data/codex_teacher_batch_b.jsonl" temporary = output_path.with_suffix(".tmp") temporary.write_text("".join(json.dumps(row, ensure_ascii=False) + "\n" for row in rows)) temporary.replace(output_path) report = {"authorship": "Original in-session Codex teacher authorship; not generated by the local 14B sampler.", "source": "Independently implemented game mechanics responding to assigned training prompts 021–032 and 065–084.", "license": "Apache-2.0", "assets": "Procedural Godot drawing and bundled default font only; no third-party game assets.", "shared_boilerplate": "Canonical Godot project/scene and text drawing helpers follow the repository's original seeds.", "blind_prompts_read": False, "engine_validation": "NOT RUN. Pending Linux import and full 60-second check; these are candidates, not admitted training data.", "candidates_sha256": hashlib.sha256(output_path.read_bytes()).hexdigest(), "count": len(rows), "games": provenance} (ROOT / "data/codex_teacher_batch_b_provenance.json").write_text(json.dumps(report, indent=2) + "\n") print(json.dumps({"candidates": len(rows), "static_contract": "passed", "max_gdscript_characters": max(x["gdscript_characters"] for x in provenance), "engine_validation": "pending"})) GAMES[65] = ("Landing Lines", '''extends Node2D var planes: Array[Dictionary] = [] var zones: Array[Vector2] = [Vector2(770, 210), Vector2(770, 480)] var selected: int = -1 var created: int = 0 var landed: int = 0 var spawn: float = 0 var outcome: String = "" func _ready() -> void: reset() func reset() -> void: planes.clear() selected = -1 created = 0 landed = 0 spawn = 0 outcome = "" func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed and e.keycode == KEY_R: reset() if e is InputEventMouseButton and e.button_index == MOUSE_BUTTON_LEFT: if e.pressed: selected = -1 for i in range(planes.size()): if planes[i]["p"].distance_to(e.position) < 25: selected = i planes[i]["path"] = [] else: selected = -1 if e is InputEventMouseMotion and selected >= 0 and selected < planes.size(): var path: Array = planes[selected]["path"] if path.is_empty() or path[-1].distance_to(e.position) > 18: path.append(e.position) func _process(dt: float) -> void: if outcome == "": spawn -= dt if spawn <= 0 and created < 8: planes.append({"p": Vector2(50, 170 + (created % 2) * 320), "zone": created % 2, "path": []}) created += 1 spawn = 5.5 for i in range(planes.size() - 1, -1, -1): var p: Dictionary = planes[i] var path: Array = p["path"] if not path.is_empty(): p["p"] = p["p"].move_toward(path[0], 85 * dt) if p["p"].distance_to(path[0]) < 2: path.pop_front() else: p["p"] += Vector2(23 * dt, 0) if p["p"].distance_to(zones[p["zone"]]) < 24: planes.remove_at(i) selected = -1 landed += 1 elif p["p"].x > 950 or p["p"].y < 90 or p["p"].y > 630: outcome = "Plane left the airspace! R: retry" for i in range(planes.size()): for j in range(i): if planes[i]["p"].distance_to(planes[j]["p"]) < 27: outcome = "Loss of separation! R: retry" if landed == 8: outcome = "Eight safe landings! R: another shift" queue_redraw() func _draw() -> void: backdrop("LANDING LINES", "Drag from a plane to draw its route | Match landing-zone color | Keep planes separated | R: restart") for i in range(2): draw_circle(zones[i], 38, Color("286c90") if i == 0 else Color("806631")) text_at(str(i + 1), zones[i] + Vector2(-8, 9), 28) for p in planes: var previous: Vector2 = p["p"] for point in p["path"]: draw_line(previous, point, Color("526d88"), 2) previous = point draw_circle(p["p"], 12, Color("79d7ff") if p["zone"] == 0 else Color("ffcd6b")) text_at("Landed %d / 8" % landed, Vector2(35, 610)) text_at(outcome, Vector2(330, 610), 24) ''') GAMES[66] = ("Six Plot Farm", '''extends Node2D var plants: Array[Dictionary] = [] var water: int = 12 var harvest: int = 0 var wilted: int = 0 var outcome: String = "" func _ready() -> void: reset() func reset() -> void: plants.clear() for i in range(6): plants.append({"stage": 0, "moisture": 0.0, "growth": 0.0}) water = 12 harvest = 0 wilted = 0 outcome = "" func plot(i: int) -> Rect2: return Rect2(170 + (i % 3) * 215, 175 + (i / 3) * 185, 185, 155) func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed and e.keycode == KEY_R: reset() if outcome == "" and e is InputEventMouseButton and e.pressed and e.button_index == MOUSE_BUTTON_LEFT: for i in range(6): if plot(i).has_point(e.position): var p: Dictionary = plants[i] if p["stage"] == 0: p["stage"] = 1 p["moisture"] = 70.0 elif p["stage"] == 2: p["stage"] = 3 harvest += 1 elif p["stage"] == 1 and water > 0: p["moisture"] = minf(100, p["moisture"] + 55) water -= 1 func _process(dt: float) -> void: if outcome == "": for p in plants: if p["stage"] == 1: p["moisture"] -= 8 * dt p["growth"] += 6 * dt if p["moisture"] <= 0: p["stage"] = 4 wilted += 1 elif p["growth"] >= 100: p["stage"] = 2 if harvest == 6: outcome = "All six crops harvested! R: replant" elif wilted > 0: outcome = "A plant wilted. R: restart the farm" queue_redraw() func _draw() -> void: backdrop("SIX PLOT FARM", "Click empty plot: plant | Click growing crop: spend water | Click gold crop: harvest | R: restart") for i in range(6): var p: Dictionary = plants[i] var r: Rect2 = plot(i) draw_rect(r, Color("684b38")) if p["stage"] == 1 or p["stage"] == 2: draw_circle(r.get_center() - Vector2(0, 14), 15 + p["growth"] * 0.2, Color("ffcd6b") if p["stage"] == 2 else Color("5ed27b")) draw_rect(Rect2(r.position + Vector2(10, 115), Vector2(p["moisture"] * 1.65, 12)), Color("79d7ff")) text_at("Growth %d%%" % int(p["growth"]), r.position + Vector2(22, 149), 17) else: text_at(["PLANT", "", "", "HARVESTED", "WILTED"][p["stage"]], r.position + Vector2(23, 80), 20) text_at("Water %d / 12 Harvest %d / 6" % [water, harvest], Vector2(300, 570)) text_at(outcome, Vector2(250, 620), 24) ''') GAMES[67] = ("Three Barrier Bankshot", '''extends Node2D var barriers: Array[Rect2] = [] var ball: Vector2 = Vector2(125, 490) var velocity: Vector2 = Vector2(210, -150) var running: bool = false var bounces: int = 0 var horizontal: bool = true var outcome: String = "" var timer: float = 0 func reset() -> void: barriers.clear() ball = Vector2(125, 490) velocity = Vector2(210, -150) running = false bounces = 0 timer = 0 outcome = "" func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed and not e.echo: if e.keycode == KEY_R: reset() elif e.keycode == KEY_SPACE and barriers.size() == 3 and outcome == "": running = true if e is InputEventMouseButton and e.pressed and not running: if e.button_index == MOUSE_BUTTON_RIGHT: horizontal = not horizontal elif e.button_index == MOUSE_BUTTON_LEFT and barriers.size() < 3 and e.position.y > 160: var size: Vector2 = Vector2(120, 18) if horizontal else Vector2(18, 120) var rect: Rect2 = Rect2(e.position - size / 2, size) if not rect.grow(25).has_point(ball) and not rect.grow(35).has_point(Vector2(785, 425)): barriers.append(rect) func _process(dt: float) -> void: if running and outcome == "": timer += dt var previous: Vector2 = ball ball += velocity * dt if ball.x < 55 or ball.x > 905: velocity.x *= -1 ball.x = clampf(ball.x, 55, 905) bounces += 1 if ball.y < 155 or ball.y > 565: velocity.y *= -1 ball.y = clampf(ball.y, 155, 565) bounces += 1 for r in barriers: if r.grow(9).has_point(ball) and not r.grow(9).has_point(previous): if previous.x < r.position.x - 9 or previous.x > r.end.x + 9: velocity.x *= -1 else: velocity.y *= -1 ball = previous bounces += 1 if ball.distance_to(Vector2(785, 425)) < 30: outcome = "Target reached in %d bounces! R: rebuild" % bounces elif bounces > 5 or timer > 25: outcome = "Route failed. R: place a new layout" queue_redraw() func _draw() -> void: backdrop("THREE BARRIER BANKSHOT", "Left click: place | Right click: rotate next barrier | Place three then Space: launch | R: restart") draw_rect(Rect2(45, 145, 870, 430), Color("46617d"), false, 3) draw_circle(Vector2(785, 425), 30, Color("287d60")) for r in barriers: draw_rect(r, Color("ffcd6b")) draw_circle(ball, 9, Color.WHITE) if not running: draw_line(ball, ball + velocity.normalized() * 75, Color("79d7ff"), 3) text_at("Barriers %d / 3 Bounces %d / 5 Next: %s" % [barriers.size(), bounces, "horizontal" if horizontal else "vertical"], Vector2(110, 122), 20) text_at(outcome, Vector2(215, 618), 24) ''') GAMES[68] = ("Merge To 128", '''extends Node2D var board: Array[int] = [] var score: int = 0 var outcome: String = "" func _ready() -> void: reset() func reset() -> void: board.clear() board.resize(16) board.fill(0) score = 0 outcome = "" spawn() spawn() func spawn() -> void: var empty: Array[int] = [] for i in range(16): if board[i] == 0: empty.append(i) if not empty.is_empty(): board[empty[randi_range(0, empty.size() - 1)]] = 2 func slide(direction: int) -> void: if outcome != "": return var before: Array[int] = board.duplicate() for line in range(4): var ids: Array[int] = [] for n in range(4): var index: int = line * 4 + n if direction == 1: index = line * 4 + 3 - n elif direction == 2: index = n * 4 + line elif direction == 3: index = (3 - n) * 4 + line ids.append(index) var values: Array[int] = [] for index in ids: if board[index] > 0: values.append(board[index]) var merged: Array[int] = [] var n: int = 0 while n < values.size(): if n + 1 < values.size() and values[n] == values[n + 1]: merged.append(values[n] * 2) score += values[n] * 2 n += 2 else: merged.append(values[n]) n += 1 for i in range(4): board[ids[i]] = merged[i] if i < merged.size() else 0 if board != before: spawn() var possible: bool = board.has(0) for y in range(4): for x in range(4): var i: int = y * 4 + x if board[i] >= 128: outcome = "128 reached! R: a new board" if x < 3 and board[i] == board[i + 1]: possible = true if y < 3 and board[i] == board[i + 4]: possible = true if not possible and outcome == "": outcome = "No legal moves. R: retry" func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed and not e.echo: if e.keycode == KEY_R: reset() elif e.keycode == KEY_LEFT: slide(0) elif e.keycode == KEY_RIGHT: slide(1) elif e.keycode == KEY_UP: slide(2) elif e.keycode == KEY_DOWN: slide(3) queue_redraw() func _draw() -> void: backdrop("MERGE TO 128", "Arrow keys: slide | Equal neighbors merge once per move | Reach 128 | R: restart") for i in range(16): var p: Vector2 = Vector2(270 + (i % 4) * 108, 120 + (i / 4) * 108) draw_rect(Rect2(p, Vector2(100, 100)), Color("273b55") if board[i] == 0 else Color.from_hsv(log(float(board[i])) * 0.06, 0.55, 0.9)) if board[i] > 0: text_at(str(board[i]), p + Vector2(30, 61), 29) text_at("Score %d" % score, Vector2(95, 160)) text_at(outcome, Vector2(280, 606), 25) ''') GAMES[69] = ("Fragile Freight", '''extends Node2D var cart: float = 110 var speed: float = 0 var cargo: float = 0 var cargo_speed: float = 0 var timer: float = 25 var outcome: String = "" func reset() -> void: cart = 110 speed = 0 cargo = 0 cargo_speed = 0 timer = 25 outcome = "" func _process(dt: float) -> void: if Input.is_physical_key_pressed(KEY_R): reset() if outcome == "": timer -= dt var acceleration: float = Input.get_axis("ui_left", "ui_right") * 95 - speed * 0.15 speed = clampf(speed + acceleration * dt, -150, 150) cart += speed * dt cargo_speed += (-acceleration * 0.25 - cargo_speed * 0.85 - cargo * 0.2) * dt cargo += cargo_speed * dt if absf(cargo) > 65 or cart < 70: outcome = "Cargo fell or cart left the road! R: retry" elif cart >= 830 and absf(speed) < 28: outcome = "Cargo delivered intact! R: drive again" elif cart > 920 or timer <= 0: outcome = "Missed the stopping zone! R: retry" queue_redraw() func _draw() -> void: backdrop("FRAGILE FREIGHT", "Left / Right: accelerate or brake | Carry the loose ball into green zone and stop | R: restart") draw_rect(Rect2(800, 370, 120, 150), Color("214f41")) draw_line(Vector2(50, 500), Vector2(930, 500), Color("c1cfe8"), 5) draw_rect(Rect2(cart - 70, 450, 140, 20), Color("79bbff")) draw_circle(Vector2(cart - 45, 483), 16, Color("62758f")) draw_circle(Vector2(cart + 45, 483), 16, Color("62758f")) draw_circle(Vector2(cart + cargo, 432), 17, Color("ffcd6b")) text_at("Speed %.0f Cargo offset %.0f Time %.1f" % [speed, cargo, maxf(timer, 0)], Vector2(240, 170)) text_at("DESTINATION", Vector2(795, 355), 18) text_at(outcome, Vector2(240, 590), 25) ''') GAMES[70] = ("One Thing Changed", '''extends Node2D var objects: Array[Vector2] = [] var changed: int = 0 var stage: int = 0 var clock: float = 0 var solved: int = 0 var mistakes: int = 0 var outcome: String = "" func _ready() -> void: new_scene() func new_scene() -> void: objects.clear() for i in range(6): objects.append(Vector2(235 + (i % 3) * 230, 230 + (i / 3) * 210)) changed = randi_range(0, 5) stage = 0 clock = 0 func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed and e.keycode == KEY_R: solved = 0 mistakes = 0 outcome = "" new_scene() if e is InputEventMouseButton and e.pressed and e.button_index == MOUSE_BUTTON_LEFT and stage == 2 and outcome == "": if e.position.distance_to(objects[changed]) < 40: solved += 1 else: mistakes += 1 if solved == 5: outcome = "Five changes spotted! R: play again" elif mistakes == 3: outcome = "Three misses. R: look more closely" else: new_scene() func _process(dt: float) -> void: if outcome == "": clock += dt if stage == 0 and clock > 2.7: stage = 1 clock = 0 elif stage == 1 and clock > 0.7: objects[changed].x += 65 if changed % 2 == 0 else -65 stage = 2 queue_redraw() func _draw() -> void: backdrop("ONE THING CHANGED", "Memorize the scene | After the brief curtain, click the object that moved | R: restart") text_at(["MEMORIZE", "CURTAIN", "WHICH OBJECT MOVED?"][stage], Vector2(330, 125), 25) if stage != 1: for i in range(objects.size()): var color: Color = Color.from_hsv(i * 0.15, 0.65, 0.95) if i % 2 == 0: draw_circle(objects[i], 33, color) else: draw_rect(Rect2(objects[i] - Vector2.ONE * 31, Vector2.ONE * 62), color) text_at(str(i + 1), objects[i] + Vector2(-7, 8), 25) else: draw_rect(Rect2(140, 160, 670, 360), Color("27344c")) text_at("Found %d / 5 Misses %d / 3" % [solved, mistakes], Vector2(300, 565)) text_at(outcome, Vector2(280, 615), 25) ''') GAMES[71] = ("Gentle Tension", '''extends Node2D var angle: float = 0 var sweet: float = 0.45 var tension: float = 0 var opened: float = 0 var picks: int = 3 var outcome: String = "" func reset() -> void: angle = 0 sweet = randf_range(-1.0, 1.0) tension = 0 opened = 0 picks = 3 outcome = "" func _process(dt: float) -> void: if Input.is_physical_key_pressed(KEY_R): reset() if outcome == "": angle = clampf(angle + Input.get_axis("ui_left", "ui_right") * dt, -1.2, 1.2) if Input.is_action_pressed("ui_accept"): tension = minf(1, tension + dt * 0.75) if absf(angle - sweet) < 0.13: opened += dt * tension * 0.6 elif tension > 0.62: picks -= 1 tension = 0 opened = 0 else: tension = maxf(0, tension - dt * 2.5) if opened >= 1: outcome = "Lock opened without force! R: another lock" elif picks <= 0: outcome = "All three picks broke. R: retry gently" queue_redraw() func _draw() -> void: backdrop("GENTLE TENSION", "Left / Right: rotate pick | Hold Space gently to test and turn | Release to ease tension | R: restart") draw_circle(Vector2(480, 345), 150, Color("52617a")) draw_circle(Vector2(480, 345), 105, Color("24344c")) var tip: Vector2 = Vector2(0, -160).rotated(angle) draw_line(Vector2(480, 345), Vector2(480, 345) + tip, Color("ffcd6b"), 8) draw_line(Vector2(480, 345), Vector2(480, 345) + Vector2(70, 0).rotated(opened * PI * 0.5), Color.WHITE, 12) var near: bool = absf(angle - sweet) < 0.13 text_at("The cylinder yields!" if near and tension > 0 else "Probe lightly; resistance means the angle is wrong.", Vector2(235, 145), 21) draw_rect(Rect2(300, 530, tension * 360, 20), Color("ff6176") if tension > 0.6 and not near else Color("5ef2d0")) text_at("Tension Picks %d Open %d%%" % [picks, int(opened * 100)], Vector2(290, 585)) text_at(outcome, Vector2(250, 625), 23) ''') GAMES[72] = ("Paper Airflow", '''extends Node2D var fans: Array[Dictionary] = [] var plane: Vector2 = Vector2(125, 440) var velocity: Vector2 = Vector2(65, 0) var facing: int = 3 var running: bool = false var timer: float = 0 var outcome: String = "" var directions: Array[Vector2] = [Vector2.RIGHT, Vector2.DOWN, Vector2.LEFT, Vector2.UP] func reset() -> void: fans.clear() plane = Vector2(125, 440) velocity = Vector2(65, 0) running = false timer = 0 outcome = "" func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed and not e.echo: if e.keycode == KEY_R: reset() elif e.keycode == KEY_SPACE and fans.size() == 2: running = true if e is InputEventMouseButton and e.pressed and not running: if e.button_index == MOUSE_BUTTON_RIGHT: facing = (facing + 1) % 4 elif e.button_index == MOUSE_BUTTON_LEFT and fans.size() < 2 and e.position.y > 150: fans.append({"p": e.position, "direction": facing}) func _process(dt: float) -> void: if running and outcome == "": timer += dt for fan in fans: if plane.distance_to(fan["p"]) < 125: velocity = velocity.move_toward(directions[fan["direction"]] * 95, 165 * dt) plane += velocity * dt if plane.distance_to(Vector2(790, 225)) < 35: outcome = "Mail delivered by airflow! R: redesign" elif plane.x < 30 or plane.x > 930 or plane.y < 125 or plane.y > 590 or timer > 18: outcome = "Paper missed the mailbox. R: redesign fans" queue_redraw() func _draw() -> void: backdrop("PAPER AIRFLOW", "Left click: place fan | Right click: rotate next fan | Place TWO then Space: launch | R: restart") for fan in fans: draw_arc(fan["p"], 125, 0, TAU, 48, Color("345068"), 2) draw_circle(fan["p"], 20, Color("5ef2d0")) draw_line(fan["p"], fan["p"] + directions[fan["direction"]] * 48, Color.WHITE, 5) draw_rect(Rect2(760, 195, 60, 60), Color("ffcd6b")) text_at("MAIL", Vector2(761, 185), 20) draw_colored_polygon(PackedVector2Array([plane + Vector2(16, 0), plane + Vector2(-12, -9), plane + Vector2(-6, 0), plane + Vector2(-12, 9)]), Color.WHITE) text_at("Fans %d / 2 Next direction: %s" % [fans.size(), ["RIGHT", "DOWN", "LEFT", "UP"][facing]], Vector2(270, 125), 20) text_at(outcome, Vector2(230, 625), 25) ''') GAMES[73] = ("Marble Bend", '''extends Node2D var chain: Array[int] = [0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2] var progress: float = 0 var next_color: int = 0 var shot: Vector2 = Vector2.ZERO var shot_velocity: Vector2 = Vector2.ZERO var active: bool = false var removed: int = 0 var outcome: String = "" var colors: Array[Color] = [Color("ff786e"), Color("79d7ff"), Color("ffcd6b")] func reset() -> void: chain = [0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2] progress = 0 next_color = 0 active = false removed = 0 outcome = "" func path(t: float) -> Vector2: return Vector2(150 + t, 255 + sin(t / 130.0) * 70) func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed and e.keycode == KEY_R: reset() if e is InputEventMouseButton and e.pressed and e.button_index == MOUSE_BUTTON_LEFT and not active and outcome == "": shot = Vector2(480, 540) shot_velocity = (e.position - shot).normalized() * 450 active = true func _process(dt: float) -> void: if outcome == "": progress += 7 * dt if active: shot += shot_velocity * dt for i in range(chain.size()): if shot.distance_to(path(progress + i * 31)) < 28: chain.insert(i, next_color) var left: int = i var right: int = i while left > 0 and chain[left - 1] == next_color: left -= 1 while right + 1 < chain.size() and chain[right + 1] == next_color: right += 1 if right - left + 1 >= 3: removed += right - left + 1 for j in range(right - left + 1): chain.remove_at(left) next_color = (next_color + 1) % 3 active = false break if shot.y < 95 or shot.x < 10 or shot.x > 950: active = false if chain.is_empty(): outcome = "Chain cleared! R: replay" elif progress + (chain.size() - 1) * 31 > 680: outcome = "Marbles reached the drain. R: retry" queue_redraw() func _draw() -> void: backdrop("MARBLE BEND", "Click: launch the displayed marble toward the chain | Insert to make runs of three | R: restart") for t in range(0, 680, 10): draw_line(path(t), path(t + 10), Color("3c506a"), 4) draw_circle(path(680), 26, Color("9e4259")) for i in range(chain.size()): draw_circle(path(progress + i * 31), 14, colors[chain[i]]) draw_circle(Vector2(480, 540), 23, colors[next_color]) if active: draw_circle(shot, 13, colors[next_color]) text_at("Removed %d Remaining %d" % [removed, chain.size()], Vector2(290, 125)) text_at(outcome, Vector2(310, 610), 25) ''') GAMES[74] = ("Moon Window", '''extends Node2D var angle: float = 0.0 var target: float = 4.0 var width: float = 0.8 var wins: int = 0 var misses: int = 0 var pause: float = 0 var outcome: String = "" func reset() -> void: angle = 0 target = 4 width = 0.8 wins = 0 misses = 0 pause = 0 outcome = "" func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed and not e.echo: if e.keycode == KEY_R: reset() elif e.keycode == KEY_SPACE and outcome == "" and pause <= 0: var distance: float = absf(wrapf(angle - target, -PI, PI)) if distance < (width + 0.28) * 0.5: wins += 1 width *= 0.77 target = fposmod(target + 2.1, TAU) else: misses += 1 pause = 0.45 if wins == 6: outcome = "Six lunar alignments! R: replay" elif misses == 3: outcome = "Three missed windows. R: retry" func _process(dt: float) -> void: if outcome == "": pause -= dt if pause <= 0: angle = fposmod(angle + (1.5 + wins * 0.22) * dt, TAU) queue_redraw() func _draw() -> void: backdrop("MOON WINDOW", "Space: stop the moving lit sector while it overlaps the fixed gold sector | R: restart") draw_circle(Vector2(480, 340), 156, Color("22334d")) draw_arc(Vector2(480, 340), 150, target - width / 2, target + width / 2, 40, Color("ffcd6b"), 24) draw_arc(Vector2(480, 340), 150, angle - 0.14, angle + 0.14, 20, Color("79d7ff"), 18) text_at("ALIGN", Vector2(431, 350), 26) text_at("Aligned %d / 6 Missed %d / 3" % [wins, misses], Vector2(300, 545)) text_at(outcome, Vector2(280, 610), 25) ''') GAMES[75] = ("Torch Return", '''extends Node2D var player: Vector2i = Vector2i(0, 4) var treasures: Array[Vector2i] = [Vector2i(3, 3), Vector2i(7, 6), Vector2i(10, 4)] var torch: float = 90 var outcome: String = "" func reset() -> void: player = Vector2i(0, 4) treasures = [Vector2i(3, 3), Vector2i(7, 6), Vector2i(10, 4)] torch = 90 outcome = "" func wall(p: Vector2i) -> bool: return p.x < 0 or p.y < 0 or p.x >= 12 or p.y >= 9 or (p.x % 3 == 2 and p.y != 1 and p.y != 7) func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed: if e.keycode == KEY_R: reset() var direction: Vector2i = Vector2i.ZERO if e.keycode == KEY_LEFT: direction = Vector2i.LEFT elif e.keycode == KEY_RIGHT: direction = Vector2i.RIGHT elif e.keycode == KEY_UP: direction = Vector2i.UP elif e.keycode == KEY_DOWN: direction = Vector2i.DOWN if outcome == "" and not wall(player + direction): player += direction treasures.erase(player) if treasures.is_empty() and player == Vector2i(0, 4): outcome = "Three treasures brought home! R: explore again" func _process(dt: float) -> void: if outcome == "": torch -= dt if torch <= 0: outcome = "Torch exhausted. R: try a shorter route" queue_redraw() func _draw() -> void: backdrop("TORCH RETURN", "Arrows: explore the dark grid | Collect three treasures, then return to entrance | R: restart") for y in range(9): for x in range(12): var p: Vector2i = Vector2i(x, y) var r: Rect2 = Rect2(180 + x * 48, 135 + y * 48, 46, 46) if Vector2(p - player).length() <= 2.5: draw_rect(r, Color("52617a") if wall(p) else Color("293e55")) if treasures.has(p): draw_circle(r.get_center(), 12, Color("ffcd6b")) if p == Vector2i(0, 4): draw_rect(r.grow(-8), Color("5ef2d0"), false, 3) else: draw_rect(r, Color("0a101b")) draw_circle(Vector2(203, 158) + Vector2(player) * 48, 12, Color.WHITE) text_at("Treasures %d / 3 Torch %.0f" % [3 - treasures.size(), maxf(torch, 0)], Vector2(300, 605)) text_at(outcome, Vector2(180, 115), 21) ''') GAMES[76] = ("Four Piston Passage", '''extends Node2D var ball: Vector2 = Vector2(180, 480) var velocity: Vector2 = Vector2.ZERO var pressure: Array[float] = [0.0, 0.0, 0.0, 0.0] var corridor: Array[Rect2] = [Rect2(130, 415, 285, 130), Rect2(295, 235, 120, 310), Rect2(295, 235, 365, 120), Rect2(540, 125, 120, 230), Rect2(540, 125, 285, 110)] var hits: int = 0 var cooldown: float = 0 var outcome: String = "" var directions: Array[Vector2] = [Vector2.LEFT, Vector2.RIGHT, Vector2.UP, Vector2.DOWN] var actions: Array[String] = ["ui_left", "ui_right", "ui_up", "ui_down"] func reset() -> void: ball = Vector2(180, 480) velocity = Vector2.ZERO pressure = [0.0, 0.0, 0.0, 0.0] hits = 0 cooldown = 0 outcome = "" func safe(p: Vector2) -> bool: for offset in [Vector2(-12, 0), Vector2(12, 0), Vector2(0, -12), Vector2(0, 12)]: var ok: bool = false for r in corridor: if r.has_point(p + offset): ok = true if not ok: return false return true func _process(dt: float) -> void: if Input.is_physical_key_pressed(KEY_R): reset() if outcome == "": cooldown -= dt for i in range(4): pressure[i] = move_toward(pressure[i], 1.0 if Input.is_action_pressed(actions[i]) else 0.0, dt * 3) velocity += directions[i] * pressure[i] * 250 * dt velocity *= exp(-3 * dt) var next: Vector2 = ball + velocity * dt if safe(next): ball = next else: velocity *= -0.3 if cooldown <= 0: hits += 1 cooldown = 0.7 if ball.distance_to(Vector2(785, 180)) < 28: outcome = "Ball delivered through all bends! R: replay" elif hits >= 8: outcome = "Eight pressure collisions. R: use gentler pulses" queue_redraw() func _draw() -> void: backdrop("FOUR PISTON PASSAGE", "Hold arrows: independent directional pistons build pressure | Guide ball through the zigzag | R: restart") for r in corridor: draw_rect(r, Color("263e57")) draw_circle(Vector2(785, 180), 28, Color("25855f")) for i in range(4): var origin: Vector2 = ball - directions[i] * (52 - pressure[i] * 20) draw_line(origin - directions[i] * 22, origin, Color("ffcd6b"), 14) draw_circle(ball, 12, Color.WHITE) text_at("Wall strikes %d / 8" % hits, Vector2(60, 585)) text_at(outcome, Vector2(260, 625), 23) ''') GAMES[77] = ("One Then Two", '''extends Node2D var ball: Vector2 = Vector2(210, 430) var velocity: Vector2 = Vector2.ZERO var targets: Array[Vector2] = [Vector2(460, 300), Vector2(690, 330)] var pockets: Array[Vector2] = [Vector2(110, 150), Vector2(850, 150), Vector2(110, 550), Vector2(850, 550)] var order: int = 0 var dragging: bool = false var drag_start: Vector2 = Vector2.ZERO var shooting: bool = false var shots: int = 0 var note: String = "Hit 1, then 2, then any corner pocket." var outcome: String = "" var contact: int = -1 func reset_ball() -> void: ball = Vector2(210, 430) velocity = Vector2.ZERO order = 0 shooting = false contact = -1 func fail_shot(reason: String) -> void: note = reason + " Balls reset." reset_ball() if shots >= 5: outcome = "Five shots exhausted. R: retry" func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed and e.keycode == KEY_R: shots = 0 outcome = "" reset_ball() if e is InputEventMouseButton and e.button_index == MOUSE_BUTTON_LEFT and outcome == "" and not shooting: if e.pressed and e.position.distance_to(ball) < 30: dragging = true drag_start = e.position elif not e.pressed and dragging: dragging = false velocity = (drag_start - e.position).limit_length(220) * 3 if velocity.length() > 25: shooting = true shots += 1 func _process(dt: float) -> void: if shooting and outcome == "": ball += velocity * dt velocity *= exp(-0.16 * dt) if ball.x < 120 or ball.x > 840: velocity.x *= -1 ball.x = clampf(ball.x, 120, 840) if ball.y < 160 or ball.y > 540: velocity.y *= -1 ball.y = clampf(ball.y, 160, 540) var touching: int = -1 for i in range(2): if ball.distance_to(targets[i]) < 28: touching = i if contact != i: if i != order: fail_shot("Wrong ball order!") break order += 1 var normal: Vector2 = (ball - targets[i]).normalized() velocity = velocity.bounce(normal) ball = targets[i] + normal * 29 contact = touching for pocket in pockets: if ball.distance_to(pocket) < 30: if order == 2: outcome = "Correct order and pocket! R: replay" else: fail_shot("Pocketed before both contacts!") if shooting and velocity.length() < 20: fail_shot("Shot stopped short.") queue_redraw() func _draw() -> void: backdrop("ONE THEN TWO", "Drag backward from cue ball, release to shoot | Hit numbered balls in order, then a pocket | R: restart") draw_rect(Rect2(100, 140, 760, 420), Color("205945")) for p in pockets: draw_circle(p, 27, Color("101b26")) for i in range(2): draw_circle(targets[i], 16, Color("ffcd6b") if i == 0 else Color("ff786e")) text_at(str(i + 1), targets[i] + Vector2(-6, 7), 20) draw_circle(ball, 12, Color.WHITE) if dragging: draw_line(ball, ball + (drag_start - get_global_mouse_position()).limit_length(220), Color("79d7ff"), 3) text_at("Contacts %d / 2 Shots %d / 5" % [order, shots], Vector2(300, 120), 20) text_at(note if outcome == "" else outcome, Vector2(210, 612), 23) ''') GAMES[78] = ("Falling Symbols", '''extends Node2D var symbols: Array[String] = ["+", "X", "O", "#"] var target: Array[int] = [0, 2, 1, 3] var rows: Array[Dictionary] = [] var next: int = 0 var completed: int = 0 var misses: int = 0 var spawn: float = 0 var outcome: String = "" func reset() -> void: rows.clear() next = 0 completed = 0 misses = 0 spawn = 0 outcome = "" func cell(row: Dictionary, column: int) -> Rect2: return Rect2(270 + column * 110, row["y"], 96, 46) func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed and e.keycode == KEY_R: reset() if e is InputEventMouseButton and e.pressed and e.button_index == MOUSE_BUTTON_LEFT and outcome == "": for row in rows: for col in range(4): if cell(row, col).has_point(e.position) and not row["used"].has(col): if row["values"][col] == target[next]: row["used"].append(col) next += 1 if next == 4: completed += 1 next = 0 else: misses += 1 return func _process(dt: float) -> void: if outcome == "": spawn -= dt if spawn <= 0: var values: Array[int] = [0, 1, 2, 3] values.shuffle() rows.append({"y": 175.0, "values": values, "used": []}) spawn = 3 for i in range(rows.size() - 1, -1, -1): rows[i]["y"] += 40 * dt if rows[i]["y"] > 550: if rows[i]["used"].size() < 4: misses += 1 rows.remove_at(i) if completed >= 6: outcome = "Six symbol sequences completed! R: replay" elif misses >= 5: outcome = "Five mistakes or escaped rows. R: retry" queue_redraw() func _draw() -> void: backdrop("FALLING SYMBOLS", "Read target left to right | Click the next required symbol in any falling row | R: restart") for i in range(4): draw_rect(Rect2(300 + i * 95, 100, 70, 50), Color("99763e") if i == next else Color("334966")) text_at(symbols[target[i]], Vector2(322 + i * 95, 136), 30) for row in rows: for col in range(4): draw_rect(cell(row, col), Color("203343") if row["used"].has(col) else Color("476587")) if not row["used"].has(col): text_at(symbols[row["values"][col]], cell(row, col).position + Vector2(37, 32), 27) draw_line(Vector2(200, 597), Vector2(770, 597), Color("ff6176"), 3) text_at("Sequences %d / 6 Misses %d / 5" % [completed, misses], Vector2(280, 625), 20) text_at(outcome, Vector2(235, 575), 22) ''') GAMES[79] = ("Corner Runner", '''extends Node2D var distance: float = 0 var jump: float = 0 var tokens: Array[bool] = [false, false, false, false] var outcome: String = "" var obstacles: Array[float] = [220.0, 760.0, 1150.0, 1660.0] func reset() -> void: distance = 0 jump = 0 tokens = [false, false, false, false] outcome = "" func point(t: float) -> Vector2: t = fposmod(t, 1840) if t < 600: return Vector2(180 + t, 190) if t < 920: return Vector2(780, 190 + t - 600) if t < 1520: return Vector2(780 - (t - 920), 510) return Vector2(180, 510 - (t - 1520)) func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed and not e.echo: if e.keycode == KEY_R: reset() elif e.keycode == KEY_SPACE and jump <= 0: jump = 0.65 func _process(dt: float) -> void: if outcome == "": distance += 175 * dt jump = maxf(0, jump - dt) var checkpoints: Array[float] = [0.0, 600.0, 920.0, 1520.0] for i in range(4): if absf(fposmod(distance - checkpoints[i] + 920, 1840) - 920) < 18: tokens[i] = true for obstacle in obstacles: if absf(fposmod(distance - obstacle + 920, 1840) - 920) < 22 and jump < 0.1: outcome = "Hit an obstacle! R: jump a little earlier" if distance >= 1840 and not tokens.has(false): outcome = "Four corner tokens and a clean lap! R: replay" queue_redraw() func _draw() -> void: backdrop("CORNER RUNNER", "Automatic perimeter run | Space: jump inward over red obstacles | Collect four corner tokens | R: restart") draw_rect(Rect2(180, 190, 600, 320), Color("52617a"), false, 7) for t in obstacles: draw_rect(Rect2(point(t) - Vector2.ONE * 15, Vector2.ONE * 30), Color("ff6176")) var corners: Array[float] = [0.0, 600.0, 920.0, 1520.0] for i in range(4): if not tokens[i]: draw_circle(point(corners[i]), 14, Color("ffcd6b")) var p: Vector2 = point(distance) if jump > 0: p += (Vector2(480, 350) - p).normalized() * sin(jump / 0.65 * PI) * 75 draw_rect(Rect2(p - Vector2.ONE * 11, Vector2.ONE * 22), Color("5ef2d0")) text_at("Lap %d%% Tokens %d / 4" % [int(minf(distance / 1840, 1) * 100), tokens.count(true)], Vector2(315, 140)) text_at(outcome, Vector2(220, 600), 24) ''') GAMES[80] = ("Drifting Radio", '''extends Node2D var settings: Array[float] = [0.25, 0.25] var target: Array[float] = [0.5, 0.65] var selected: int = -1 var clock: float = 0 var stable: float = 0 var outcome: String = "" func reset() -> void: settings = [0.25, 0.25] clock = 0 stable = 0 outcome = "" func slider(i: int) -> Rect2: return Rect2(180, 430 + i * 90, 600, 35) func adjust(p: Vector2) -> void: if selected >= 0: settings[selected] = clampf((p.x - 180) / 600, 0, 1) func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed and e.keycode == KEY_R: reset() if e is InputEventMouseButton and e.button_index == MOUSE_BUTTON_LEFT: if e.pressed: for i in range(2): if slider(i).grow(14).has_point(e.position): selected = i adjust(e.position) else: selected = -1 if e is InputEventMouseMotion: adjust(e.position) func _process(dt: float) -> void: if outcome == "": clock += dt target = [0.5 + sin(clock * 0.3) * 0.18, 0.5 + cos(clock * 0.19) * 0.15] var error: float = absf(settings[0] - target[0]) + absf(settings[1] - target[1]) stable = minf(8, stable + dt) if error < 0.09 else maxf(0, stable - dt * 2) if stable >= 8: outcome = "Signal locked for eight seconds! R: retune" elif clock > 90: outcome = "Transmission ended. R: retry" queue_redraw() func _draw() -> void: backdrop("DRIFTING RADIO", "Drag FREQUENCY and PHASE sliders | Steady the waveform and track its drift for eight seconds | R: restart") var error: float = absf(settings[0] - target[0]) + absf(settings[1] - target[1]) var previous: Vector2 = Vector2(160, 280) for i in range(101): var x: float = i / 100.0 var y: float = sin(x * 30 + clock * error * 12) * error * 150 + sin(x * 10 + settings[1] * TAU) * 15 var point: Vector2 = Vector2(160 + x * 640, 280 + y) if i > 0: draw_line(previous, point, Color("5ef2d0") if error < 0.09 else Color("ff9568"), 3) previous = point for i in range(2): draw_rect(slider(i), Color("334966")) draw_circle(Vector2(180 + settings[i] * 600, 447 + i * 90), 17, Color("ffcd6b")) var guidance: String = "raise" if settings[i] < target[i] - 0.03 else "lower" if settings[i] > target[i] + 0.03 else "near lock" text_at(("FREQUENCY" if i == 0 else "PHASE") + " - " + guidance, Vector2(180, 416 + i * 90), 20) text_at("Stable %.1f / 8 seconds" % stable, Vector2(340, 140)) text_at(outcome, Vector2(255, 613), 23) ''') GAMES[81] = ("Three Plank Bridge", '''extends Node2D var gaps: Array[int] = [3, 4, 5, 8, 9, 12, 13, 14] var planks: Array[int] = [] var x: float = 105 var running: bool = false var outcome: String = "" func reset() -> void: planks.clear() x = 105 running = false outcome = "" func supported(cell: int) -> bool: if not gaps.has(cell): return true for start in planks: if cell >= start and cell < start + 3: return true return false func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed and not e.echo: if e.keycode == KEY_R: reset() elif e.keycode == KEY_SPACE and outcome == "": running = true if e is InputEventMouseButton and e.pressed and not running and e.position.y > 270 and e.position.y < 520: var cell: int = clampi(floori((e.position.x - 84) / 44), 0, 15) if e.button_index == MOUSE_BUTTON_LEFT and planks.size() < 3: planks.append(cell) elif e.button_index == MOUSE_BUTTON_RIGHT: for i in range(planks.size() - 1, -1, -1): if cell >= planks[i] and cell < planks[i] + 3: planks.remove_at(i) break func _process(dt: float) -> void: if running and outcome == "": x += 105 * dt var cell: int = floori((x - 84) / 44) if not supported(cell): outcome = "Unsupported step! R: rebuild the bridge" elif x >= 855: outcome = "Bridge test passed within budget! R: rebuild" queue_redraw() func _draw() -> void: backdrop("THREE PLANK BRIDGE", "Left click: place a three-tile plank starting there | Right click: remove | Space: test | R: restart") for i in range(18): var r: Rect2 = Rect2(84 + i * 44, 445, 44, 110) if not gaps.has(i): draw_rect(r, Color("46617d")) else: draw_rect(r, Color("142131")) text_at(str(i), Vector2(97 + i * 44, 590), 16) for start in planks: draw_rect(Rect2(84 + start * 44, 433, 132, 12), Color("ffcd6b")) draw_rect(Rect2(84 + start * 44, 433, 132, 12), Color("996b32"), false, 2) draw_rect(Rect2(x - 10, 405, 20, 28), Color("5ef2d0")) text_at("Budget: %d / 3 planks" % planks.size(), Vector2(335, 190), 25) text_at("Cover every dark gap. Unsupported steps fail immediately.", Vector2(205, 250), 20) text_at(outcome, Vector2(230, 625), 23) ''') GAMES[82] = ("Five Card Skirmish", '''extends Node2D var hp: int = 12 var enemy: int = 16 var energy: int = 3 var turn: int = 0 var intent: int = 0 var shield: int = 0 var note: String = "Choose a card; the previewed enemy action resolves next." var outcome: String = "" var names: Array[String] = ["STRIKE", "HEAVY", "SHIELD", "HEAL", "CHARGE"] var costs: Array[int] = [1, 2, 1, 2, 0] func reset() -> void: hp = 12 enemy = 16 energy = 3 turn = 0 intent = 0 shield = 0 outcome = "" func card(i: int) -> Rect2: return Rect2(50 + i * 174, 390, 160, 155) func play(i: int) -> void: if outcome != "": return if energy < costs[i]: note = "Not enough energy. Use CHARGE." return energy -= costs[i] shield = 0 match i: 0: enemy -= 3 1: enemy -= 6 2: shield = 5 3: hp = mini(12, hp + 5) 4: energy = mini(6, energy + 3) if enemy <= 0: outcome = "Enemy defeated! R: a new skirmish" return if intent == 0: hp -= maxi(0, 3 - shield) note = "Enemy attacked for 3, reduced by this turn's shield." elif intent == 1: hp -= maxi(0, 5 - shield) note = "Enemy used its previewed heavy attack." else: enemy = mini(16, enemy + 2) note = "Enemy recovered 2 health." turn += 1 intent = turn % 3 if hp <= 0: outcome = "You were defeated. R: plan against the preview" func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed and not e.echo: if e.keycode == KEY_R: reset() for i in range(5): if e.keycode == KEY_1 + i: play(i) if e is InputEventMouseButton and e.pressed and e.button_index == MOUSE_BUTTON_LEFT: for i in range(5): if card(i).has_point(e.position): play(i) queue_redraw() func _draw() -> void: backdrop("FIVE CARD SKIRMISH", "Click one of five cards or press 1–5 | Your action, then the previewed enemy turn | R: restart") text_at("YOU: %d / 12 HP Energy %d / 6" % [hp, energy], Vector2(80, 165), 24) text_at("ENEMY: %d / 16 HP" % enemy, Vector2(610, 165), 24) text_at("NEXT ENEMY: " + ["Attack 3", "Heavy attack 5", "Recover 2 HP"][intent], Vector2(285, 245), 26, Color("ff9568")) for i in range(5): draw_rect(card(i), Color("3a526e")) text_at(names[i], card(i).position + Vector2(14, 40), 22) text_at("Cost %d" % costs[i], card(i).position + Vector2(17, 83), 20) text_at(["3 damage", "6 damage", "Block 5", "Heal 5", "+3 energy"][i], card(i).position + Vector2(14, 125), 18) text_at(note if outcome == "" else outcome, Vector2(125, 610), 23) ''') GAMES[83] = ("Color Cargo Train", '''extends Node2D var train: Vector2i = Vector2i(1, 5) var direction: Vector2i = Vector2i.RIGHT var wagons: Dictionary = {Vector2i(3, 5): 0, Vector2i(6, 2): 1, Vector2i(9, 6): 2} var cargo: Array[int] = [] var target: Array[int] = [0, 1, 2] var history: Array[Vector2i] = [] var clock: float = 0 var outcome: String = "" var colors: Array[Color] = [Color("ff6176"), Color("79d7ff"), Color("ffcd6b")] func reset() -> void: train = Vector2i(1, 5) direction = Vector2i.RIGHT wagons = {Vector2i(3, 5): 0, Vector2i(6, 2): 1, Vector2i(9, 6): 2} cargo.clear() history.clear() clock = 0 outcome = "" func _input(e: InputEvent) -> void: if e is InputEventKey and e.pressed: if e.keycode == KEY_R: reset() var next: Vector2i = direction if e.keycode == KEY_LEFT: next = Vector2i.LEFT elif e.keycode == KEY_RIGHT: next = Vector2i.RIGHT elif e.keycode == KEY_UP: next = Vector2i.UP elif e.keycode == KEY_DOWN: next = Vector2i.DOWN if next != -direction: direction = next func _process(dt: float) -> void: if outcome == "": clock += dt if clock >= 0.35: clock = 0 history.push_front(train) if history.size() > 3: history.pop_back() train += direction if train.x < 0 or train.x >= 12 or train.y < 0 or train.y >= 8: outcome = "Train left the tracks! R: retry" elif wagons.has(train): cargo.append(wagons[train]) wagons.erase(train) if cargo[-1] != target[cargo.size() - 1]: outcome = "Wrong wagon order! R: reroute" if train == Vector2i(10, 1): outcome = "Matching train arrived! R: replay" if cargo == target else "Station rejected an incomplete sequence. R: retry" queue_redraw() func point(p: Vector2i) -> Vector2: return Vector2(215, 162) + Vector2(p) * 45 func _draw() -> void: backdrop("COLOR CARGO TRAIN", "Arrows: steer the moving train | Collect RED, BLUE, GOLD in order, then enter station S | R: restart") for y in range(8): for x in range(12): draw_rect(Rect2(point(Vector2i(x, y)) - Vector2.ONE * 21, Vector2.ONE * 42), Color("26394e"), false, 1) for p in wagons: draw_rect(Rect2(point(p) - Vector2.ONE * 15, Vector2.ONE * 30), colors[wagons[p]]) draw_rect(Rect2(point(Vector2i(10, 1)) - Vector2.ONE * 20, Vector2.ONE * 40), Color("31785a")) text_at("S", point(Vector2i(10, 1)) + Vector2(-7, 8), 24) for i in range(mini(cargo.size(), history.size())): draw_rect(Rect2(point(history[i]) - Vector2.ONE * 13, Vector2.ONE * 26), colors[cargo[i]]) draw_circle(point(train), 16, Color.WHITE) text_at("Wagons %d / 3 TARGET: RED > BLUE > GOLD" % cargo.size(), Vector2(230, 555)) text_at(outcome, Vector2(210, 610), 23) ''') GAMES[84] = ("Bubble Passage", '''extends Node2D var bubble: Vector2 = Vector2(160, 570) var air: float = 55 var walls: Array[Rect2] = [Rect2(20, 455, 395, 25), Rect2(445, 455, 495, 25), Rect2(20, 340, 625, 25), Rect2(675, 340, 265, 25), Rect2(20, 225, 305, 25), Rect2(335, 225, 605, 25)] var outcome: String = "" var radius: float = 16 func reset() -> void: bubble = Vector2(160, 570) air = 55 outcome = "" func _process(dt: float) -> void: if Input.is_physical_key_pressed(KEY_R): reset() if outcome == "": var shrink: bool = Input.is_action_pressed("ui_accept") radius = 4.0 if shrink else 16.0 air -= dt * (1.8 if shrink else 1.0) var movement: Vector2 = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") * 175 var next: Vector2 = bubble + movement * dt next.x = clampf(next.x, 25 + radius, 935 - radius) next.y = minf(600 - radius, next.y) var blocked: bool = false for r in walls: if r.grow(radius).has_point(next): blocked = true if not blocked: bubble = next if bubble.y < 130: outcome = "Surface reached with air to spare! R: dive again" elif air <= 0: outcome = "Air exhausted. R: shrink only at narrow gates" queue_redraw() func _draw() -> void: backdrop("BUBBLE PASSAGE", "Arrows: swim upward through the gates | Hold Space: shrink, using extra air | R: restart") draw_rect(Rect2(20, 95, 920, 35), Color("276c86")) text_at("SURFACE", Vector2(420, 120), 20) for r in walls: draw_rect(r, Color("46617d")) draw_circle(bubble, radius, Color("79d7ff")) draw_arc(bubble, radius, 0, TAU, 24, Color.WHITE, 2) text_at("Air %.1f %s" % [maxf(air, 0), "SHRUNK" if radius < 10 else "NORMAL"], Vector2(30, 625), 22) text_at(outcome, Vector2(320, 625), 22) ''') if __name__ == "__main__": main()