Reviewed against the rule issues #6 and #10 set for the buildings: geometry is rasterised once and thereafter only moved, scaled or faded, because every NeonDraw call expands into four antialiased polylines. The planet visuals never got that refactor. The black hole rebuilt ten glowing paths of twenty-five points every frame - forty polylines - to spin five rings; each ring is a NeonPiece that rotates now. The research lab spent nine draw calls a frame, eight of them fixed geometry, to turn one dish and blink six lights; the dish is a child that rotates and the lights a child whose modulate breathes. The gas giant's bands genuinely deform, so they still draw, but its constant rim moved out to a child. NeonPiece gained add_path, which it needed for open arcs. And I had broken the rule myself. ScannerGuidance re-queued a redraw of its arrow every frame for a colour that changes only with the destination - and it runs with PROCESS_MODE_ALWAYS, so it was re-tessellating through every dialog that stops the rest of the game. Guarded, and pinned by a test that counts CanvasItem's own draw signal: 36 rasterisations in 0.6s before, one after. Two smaller things from the same pass: the station menu drew its condition bar by hand where the ship lab already uses a ProgressBar node, so it uses one now and its _draw is gone; and station/upkeep refreshes were wired into _refresh_garrison(), which nothing but a test calls, so both menus showed whatever was true when they opened. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
111 lines
3.6 KiB
GDScript
111 lines
3.6 KiB
GDScript
extends SceneTree
|
|
|
|
# The flight marker must not re-rasterise itself to point somewhere.
|
|
#
|
|
# Issues #6 and #10 set this rule for the rest of the game: geometry is drawn
|
|
# ONCE and thereafter moved, rotated, scaled or faded, because every NeonDraw
|
|
# call expands into four antialiased polylines and redrawing to animate
|
|
# re-tessellates all of them. The marker broke it - it re-queued a redraw
|
|
# every frame for a glow colour that only changes when the DESTINATION does -
|
|
# and it is the worst node in the game to get wrong, because it runs with
|
|
# PROCESS_MODE_ALWAYS: it kept working through every dialog that stops the
|
|
# rest of the game.
|
|
#
|
|
# Counted off CanvasItem's own `draw` signal rather than a counter of ours,
|
|
# so what is measured is real rasterisation.
|
|
#
|
|
# Covers:
|
|
# A. a marker tracking one destination settles - it stops redrawing
|
|
# B. it is genuinely still tracking (so this cannot pass by freezing)
|
|
# C. a destination of a different colour does redraw it, once
|
|
|
|
var state: Node
|
|
var scene: Node
|
|
var indicator: Control
|
|
var draws: int = 0
|
|
var stage: int = 0
|
|
var elapsed: float = 0.0
|
|
var settled_at: int = 0
|
|
var first_position: Vector2
|
|
|
|
|
|
func _initialize() -> void:
|
|
state = root.get_node("GameState")
|
|
state.reset_new_game()
|
|
state.intro_active = false
|
|
state.reset_quests()
|
|
state.buildings.clear()
|
|
scene = load("res://world/Main.tscn").instantiate()
|
|
root.add_child(scene)
|
|
current_scene = scene
|
|
indicator = scene.get_node("UI/ScannerGuidance/Indicator")
|
|
indicator.draw.connect(func(): draws += 1)
|
|
|
|
|
|
func _process(delta: float) -> bool:
|
|
elapsed += delta
|
|
match stage:
|
|
0:
|
|
if elapsed < 0.4:
|
|
return false
|
|
# A destination far off, so the marker is pinned to a screen edge
|
|
# and its position keeps being recomputed every frame.
|
|
state.scanner_target = {
|
|
"planet_id": "redraw:probe", "definition_id": "rocky",
|
|
"name": "Probe", "world_position": Vector2(90000.0, -40000.0),
|
|
}
|
|
elapsed = 0.0
|
|
stage = 1
|
|
return false
|
|
1:
|
|
# Let it take up the target and draw whatever it needs to.
|
|
if elapsed < 0.5:
|
|
return false
|
|
settled_at = draws
|
|
first_position = indicator.position
|
|
elapsed = 0.0
|
|
stage = 2
|
|
return false
|
|
2:
|
|
# --- A. thirty-odd frames of tracking, no rasterising ---------
|
|
if elapsed < 0.6:
|
|
return false
|
|
var while_tracking: int = draws - settled_at
|
|
if while_tracking > 1:
|
|
return _fail("the marker rasterised %d times in %.1fs of tracking one destination" \
|
|
% [while_tracking, elapsed])
|
|
# --- B. and it really was tracking ---------------------------
|
|
if not scene.get_node("UI/ScannerGuidance").visible:
|
|
return _fail("the marker was not even visible, so this proves nothing")
|
|
print("tracking one destination: %d redraws in %.1fs" % [while_tracking, elapsed])
|
|
|
|
# --- C. a different world does repaint it --------------------
|
|
var before: int = draws
|
|
state.scanner_target = {
|
|
"planet_id": "redraw:probe2", "definition_id": "gas_giant",
|
|
"name": "Probe Two", "world_position": Vector2(-70000.0, 55000.0),
|
|
}
|
|
elapsed = 0.0
|
|
stage = 3
|
|
settled_at = before
|
|
return false
|
|
3:
|
|
if elapsed < 0.4:
|
|
return false
|
|
var repaints: int = draws - settled_at
|
|
if repaints < 1:
|
|
return _fail("changing destination never recoloured the marker")
|
|
if repaints > 2:
|
|
return _fail("changing destination rasterised %d times, expected about one" % repaints)
|
|
print("changing destination repaints it %d time(s), then settles" % repaints)
|
|
|
|
print("TEST_GUIDANCE_MARKER_REDRAW: PASS")
|
|
quit(0)
|
|
return true
|
|
return false
|
|
|
|
|
|
func _fail(message: String) -> bool:
|
|
print("TEST_GUIDANCE_MARKER_REDRAW: FAIL (%s)" % message)
|
|
quit(1)
|
|
return true
|