mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-10 16:04:04 +00:00
4fb7ddfecf
multiplayer-todo.md and multiplayer-next.md tracked overlapping information in two places. Fold everything into multiplayer-next.md (architecture decisions, wire format, task breakdown with checkboxes, gotchas list, testing notes) and delete multiplayer-todo.md. Section numbers are unchanged, so existing code comments citing them by section/task number still resolve; update every such reference to point at the new filename.
63 lines
2.3 KiB
GDScript
63 lines
2.3 KiB
GDScript
extends CanvasLayer
|
|
|
|
# Autoload: toggleable frame-time/bottleneck overlay (F3 by default — see
|
|
# toggle_perf_overlay in project.godot's [input]). Read-only against
|
|
# Performance monitors; never touches rendering or gameplay state. Exists so
|
|
# 0.17/0.17b's graphics presets and resolution scaling are self-diagnosing —
|
|
# TIME_PROCESS vs total frame time tells the player whether they're CPU- or
|
|
# GPU-bound. See multiplayer-next.md task 0.20.
|
|
|
|
# ~2s of history at 60 fps; enough to make p50/p99 meaningful without the
|
|
# history itself being a rate-dependent quantity.
|
|
const HISTORY_SIZE := 120
|
|
|
|
var _label: Label
|
|
var _frame_times_ms: PackedFloat32Array = PackedFloat32Array()
|
|
var _history_index := 0
|
|
var _history_filled := 0
|
|
|
|
|
|
func _ready() -> void:
|
|
# A headless server never renders and has no input to toggle this with.
|
|
if DisplayServer.get_name() == "headless":
|
|
set_process(false)
|
|
return
|
|
layer = 100
|
|
_label = Label.new()
|
|
_label.add_theme_font_size_override("font_size", 14)
|
|
_label.add_theme_color_override("font_color", Color(0.4, 1.0, 0.5))
|
|
_label.add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.85))
|
|
_label.add_theme_constant_override("shadow_offset_x", 1)
|
|
_label.add_theme_constant_override("shadow_offset_y", 1)
|
|
_label.position = Vector2(12, 12)
|
|
_label.visible = false
|
|
add_child(_label)
|
|
_frame_times_ms.resize(HISTORY_SIZE)
|
|
_frame_times_ms.fill(0.0)
|
|
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
if event.is_action_pressed("toggle_perf_overlay") and _label:
|
|
_label.visible = not _label.visible
|
|
|
|
|
|
func _process(_delta: float) -> void:
|
|
if not _label or not _label.visible:
|
|
return
|
|
var frame_ms := Performance.get_monitor(Performance.TIME_PROCESS) * 1000.0
|
|
var physics_ms := Performance.get_monitor(Performance.TIME_PHYSICS_PROCESS) * 1000.0
|
|
_frame_times_ms[_history_index] = frame_ms
|
|
_history_index = (_history_index + 1) % HISTORY_SIZE
|
|
_history_filled = mini(_history_filled + 1, HISTORY_SIZE)
|
|
|
|
var sorted := _frame_times_ms.slice(0, _history_filled)
|
|
sorted.sort()
|
|
var p50 := sorted[sorted.size() / 2]
|
|
var p99 := sorted[int(sorted.size() * 0.99)]
|
|
|
|
_label.text = "FPS %d (p50 %.2fms p99 %.2fms)\nprocess %.2fms physics %.2fms\ndraw calls %d" % [
|
|
Performance.get_monitor(Performance.TIME_FPS),
|
|
p50, p99, frame_ms, physics_ms,
|
|
Performance.get_monitor(Performance.RENDER_TOTAL_DRAW_CALLS_IN_FRAME),
|
|
]
|