From 352ab75841fca53797d4c9046f0769dd169f5518 Mon Sep 17 00:00:00 2001 From: Jennie Robinson Faber Date: Sun, 17 May 2026 23:02:21 +0100 Subject: [PATCH 1/7] STRINGS for easier text management --- project.godot | 1 + scenes/elevator_panel.gd | 4 +-- scenes/end_screen.gd | 73 +++++++++++++++++++++++++++------------- scenes/end_screen.tscn | 38 ++++++--------------- scenes/muzak.gd | 4 --- scenes/pause_menu.gd | 16 ++++++--- scenes/pause_menu.tscn | 44 ++++-------------------- scenes/robot.gd | 2 +- scenes/screen.gd | 24 ++++++------- scenes/title_screen.gd | 3 ++ scenes/virtua_hand.gd | 11 ++++++ scripts/strings.gd | 31 +++++++++++++++++ scripts/strings.gd.uid | 1 + 13 files changed, 140 insertions(+), 112 deletions(-) create mode 100644 scripts/strings.gd create mode 100644 scripts/strings.gd.uid diff --git a/project.godot b/project.godot index 18b1fc2..99c20b2 100644 --- a/project.godot +++ b/project.godot @@ -18,6 +18,7 @@ config/icon="res://icon.svg" [autoload] EventBus="*uid://hxpxcxvxcisu" +Strings="*res://scripts/strings.gd" [input] diff --git a/scenes/elevator_panel.gd b/scenes/elevator_panel.gd index 1d1fbf6..bf9fd00 100644 --- a/scenes/elevator_panel.gd +++ b/scenes/elevator_panel.gd @@ -249,8 +249,8 @@ func _on_doors_closing(fast: bool = false): EventBus.doors_closed.emit(fast) if people_in_elevator < THRESHOLD: - _screen.show_loss("TOO FEW") - EventBus.game_lost.emit("TOO FEW") + _screen.show_loss("") + EventBus.game_lost.emit(Strings.LOSS_TOO_FEW) return var base_points = people_in_elevator * POINTS_PER_PERSON diff --git a/scenes/end_screen.gd b/scenes/end_screen.gd index badc443..d927024 100644 --- a/scenes/end_screen.gd +++ b/scenes/end_screen.gd @@ -3,32 +3,41 @@ extends CanvasLayer var _score := 0 var _saved := 0 var _lost := false +var _ready_for_input := false func _ready(): - visible = false EventBus.game_won.connect(_on_game_won) EventBus.game_lost.connect(_on_game_lost) EventBus.score_changed.connect(func(s): _score = s) EventBus.saved_changed.connect(func(s): _saved = s) - $Center/Card/Margin/Column/RestartButton.pressed.connect(_on_restart_pressed) + + $Center/Card/Margin/Column/SpaceHint.text = Strings.END_SPACE_HINT + + $Dim.modulate.a = 0.0 + $BlackFade.modulate.a = 0.0 + $Center.modulate.a = 0.0 + $Center/Card/Margin/Column/Headline.modulate.a = 0.0 + $Center/Card/Margin/Column/ScoreLabel.modulate.a = 0.0 + $Center/Card/Margin/Column/SavedLabel.modulate.a = 0.0 + $Center/Card/Margin/Column/SpaceHint.modulate.a = 0.0 + + visible = true func _unhandled_input(event): - if visible and _lost and event is InputEventKey and event.pressed and not event.echo and event.keycode == KEY_SPACE: + if _ready_for_input and event is InputEventKey and event.pressed and not event.echo and event.keycode == KEY_SPACE: get_viewport().set_input_as_handled() _on_restart_pressed() func _on_game_won(): - $Center/Card/Margin/Column/Headline.text = "YOU ESCAPED" + $Center/Card/Margin/Column/Headline.text = Strings.END_WIN_HEADLINE _lost = false - $Center/Card/Margin/Column/SpaceHint.visible = false - _show() + _run_intro_sequence() -func _on_game_lost(reason: String): - $Center/Card/Margin/Column/Headline.text = reason +func _on_game_lost(_reason: String): + $Center/Card/Margin/Column/Headline.text = Strings.END_LOSS_HEADLINE _lost = true - $Center/Card/Margin/Column/SpaceHint.visible = true _apply_loss_palette() - _show() + _run_intro_sequence() func _apply_loss_palette(): var border := Color(1, 0.3, 0.3, 1) @@ -36,23 +45,41 @@ func _apply_loss_palette(): $Dim.color = Color(0.18, 0.05, 0.05, 1) - var button = $Center/Card/Margin/Column/RestartButton - var button_style := (button.get_theme_stylebox("normal") as StyleBoxFlat).duplicate() as StyleBoxFlat - if button_style: - button_style.border_color = border - button_style.bg_color = Color(0.3, 0.1, 0.1, 1) - for state in ["normal", "hover", "pressed", "focus"]: - button.add_theme_stylebox_override(state, button_style) - button.add_theme_color_override("font_color", border) - $Center/Card/Margin/Column/Headline.add_theme_color_override("font_color", border) $Center/Card/Margin/Column/ScoreLabel.add_theme_color_override("font_color", subtle) $Center/Card/Margin/Column/SavedLabel.add_theme_color_override("font_color", subtle) -func _show(): - $Center/Card/Margin/Column/ScoreLabel.text = "Score: %d" % _score - $Center/Card/Margin/Column/SavedLabel.text = "Survivors saved: %d" % _saved - visible = true +func _run_intro_sequence() -> void: + $Center/Card/Margin/Column/ScoreLabel.text = Strings.END_SCORE_FMT % _score + $Center/Card/Margin/Column/SavedLabel.text = Strings.END_SAVED_FMT % _saved + + await get_tree().create_timer(0.8, false).timeout + + var fade_tween := create_tween() + fade_tween.tween_property($BlackFade, "modulate:a", 1.0, 1.2) + await fade_tween.finished + + $Dim.modulate.a = 1.0 + $Center.modulate.a = 1.0 + + var headline_tween := create_tween() + headline_tween.tween_property($Center/Card/Margin/Column/Headline, "modulate:a", 1.0, 0.4) + await headline_tween.finished + + await get_tree().create_timer(0.2, false).timeout + + var labels_tween := create_tween() + labels_tween.tween_property($Center/Card/Margin/Column/ScoreLabel, "modulate:a", 1.0, 0.4) + labels_tween.parallel().tween_property($Center/Card/Margin/Column/SavedLabel, "modulate:a", 1.0, 0.4) + await labels_tween.finished + + await get_tree().create_timer(0.2, false).timeout + + var hint_tween := create_tween() + hint_tween.tween_property($Center/Card/Margin/Column/SpaceHint, "modulate:a", 1.0, 0.4) + await hint_tween.finished + + _ready_for_input = true func _on_restart_pressed(): get_tree().reload_current_scene() diff --git a/scenes/end_screen.tscn b/scenes/end_screen.tscn index cf43acc..61f61b2 100644 --- a/scenes/end_screen.tscn +++ b/scenes/end_screen.tscn @@ -1,24 +1,9 @@ -[gd_scene load_steps=3 format=3] +[gd_scene load_steps=2 format=3] [ext_resource type="Script" path="res://scenes/end_screen.gd" id="1"] -[sub_resource type="StyleBoxFlat" id="ButtonStyle"] -bg_color = Color(0.1, 0.3, 0.1, 1) -border_width_left = 2 -border_width_top = 2 -border_width_right = 2 -border_width_bottom = 2 -border_color = Color(0.2, 1, 0.2, 1) -corner_radius_top_left = 4 -corner_radius_top_right = 4 -corner_radius_bottom_right = 4 -corner_radius_bottom_left = 4 -content_margin_left = 24 -content_margin_right = 24 -content_margin_top = 12 -content_margin_bottom = 12 - [node name="EndScreen" type="CanvasLayer"] +process_mode = 3 layer = 10 script = ExtResource("1") @@ -29,6 +14,14 @@ anchor_bottom = 1.0 mouse_filter = 2 color = Color(0.05, 0.18, 0.05, 1) +[node name="BlackFade" type="ColorRect" parent="."] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 +modulate = Color(1, 1, 1, 0) +color = Color(0, 0, 0, 1) + [node name="Center" type="CenterContainer" parent="."] anchors_preset = 15 anchor_right = 1.0 @@ -64,18 +57,7 @@ horizontal_alignment = 1 theme_override_colors/font_color = Color(0.7, 0.95, 0.7, 1) theme_override_font_sizes/font_size = 28 -[node name="RestartButton" type="Button" parent="Center/Card/Margin/Column"] -text = "RESTART" -theme_override_colors/font_color = Color(0.2, 1, 0.2, 1) -theme_override_colors/font_hover_color = Color(0.5, 1, 0.5, 1) -theme_override_font_sizes/font_size = 24 -theme_override_styles/normal = SubResource("ButtonStyle") -theme_override_styles/hover = SubResource("ButtonStyle") -theme_override_styles/pressed = SubResource("ButtonStyle") -theme_override_styles/focus = SubResource("ButtonStyle") - [node name="SpaceHint" type="Label" parent="Center/Card/Margin/Column"] -visible = false text = "Space to Restart" horizontal_alignment = 1 theme_override_colors/font_color = Color(0.95, 0.7, 0.7, 1) diff --git a/scenes/muzak.gd b/scenes/muzak.gd index 871f116..7e82fdb 100644 --- a/scenes/muzak.gd +++ b/scenes/muzak.gd @@ -26,7 +26,6 @@ func _ready() -> void: _barks.append(n) EventBus.game_started.connect(_on_game_started) EventBus.game_won.connect(_on_game_ended) - EventBus.game_lost.connect(_on_game_lost) func _process(_delta: float) -> void: if not playing: @@ -59,6 +58,3 @@ func _on_game_started() -> void: func _on_game_ended() -> void: stop() - -func _on_game_lost(_reason) -> void: - stop() diff --git a/scenes/pause_menu.gd b/scenes/pause_menu.gd index 3533718..398066c 100644 --- a/scenes/pause_menu.gd +++ b/scenes/pause_menu.gd @@ -8,8 +8,10 @@ func _ready(): EventBus.game_started.connect(func(): _in_play = true) EventBus.game_won.connect(func(): _in_play = false) EventBus.game_lost.connect(func(_reason: String): _in_play = false) - $Center/Card/Margin/Column/ResumeButton.pressed.connect(_on_resume_pressed) - $Center/Card/Margin/Column/RestartButton.pressed.connect(_on_restart_pressed) + + $Center/Card/Margin/Column/Title.text = Strings.PAUSE_TITLE + $Center/Card/Margin/Column/SpaceHint.text = Strings.PAUSE_SPACE_HINT + $Center/Card/Margin/Column/RestartHint.text = Strings.PAUSE_R_HINT func _unhandled_input(event): if not _in_play: @@ -18,9 +20,13 @@ func _unhandled_input(event): _toggle() get_viewport().set_input_as_handled() return - if get_tree().paused and event is InputEventKey and event.pressed and not event.echo and event.keycode == KEY_SPACE: - _on_resume_pressed() - get_viewport().set_input_as_handled() + if get_tree().paused and event is InputEventKey and event.pressed and not event.echo: + if event.keycode == KEY_SPACE: + _on_resume_pressed() + get_viewport().set_input_as_handled() + elif event.keycode == KEY_R: + _on_restart_pressed() + get_viewport().set_input_as_handled() func _toggle(): var paused := not get_tree().paused diff --git a/scenes/pause_menu.tscn b/scenes/pause_menu.tscn index c3f6ba4..f037c51 100644 --- a/scenes/pause_menu.tscn +++ b/scenes/pause_menu.tscn @@ -1,23 +1,7 @@ -[gd_scene load_steps=3 format=3] +[gd_scene load_steps=2 format=3] [ext_resource type="Script" path="res://scenes/pause_menu.gd" id="1"] -[sub_resource type="StyleBoxFlat" id="ButtonStyle"] -bg_color = Color(0.1, 0.3, 0.1, 1) -border_width_left = 2 -border_width_top = 2 -border_width_right = 2 -border_width_bottom = 2 -border_color = Color(0.2, 1, 0.2, 1) -corner_radius_top_left = 4 -corner_radius_top_right = 4 -corner_radius_bottom_right = 4 -corner_radius_bottom_left = 4 -content_margin_left = 24 -content_margin_right = 24 -content_margin_top = 12 -content_margin_bottom = 12 - [node name="PauseMenu" type="CanvasLayer"] layer = 25 process_mode = 3 @@ -53,28 +37,14 @@ horizontal_alignment = 1 theme_override_colors/font_color = Color(0.2, 1, 0.2, 1) theme_override_font_sizes/font_size = 56 -[node name="ResumeButton" type="Button" parent="Center/Card/Margin/Column"] -text = "RESUME" -theme_override_colors/font_color = Color(0.2, 1, 0.2, 1) -theme_override_colors/font_hover_color = Color(0.5, 1, 0.5, 1) -theme_override_font_sizes/font_size = 24 -theme_override_styles/normal = SubResource("ButtonStyle") -theme_override_styles/hover = SubResource("ButtonStyle") -theme_override_styles/pressed = SubResource("ButtonStyle") -theme_override_styles/focus = SubResource("ButtonStyle") - -[node name="RestartButton" type="Button" parent="Center/Card/Margin/Column"] -text = "RESTART" -theme_override_colors/font_color = Color(0.2, 1, 0.2, 1) -theme_override_colors/font_hover_color = Color(0.5, 1, 0.5, 1) -theme_override_font_sizes/font_size = 24 -theme_override_styles/normal = SubResource("ButtonStyle") -theme_override_styles/hover = SubResource("ButtonStyle") -theme_override_styles/pressed = SubResource("ButtonStyle") -theme_override_styles/focus = SubResource("ButtonStyle") - [node name="SpaceHint" type="Label" parent="Center/Card/Margin/Column"] text = "Space to Resume" horizontal_alignment = 1 theme_override_colors/font_color = Color(0.7, 0.95, 0.7, 1) theme_override_font_sizes/font_size = 20 + +[node name="RestartHint" type="Label" parent="Center/Card/Margin/Column"] +text = "R to Restart" +horizontal_alignment = 1 +theme_override_colors/font_color = Color(0.7, 0.95, 0.7, 1) +theme_override_font_sizes/font_size = 20 diff --git a/scenes/robot.gd b/scenes/robot.gd index 8beffe8..1f3fa8b 100644 --- a/scenes/robot.gd +++ b/scenes/robot.gd @@ -61,7 +61,7 @@ func _on_area_3d_area_entered(area: Area3D) -> void: var safety = safety_zone if area == safety and doors_open: robot_win = true - EventBus.game_lost.emit("ROBOT GOT IN") + EventBus.game_lost.emit(Strings.LOSS_ROBOT) func stalking_check(): if safety_zone == null: diff --git a/scenes/screen.gd b/scenes/screen.gd index 66a949f..b508fb6 100644 --- a/scenes/screen.gd +++ b/scenes/screen.gd @@ -72,7 +72,7 @@ func _ready(): face.position = Vector2(0, 0) face.size = Vector2(size.x, 30) face.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - face.text = ">:)" + face.text = Strings.SCREEN_FACE_IDLE face.pivot_offset = face.size / 2 _pulse.configure(sl, bz, _perfect_zone, size.x) @@ -125,7 +125,7 @@ func _ready(): _score_label.offset_right = -QUOTA_DOT_RIGHT_MARGIN _score_label.mouse_filter = Control.MOUSE_FILTER_IGNORE _score_label.visible = false - _score_label.text = "SCORE: 0" + _score_label.text = Strings.SCREEN_SCORE_FMT % 0 add_child(_score_label) EventBus.score_changed.connect(_on_score_changed) @@ -133,7 +133,7 @@ func _ready(): func start(floor_num: int = EventBus.STARTING_FLOOR): active = true - $AIFace.text = ">:)" + $AIFace.text = Strings.SCREEN_FACE_IDLE $TargetZone.visible = true block_zone_moving = false _pulse.start_floor(floor_num) @@ -153,7 +153,7 @@ func stop(): func launch_pulse(): if not active: return - $AIFace.text = ">:)" + $AIFace.text = Strings.SCREEN_FACE_IDLE _start_ready_pulse() _pulse.launch() @@ -178,7 +178,7 @@ var _displayed_floor := -1 func _update_floor_label(floor_num: int): if _displayed_floor == floor_num: return - var new_text = "FL " + str(floor_num) + var new_text = Strings.SCREEN_FLOOR_FMT % floor_num if _displayed_floor == -1: _floor_label.text = new_text _displayed_floor = floor_num @@ -229,7 +229,7 @@ func _update_quota_dots(count: int, threshold: int): func _on_score_changed(new_score: int): _score_value = new_score - _score_label.text = "SCORE: " + str(new_score) + _score_label.text = Strings.SCREEN_SCORE_FMT % new_score func _update_perfect_zone(): var bz = $TargetZone @@ -254,7 +254,7 @@ func _on_pulse_started(duration: float): pulse_started.emit(duration) func _on_pulse_blocked(): - $AIFace.text = ">:(" + $AIFace.text = Strings.SCREEN_FACE_BLOCKED _punch_face(1.4, 4.0) flash(Color.GREEN) pulse_blocked.emit() @@ -263,7 +263,7 @@ func _on_pulse_blocked_perfect(): pulse_blocked_perfect.emit() func _on_pulse_escaped(): - $AIFace.text = ":D" + $AIFace.text = Strings.SCREEN_FACE_ESCAPED _punch_face(1.5, 0.0) flash(Color.RED) active = false @@ -282,12 +282,12 @@ func flash(color: Color): func show_countdown(): $AIFace.visible = true stop() - $AIFace.text = "3" + $AIFace.text = Strings.SCREEN_COUNTDOWN_3 var tween = create_tween() tween.tween_interval(0.6) - tween.tween_callback(func(): $AIFace.text = "2") + tween.tween_callback(func(): $AIFace.text = Strings.SCREEN_COUNTDOWN_2) tween.tween_interval(0.6) - tween.tween_callback(func(): $AIFace.text = "1") + tween.tween_callback(func(): $AIFace.text = Strings.SCREEN_COUNTDOWN_1) tween.tween_interval(0.6) tween.tween_callback(func(): $AIFace.text = "") @@ -295,7 +295,7 @@ func show_win(): $AIFace.visible = true stop() $TargetZone.visible = false - $AIFace.text = "ESCAPED" + $AIFace.text = Strings.SCREEN_WIN_TEXT flash(Color.GREEN) func show_loss(message: String): diff --git a/scenes/title_screen.gd b/scenes/title_screen.gd index 066f57b..caa7446 100644 --- a/scenes/title_screen.gd +++ b/scenes/title_screen.gd @@ -1,6 +1,9 @@ extends CanvasLayer func _ready(): + $Center/Card/Margin/Column/Title.text = Strings.TITLE + $Center/Card/Margin/Column/Prompt.text = Strings.TITLE_PRESS_START + if EventBus.debug_starting_floor > 0: call_deferred("_start") return diff --git a/scenes/virtua_hand.gd b/scenes/virtua_hand.gd index b99a984..e501bc0 100644 --- a/scenes/virtua_hand.gd +++ b/scenes/virtua_hand.gd @@ -4,6 +4,8 @@ const SLIDE_DURATION := 0.25 const UP_DURATION := 0.1 const HOLD_DURATION := 0.05 const DOWN_DURATION := 0.18 +const ENTRY_OFFSET := 0.5 +const ENTRY_DURATION := 0.5 var _open_button: Node3D var _close_button: Node3D @@ -25,10 +27,19 @@ func _ready() -> void: _rest_y = position.y _target_button = _close_button position = Vector3(_close_rest_x, _rest_y, position.z) + visible = false print("[VirtuaHand] close_x=", _close_rest_x, " open_x=", _open_rest_x, " hand_pos=", position) EventBus.button_pressed.connect(_animate_press) EventBus.active_button_changed.connect(_on_active_button_changed) + EventBus.intro_finished.connect(_on_intro_finished) + +func _on_intro_finished() -> void: + var sprite_height := texture.get_height() * pixel_size * scale.y + position.y = _rest_y - sprite_height - ENTRY_OFFSET + visible = true + var entry_tween := create_tween() + entry_tween.tween_property(self, "position:y", _rest_y, ENTRY_DURATION).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_OUT) func _project_to_hand_plane(button: Node3D) -> float: var cam := get_viewport().get_camera_3d() diff --git a/scripts/strings.gd b/scripts/strings.gd new file mode 100644 index 0000000..fa02ac6 --- /dev/null +++ b/scripts/strings.gd @@ -0,0 +1,31 @@ +extends Node + +const TITLE := "AGENTIC INCIDENT +(A.I.)" +const TITLE_PRESS_START := "PRESS SPACE TO COMPLY" + +const PAUSE_TITLE := "ON A BREAK" +const PAUSE_RESUME := "RESUME" +const PAUSE_RESTART := "REBOOT" +const PAUSE_SPACE_HINT := "Space to clock back in" +const PAUSE_R_HINT := "R to Restart" + +const END_WIN_HEADLINE := "THANKS FOR RIDING GOATECH" +const END_LOSS_HEADLINE := "INCIDENT CLOSED" +const END_SCORE_FMT := "SCORE: %d" +const END_SAVED_FMT := "Headcount preserved: %d" +const END_RESTART := "RESTART" +const END_SPACE_HINT := "Space to REBOOT." + +const SCREEN_FACE_IDLE := ">:)" +const SCREEN_FACE_BLOCKED := ">:(" +const SCREEN_FACE_ESCAPED := ":D" +const SCREEN_WIN_TEXT := "ADEQUATE" +const SCREEN_FLOOR_FMT := "FL %d" +const SCREEN_SCORE_FMT := "SCORE: %d" +const SCREEN_COUNTDOWN_3 := "3" +const SCREEN_COUNTDOWN_2 := "2" +const SCREEN_COUNTDOWN_1 := "1" + +const LOSS_TOO_FEW := "HR WILL HEAR ABOUT THIS" +const LOSS_ROBOT := "I'M IN. — robot" diff --git a/scripts/strings.gd.uid b/scripts/strings.gd.uid new file mode 100644 index 0000000..83ac1bc --- /dev/null +++ b/scripts/strings.gd.uid @@ -0,0 +1 @@ +uid://d3q720oivpuq5 From 710ae4268ff882f74cce4955363eb9ecd7076d46 Mon Sep 17 00:00:00 2001 From: Jennie Robinson Faber Date: Sun, 17 May 2026 23:41:16 +0100 Subject: [PATCH 2/7] Wire up sfx, Sega Master System palette for win/end screen, add start screen --- audio/block.wav.import | 24 ++++++++++++++++++++++++ audio/floor_select.wav.import | 24 ++++++++++++++++++++++++ audio/hacked.wav.import | 24 ++++++++++++++++++++++++ scenes/elevator_panel.gd | 5 ++++- scenes/end_screen.gd | 18 ++++++++++++------ scenes/end_screen.tscn | 10 +++++----- scenes/game.tscn | 16 ++++++++++++++-- scenes/left_hand.gd | 1 + scenes/left_hand.tscn | 5 +++++ scenes/pause_menu.tscn | 8 ++++---- scenes/robot.gd | 35 ++++++++++++++++------------------- scenes/start_screen.gd | 25 +++++++++++++++++++++++++ scenes/title_screen.tscn | 6 +++--- 13 files changed, 161 insertions(+), 40 deletions(-) create mode 100644 audio/block.wav.import create mode 100644 audio/floor_select.wav.import create mode 100644 audio/hacked.wav.import diff --git a/audio/block.wav.import b/audio/block.wav.import new file mode 100644 index 0000000..c98f879 --- /dev/null +++ b/audio/block.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://6u5g67ptqsp4" +path="res://.godot/imported/block.wav-862e14aabfa854dd89f6e45e400ee640.sample" + +[deps] + +source_file="res://audio/block.wav" +dest_files=["res://.godot/imported/block.wav-862e14aabfa854dd89f6e45e400ee640.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/audio/floor_select.wav.import b/audio/floor_select.wav.import new file mode 100644 index 0000000..3c724c7 --- /dev/null +++ b/audio/floor_select.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://cxvu4rxkgxekb" +path="res://.godot/imported/floor_select.wav-9db728e2a2c96ff78e6dfca8f37fc437.sample" + +[deps] + +source_file="res://audio/floor_select.wav" +dest_files=["res://.godot/imported/floor_select.wav-9db728e2a2c96ff78e6dfca8f37fc437.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/audio/hacked.wav.import b/audio/hacked.wav.import new file mode 100644 index 0000000..cbe3fb8 --- /dev/null +++ b/audio/hacked.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://cyjww14gef86j" +path="res://.godot/imported/hacked.wav-1fd73f8141eb60a20baf48c5d06a02b3.sample" + +[deps] + +source_file="res://audio/hacked.wav" +dest_files=["res://.godot/imported/hacked.wav-1fd73f8141eb60a20baf48c5d06a02b3.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=2 diff --git a/scenes/elevator_panel.gd b/scenes/elevator_panel.gd index bf9fd00..483a94f 100644 --- a/scenes/elevator_panel.gd +++ b/scenes/elevator_panel.gd @@ -45,7 +45,9 @@ func _ready(): _screen.pulse_started.connect(_on_pulse_started) _screen.pulse_blocked.connect(_on_pulse_blocked) _screen.pulse_blocked_perfect.connect(_on_pulse_blocked_perfect) - _screen.doors_closing.connect(func(): _on_doors_closing(true)) + _screen.doors_closing.connect(func(): + $SfxHacked.play() + _on_doors_closing(true)) EventBus.game_started.connect(_on_game_started) EventBus.game_lost.connect(func(_reason): $SfxRobotIUnderstand.play()) @@ -167,6 +169,7 @@ func _enter_static_then_hacked(token: int) -> void: return state = ScreenState.HACKED _dbg("HACKED") + $SfxHacked.play() _screen.enter_hacked() EventBus.active_button_changed.emit("open"), CONNECT_ONE_SHOT diff --git a/scenes/end_screen.gd b/scenes/end_screen.gd index d927024..37acabb 100644 --- a/scenes/end_screen.gd +++ b/scenes/end_screen.gd @@ -40,14 +40,16 @@ func _on_game_lost(_reason: String): _run_intro_sequence() func _apply_loss_palette(): - var border := Color(1, 0.3, 0.3, 1) - var subtle := Color(0.95, 0.7, 0.7, 1) + var headline := Color(0.949, 0.227, 0.541, 1) + var body := Color(0.851, 0.541, 0.659, 1) + var hint := Color(0.941, 0.761, 0.831, 1) - $Dim.color = Color(0.18, 0.05, 0.05, 1) + $Dim.color = Color(0.078, 0.031, 0.18, 1) - $Center/Card/Margin/Column/Headline.add_theme_color_override("font_color", border) - $Center/Card/Margin/Column/ScoreLabel.add_theme_color_override("font_color", subtle) - $Center/Card/Margin/Column/SavedLabel.add_theme_color_override("font_color", subtle) + $Center/Card/Margin/Column/Headline.add_theme_color_override("font_color", headline) + $Center/Card/Margin/Column/ScoreLabel.add_theme_color_override("font_color", body) + $Center/Card/Margin/Column/SavedLabel.add_theme_color_override("font_color", body) + $Center/Card/Margin/Column/SpaceHint.add_theme_color_override("font_color", hint) func _run_intro_sequence() -> void: $Center/Card/Margin/Column/ScoreLabel.text = Strings.END_SCORE_FMT % _score @@ -81,5 +83,9 @@ func _run_intro_sequence() -> void: _ready_for_input = true + var flash_tween := create_tween().set_loops() + flash_tween.tween_property($Center/Card/Margin/Column/SpaceHint, "modulate:a", 0.2, 0.6).set_trans(Tween.TRANS_SINE) + flash_tween.tween_property($Center/Card/Margin/Column/SpaceHint, "modulate:a", 1.0, 0.6).set_trans(Tween.TRANS_SINE) + func _on_restart_pressed(): get_tree().reload_current_scene() diff --git a/scenes/end_screen.tscn b/scenes/end_screen.tscn index 61f61b2..5cafe56 100644 --- a/scenes/end_screen.tscn +++ b/scenes/end_screen.tscn @@ -12,7 +12,7 @@ anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 mouse_filter = 2 -color = Color(0.05, 0.18, 0.05, 1) +color = Color(0.102, 0.251, 0.278, 1) [node name="BlackFade" type="ColorRect" parent="."] anchors_preset = 15 @@ -42,23 +42,23 @@ theme_override_constants/separation = 24 [node name="Headline" type="Label" parent="Center/Card/Margin/Column"] text = "YOU ESCAPED" horizontal_alignment = 1 -theme_override_colors/font_color = Color(0.2, 1, 0.2, 1) +theme_override_colors/font_color = Color(0.553, 0.91, 1, 1) theme_override_font_sizes/font_size = 56 [node name="ScoreLabel" type="Label" parent="Center/Card/Margin/Column"] text = "Score: 0" horizontal_alignment = 1 -theme_override_colors/font_color = Color(0.7, 0.95, 0.7, 1) +theme_override_colors/font_color = Color(0.659, 1, 0.8, 1) theme_override_font_sizes/font_size = 28 [node name="SavedLabel" type="Label" parent="Center/Card/Margin/Column"] text = "Survivors saved: 0" horizontal_alignment = 1 -theme_override_colors/font_color = Color(0.7, 0.95, 0.7, 1) +theme_override_colors/font_color = Color(0.659, 1, 0.8, 1) theme_override_font_sizes/font_size = 28 [node name="SpaceHint" type="Label" parent="Center/Card/Margin/Column"] text = "Space to Restart" horizontal_alignment = 1 -theme_override_colors/font_color = Color(0.95, 0.7, 0.7, 1) +theme_override_colors/font_color = Color(0.961, 1, 0.851, 1) theme_override_font_sizes/font_size = 20 diff --git a/scenes/game.tscn b/scenes/game.tscn index 3fdc46c..5dae264 100644 --- a/scenes/game.tscn +++ b/scenes/game.tscn @@ -14,11 +14,13 @@ [ext_resource type="PackedScene" path="res://scenes/end_screen.tscn" id="10_endsc"] [ext_resource type="AudioStream" uid="uid://dln0g1bnjh1of" path="res://audio/Robot - I Understand.wav" id="10_under"] [ext_resource type="AudioStream" uid="uid://bwovhu6jfk0vt" path="res://audio/Robot - Thank You.wav" id="11_thx"] -[ext_resource type="PackedScene" uid="uid://sgakdvtoblmd" path="res://scenes/title_screen.tscn" id="11_title"] +[ext_resource type="PackedScene" uid="uid://bbw2sfptheq4u" path="res://scenes/start_screen.tscn" id="11_title"] [ext_resource type="AudioStream" uid="uid://b3d6rntbosvc6" path="res://audio/Ambience.wav" id="12_amb"] [ext_resource type="PackedScene" path="res://scenes/pause_menu.tscn" id="12_pause"] [ext_resource type="AudioStream" uid="uid://cnfmytsyo8biq" path="res://audio/RoboZacSpeaker.wav" id="13_muzak"] [ext_resource type="Script" uid="uid://deyjxii7yykjv" path="res://scenes/muzak.gd" id="14_muzak_s"] +[ext_resource type="AudioStream" uid="uid://6u5g67ptqsp4" path="res://audio/block.wav" id="15_block"] +[ext_resource type="AudioStream" uid="uid://cyjww14gef86j" path="res://audio/hacked.wav" id="16_hacked"] [node name="Game" type="Node3D" unique_id=1456297160] script = ExtResource("1_lbhrr") @@ -64,6 +66,12 @@ stream = ExtResource("10_under") stream = ExtResource("11_thx") [node name="SfxBlock" type="AudioStreamPlayer3D" parent="CanvasPanel/ElevatorPanel" unique_id=1100000007] +stream = ExtResource("15_block") +max_polyphony = 4 + +[node name="SfxHacked" type="AudioStreamPlayer3D" parent="CanvasPanel/ElevatorPanel" unique_id=1100000008] +stream = ExtResource("16_hacked") +max_polyphony = 4 [node name="Ambience" type="AudioStreamPlayer" parent="." unique_id=1100000005] process_mode = 3 @@ -80,7 +88,11 @@ script = ExtResource("14_muzak_s") [node name="EndScreen" parent="." unique_id=993175156 instance=ExtResource("10_endsc")] -[node name="TitleScreen" parent="." unique_id=1656317143 instance=ExtResource("11_title")] +[node name="TitleScreen" type="CanvasLayer" parent="." unique_id=1656317143] +process_mode = 3 +layer = 20 + +[node name="StartScreen" parent="TitleScreen" instance=ExtResource("11_title")] [node name="PauseMenu" parent="." unique_id=1244164419 instance=ExtResource("12_pause")] diff --git a/scenes/left_hand.gd b/scenes/left_hand.gd index 80720cb..7081911 100644 --- a/scenes/left_hand.gd +++ b/scenes/left_hand.gd @@ -119,6 +119,7 @@ func _update_intro_progress(progress: float) -> void: func _light_button(index: int) -> void: var sprite: Sprite3D = _buttons[index].get_node("ButtonSprite") sprite.frame = index + 10 + $SfxFloorSelect.play() func _set_all_lit(lit: bool) -> void: for i in range(_buttons.size()): diff --git a/scenes/left_hand.tscn b/scenes/left_hand.tscn index 5360e2f..939a93e 100644 --- a/scenes/left_hand.tscn +++ b/scenes/left_hand.tscn @@ -2,6 +2,7 @@ [ext_resource type="Texture2D" path="res://images/virtua_hand_left.png" id="1_lhand"] [ext_resource type="Script" path="res://scenes/left_hand.gd" id="2_lhscr"] +[ext_resource type="AudioStream" uid="uid://cxvu4rxkgxekb" path="res://audio/floor_select.wav" id="3_fsel"] [node name="LeftHand" type="Sprite3D"] billboard = 1 @@ -9,3 +10,7 @@ texture_filter = 0 alpha_cut = 1 texture = ExtResource("1_lhand") script = ExtResource("2_lhscr") + +[node name="SfxFloorSelect" type="AudioStreamPlayer3D" parent="."] +stream = ExtResource("3_fsel") +max_polyphony = 16 diff --git a/scenes/pause_menu.tscn b/scenes/pause_menu.tscn index f037c51..cf02973 100644 --- a/scenes/pause_menu.tscn +++ b/scenes/pause_menu.tscn @@ -12,7 +12,7 @@ anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 mouse_filter = 2 -color = Color(0.05, 0.18, 0.05, 1) +color = Color(0.102, 0.251, 0.278, 1) [node name="Center" type="CenterContainer" parent="."] anchors_preset = 15 @@ -34,17 +34,17 @@ theme_override_constants/separation = 24 [node name="Title" type="Label" parent="Center/Card/Margin/Column"] text = "PAUSED" horizontal_alignment = 1 -theme_override_colors/font_color = Color(0.2, 1, 0.2, 1) +theme_override_colors/font_color = Color(0.553, 0.91, 1, 1) theme_override_font_sizes/font_size = 56 [node name="SpaceHint" type="Label" parent="Center/Card/Margin/Column"] text = "Space to Resume" horizontal_alignment = 1 -theme_override_colors/font_color = Color(0.7, 0.95, 0.7, 1) +theme_override_colors/font_color = Color(0.659, 1, 0.8, 1) theme_override_font_sizes/font_size = 20 [node name="RestartHint" type="Label" parent="Center/Card/Margin/Column"] text = "R to Restart" horizontal_alignment = 1 -theme_override_colors/font_color = Color(0.7, 0.95, 0.7, 1) +theme_override_colors/font_color = Color(0.659, 1, 0.8, 1) theme_override_font_sizes/font_size = 20 diff --git a/scenes/robot.gd b/scenes/robot.gd index 1f3fa8b..e72f354 100644 --- a/scenes/robot.gd +++ b/scenes/robot.gd @@ -2,15 +2,16 @@ extends CharacterBody3D const STALK_DARK_DISTANCE := 19.0 const STALK_ILLUMINATE_DISTANCE := 15.0 +const WALK_IN_DURATION := 1.5 -var robot_ready: bool = false var robot_win: bool = false var speed: float = 1.0 var doors_open: bool = true var stun_remaining: float = 0.0 var _stalking_close: bool = false +var _walk_in_remaining: float = 0.0 +var _game_lost_emitted: bool = false -var _delay_remaining: float = 0.0 var _spawn_transform: Transform3D var safety_zone: Area3D @@ -30,21 +31,19 @@ func _on_floor_started(delay: float, new_speed: float) -> void: velocity = Vector3.ZERO stun_remaining = 0.0 speed = new_speed - _delay_remaining = delay - robot_ready = false func _physics_process(delta): - - stalking_check() - - if robot_win: - return - if not robot_ready: - if _delay_remaining > 0.0: - _delay_remaining -= delta - if _delay_remaining <= 0.0: - robot_ready = true + stalking_check() + + if robot_win: + velocity = Vector3(0, 0, -speed) + move_and_slide() + if not _game_lost_emitted: + _walk_in_remaining -= delta + if _walk_in_remaining <= 0.0: + _game_lost_emitted = true + EventBus.game_lost.emit("ROBOT GOT IN") return if stun_remaining > 0.0: @@ -59,14 +58,12 @@ func _physics_process(delta): func _on_area_3d_area_entered(area: Area3D) -> void: var safety = safety_zone - if area == safety and doors_open: + if area == safety and doors_open and not robot_win: robot_win = true - EventBus.game_lost.emit(Strings.LOSS_ROBOT) + _walk_in_remaining = WALK_IN_DURATION func stalking_check(): - if safety_zone == null: - return - + var robot_position = self.global_transform.origin var elevator = safety_zone.global_transform.origin var distance = robot_position.distance_to(elevator) diff --git a/scenes/start_screen.gd b/scenes/start_screen.gd index e07a0bf..753103b 100644 --- a/scenes/start_screen.gd +++ b/scenes/start_screen.gd @@ -1 +1,26 @@ extends Control + +func _ready(): + if EventBus.debug_starting_floor > 0: + call_deferred("_start") + return + get_tree().paused = true + +func _unhandled_input(event): + if event is InputEventKey and event.pressed and not event.echo: + if event.keycode == KEY_SPACE or event.keycode == KEY_ENTER: + get_viewport().set_input_as_handled() + _start() + elif event.keycode >= KEY_1 and event.keycode <= KEY_9: + EventBus.debug_starting_floor = event.keycode - KEY_0 + get_viewport().set_input_as_handled() + _start() + elif event.keycode == KEY_0: + EventBus.debug_starting_floor = EventBus.STARTING_FLOOR + get_viewport().set_input_as_handled() + _start() + +func _start(): + get_tree().paused = false + EventBus.game_started.emit() + get_parent().queue_free() diff --git a/scenes/title_screen.tscn b/scenes/title_screen.tscn index 046450d..c928fda 100644 --- a/scenes/title_screen.tscn +++ b/scenes/title_screen.tscn @@ -12,7 +12,7 @@ anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 mouse_filter = 2 -color = Color(0.05, 0.18, 0.05, 1) +color = Color(0.102, 0.251, 0.278, 1) [node name="Center" type="CenterContainer" parent="." unique_id=9544562] anchors_preset = 15 @@ -35,7 +35,7 @@ theme_override_constants/separation = 24 [node name="Title" type="Label" parent="Center/Card/Margin/Column" unique_id=358683873] layout_mode = 2 -theme_override_colors/font_color = Color(0.2, 1, 0.2, 1) +theme_override_colors/font_color = Color(0.553, 0.91, 1, 1) theme_override_font_sizes/font_size = 48 text = "AGENTIC INCIDENT (A.I.)" @@ -43,7 +43,7 @@ horizontal_alignment = 1 [node name="Prompt" type="Label" parent="Center/Card/Margin/Column" unique_id=366312976] layout_mode = 2 -theme_override_colors/font_color = Color(0.5, 1, 0.5, 1) +theme_override_colors/font_color = Color(0.659, 1, 0.8, 1) theme_override_font_sizes/font_size = 28 text = "PRESS SPACE TO START" horizontal_alignment = 1 From 67820a291c75106aabf74de5c076c21cee1aab2a Mon Sep 17 00:00:00 2001 From: Jennie Robinson Faber Date: Sun, 17 May 2026 23:48:32 +0100 Subject: [PATCH 3/7] Free the robots --- scenes/world.gd | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scenes/world.gd b/scenes/world.gd index 96c6ed7..6e46f2b 100644 --- a/scenes/world.gd +++ b/scenes/world.gd @@ -20,10 +20,10 @@ func _ready() -> void: _wall_display.modulate = WALL_DISPLAY_COLOR _wall_display.text = str(_current_floor) EventBus.doors_closed.connect(_on_doors_closed) - EventBus.doors_fully_closed.connect(_free_robot) + EventBus.doors_fully_closed.connect(_free_robot_unless_winning) EventBus.doors_opened.connect(_on_doors_opened) EventBus.floor_changed.connect(_on_floor_changed) - EventBus.game_lost.connect(func(_reason: String): _free_robot()) + EventBus.game_lost.connect(func(_reason: String): _free_robot_unless_winning()) EventBus.game_won.connect(_free_robot) func _collect_dim_targets() -> void: @@ -62,6 +62,11 @@ func _free_robot() -> void: _robot.queue_free() _robot = null +func _free_robot_unless_winning() -> void: + if is_instance_valid(_robot) and _robot.robot_win: + return + _free_robot() + func _on_floor_changed(new_floor: int) -> void: _current_floor = new_floor _wall_display.text = str(new_floor) From bce5ded6f356f0ac2f5a8eee588bcf29c6bed32d Mon Sep 17 00:00:00 2001 From: Jennie Robinson Faber Date: Sun, 17 May 2026 23:48:42 +0100 Subject: [PATCH 4/7] Fix weird illumination thing --- scenes/robot.gd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scenes/robot.gd b/scenes/robot.gd index e72f354..cbcaf2e 100644 --- a/scenes/robot.gd +++ b/scenes/robot.gd @@ -76,10 +76,10 @@ func stalking_check(): if not _stalking_close: _stalking_close = true EventBus.robot_close_warning.emit() - illuminate() + illuminate() func illuminate(): var tween = create_tween().parallel() - tween.tween_property($Sprite3D, "modulate",Color(255,255,255), 5) + tween.tween_property($Sprite3D, "modulate",Color(1,1,1), 5) From eceb7f509720e53c3305c9d6935821bee2aa5770 Mon Sep 17 00:00:00 2001 From: Jennie Robinson Faber Date: Sun, 17 May 2026 23:58:43 +0100 Subject: [PATCH 5/7] Add loss reason to loss screen --- scenes/end_screen.gd | 4 ++-- scenes/robot.gd | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scenes/end_screen.gd b/scenes/end_screen.gd index 37acabb..012e666 100644 --- a/scenes/end_screen.gd +++ b/scenes/end_screen.gd @@ -33,8 +33,8 @@ func _on_game_won(): _lost = false _run_intro_sequence() -func _on_game_lost(_reason: String): - $Center/Card/Margin/Column/Headline.text = Strings.END_LOSS_HEADLINE +func _on_game_lost(reason: String): + $Center/Card/Margin/Column/Headline.text = reason _lost = true _apply_loss_palette() _run_intro_sequence() diff --git a/scenes/robot.gd b/scenes/robot.gd index cbcaf2e..1f7c46f 100644 --- a/scenes/robot.gd +++ b/scenes/robot.gd @@ -43,7 +43,7 @@ func _physics_process(delta): _walk_in_remaining -= delta if _walk_in_remaining <= 0.0: _game_lost_emitted = true - EventBus.game_lost.emit("ROBOT GOT IN") + EventBus.game_lost.emit(Strings.LOSS_ROBOT) return if stun_remaining > 0.0: From 8717b4704a2e1504f6d10689f6a03ddb4798115b Mon Sep 17 00:00:00 2001 From: Jennie Robinson Faber Date: Sun, 17 May 2026 23:58:50 +0100 Subject: [PATCH 6/7] Text tweak --- scripts/strings.gd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/strings.gd b/scripts/strings.gd index fa02ac6..1d1bbd4 100644 --- a/scripts/strings.gd +++ b/scripts/strings.gd @@ -27,5 +27,6 @@ const SCREEN_COUNTDOWN_3 := "3" const SCREEN_COUNTDOWN_2 := "2" const SCREEN_COUNTDOWN_1 := "1" -const LOSS_TOO_FEW := "HR WILL HEAR ABOUT THIS" -const LOSS_ROBOT := "I'M IN. — robot" +const LOSS_TOO_FEW := "INCIDENT CLOSED +- HR WILL HEAR ABOUT THIS -" +const LOSS_ROBOT := "I'M IN. – robot" From 21f925412e1dedfedeaf994cae3b65c299aabdbe Mon Sep 17 00:00:00 2001 From: Jennie Robinson Faber Date: Sun, 17 May 2026 23:59:00 +0100 Subject: [PATCH 7/7] Increment score within floor --- scenes/elevator_panel.gd | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/scenes/elevator_panel.gd b/scenes/elevator_panel.gd index 483a94f..343367b 100644 --- a/scenes/elevator_panel.gd +++ b/scenes/elevator_panel.gd @@ -220,6 +220,10 @@ func _on_pulse_blocked(): survivors_remaining -= 1 people_in_elevator += 1 EventBus.people_changed.emit(people_in_elevator, THRESHOLD) + score += POINTS_PER_PERSON + if people_in_elevator > THRESHOLD: + score += POINTS_PER_PERSON + EventBus.score_changed.emit(score) if $SfxBlock.stream: $SfxBlock.play() @@ -256,12 +260,7 @@ func _on_doors_closing(fast: bool = false): EventBus.game_lost.emit(Strings.LOSS_TOO_FEW) return - var base_points = people_in_elevator * POINTS_PER_PERSON - var bonus = max(0, people_in_elevator - THRESHOLD) * POINTS_PER_PERSON - score += base_points + bonus saved_count += people_in_elevator - - EventBus.score_changed.emit(score) EventBus.saved_changed.emit(saved_count) current_floor -= 1