When a SNAP window ends (rage.calmed), scripts/Receipt.gd prints a dot-matrix incident report on green-bar paper, line by line with a chirp each: every material you broke DURING the meltdown as OBJECT / unit $ / xN, then TOTAL DAMAGES, then DEDUCTED FROM PAY. It's a reading of score data the payslip already tracks, made legible in the moment it costs you. Any key finishes the print then dismisses; five seconds does it on its own. A meltdown where you broke nothing prints nothing. dev/probe_receipt.gd: empty meltdown -> no receipt; glass x2 + paper -> $85 total. All gates green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
58 lines
1.7 KiB
GDScript
58 lines
1.7 KiB
GDScript
extends SceneTree
|
|
|
|
## The incident report contract:
|
|
## - a meltdown with breakage produces a report with the right total
|
|
## - a meltdown with NO breakage produces NOTHING (no empty receipt)
|
|
##
|
|
## Godot --headless --path game --script dev/probe_receipt.gd
|
|
|
|
func _initialize() -> void:
|
|
var main: Node = (load("res://main.tscn") as PackedScene).instantiate()
|
|
get_root().add_child(main)
|
|
await process_frame
|
|
for i in 20:
|
|
await physics_frame
|
|
|
|
var rage = main.get("_rage")
|
|
var receipt: Receipt = main.get("_receipt")
|
|
if rage == null or receipt == null:
|
|
print("FAIL: rage or receipt missing")
|
|
quit(1)
|
|
return
|
|
|
|
# --- case 1: empty meltdown -> no report ---
|
|
rage._snap()
|
|
await physics_frame
|
|
rage._calm()
|
|
await physics_frame
|
|
if receipt.visible:
|
|
print("FAIL: empty meltdown produced a receipt")
|
|
quit(1)
|
|
return
|
|
print("empty meltdown -> no receipt: OK")
|
|
|
|
# --- case 2: break three things during a meltdown ---
|
|
rage._snap()
|
|
await physics_frame
|
|
main._on_smashed("glass", Vector3.ZERO, 8) # $40
|
|
main._on_smashed("glass", Vector3.ZERO, 8) # $40
|
|
main._on_smashed("paper", Vector3.ZERO, 3) # $5
|
|
rage._calm()
|
|
await physics_frame
|
|
if not receipt.visible:
|
|
print("FAIL: meltdown with breakage produced no receipt")
|
|
quit(1)
|
|
return
|
|
# assert on the built lines (the animated label reveals over real seconds, which a
|
|
# near-instant headless frame loop won't advance)
|
|
var txt: String = "\n".join(receipt._lines)
|
|
print("--- receipt ---")
|
|
print(txt)
|
|
print("---------------")
|
|
if txt.contains("TOTAL DAMAGES") and txt.contains("85") and txt.contains("Glazing") and txt.contains("x2"):
|
|
print("RECEIPT OK")
|
|
quit(0)
|
|
else:
|
|
print("FAIL: receipt total/lines wrong (expected $85, glass x2)")
|
|
quit(1)
|