Linked repository source
examples/boid_flock/project/main.gd
This read-only view comes from the file in the Gododin repository. It retains its design, example or evidence context.
Download the original file · Return to the guide
extends Node3D
## Scene orchestration and bounded measurement. Only the selected flock runs.
## Callback timing covers producer+submission; separate monotonic frame-entry
## intervals include scene, renderer and pacing. Raw samples are saved after timing.
## Native 10,000 agents remains the original workload; --mode=native|gd at
## --count=400 is a separate matched-population implementation comparison.
##
## EX-BOID: the scene's controls initialize from the Flock's saved
## and never write back), and the predator is a visible saved Node3D actor —
## mouse mode moves that node by hand, patrol mode lets its deterministic Godot
## animation move it — whose transform feeds both simulation arms identically.
## Evaluation runs disable the actor entirely; the canonical workload is
## unchanged.
const SIMULATION_SEED := 20260911
const MAX_SPEED := 6.0
const BASELINE_CAP := 500
enum PredatorMode { OFF, MOUSE, PATROL }
var eval_mode := false
var profile_render := false
var start_on_click := false
var eval_started := false
var eval_count := 10000
var eval_frames := 600
var eval_variant := "native"
var _eval_frame := 0
var _eval_usec := 0.0
var _measured_frames := 0
var _failed := false
var _ready_done := false
var _predator_mode: int = PredatorMode.OFF
var _sim_seed := SIMULATION_SEED
var _max_speed := MAX_SPEED
var _mouse_painting := false
var _headless := false
var _finished := false
var _captured := false
var _verify_cases := 0
var _sample_intervals := PackedInt64Array()
var _previous_entry := 0
var _callback_samples := PackedInt64Array()
var unfocused_samples := 0
@onready var _field: Node = %Flock
@onready var _baseline: Node3D = %Baseline
@onready var _predator: Node3D = %Predator
@onready var _camera: Camera3D = %CameraRig.get_node("Camera3D")
const RENDER_PROFILE_WIDTH := 9
var _render_profile_samples := PackedFloat64Array()
var _render_profile_count := 0
var _render_profile_viewport: RID
var _render_profile_active := false
var _render_wall_started := 0
var _render_wall_usec := 0
var _profile_stats_usec := 0
var _profile_stats_calls := 0
func _ready() -> void:
if not RenderingServer.is_on_render_thread():
_fail("separate_render_thread_unsupported")
return
_baseline.set_process(false)
%Mode.add_item("Native staged")
%Mode.add_item("GDScript per instance (≤500)")
%Mode.item_selected.connect(_on_mode_selected)
%Count.value_changed.connect(_on_count_slider)
%UI.get_node("CountApplyTimer").timeout.connect(_apply_count)
for slider in [%Separation, %Alignment, %Cohesion, %Perception]:
slider.value_changed.connect(_on_steering_changed)
%PredatorMode.add_item("Predator: off")
%PredatorMode.add_item("Predator: mouse")
%PredatorMode.add_item("Predator: patrol")
%PredatorMode.item_selected.connect(_on_predator_mode_selected)
%UI.get_node("StatsTimer").timeout.connect(_on_stats_tick)
var seen := {}
for arg in OS.get_cmdline_user_args():
var key: String = arg.split("=")[0]
if seen.has(key):
_fail("duplicate_argument=" + key)
return
seen[key] = true
if arg == "--eval":
eval_mode = true
elif arg == "--eval-profile-render":
profile_render = true
elif arg == "--eval-start-on-click":
start_on_click = true
elif arg.begins_with("--count=") and arg.trim_prefix("--count=").is_valid_int():
eval_count = int(arg.trim_prefix("--count="))
elif arg.begins_with("--frames=") and arg.trim_prefix("--frames=").is_valid_int():
eval_frames = int(arg.trim_prefix("--frames="))
elif arg.begins_with("--mode="):
eval_variant = arg.trim_prefix("--mode=")
else:
_fail("unknown_or_invalid_argument=" + arg)
return
if eval_count < 1 or eval_count > 1000000 or eval_frames < 2 or eval_frames > 100000 or eval_variant not in ["native", "gd"]:
_fail("bad_arguments")
return
if eval_variant == "gd" and eval_count > BASELINE_CAP:
_fail("gd_count_exceeds_500")
return
# EX-BOID: initialize the interactive controls from the saved settings
# Resource — the authoring truth — before anything consumes them.
if not eval_mode:
var settings: Resource = _field.get("settings")
if settings != null:
_sim_seed = int(settings.population_seed)
_max_speed = float(settings.max_speed)
%Count.value = clampf(float(int(settings.count)), %Count.min_value, %Count.max_value)
%Separation.value = float(settings.separation)
%Alignment.value = float(settings.alignment)
%Cohesion.value = float(settings.cohesion)
%Perception.value = float(settings.perception)
%CountValue.text = str(int(%Count.value))
var count := eval_count if eval_mode else int(%Count.value)
var setup_error: int = _field.call("setup", count, _sim_seed)
if setup_error != 0:
_fail("setup code=%d" % setup_error)
return
if profile_render and not eval_mode:
_fail("render_profile_requires_eval")
return
# Mark readiness before the initial apply: assigning the authored settings
# to the sliders above fires their value_changed signals, and a reopened
# scene's saved values differ from the scene defaults, so those signals may
# arrive before setup has configured the field.
_ready_done = not _failed
if eval_mode:
_predator.visible = false
_start_eval()
elif _ready_done:
_apply_params()
func _process(_delta: float) -> void:
if not _ready_done or _failed or _finished:
return
if eval_mode:
_eval_process()
return
var code: int = _field.call("error")
if code != 0:
_fail("autonomous_submit=%d" % code)
return
if _predator_mode == PredatorMode.PATROL:
# The Godot animation moves the actor; its transform feeds both arms.
_feed_predator(true)
func _unhandled_input(event: InputEvent) -> void:
if not eval_mode and event is InputEventKey and event.pressed and event.keycode == KEY_ESCAPE:
_quit(0)
if eval_mode or not _ready_done or _failed:
return
if _predator_mode != PredatorMode.MOUSE:
return
# Mouse mode moves the saved actor over the ground plane; a click sets it,
# a drag carries it, and the actor's transform feeds both simulation arms.
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
_mouse_painting = event.pressed
if event.pressed:
_move_predator_to_mouse()
elif _mouse_painting and event is InputEventMouseMotion:
_move_predator_to_mouse()
func _move_predator_to_mouse() -> void:
var mouse := get_viewport().get_mouse_position()
var origin := _camera.project_ray_origin(mouse)
var normal := _camera.project_ray_normal(mouse)
if absf(normal.y) < 0.0001:
return
var t := -origin.y / normal.y
if t <= 0.0:
return
_predator.position = origin + normal * t
_feed_predator(true)
## The one place the predator reaches the simulations: the saved actor's
## transform feeds the native arm and the GDScript arm with identical values.
func _feed_predator(active: bool) -> void:
var p := _predator.position
if _field.call("set_predator", p.x, p.y, p.z, active) != 0:
_fail("set_predator")
return
_baseline.predator = p
_baseline.predator_active = active
_predator.visible = active
func _apply_params() -> void:
# Slider value_changed signals fire while _ready is still assigning the
# authored settings; before the field is set up there is nothing to apply.
if not _ready_done or _failed:
return
if _field.call("set_params", %Separation.value, %Alignment.value, %Cohesion.value, %Perception.value, _max_speed) != 0:
_fail("set_params")
return
_baseline.separation = %Separation.value
_baseline.alignment = %Alignment.value
_baseline.cohesion = %Cohesion.value
_baseline.perception = %Perception.value
_baseline.max_speed = _max_speed
%SeparationValue.text = "%.2f" % %Separation.value
%AlignmentValue.text = "%.2f" % %Alignment.value
%CohesionValue.text = "%.2f" % %Cohesion.value
%PerceptionValue.text = "%.2f" % %Perception.value
func _on_mode_selected(index: int) -> void:
var native := index == 0
_field.visible = native
_field.set_process(native)
_baseline.visible = not native
_baseline.set_process(not native)
%PredatorHint.visible = true
_apply_count()
func _on_count_slider(value: float) -> void:
%CountValue.text = "%d pending" % int(value)
%UI.get_node("CountApplyTimer").start()
func _apply_count() -> void:
if eval_mode or _failed:
return
var native: bool = %Mode.selected == 0
var requested := int(%Count.value)
var actual := requested if native else mini(requested, BASELINE_CAP)
if _field.call("set_count", actual) != 0:
_fail("set_count")
return
if not native and not _baseline.set_count(actual, _field.call("state_bytes")):
_fail("baseline_setup")
return
%CountValue.text = str(actual) if actual == requested else "%d (cap)" % actual
func _on_steering_changed(_value: float) -> void:
_apply_params()
func _on_predator_mode_selected(index: int) -> void:
_predator_mode = index
if not eval_mode and _ready_done and not _failed:
if index == PredatorMode.OFF:
_feed_predator(false)
%PredatorHint.text = "predator off — the flock flies free"
elif index == PredatorMode.MOUSE:
# The actor appears at its saved (or last placed) position; the
# next click or drag over the ground carries it.
_feed_predator(true)
%PredatorHint.text = "mouse: click or drag over the ground"
else:
%Predator.seek_patrol(0.0)
_feed_predator(true)
%PredatorHint.text = "patrol: the saved trajectory flies itself"
func _on_stats_tick() -> void:
if not profile_render:
_on_stats_tick_display()
return
var entered := Time.get_ticks_usec()
_on_stats_tick_display()
_profile_stats_usec += Time.get_ticks_usec() - entered
_profile_stats_calls += 1
func _on_stats_tick_display() -> void:
if eval_mode and start_on_click and not eval_started:
%Stats.text = "Click the scene to start the focused evaluation"
return
if not _ready_done:
return
var native: bool = eval_variant == "native" if eval_mode else %Mode.selected == 0
var agents: int = _field.call("count") if native else _baseline.count
var neighbors: int = _field.call("max_neighbors") if native else _baseline.max_neighbors
%Stats.text = "FPS %d | agents %d | max neighbors/agent %d" % [Engine.get_frames_per_second(), agents, neighbors]
func _start_eval() -> void:
_start_render_profile()
Engine.max_fps = 0
if DisplayServer.get_name() != "headless":
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED, get_window().get_window_id())
if not _eval_pacing_ok():
return
_sample_intervals.resize(eval_frames - int(eval_frames / 2))
_callback_samples.resize(_sample_intervals.size())
_headless = DisplayServer.get_name() == "headless"
_field.set_process(false)
_baseline.set_process(false)
if _field.call("set_driver_driven", true) != 0:
_fail("driver_handoff")
return
for control in [%Mode, %PredatorMode]:
control.disabled = true
for slider in [%Count, %Separation, %Alignment, %Cohesion, %Perception]:
slider.editable = false
%CameraRig.set_process_unhandled_input(false)
# Independent runtime implementation check, outside every measured window.
# Reset GD from exact old native state before each single step, so this
# tolerance tests one-step rules rather than long chaotic divergence.
if _field.call("set_count", 64) != 0:
_fail("comparison_setup")
return
if not _baseline.set_count(64, _field.call("state_bytes")):
_fail("comparison_snapshot")
return
if _field.call("verify") != -3:
_fail("verify_before_submit")
return
for bad in [NAN, INF, -1.0, 1.0e300]:
if _field.call("set_params", bad, 1.0, 0.9, 3.5, MAX_SPEED) == 0:
_fail("invalid_params_accepted")
return
if _field.call("set_predator", NAN, 0.0, 0.0, true) == 0:
_fail("invalid_predator_accepted")
return
for radius in [0.5, 3.5, 8.0]:
if _field.call("set_params", 1.5, 1.0, 0.9, radius, MAX_SPEED) != 0 or _field.call("set_predator", 0.0, 0.0, 0.0, true) != 0:
_fail("comparison_params")
return
_baseline.perception = radius
_baseline.predator_active = true
for step in 4:
if not _baseline.load_state(_field.call("state_bytes")):
_fail("comparison_load")
return
_baseline._step()
if _field.call("submit_frame") != 0 or _field.call("verify_state", _baseline.state_values(), 0.0001) != 0:
_fail("comparison_state radius=%s step=%s" % [radius, step])
return
_verify_cases += 1
if not _headless:
# Reading transforms must not make a later retained write detach.
for probe in 3:
if _field.call("verify") != 0 or _field.call("submit_frame") != 0:
_fail("retained_readback_reuse=%d" % probe)
return
print("GODODIN_BOID_FLOCK_RETAINED_REUSE_PASS cycles=3")
if _field.call("set_params", 1.5, 1.0, 0.9, 3.5, MAX_SPEED) != 0 or _field.call("set_predator", 0.0, 0.0, 0.0, false) != 0 or _field.call("set_count", eval_count) != 0:
_fail("measurement_reset")
return
_baseline.perception = 3.5
_baseline.predator_active = false
if eval_variant == "gd" and not _baseline.set_count(eval_count, _field.call("state_bytes")):
_fail("gd_measurement_setup")
return
_field.visible = eval_variant == "native"
_baseline.visible = eval_variant == "gd"
%Mode.select(0 if eval_variant == "native" else 1)
%CountValue.text = str(eval_count)
print("GODODIN_BOID_FLOCK_COMPARISON_PASS one_step_cases=%d count=64 tolerance=0.0001" % _verify_cases)
func _eval_process() -> void:
if start_on_click and not eval_started:
return
# Windowed campaigns start only after the operator brings the window forward.
# This leaves the seed, warm-up steps and measured workload unchanged.
if _eval_frame == 0 and DisplayServer.get_name() != "headless" and not get_window().has_focus():
return
if _field.is_processing() or _baseline.is_processing():
_fail("unowned_background_processing")
return
var entry := Time.get_ticks_usec()
if _previous_entry != 0 and _eval_frame >= eval_frames / 2:
_sample_intervals[_measured_frames] = entry - _previous_entry
if not get_window().has_focus():
unfocused_samples += 1
_previous_entry = entry
if profile_render:
if _eval_frame >= eval_frames / 2:
_sample_render_profile(_measured_frames)
_profile_stats_usec = 0
_profile_stats_calls = 0
var t0 := Time.get_ticks_usec()
var code: int = 0
if eval_variant == "native":
code = _field.call("submit_frame")
else:
_baseline._step()
var elapsed := Time.get_ticks_usec() - t0
if code != 0:
_fail("submit=%d" % code)
return
_eval_frame += 1
if _eval_frame > eval_frames / 2:
_callback_samples[_measured_frames] = elapsed
_eval_usec += elapsed
_measured_frames += 1
if _eval_frame < eval_frames:
return
_finished = true
_finish_eval()
func _finish_eval() -> void:
_stop_render_profile()
if not _eval_pacing_ok():
return
var verify_note := "skipped-headless-dummy-renderer" if _headless else "ok"
if not _headless:
if eval_variant == "native" and _field.call("verify") != 0:
_fail("native_readback")
return
if eval_variant == "gd" and not _baseline.verify_readback():
_fail("gd_readback")
return
await RenderingServer.frame_post_draw
var image := get_viewport().get_texture().get_image()
if image == null or image.save_png("user://boids.png") != OK:
_fail("screenshot")
return
_captured = true
if _measured_frames < 1 or _verify_cases != 12:
_fail("missing_measurements")
return
if not _save_profile_samples() or not _save_render_profile():
return
var frame_avg := 0.0
for interval in _sample_intervals:
frame_avg += interval
frame_avg /= maxi(1, _sample_intervals.size())
_sample_intervals.sort()
var p95: int = _sample_intervals[mini(_sample_intervals.size()-1, ceili(_sample_intervals.size()*0.95)-1)] if not _sample_intervals.is_empty() else 0
print("GODODIN_BOID_FLOCK_PASS mode=%s count=%d frames=%d measured_frames=%d avg_usec=%.3f frame_avg_usec=%.3f frame_p95_usec=%d verify=%s" % [eval_variant, eval_count, _eval_frame, _measured_frames, _eval_usec / _measured_frames, frame_avg, p95, verify_note])
if _field.call("shutdown") != 0 or _field.call("staging_live") or _field.call("count") != 0:
_fail("shutdown")
return
print("GODODIN_BOID_FLOCK_TEARDOWN_PASS frames=%d" % _eval_frame)
_quit(0)
func _quit(code: int) -> void:
if is_instance_valid(_field) and _field.call("shutdown") != 0:
print("GODODIN_BOID_FLOCK_FAIL shutdown")
code = 1
get_tree().quit(code)
func _exit_tree() -> void:
_stop_render_profile()
# Normal window close/scene removal uses the same explicit owner cleanup.
if is_instance_valid(_field) and _field.call("shutdown") != 0:
push_error("GODODIN_BOID_FLOCK_FAIL exit_shutdown")
func _fail(reason: String) -> void:
if _failed:
return
_failed = true
print("GODODIN_BOID_FLOCK_FAIL ", reason)
_quit(1)
# Arrival N's interval covers entry N-1 to entry N; its callback is step N.
# Buffers are allocated before simulation; file I/O occurs after measurement.
func _save_profile_samples() -> bool:
var file := FileAccess.open("user://boid-profile.csv", FileAccess.WRITE)
if file == null:
_fail("profile_samples_open")
return false
file.store_line("arrival_frame,callback_usec,previous_frame_interval_usec")
for index in range(_measured_frames):
file.store_line("%d,%d,%d" % [int(eval_frames / 2) + 1 + index, _callback_samples[index], _sample_intervals[index]])
file.flush()
if file.get_error() != OK:
_fail("profile_samples_write")
return false
print("GODODIN_BOID_FLOCK_PROFILE_FOCUS samples=%d unfocused=%d headless=%s" % [_measured_frames, unfocused_samples, DisplayServer.get_name() == "headless"])
if DisplayServer.get_name() != "headless" and unfocused_samples != 0:
_fail("profile_window_not_focused")
return false
print("GODODIN_BOID_FLOCK_PROFILE_SAMPLES count=%d path=user://boid-profile.csv" % _measured_frames)
return true
# The windowed runner uses an explicit input event to establish foreground
# readiness before any simulation steps. Ordinary play and headless runs bypass it.
func _input(event: InputEvent) -> void:
if eval_mode and start_on_click and not eval_started and event is InputEventMouseButton and event.pressed and get_window().has_focus():
eval_started = true
func _eval_pacing_ok() -> bool:
var headless := DisplayServer.get_name() == "headless"
if Engine.max_fps != 0 or (not headless and DisplayServer.window_get_vsync_mode(get_window().get_window_id()) != DisplayServer.VSYNC_DISABLED):
_fail("eval_pacing_changed")
return false
print("GODODIN_BOID_FLOCK_EVAL_PACING vsync=%s max_fps=%d" % ["not_applicable" if headless else "disabled", Engine.max_fps])
return true
# Opt-in instrumentation, outside the native callback timer. Dev5's GL query
# results use a three-frame ring (drivers/gles3/storage/utilities.cpp:351).
# These are buffered viewport observations, not timings for arrival_frame's
# callback. Their distributions may be compared; they cannot be added rowwise.
# Viewport spans exclude screen blit/swap (renderer_viewport.cpp:954). Engine
# timer queries and these reads add overhead included in whole-frame intervals.
func _start_render_profile() -> void:
if not profile_render:
return
_render_profile_samples.resize((eval_frames - int(eval_frames / 2)) * RENDER_PROFILE_WIDTH)
_render_profile_viewport = get_viewport().get_viewport_rid()
if DisplayServer.get_name() != "headless":
RenderingServer.viewport_set_measure_render_time(_render_profile_viewport, true)
_render_profile_active = true
RenderingServer.frame_pre_draw.connect(_render_profile_pre_draw)
RenderingServer.frame_post_draw.connect(_render_profile_post_draw)
func _sample_render_profile(index: int) -> void:
var offset := index * RENDER_PROFILE_WIDTH
if _render_profile_active:
_render_profile_samples[offset] = RenderingServer.viewport_get_measured_render_time_cpu(_render_profile_viewport)
_render_profile_samples[offset + 1] = RenderingServer.viewport_get_measured_render_time_gpu(_render_profile_viewport)
_render_profile_samples[offset + 2] = RenderingServer.get_frame_setup_time_cpu()
_render_profile_samples[offset + 3] = RenderingServer.viewport_get_render_info(_render_profile_viewport, RenderingServer.VIEWPORT_RENDER_INFO_TYPE_VISIBLE, RenderingServer.VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME)
_render_profile_samples[offset + 4] = RenderingServer.viewport_get_render_info(_render_profile_viewport, RenderingServer.VIEWPORT_RENDER_INFO_TYPE_SHADOW, RenderingServer.VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME)
_render_profile_samples[offset + 5] = RenderingServer.viewport_get_render_info(_render_profile_viewport, RenderingServer.VIEWPORT_RENDER_INFO_TYPE_CANVAS, RenderingServer.VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME)
# Stats callbacks occur between frame entries; this cost does correspond to
# arrival_frame's previous_frame_interval_usec, unlike buffered GL queries.
_render_profile_samples[offset + 6] = _profile_stats_usec
_render_profile_samples[offset + 7] = _profile_stats_calls
_render_profile_samples[offset + 8] = _render_wall_usec
_render_wall_usec = 0
_render_profile_count += 1
# On the synchronous render path this wall bracket includes viewport work,
# blit/swap waiting, and earlier frame-drawn callbacks. It is not GPU execution
# time. Signal callbacks add overhead. The latest completed draw belongs to
# the previous frame interval; buffered viewport timestamps have a different lag.
func _render_profile_pre_draw() -> void:
_render_wall_started = Time.get_ticks_usec()
func _render_profile_post_draw() -> void:
_render_wall_usec = Time.get_ticks_usec() - _render_wall_started
func _stop_render_profile() -> void:
if _render_profile_active:
RenderingServer.viewport_set_measure_render_time(_render_profile_viewport, false)
_render_profile_active = false
RenderingServer.frame_pre_draw.disconnect(_render_profile_pre_draw)
RenderingServer.frame_post_draw.disconnect(_render_profile_post_draw)
func _save_render_profile() -> bool:
if not profile_render:
return true
if _render_profile_count != _measured_frames or _render_profile_count == 0:
_fail("render_profile_sample_count")
return false
var file := FileAccess.open("user://boid-render-profile.csv", FileAccess.WRITE)
if file == null:
_fail("render_profile_open")
return false
file.store_line("arrival_frame,viewport_cpu_ms,viewport_gpu_ms,setup_cpu_ms,visible_draw_calls,shadow_draw_calls,canvas_draw_calls,stats_usec,stats_calls,render_wall_usec")
var totals := PackedFloat64Array()
totals.resize(RENDER_PROFILE_WIDTH)
var cpu_positive := 0
var gpu_positive := 0
var wall_positive := 0
for index in range(_render_profile_count):
var offset := index * RENDER_PROFILE_WIDTH
for column in range(RENDER_PROFILE_WIDTH):
var value := _render_profile_samples[offset + column]
if not is_finite(value) or value < 0.0:
_fail("invalid_render_profile_sample")
return false
totals[column] += value
if _render_profile_samples[offset] > 0.0:
cpu_positive += 1
if _render_profile_samples[offset + 1] > 0.0:
gpu_positive += 1
if _render_profile_samples[offset + 8] > 0.0:
wall_positive += 1
file.store_line("%d,%.6f,%.6f,%.6f,%.0f,%.0f,%.0f,%.0f,%.0f,%.0f" % [int(eval_frames / 2) + 1 + index, _render_profile_samples[offset], _render_profile_samples[offset + 1], _render_profile_samples[offset + 2], _render_profile_samples[offset + 3], _render_profile_samples[offset + 4], _render_profile_samples[offset + 5], _render_profile_samples[offset + 6], _render_profile_samples[offset + 7], _render_profile_samples[offset + 8]])
file.flush()
if file.get_error() != OK:
_fail("render_profile_write")
return false
var headless := DisplayServer.get_name() == "headless"
# Preserve zeros in the CSV. An all-zero series is unavailable/unproven,
# never proof of free rendering; headless has no rendering observation.
var cpu_status := "unavailable" if headless or cpu_positive == 0 else "observed"
var gpu_status := "unavailable" if headless or gpu_positive == 0 else "observed"
var wall_status := "unavailable" if headless or wall_positive == 0 else "observed"
print("GODODIN_BOID_FLOCK_RENDER_PROFILE samples=%d cpu_status=%s gpu_status=%s cpu_positive=%d gpu_positive=%d viewport_cpu_ms=%.6f viewport_gpu_ms=%.6f setup_cpu_ms=%.6f stats_avg_usec=%.6f stats_calls=%d render_wall_usec=%.6f wall_status=%s wall_positive=%d render_wall_scope=pre_to_post_draw render_wall_swap_included=true lag=renderer_buffered viewport_swap_included=false overhead=included headless=%s path=user://boid-render-profile.csv" % [_render_profile_count, cpu_status, gpu_status, cpu_positive, gpu_positive, totals[0] / _render_profile_count, totals[1] / _render_profile_count, totals[2] / _render_profile_count, totals[6] / _render_profile_count, int(totals[7]), totals[8] / _render_profile_count, wall_status, wall_positive, headless])
return true