Unveränderter Ausgangsstand inklusive Masterprompt und Konzeptbildern unter assets/. .godot/ und docs/screenshots/ bleiben laut .gitignore unversioniert; letztere sind unter ../backups gesichert. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
83 lines
3.9 KiB
GDScript
83 lines
3.9 KiB
GDScript
extends Node
|
|
## Menu load time and frame cost on the current machine (no general performance claim).
|
|
## Run: godot --path . --resolution 1920x1080 res://tools/menu_benchmark.tscn -- --label=after
|
|
var main: Node3D
|
|
func _ready() -> void:
|
|
call_deferred("run")
|
|
func viewports() -> Array[RID]:
|
|
var list: Array[RID] = [get_viewport().get_viewport_rid()]
|
|
for node: Node in get_tree().root.find_children("*", "SubViewport", true, false):
|
|
if (node as SubViewport).render_target_update_mode != SubViewport.UPDATE_DISABLED:
|
|
list.append((node as SubViewport).get_viewport_rid())
|
|
return list
|
|
func run() -> void:
|
|
var label := "run"
|
|
for arg: String in OS.get_cmdline_user_args():
|
|
if arg.begins_with("--label="):
|
|
label = arg.substr(8)
|
|
Soundscape.enabled = false
|
|
WaveManager.set_physics_process(false)
|
|
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED)
|
|
var started: int = Time.get_ticks_usec()
|
|
main = load("res://scenes/main.tscn").instantiate()
|
|
add_child(main)
|
|
var instanced: int = Time.get_ticks_usec()
|
|
await RenderingServer.frame_post_draw
|
|
var first_frame: int = Time.get_ticks_usec()
|
|
var in_game: bool = "--in-game" in OS.get_cmdline_user_args()
|
|
var stage_ready_ms: float = -1.0
|
|
var menu: Node = main.hud.get("main_menu")
|
|
if menu != null:
|
|
while not (menu.stage.is_ready("glutpakt") and menu.stage.is_ready("wurzelbund")):
|
|
await get_tree().process_frame
|
|
stage_ready_ms = (Time.get_ticks_usec() - started) / 1000.0
|
|
if in_game:
|
|
main.hud._overlay_action.pressed.emit()
|
|
label += "-build"
|
|
await get_tree().create_timer(1.0).timeout
|
|
for rid: RID in viewports():
|
|
RenderingServer.viewport_set_measure_render_time(rid, true)
|
|
var warm_until: int = Time.get_ticks_msec() + 2500
|
|
while Time.get_ticks_msec() < warm_until:
|
|
await get_tree().process_frame
|
|
var frames: Array[float] = []
|
|
var gpu: Array[float] = []
|
|
var cpu_render: Array[float] = []
|
|
var draw_calls: Array[float] = []
|
|
var last: int = Time.get_ticks_usec()
|
|
var end: int = Time.get_ticks_msec() + 6000
|
|
while Time.get_ticks_msec() < end:
|
|
await RenderingServer.frame_post_draw
|
|
var now: int = Time.get_ticks_usec()
|
|
frames.append((now - last) / 1000.0)
|
|
last = now
|
|
var g: float = 0.0
|
|
var c: float = 0.0
|
|
for rid: RID in viewports():
|
|
g += RenderingServer.viewport_get_measured_render_time_gpu(rid)
|
|
c += RenderingServer.viewport_get_measured_render_time_cpu(rid)
|
|
gpu.append(g)
|
|
cpu_render.append(c)
|
|
draw_calls.append(Performance.get_monitor(Performance.RENDER_TOTAL_DRAW_CALLS_IN_FRAME))
|
|
frames.sort()
|
|
var mean := func(values: Array[float]) -> float:
|
|
var total: float = 0.0
|
|
for v: float in values: total += v
|
|
return total / maxf(1, values.size())
|
|
var report := {
|
|
"label": label, "window": get_window().size, "canvas": get_viewport().get_visible_rect().size,
|
|
"renderer": RenderingServer.get_current_rendering_method(), "gpu": RenderingServer.get_video_adapter_name(),
|
|
"driver": RenderingServer.get_video_adapter_api_version(), "engine": Engine.get_version_info().string,
|
|
"os": OS.get_name() + " " + OS.get_version(), "cpu": OS.get_processor_name(),
|
|
"instantiate_ms": (instanced - started) / 1000.0, "first_frame_ms": (first_frame - started) / 1000.0, "stage_ready_ms": stage_ready_ms,
|
|
"frames": frames.size(), "frame_ms_mean": mean.call(frames), "frame_ms_p95": frames[int(frames.size() * .95)],
|
|
"gpu_ms_mean": mean.call(gpu), "render_cpu_ms_mean": mean.call(cpu_render),
|
|
"draw_calls_mean": mean.call(draw_calls), "video_mem_mb": Performance.get_monitor(Performance.RENDER_VIDEO_MEM_USED) / 1048576.0,
|
|
"static_mem_mb": Performance.get_monitor(Performance.MEMORY_STATIC) / 1048576.0,
|
|
"vsync": "disabled", "phase": GameState.phase_name(), "viewports_measured": viewports().size()}
|
|
var path := "res://docs/phase20-logs/perf-%s-%dx%d.json" % [label, get_window().size.x, get_window().size.y]
|
|
var file := FileAccess.open(path, FileAccess.WRITE)
|
|
file.store_string(JSON.stringify(report, "\t"))
|
|
file.close()
|
|
print("MENU_BENCHMARK: ", JSON.stringify(report))
|
|
await Soundscape.quit_game()
|