Polish the bear's thank-you ending screen; add a video debug command
CI / Decide whether to run (push) Has been cancelled
CI / Lint & headless tests (push) Has been cancelled

- The finish screen's continue button now reads "Play Again" and starts
  a fresh run instead of "Continue"-ing to a lobby gate that no longer
  exists past the run's last fight.
- The "Your Time" readout moves from the top (overlapping the bull in
  thankyou.ogv) to just under the clip's own baked title, restyled to
  match its flat dark-ink look instead of the gold HUD outline, and
  pulses on the same ~1.4s breathing cycle sampled off the source clip
  so it reads as part of the poster rather than a readout stamped on it.
- Added a `video <win|loss|finish>` debug console command to preview
  any outcome screen without playing through a fight, via a new
  hud.gd debug entry point (`debug_force_outcome`).
- Dropped the console's per-frame "focus stolen by ... — reclaiming"
  log line — its own comment flagged it as temporary diagnostic
  instrumentation, and it fired on every console open.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MXBNaEBmrYDSMcv4NgUWtV
This commit is contained in:
2026-09-10 17:36:03 +03:00
parent cd54242de0
commit 1ea4171863
2 changed files with 142 additions and 16 deletions
+24 -6
View File
@@ -20,6 +20,7 @@ const _COMMANDS := {
"list": "print params (optional section)",
"level": "select level and reload (level <id> — arena / arena_boss / bear)",
"restart": "reload the current level scene",
"video": "preview an outcome screen (video win / loss / finish)",
"clear": "clear the log",
"help": "show this help",
}
@@ -206,12 +207,6 @@ func _input(event: InputEvent) -> void:
# while the console is open — cheap, and it never lets the command line go dark.
func _process(_delta: float) -> void:
if _is_open and not _input_field.has_focus():
# Diagnostic: name whatever currently holds focus before we snatch it back, so
# a persistent thief (a HUD button, a menu control) shows up in the log instead
# of us guessing. Remove once the culprit is identified.
var owner: Control = get_viewport().gui_get_focus_owner()
var who: String = String(owner.name) if owner != null else "<nothing>"
_log_warn("focus stolen by %s — reclaiming" % who)
_input_field.grab_focus()
@@ -476,6 +471,8 @@ func _run_command(parts: PackedStringArray) -> bool:
_cmd_list(parts)
"level":
_cmd_level(parts)
"video":
_cmd_video(parts)
"restart":
_log_ok("Restarting…")
get_tree().paused = false
@@ -608,6 +605,27 @@ func _set_param(key: String, meta: Dictionary, raw: String) -> void:
_log_warn("Cannot set param of type %d" % meta["type"])
# Jumps straight to an outcome screen (win / loss / the bear's thankyou.ogv finish clip)
# via hud.gd's debug-only entry point — a quick way to preview a clip's framing/timing
# without actually clearing (or dying to) a fight.
const _VIDEO_KINDS := ["win", "loss", "finish"]
func _cmd_video(parts: PackedStringArray) -> void:
if parts.size() < 2 or not _VIDEO_KINDS.has(parts[1].to_lower()):
_log_warn("Usage: video <%s>" % "|".join(_VIDEO_KINDS))
return
var hud: Node = get_tree().get_first_node_in_group(&"hud")
if hud == null:
_log_warn("No HUD in the current scene.")
return
var kind := parts[1].to_lower()
get_tree().paused = false
_toggle() # close the console so it doesn't sit on top of the outcome screen
hud.debug_force_outcome(kind)
_log_ok("Playing '%s' outcome…" % kind)
func _cmd_level(parts: PackedStringArray) -> void:
if parts.size() == 1:
var cur := Run.active_level()