extends Node ## Frame and simulation cost in a real match scene at representative maximum occupation: ## six armies at the supply cap and a round-13 wave (synthetic fixture, gold granted to the ## fixture only). VSync off; figures apply to this machine only. ## Run: godot --path . --resolution 1920x1080 res://tools/luneraria/lune_benchmark.tscn const Game = preload("res://scripts/luneraria/lune_game.gd") func _ready() -> void: call_deferred("run") func run() -> void: Soundscape.enabled = false DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED) var t0: int = Time.get_ticks_usec() var game: Node3D = Game.new() add_child(game) game.start({"seed": 5, "human_slot": 0}) var build_ms: float = (Time.get_ticks_usec() - t0) / 1000.0 var state: LuneMatch = game.match_state state.round_number = 13 for slot: int in range(6): state.players[slot].draft.gold = 100000 state.players[slot].draft.roster.clear() LuneBot.plan(state, slot, "ausgewogen") game._on_ready() game.camera.look_at_point(Vector3(-10, 0, 10), 34.0, true) for i in 30: await get_tree().process_frame RenderingServer.viewport_set_measure_render_time(get_viewport().get_viewport_rid(), true) var frames: Array[float] = [] var gpu: Array[float] = [] var sim: Array[float] = [] var draws: Array[float] = [] var mobile: Array[int] = [] var last: int = Time.get_ticks_usec() var end: int = Time.get_ticks_msec() + 8000 game.speed_index = 1 while Time.get_ticks_msec() < end and state.phase == LuneMatch.Phase.COMBAT: var s0: int = Time.get_ticks_usec() var before: int = state.combat.steps await RenderingServer.frame_post_draw var now: int = Time.get_ticks_usec() frames.append((now - last) / 1000.0) last = now gpu.append(RenderingServer.viewport_get_measured_render_time_gpu(get_viewport().get_viewport_rid())) draws.append(Performance.get_monitor(Performance.RENDER_TOTAL_DRAW_CALLS_IN_FRAME)) mobile.append(state.combat.mobile_count()) # Pure simulation cost of one fixed step at this occupation, measured separately. var probe := LuneMatch.new() probe.setup({"seed": 5, "human_slot": -1}) probe.round_number = 13 for slot: int in range(6): probe.players[slot].draft.gold = 100000 LuneBot.plan(probe, slot, "ausgewogen") probe.begin_combat() var start_units: int = probe.combat.mobile_count() var s1: int = Time.get_ticks_usec() for i in 200: probe.step_combat() var step_ms: float = (Time.get_ticks_usec() - s1) / 1000.0 / 200.0 frames.sort() var mean := func(v: Array) -> float: var t: float = 0.0 for x in v: t += float(x) return t / maxf(1, v.size()) var report := {"window": get_window().size, "renderer": RenderingServer.get_current_rendering_method(), "gpu": RenderingServer.get_video_adapter_name(), "cpu": OS.get_processor_name(), "engine": Engine.get_version_info().string, "scene_build_ms": build_ms, "mobile_units_at_start": start_units, "mobile_units_mean_measured": mean.call(mobile), "buildings": 18, "frames": frames.size(), "frame_ms_mean": mean.call(frames), "frame_ms_p95": frames[int(frames.size() * .95)] if frames.size() > 0 else -1, "gpu_ms_mean": mean.call(gpu), "draw_calls_mean": mean.call(draws), "sim_step_ms": step_ms, "sim_speed": "2x (40 steps/s)", "video_mem_mb": Performance.get_monitor(Performance.RENDER_VIDEO_MEM_USED) / 1048576.0, "static_mem_mb": Performance.get_monitor(Performance.MEMORY_STATIC) / 1048576.0} var file := FileAccess.open("res://docs/luneraria/logs/perf-%dx%d.json" % [get_window().size.x, get_window().size.y], FileAccess.WRITE) file.store_string(JSON.stringify(report, "\t")) file.close() print("LUNE_BENCH ", JSON.stringify(report)) get_tree().quit()