-
-
Notifications
You must be signed in to change notification settings - Fork 0
Fix main scene orphan leaks and tune parallax decor with tests #550
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ikostan
merged 32 commits into
main
from
orphan-node-leak-from-placeholder-sprites-in-main_scenegd
Apr 16, 2026
Merged
Changes from 21 commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
8a26313
[BUG] Orphan Node Leak from Placeholder Sprites in main_scene.gd #540
ikostan faa58f0
[QA] Orphan Node Leak Fix – Test Plan #549
ikostan 4782dba
Update test/gut/test_main_scene_orphan_nodes.gd
ikostan 49ac64a
Update main_scene.gd
ikostan 7bfa831
Add orphan leak helper and update tests
ikostan 1bfd05f
Update main_scene.gd
ikostan 2a647aa
suggestion: Consider tightening the type of stats_panel instead of us…
ikostan 3713757
Update test_main_scene_orphan_nodes.gd
ikostan 437369f
Update test_player_lifecycle.gd
ikostan c36a488
Update main_scene.gd
ikostan 5822274
Update test_player_lifecycle.gd
ikostan 608020e
[FEATURE] Randomize rotation for organic decor sprites in main scene …
ikostan 8eb7436
Update main_scene.gd
ikostan 237b33b
Make the background look as random and organic as possible
ikostan 4d999f4
Update main_scene.gd
ikostan 95b2b9e
[FEATURE] Increase parallax background chunk size to prevent visual r…
ikostan d63252e
Add GUT tests for parallax chunk sizes
ikostan 26f42a0
GUT test file dedicated specifically to verifying the randomized tran…
ikostan f38072c
Adjust bushes/decor layer height and density
ikostan cb04302
assertions that lock in the "Goldilocks Zone"
ikostan f7df782
Update test_main_scene_parallax_chunks.gd
ikostan 221cbd6
Update scripts/main_scene.gd
ikostan 60e24c2
Update main_scene.gd
ikostan 909d4a1
Merge branch 'orphan-node-leak-from-placeholder-sprites-in-main_scene…
ikostan aaddd37
Update test_decor_layer_transformations.gd
ikostan 7127f19
Rename performance test & add parallax checks
ikostan 3740a4c
Improve test teardown and prevent orphan nodes
ikostan deb1ae2
Performance assertion is likely to be CI-flaky, and _process side eff…
ikostan 2588460
suggestion: The hardcoded screens_tall = 8.0 is duplicated and would …
ikostan 2f94791
Update gut_test_helper.gd
ikostan a1c6821
Update test_main_scene_parallax_and_performance.gd
ikostan b9cfc17
Use GutHelper.safe_hard_free in tests
ikostan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| ## Copyright (C) 2026 Egor Kostan | ||
| ## SPDX-License-Identifier: GPL-3.0-or-later | ||
| ## test_decor_layer_transformations.gd | ||
| ## | ||
| ## GUT unit tests for verifying randomized rotations, scaling, | ||
| ## and flipping applied to the main scene's decor layer. | ||
|
|
||
| extends "res://addons/gut/test.gd" | ||
|
|
||
| var main_scene: MainScene | ||
| var viewport_mock: Vector2 = Vector2(1920, 1080) | ||
|
|
||
|
|
||
| ## Per-test setup: Isolate state and initialize scene. | ||
| ## :rtype: void | ||
| func before_each() -> void: | ||
| await get_tree().process_frame | ||
| main_scene = preload("res://scenes/main_scene.tscn").instantiate() | ||
| add_child_autofree(main_scene) | ||
| await get_tree().process_frame | ||
|
|
||
|
|
||
| ## Per-test teardown: Aggressive memory cleanup. | ||
| ## :rtype: void | ||
| func after_each() -> void: | ||
| if is_instance_valid(main_scene): | ||
| main_scene.free() | ||
| await get_tree().process_frame | ||
|
|
||
|
|
||
| ## test_decor_sprites_have_valid_cardinal_rotations | | ||
| ## Verifies every decor sprite is snapped to exactly 0, 90, 180, or -90 degrees. | ||
| ## :rtype: void | ||
| func test_decor_sprites_have_valid_cardinal_rotations() -> void: | ||
| gut.p("Testing: All decor sprites must use strict cardinal rotations.") | ||
|
|
||
| main_scene.setup_decor_layer(viewport_mock) | ||
|
|
||
| var active_sprites: Array[Node] = main_scene.decor_layer.get_children().filter( | ||
| func(c: Node) -> bool: return not c.is_queued_for_deletion() | ||
| ) | ||
|
|
||
| var allowed_radians: Array[float] = [ | ||
| 0.0, | ||
| deg_to_rad(90.0), | ||
| deg_to_rad(180.0), | ||
| deg_to_rad(-90.0) | ||
| ] | ||
|
|
||
| var invalid_rotations: Array[float] = [] | ||
|
|
||
| for node in active_sprites: | ||
| var sprite := node as Sprite2D | ||
| var is_valid := false | ||
|
|
||
| # Check if the sprite's rotation matches any allowed radian (using approx to handle float drift) | ||
| for allowed_rad in allowed_radians: | ||
| if is_equal_approx(sprite.rotation, allowed_rad): | ||
| is_valid = true | ||
| break | ||
|
|
||
| if not is_valid: | ||
| invalid_rotations.append(sprite.rotation) | ||
|
|
||
| assert_eq(invalid_rotations.size(), 0, "Found decor sprites with non-cardinal rotations.") | ||
|
|
||
|
|
||
| ## test_decor_sprites_have_valid_scale_ranges | | ||
| ## Verifies every decor sprite scale falls between 0.5 and 1.5, and is uniformly scaled. | ||
| ## :rtype: void | ||
| func test_decor_sprites_have_valid_scale_ranges() -> void: | ||
| gut.p("Testing: All decor sprites must be uniformly scaled between 0.5 and 1.5.") | ||
|
|
||
| main_scene.setup_decor_layer(viewport_mock) | ||
|
|
||
| var active_sprites: Array[Node] = main_scene.decor_layer.get_children().filter( | ||
| func(c: Node) -> bool: return not c.is_queued_for_deletion() | ||
| ) | ||
|
|
||
| var out_of_bounds_scales: Array[Vector2] = [] | ||
| var non_uniform_scales: Array[Vector2] = [] | ||
|
|
||
| for node in active_sprites: | ||
| var sprite := node as Sprite2D | ||
| var s: Vector2 = sprite.scale | ||
|
|
||
| # Check bounds (using 0.49 and 1.51 to safely absorb floating point precision errors) | ||
| if s.x < 0.49 or s.x > 1.51: | ||
| out_of_bounds_scales.append(s) | ||
|
|
||
| # Check uniformity (x scale must equal y scale) | ||
| if not is_equal_approx(s.x, s.y): | ||
| non_uniform_scales.append(s) | ||
|
|
||
| assert_eq(out_of_bounds_scales.size(), 0, "Found decor sprites outside the 0.5 - 1.5 scale range.") | ||
| assert_eq(non_uniform_scales.size(), 0, "Found decor sprites with non-uniform (squished/stretched) scaling.") | ||
|
|
||
|
|
||
| ## test_decor_sprites_have_boolean_flips | | ||
| ## Verifies that flip_h and flip_v properties are actively being assigned. | ||
| ## :rtype: void | ||
| func test_decor_sprites_have_boolean_flips() -> void: | ||
| gut.p("Testing: Decor sprites should successfully assign horizontal and vertical flips.") | ||
|
|
||
| main_scene.setup_decor_layer(viewport_mock) | ||
|
|
||
| var active_sprites: Array[Node] = main_scene.decor_layer.get_children().filter( | ||
| func(c: Node) -> bool: return not c.is_queued_for_deletion() | ||
| ) | ||
|
|
||
| var null_flips_found: int = 0 | ||
|
|
||
| for node in active_sprites: | ||
| var sprite := node as Sprite2D | ||
| # Verify the properties are valid booleans and not null/undefined | ||
| if typeof(sprite.flip_h) != TYPE_BOOL or typeof(sprite.flip_v) != TYPE_BOOL: | ||
| null_flips_found += 1 | ||
|
|
||
| assert_eq(null_flips_found, 0, "All decor sprites must have valid boolean flip states.") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| uid://dn1cexpx24og0 |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.