Skip to content

Refactor Phase 4: Migrate Resources, Path Centralization, Test Suite Stabilization, and Docs Alignment#582

Merged
ikostan merged 10 commits intomainfrom
migrate-resources-entities-and-system-scripts
Apr 23, 2026
Merged

Refactor Phase 4: Migrate Resources, Path Centralization, Test Suite Stabilization, and Docs Alignment#582
ikostan merged 10 commits intomainfrom
migrate-resources-entities-and-system-scripts

Conversation

@ikostan
Copy link
Copy Markdown
Owner

@ikostan ikostan commented Apr 22, 2026


🚀 PR Update: Path Centralization, Test Suite Stabilization, and Docs Alignment

Based on the code review feedback and subsequent CI runs, the following updates have been pushed to this PR:

1. Architectural Enhancements (GamePaths Implementation)

  • Created GamePaths Class: Introduced scripts/core/game_paths.gd (class_name GamePaths extends RefCounted) to act as a single source of truth for canonical script and scene paths.
  • Refactored Hardcoded Strings: Replaced fragile string literals (e.g., "res://scripts/ui/menus/gameplay_settings.gd") in the newly organized test and helper files with type-safe constants (e.g., GamePaths.GAMEPLAY_SETTINGS).
  • Note: Created a follow-up Tech Debt issue to incrementally migrate the remaining resources, audio assets, and UI scenes to GamePaths in future PRs to keep this PR's scope focused.

2. Test Suite Stabilization (100% Pass Rate & 0 Orphans)

  • Fixed Memory Leaks (Orphans): Wrapped the mock Control.new() nodes in GUT's autofree() method across test_master_volume_control_and_music.gd, test_sfx_rotor_volume_control.gd, and test_sfx_weapon_volume_control.gd. This successfully eliminated the orphan node warnings during tree exit simulation tests (Test 15s).
  • Resolved Mocking Errors: Removed invalid stub() calls on the active Globals Autoload node in test_pause_menu.gd, clearing out the 15+ GUT runtime errors.
  • Prevented Unintended Disk I/O: Fixed test failures in test_preserve_other_sections.gd and test_reset_scenarios.gd caused by the new Observer Pattern. Guarded direct assignments to Globals.settings with the Globals._is_loading_settings flag to prevent setting_changed signals from triggering automatic ConfigFile saves to disk during automated tests.

3. Documentation Corrections

  • Aligned Development_Guide.md: Updated the architecture guide to accurately reflect the newly relocated res://scripts/resources/game_settings_resource.gd.
  • Clarified Persistence: Updated the documentation table to explicitly outline that while GameSettingsResource holds the state and emits signals, globals.gd remains the exclusive owner of persistence (_save_settings / _load_settings).

All CI checks are now green, memory leaks are resolved, and the codebase aligns with the new Phase 4 directory structure. Ready to merge!


name: Default Pull Request Template
about: Suggesting changes to SkyLockAssault
title: ''
labels: ''
assignees: ''

Description

What does this PR do? (e.g., "Fixes player jump physics in level 2" or "Adds
new enemy AI script")

Related Issue

Closes #ISSUE_NUMBER (if applicable)

Changes

  • List key changes here (e.g., "Updated Jump.gd to use Godot 4.4's new Tween
    system")
  • Any breaking changes? (e.g., "Deprecated old signal; migrate to new one")

Testing

  • Ran the game in Godot v4.5 editor—describe what you tested (e.g., "Jump
    works on Win10 with 60 FPS")
  • Any new unit tests added? (Link to test scene if yes)
  • Screenshots/GIFs if UI-related: (Attach below)

Checklist

  • Code follows Godot style guide (e.g., snake_case for variables)
  • No console errors in editor/output
  • Ready for review!

Additional Notes

Anything else? (e.g., "Tested on Win10 64-bit; needs Linux validation")

Summary by Sourcery

Reorganize script resources, entities, and system scripts into dedicated subdirectories and update scene and project references accordingly.

Enhancements:

  • Standardize the project folder structure by moving settings, entity, system, UI, and manager scripts into dedicated subdirectories instead of the root scripts folder.

Chores:

  • Update references in project, settings, and scene files to point to the new script locations, ensuring no loose .gd files remain in the base scripts directory.

Summary by Sourcery

Centralize script and scene paths into a new GamePaths core helper and update references across tests and docs while aligning documentation with the new folder structure.

Enhancements:

  • Introduce a GamePaths core utility to hold canonical script and scene paths for entities, UI, settings, and key menus.
  • Align the development guide documentation with the new scripts/resources and scripts/ui/menus structure, deprecating outdated globals/settings references.

Tests:

  • Update GUT tests to use GamePaths constants instead of hardcoded paths, adjust Globals/settings interactions to avoid unintended persistence, and fix minor memory-leak and stub issues in test setups.

Summary by CodeRabbit

  • Chores
    • Internal resource paths reorganized and centralized; tests and runtime references updated to use the new centralized path constants. No user-facing behavior changes.
  • Documentation
    • Core files reference table updated to reflect relocated resources and cleaned up obsolete entries.

Here is a summary of @ikostan's core contributions to Pull Request #582:

1. Architectural Refactoring & Folder Reorganization

Executed "Refactor Phase 4" to eliminate the "junk drawer" effect at the root of the scripts/ directory by meticulously categorizing and migrating files:

  • Resources: Moved data containers and configuration scripts (e.g., game_settings_resource.gd, audio_settings.gd, gameplay_settings.gd, audio_constants.gd) to scripts/resources/.
  • Entities: Moved game objects (e.g., player.gd, bullet.gd, weapon.gd) to scripts/entities/.
  • System: Moved core system and platform integrations (e.g., OSWrapper.gd, JavaScriptBridgeWrapper.gd, audio_web_bridge.gd) to scripts/system/.
  • UI & Managers: Relocated hud.gd to scripts/ui/ and parallax_manager.gd to scripts/managers/.
  • Updated all project, settings, and scene file references to point to these new locations.

2. Implementation of Centralized Path Management

  • Designed and implemented the new GamePaths core helper (scripts/core/game_paths.gd) to serve as a single source of truth for canonical script and scene paths.
  • Replaced fragile, hardcoded string literals across multiple test files and helper scripts with the new type-safe GamePaths constants, significantly improving the maintainability of the codebase.

3. Test Suite Stabilization & Bug Fixes

  • Memory Leak Resolution: Fixed orphan node memory leaks across the audio test suite (test_master_volume_control_and_music.gd, test_sfx_rotor_volume_control.gd, test_sfx_weapon_volume_control.gd) by correctly applying GUT's autofree() method to simulated UI controls.
  • Test Isolation & Disk I/O Prevention: Guarded Globals.settings modifications with the _is_loading_settings flag in test_preserve_other_sections.gd and test_reset_scenarios.gd. This prevents the newly implemented Observer Pattern from triggering unintended _save_settings() disk writes during automated testing.
  • Mocking Corrections: Resolved GUT stubbing errors in test_pause_menu.gd by removing invalid stub() calls on the active Globals Autoload node.

4. Documentation Updates

  • Updated Development_Guide.md to accurately reflect the new folder structure (e.g., res://scripts/resources/game_settings_resource.gd).
  • Clarified the architecture documentation to explicitly define the persistence relationship, ensuring developers understand that while the GameSettingsResource holds the state, globals.gd handles the actual ConfigFile saving and loading.

Here is a summary of the automated AI and bot contributions for Pull Request #582:

  • @sourcery-ai: Generated the automated pull request summaries detailing the structural refactoring (moving resources, entities, and system scripts into dedicated subdirectories) and the creation of the centralized GamePaths utility. It also conducted a high-level code review, flagging outdated paths in Development_Guide.md and warning about potential markdown rendering issues with HTML tags inside pipe tables.
  • @coderabbitai: Provided actionable code review feedback by analyzing the documentation. It identified logical contradictions in Development_Guide.md outside of the immediate diff range, specifically catching that the guide still referenced the old game_settings_resource.gd path and contained conflicting instructions regarding persistence responsibilities.
  • @deepsource (DeepsourceReview): Conducted automated static analysis and code quality checks across the newly reorganized directories, ensuring that the structural migrations and path updates adhere to the project's safety and maintainability standards.

Using the Godot Editor (Drag and Drop):

Move to resources/: game_settings_resource.gd, audio_settings.gd, gameplay_settings.gd, audio_constants.gd.
Move to entities/: player.gd, bullet.gd, weapon.gd.
Move to system/: OSWrapper.gd, JavaScriptBridgeWrapper.gd, audio_web_bridge.gd.
Move hud.gd and parallax_manager.gd into specific subdirectories to ensure the root only contains essential configuration if necessary.
hud.gd
→
 scripts/ui/hud.gd
parallax_manager.gd
→
 scripts/managers/parallax_manager.gd
Additional Context:
This should leave no loose .gd files in the base res://scripts/ directory.
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Apr 22, 2026

Reviewer's Guide

Centralizes script and scene paths via a new GamePaths core utility and updates tests, docs, and references to use it while reflecting the new scripts folder structure (resources, entities, system, ui, core) with no loose scripts in the root scripts directory.

Class diagram for new GamePaths core utility

classDiagram
    class GamePaths {
        <<utility>>
        +PLAYER String
        +HUD String
        +AUDIO_WEB_BRIDGE String
        +INPUT_REMAP_BUTTON String
        +GAMEPLAY_SETTINGS String
        +SETTINGS String
        +AUDIO_SETTINGS_SCENE String
        +MAIN_SCENE String
        +KEY_MAPPING_SCENE String
        +GAMEPLAY_SETTINGS_SCENE String
        +PAUSE_MENU_SCENE String
        +OPTIONS_MENU_SCENE String
    }

    class Player {
    }

    class Hud {
    }

    class AudioWebBridge {
    }

    class InputRemapButton {
    }

    class GameplaySettingsMenu {
    }

    class SettingsCore {
    }

    class AudioSettingsScene {
    }

    class MainScene {
    }

    class KeyMappingScene {
    }

    class PauseMenuScene {
    }

    class OptionsMenuScene {
    }

    Player ..> GamePaths : uses path constants
    Hud ..> GamePaths : uses path constants
    AudioWebBridge ..> GamePaths : uses path constants
    InputRemapButton ..> GamePaths : uses path constants
    GameplaySettingsMenu ..> GamePaths : uses path constants
    SettingsCore ..> GamePaths : uses path constants
    AudioSettingsScene ..> GamePaths : uses path constants
    MainScene ..> GamePaths : uses path constants
    KeyMappingScene ..> GamePaths : uses path constants
    PauseMenuScene ..> GamePaths : uses path constants
    OptionsMenuScene ..> GamePaths : uses path constants
Loading

File-Level Changes

Change Details Files
Introduce GamePaths core utility to centralize hardcoded script and scene paths and migrate call sites.
  • Add scripts/core/game_paths.gd with constants for key script paths (player, hud, audio web bridge, input remap button, gameplay settings, settings) and scene paths (audio settings, main scene, key mapping, gameplay settings, pause menu, options menu).
  • Update GUT tests to preload/load scenes and scripts via GamePaths constants instead of raw string paths (e.g., AUDIO_SETTINGS_SCENE, MAIN_SCENE, KEY_MAPPING_SCENE, GAMEPLAY_SETTINGS, INPUT_REMAP_BUTTON, SETTINGS).
  • Update shared GUT helpers to use GamePaths for player and HUD script paths.
scripts/core/game_paths.gd
scripts/core/game_paths.gd.uid
test/gut/gut_test_helper.gd
test/gut/test_master_volume_control_and_music.gd
test/gut/test_pause_menu.gd
test/gut/test_reset_scenarios.gd
test/gut/test_game_settings_resource.gd
test/gut/test_gameplay_settings_lifecycle.gd
test/gut/test_integration_key_mapping.gd
test/gut/test_sfx_rotor_volume_control.gd
test/gut/test_sfx_weapon_volume_control.gd
test/gut/test_gameplay_settings_js.gd
test/gut/test_gameplay_settings_ui.gd
test/gut/test_main_scene_orphan_nodes.gd
test/gut/test_player_lifecycle.gd
test/gut/test_audio_reset_button.gd
test/gut/test_audio_web_bridge.gd
test/gut/test_blank_key_labels_on_missing_config.gd
test/gut/test_decor_layer_transformations.gd
test/gut/test_deduplication_on_device_switch.gd
test/gut/test_deduplication_on_rapid_remap.gd
test/gut/test_deduplication_on_remap.gd
test/gut/test_deduplication_on_reset.gd
test/gut/test_fuel_additional_edge_cases.gd
test/gut/test_get_pause_binding_label_for_device.gd
test/gut/test_input_remap_button.gd
test/gut/test_input_remap_button_device_aware.gd
test/gut/test_input_remap_ec.gd
test/gut/test_key_mapping_menu.gd
test/gut/test_key_mapping_menu_device_aware.gd
test/gut/test_main_scene_parallax_and_performance.gd
test/gut/test_settings_unbound_scenarios.gd
test/gut/test_sfx_volume_control.gd
test/gut/test_version_display.gd
Align docs and tests with new scripts folder structure (resources, ui subfolders, core) and preserve behavior of settings and audio systems.
  • Update Development_Guide core files reference table to point to scripts/resources and scripts/ui paths, and mark deprecated Globals/settings rows as deleted using HTML and markdownlint suppression.
  • Adjust tests that manipulate Globals.settings and difficulty/log level to guard changes with _is_loading_settings to avoid unintended saves and keep behavior consistent.
  • Tweak long test case description comments to wrap lines and improve readability without changing semantics.
files/docs/Development_Guide.md
test/gut/test_preserve_other_sections.gd
test/gut/test_reset_scenarios.gd
Fix memory-management and stubbing issues in tests to avoid leaks and invalid stubs under GUT.
  • Wrap ad-hoc Control instances used only as mock previous menus in autofree() so they are cleaned up after tests and do not leak (in music and SFX rotor/weapon tests).
  • Remove invalid stub() calls on Autoload singletons in pause menu tests, relying instead on natural flows since those methods are not invoked in the tested scenarios.
  • Ensure some test scenes are added with add_child_autoqfree where appropriate to avoid orphan nodes (e.g., fuel integration tests).
test/gut/test_master_volume_control_and_music.gd
test/gut/test_sfx_rotor_volume_control.gd
test/gut/test_sfx_weapon_volume_control.gd
test/gut/test_pause_menu.gd
test/gut/test_fuel_additional_edge_cases.gd

Assessment against linked issues

Issue Objective Addressed Explanation
#524 Create the new folder hierarchy under res://scripts/ (core/, managers/, resources/, entities/, system/, and ui/ with ui/menus/, ui/components/, and ui/screens/) to serve as an empty directory skeleton. The diff does not show the introduction of the requested empty directory skeleton as a standalone change. Instead, it introduces GamePaths, updates documentation, tests, project and scene references, and (per the PR description) moves various scripts into resources/, entities/, system/, ui/, and managers/. This corresponds to a later refactor phase that assumes the structure already exists rather than implementing the initial creation of the empty directory skeleton.
#524 Leave all existing scripts in place and make no code, path, or configuration changes; this issue is strictly to create empty folders inside the Godot Editor. The PR explicitly performs code and asset refactoring: it moves scripts into subdirectories, centralizes paths in scripts/core/game_paths.gd, updates test preloads and scene loads to use GamePaths, modifies documentation (Development_Guide.md), and updates project/scene references. These actions contradict the issue’s constraint to not move any scripts or change paths/configuration as part of this task.
#527 Refactor resource and settings-related scripts by moving game_settings_resource.gd (and other settings-related scripts such as audio_constants.gd) into a dedicated scripts/resources/ (and related UI subdirectories), and update documentation and references to use the new paths so that none of these remain loose in res://scripts/.
#527 Refactor entity scripts by moving player.gd, bullet.gd, and weapon.gd into a dedicated scripts/entities/ directory and update all scene, project, and test references accordingly so they no longer reside in the res://scripts/ root.
#527 Refactor system and UI/manager scripts by moving OSWrapper.gd, JavaScriptBridgeWrapper.gd, audio_web_bridge.gd, hud.gd, and parallax_manager.gd into appropriate subdirectories (e.g., scripts/system/, scripts/ui/, scripts/managers/), centralize paths (e.g., via GamePaths), and ensure no loose .gd files remain in the base res://scripts/ directory.
#528 Update all hardcoded script and scene path strings (e.g., res://scripts/..., res://scenes/...) to the new folder structure so that no 'Cannot load resource' errors occur after refactoring.
#528 Introduce a less fragile mechanism for referencing scripts/scenes so future file moves do not break dependencies (i.e., centralize path definitions instead of scattering string literals).
#528 Ensure documentation and tests are aligned with the new script/scene locations so that developer guidance and automated checks reflect the updated dependency structure.
#583 Introduce a centralized GamePaths class in scripts/core/game_paths.gd, declared with class_name GamePaths, that defines string constants for frequently used script and scene paths (e.g., player.gd, HUD, gameplay_settings.gd, input_remap_button.gd, settings.gd, and common menu/scene .tscn files).
#583 Refactor GUT tests and helper scripts to replace hardcoded script and scene path string literals with the corresponding GamePaths constants, so tests and helpers no longer rely on embedded res:// path strings for these core scripts and scenes.
#583 Migrate existing standalone path constants (such as UI_NAV_SOUND_PATH in globals.gd) into the new GamePaths class so that script and resource paths are fully centralized. The diff does not show any changes to globals.gd or migration of existing standalone path constants into GamePaths; only new constants are added and tests/helpers are updated to use them.

Possibly linked issues

  • #: Link: the PR executes the specified script relocations (resources, entities, system, HUD, parallax) and cleans scripts/ root.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 22, 2026

📝 Walkthrough

Walkthrough

Adds a centralized GamePaths class and relocates many script files; updates scene ext_resource script paths, autoload script paths, a settings resource reference, documentation table entries, and numerous tests to use GamePaths constants. No functional logic changes beyond path centralization.

Changes

Cohort / File(s) Summary
Configuration & Autoloads
config_resources/default_settings.tres, project.godot
Updated ext_resource/script paths: default settings resource now references res://scripts/resources/game_settings_resource.gd; autoloads AudioConstants and AudioWebBridge point to relocated script paths.
Entity Scenes
scenes/Player.tscn, scenes/bullet.tscn, scenes/weapon.tscn
Scene script ext_resource paths updated to res://scripts/entities/... for player, bullet, and weapon scenes.
UI & Managers Scenes
scenes/main_scene.tscn
HUD and parallax manager ext_resource paths updated to res://scripts/ui/hud.gd and res://scripts/managers/parallax_manager.gd.
Core Paths
scripts/core/game_paths.gd, scripts/core/game_paths.gd.uid
New GamePaths RefCounted class with named const String resource/scene/script paths and accompanying .uid file.
Tests
test/gut/* (many files, e.g., test/gut/*.gd)
Numerous test files switched from hardcoded res:// strings to GamePaths constants; a few tests adjusted lifetime management (use of autofree(...)) and small comment/whitespace edits.
Documentation
files/docs/Development_Guide.md
Updated Core Files Reference table: moved entries to new res:// paths and removed two rows via <del>; adjusted MD033 linting directives.

Sequence Diagram(s)

(Skipped — changes are path refactors and centralized constants without a new multi-component sequential flow.)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

Suggested labels

testing, documentation

Poem

🐰 I hopped through folders, paths in my paws,
Moved scripts to neat nests without a pause.
Constants now point where each file belongs,
Tests follow suit — a tidy set of prongs.
Hop, patch, commit — the repo hums its song.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: reorganizing scripts into structured subdirectories (resources, entities, system) during refactoring phase 4.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering all template sections with detailed explanations of architectural enhancements, test stabilization, and documentation updates.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch migrate-resources-entities-and-system-scripts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@project.godot`:
- Around line 29-31: Tests, helper and docs still reference old script paths;
update the hardcoded preload()/load() calls and string literals in the listed
files to the new locations or use the autoload singletons defined in
project.godot. Specifically: in test_gameplay_settings_ui.gd,
test_gameplay_settings_lifecycle.gd, test_gameplay_settings_js.gd,
test_game_settings_resource.gd, and test_audio_web_bridge.gd replace
preload("res://scripts/audio_web_bridge.gd")/preload("res://scripts/gameplay_settings.gd")
with the new path or the autoload singleton (e.g., use AudioWebBridge or
preload("res://scripts/system/audio_web_bridge.gd") as defined by AudioWebBridge
in project.godot); in gut_test_helper.gd update the string literals
"res://scripts/player.gd" and "res://scripts/hud.gd" to their new locations or
reference the appropriate singleton/class; and update the table entries in
Development_Guide.md to match the new paths (AudioConstants ->
res://scripts/resources/audio_constants.gd, AudioManager ->
res://scripts/managers/audio_manager.gd, AudioWebBridge ->
res://scripts/system/audio_web_bridge.gd). Ensure all replacements use exact
symbols/names from project.godot so tests and docs point to valid files.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: be174320-e538-4d3a-8141-88616e9e8cbe

📥 Commits

Reviewing files that changed from the base of the PR and between c9f1404 and 47e4797.

📒 Files selected for processing (26)
  • config_resources/default_settings.tres
  • project.godot
  • scenes/Player.tscn
  • scenes/bullet.tscn
  • scenes/main_scene.tscn
  • scenes/weapon.tscn
  • scripts/entities/bullet.gd
  • scripts/entities/bullet.gd.uid
  • scripts/entities/player.gd
  • scripts/entities/player.gd.uid
  • scripts/entities/weapon.gd
  • scripts/entities/weapon.gd.uid
  • scripts/managers/parallax_manager.gd
  • scripts/managers/parallax_manager.gd.uid
  • scripts/resources/audio_constants.gd
  • scripts/resources/audio_constants.gd.uid
  • scripts/resources/game_settings_resource.gd
  • scripts/resources/game_settings_resource.gd.uid
  • scripts/system/JavaScriptBridgeWrapper.gd
  • scripts/system/JavaScriptBridgeWrapper.gd.uid
  • scripts/system/OSWrapper.gd
  • scripts/system/OSWrapper.gd.uid
  • scripts/system/audio_web_bridge.gd
  • scripts/system/audio_web_bridge.gd.uid
  • scripts/ui/hud.gd
  • scripts/ui/hud.gd.uid
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: GDUnit4 Unit Tests / unit-test
  • GitHub Check: GUT Unit Tests / unit-test
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-04-10T00:07:55.427Z
Learnt from: ikostan
Repo: ikostan/SkyLockAssault PR: 534
File: scripts/player.gd:146-149
Timestamp: 2026-04-10T00:07:55.427Z
Learning: In `scripts/globals.gd` and `scripts/player.gd` (GDScript, Godot 4), `current_fuel` is intentionally treated as volatile session data and should NOT be saved to or loaded from `settings.cfg`. Only `max_fuel` (tank capacity) is a persistent setting. `current_fuel` is always reset to `max_fuel` unconditionally in `player._ready()`. Persisting `current_fuel` is considered an architectural mistake by the project maintainer (ikostan). Mid-run fuel state persistence is planned via a separate `SaveGameResource` in PR `#535`.

Applied to files:

  • scenes/Player.tscn
🔇 Additional comments (5)
scenes/weapon.tscn (1)

3-3: LGTM!

Script path updated to new entities/ location; UID and ext_resource id preserved.

scenes/Player.tscn (1)

3-3: LGTM!

Path relocation to scripts/entities/player.gd with preserved UID.

scenes/bullet.tscn (1)

3-3: LGTM!

Bullet script path updated consistently with the entities reorg.

scenes/main_scene.tscn (1)

79-80: LGTM!

HUD and parallax manager script paths updated to scripts/ui/ and scripts/managers/; UIDs and ext_resource ids preserved, so node bindings on lines 128 and 208 remain valid.

config_resources/default_settings.tres (1)

5-5: LGTM!

game_settings_resource.gd path updated to scripts/resources/; UID preserved so the script_class="GameSettingsResource" and metadata/_custom_type_script references remain consistent.

Comment thread project.godot
@deepsource-io
Copy link
Copy Markdown

deepsource-io Bot commented Apr 22, 2026

DeepSource Code Review

We reviewed changes in c9f1404...bbc1766 on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade   Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
Python Apr 23, 2026 6:47p.m. Review ↗
JavaScript Apr 23, 2026 6:47p.m. Review ↗

Important

AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.

ikostan added 3 commits April 21, 2026 21:07
…rence old script locations.

The autoload updates are correct and singleton references work fine, but verification found multiple broken preload()/load() calls and string literals pointing to old paths:

Test files (5 refs): test_gameplay_settings_ui.gd, test_gameplay_settings_lifecycle.gd, test_gameplay_settings_js.gd, test_game_settings_resource.gd, test_audio_web_bridge.gd all use preload("res://scripts/gameplay_settings.gd") or preload("res://scripts/audio_web_bridge.gd")
Test helper (2 refs): gut_test_helper.gd has string literals "res://scripts/player.gd" and "res://scripts/hud.gd" that need updating
Documentation (2 refs): Development_Guide.md references old paths in tables
These need to be updated to reflect the new script locations.
@ikostan
Copy link
Copy Markdown
Owner Author

ikostan commented Apr 22, 2026

@sourcery-ai review

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The Development_Guide table lists gameplay_settings.gd at res://scripts/ui/gameplay_settings.gd and advanced_settings.gd at res://scripts/menus/advanced_settings.gd, but the tests now preload res://scripts/ui/menus/gameplay_settings.gd; please align these documented paths with the actual folder structure so the guide matches the codebase.
  • In the Development_Guide table you’re using <del> inside a pipe table with markdownlint disabled; double-check that this renders correctly in your primary docs viewer (GitHub, GitLab, etc.) and consider using a separate section or bullet list if the table layout becomes hard to read.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The Development_Guide table lists `gameplay_settings.gd` at `res://scripts/ui/gameplay_settings.gd` and `advanced_settings.gd` at `res://scripts/menus/advanced_settings.gd`, but the tests now preload `res://scripts/ui/menus/gameplay_settings.gd`; please align these documented paths with the actual folder structure so the guide matches the codebase.
- In the Development_Guide table you’re using `<del>` inside a pipe table with markdownlint disabled; double-check that this renders correctly in your primary docs viewer (GitHub, GitLab, etc.) and consider using a separate section or bullet list if the table layout becomes hard to read.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

The Development_Guide table lists gameplay_settings.gd at res://scripts/ui/gameplay_settings.gd and advanced_settings.gd at res://scripts/menus/advanced_settings.gd, but the tests now preload res://scripts/ui/menus/gameplay_settings.gd; please align these documented paths with the actual folder structure so the guide matches the codebase.
@ikostan
Copy link
Copy Markdown
Owner Author

ikostan commented Apr 22, 2026

  • The Development_Guide table lists gameplay_settings.gd at res://scripts/ui/gameplay_settings.gd and advanced_settings.gd at res://scripts/menus/advanced_settings.gd, but the tests now preload res://scripts/ui/menus/gameplay_settings.gd; please align these documented paths with the actual folder structure so the guide matches the codebase.

Fixed

@ikostan
Copy link
Copy Markdown
Owner Author

ikostan commented Apr 22, 2026

  • In the Development_Guide table you’re using <del> inside a pipe table with markdownlint disabled; double-check that this renders correctly in your primary docs viewer (GitHub, GitLab, etc.) and consider using a separate section or bullet list if the table layout becomes hard to read.

Won't fix

@ikostan
Copy link
Copy Markdown
Owner Author

ikostan commented Apr 22, 2026

@sourcery-ai review

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The core files reference table now mixes active and deleted entries using HTML <del> tags; consider moving deprecated items into a separate "Deprecated" subsection/table to keep the main reference concise and easier to scan.
  • Several tests and helpers hardcode script paths (e.g., multiple references to scripts/ui/menus/gameplay_settings.gd and scripts/entities/player.gd); centralizing these into shared constants or a small path helper would make future refactors like this less error-prone.
  • The Markdown lint suppression (markdownlint-disable MD033) currently wraps the whole table block; if possible, narrow its scope to just the lines that need raw HTML to reduce the chance of unintentionally allowing other inline HTML later.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The core files reference table now mixes active and deleted entries using HTML `<del>` tags; consider moving deprecated items into a separate "Deprecated" subsection/table to keep the main reference concise and easier to scan.
- Several tests and helpers hardcode script paths (e.g., multiple references to `scripts/ui/menus/gameplay_settings.gd` and `scripts/entities/player.gd`); centralizing these into shared constants or a small path helper would make future refactors like this less error-prone.
- The Markdown lint suppression (`markdownlint-disable MD033`) currently wraps the whole table block; if possible, narrow its scope to just the lines that need raw HTML to reduce the chance of unintentionally allowing other inline HTML later.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@ikostan
Copy link
Copy Markdown
Owner Author

ikostan commented Apr 23, 2026

  • Several tests and helpers hardcode script paths (e.g., multiple references to scripts/ui/menus/gameplay_settings.gd and scripts/entities/player.gd); centralizing these into shared constants or a small path helper would make future refactors like this less error-prone.

Working on it.

@ikostan
Copy link
Copy Markdown
Owner Author

ikostan commented Apr 23, 2026

  • The core files reference table now mixes active and deleted entries using HTML <del> tags; consider moving deprecated items into a separate "Deprecated" subsection/table to keep the main reference concise and easier to scan.
  • The Markdown lint suppression (markdownlint-disable MD033) currently wraps the whole table block; if possible, narrow its scope to just the lines that need raw HTML to reduce the chance of unintentionally allowing other inline HTML later.

Won't fix.

…ass #583

Description:

Currently, several tests and helper scripts hardcode script paths as string literals. For example, there are multiple hardcoded references to res://scripts/ui/menus/gameplay_settings.gd and res://scripts/entities/player.gd. This issue tracks the refactoring required to centralize these paths into a single source of truth.

Why is this useful?

Hardcoding script paths makes the codebase fragile. Centralizing these into shared constants or a small path helper makes future refactoring (like moving or renaming files) significantly less error-prone. By using a centralized class_name, we ensure that if a file is relocated, the path only needs to be updated in one place rather than doing a global search-and-replace across multiple test and helper files. It also provides better autocompletion and type safety within the Godot editor.
@ikostan
Copy link
Copy Markdown
Owner Author

ikostan commented Apr 23, 2026

@sourcery-ai review

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • In Development_Guide.md, the use of <del> tags inside the markdown table (and disabling MD033) makes the table harder to read and may not render consistently; consider moving deprecated entries to a separate section or marking them as deprecated in plain text instead of using inline HTML strikethroughs.
  • GamePaths is a good centralization point, but it currently only covers a subset of scripts/scenes; if the intent is to eliminate fragile string paths, consider incrementally adding remaining frequently used paths (e.g., resources like game_settings_resource.gd) and updating callers to use the constants for consistency.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `Development_Guide.md`, the use of `<del>` tags inside the markdown table (and disabling MD033) makes the table harder to read and may not render consistently; consider moving deprecated entries to a separate section or marking them as deprecated in plain text instead of using inline HTML strikethroughs.
- `GamePaths` is a good centralization point, but it currently only covers a subset of scripts/scenes; if the intent is to eliminate fragile string paths, consider incrementally adding remaining frequently used paths (e.g., resources like `game_settings_resource.gd`) and updating callers to use the constants for consistency.

## Individual Comments

### Comment 1
<location path="files/docs/Development_Guide.md" line_range="125" />
<code_context>
+| <del>**Logic Observer**             | <del>`res://scripts/globals.gd`</del>               | <del>Connects to the resource to trigger centralized logging and `_save_settings()`.</del> |
</code_context>
<issue_to_address>
**issue (bug_risk):** The `<del>` tag in the first cell of this row is not closed, unlike the other cells.

The first cell starts a `<del>` tag but never closes it, unlike the other cells. Please wrap the full cell content in a matching pair, e.g. `| <del>**Logic Observer**</del> | ...`, to keep the markup consistent and avoid rendering issues.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread files/docs/Development_Guide.md
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
files/docs/Development_Guide.md (2)

84-99: ⚠️ Potential issue | 🟡 Minor

Observer-pattern steps contradict the deleted table rows.

Two issues in this block:

  1. Line 90 still points to scripts/game_settings_resource.gd, but the resource was relocated to res://scripts/resources/game_settings_resource.gd (as correctly reflected in the updated table on line 124).
  2. Step 2 instructs updating _save_settings() / _load_settings() in globals.gd, yet the Logic Observer row for globals.gd was struck out in the table on line 125 (suggesting those responsibilities moved). Either the table deletion or this instruction is wrong — please reconcile.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@files/docs/Development_Guide.md` around lines 84 - 99, Update the docs to use
the correct resource path and reconcile who handles persistence: change the
reference from scripts/game_settings_resource.gd to
res://scripts/resources/game_settings_resource.gd in the "Define the Property"
step, and then clarify whether _save_settings()/_load_settings() in globals.gd
still manage persistence or if that responsibility moved to the resource (or
another class) — update Step 2 to point to the actual current persistence owner
(referencing _save_settings, _load_settings, globals.gd, and
game_settings_resource.gd) and adjust the table entries so the text and table
consistently reflect the single source of truth.

11-20: ⚠️ Potential issue | 🟡 Minor

Stale paths in "Key Files" and outdated engine version.

This section was not updated to reflect the PR's file relocations and target engine:

  • Line 11 says Godot v4.4, but the PR targets v4.5.
  • Line 19 should reference res://scripts/entities/player.gd.
  • Line 20 references scripts/Globals.gd (wrong casing) and should be aligned with the actual autoload path (res://scripts/globals.gd or wherever it now lives post-refactor).

Since this PR explicitly aims to keep documented paths in sync with code, please update this section too — otherwise only the "Core Files Reference" table is consistent.

📝 Proposed fix
-- **Engine**: Godot v4.4 (64-bit Windows compatible).
+- **Engine**: Godot v4.5 (64-bit Windows compatible).
@@
-  - `scripts/main_menu.gd`: Handles signals, quit logic.
-  - `scripts/player.gd`: Top-down movement.
-  - `scripts/Globals.gd`: Global vars (e.g., logging).
+  - `scripts/main_menu.gd`: Handles signals, quit logic.
+  - `scripts/entities/player.gd`: Top-down movement.
+  - `scripts/globals.gd`: Global vars (e.g., logging).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@files/docs/Development_Guide.md` around lines 11 - 20, Update the "Key Files"
list to match the PR refactor: change the Engine version from "Godot v4.4" to
"Godot v4.5"; replace `scripts/player.gd` with its new path
`res://scripts/entities/player.gd`; and fix the globals entry from
`scripts/Globals.gd` to the autoload path `res://scripts/globals.gd` (lowercase)
so the documented symbols project.godot, scenes/main_menu.tscn,
scripts/main_menu.gd, res://scripts/entities/player.gd, and
res://scripts/globals.gd reflect the repo structure and engine target.
test/gut/test_preserve_other_sections.gd (1)

42-44: ⚠️ Potential issue | 🟠 Major

Inconsistency with the new guarded-reset pattern in test_reset_scenarios.gd.

test_reset_scenarios.gd::before_each() now wraps the same current_log_level / difficulty resets in Globals._is_loading_settings = true/false to suppress the auto _save_settings() side effect, but this file's before_each() does not. Since the reactive handler in scripts/core/globals.gd::_on_setting_changed will call _save_settings() on each assignment here, every test in this file will trigger disk I/O against the real Settings.CONFIG_PATH during setup. Recommend applying the same guard for consistency and to avoid polluting the user's real settings file from the test suite.

♻️ Proposed fix
-	# Reset Globals settings
-	Globals.settings.current_log_level = Globals.LogLevel.INFO
-	Globals.settings.difficulty = 1.0
+	# Reset Globals settings (guarded to prevent automatic _save_settings() to disk)
+	Globals._is_loading_settings = true
+	Globals.settings.current_log_level = Globals.LogLevel.INFO
+	Globals.settings.difficulty = 1.0
+	Globals._is_loading_settings = false
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/gut/test_preserve_other_sections.gd` around lines 42 - 44, The test
resets Globals.settings.current_log_level and Globals.settings.difficulty
directly in before_each(), which triggers
scripts/core/globals.gd::_on_setting_changed and causes _save_settings() disk
I/O; wrap those assignments with Globals._is_loading_settings = true before the
changes and set it back to false after to suppress the auto-save (mirror the
pattern used in test_reset_scenarios.gd::before_each()), ensuring
current_log_level and difficulty are set while loading is guarded so tests do
not write to Settings.CONFIG_PATH.
🧹 Nitpick comments (10)
test/gut/test_input_remap_ec.gd (1)

9-9: Nit: align the typing style with the sibling test file.

test/gut/test_input_remap_button_device_aware.gd declares this as const InputRemapButton: Script = preload(...). Matching that here keeps the type annotation consistent across the GUT suite. Behavior is identical.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/gut/test_input_remap_ec.gd` at line 9, Update the constant declaration
for InputRemapButton to include the same Godot type annotation used in the
sibling test (i.e., declare const InputRemapButton: Script = preload(...)) so it
matches test/gut/test_input_remap_button_device_aware.gd; modify the preload
line for the InputRemapButton symbol accordingly to add the : Script type
annotation.
test/gut/test_sfx_volume_control.gd (1)

11-11: Nit: prefer preload for a static scene reference.

Other tests in this PR use preload(GamePaths.MAIN_SCENE) for scene constants. Here load() works but defers resolution to script-init time (slightly slower, error surfaces later). For consistency:

-var audio_scene: PackedScene = load(GamePaths.AUDIO_SETTINGS_SCENE)
+var audio_scene: PackedScene = preload(GamePaths.AUDIO_SETTINGS_SCENE)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/gut/test_sfx_volume_control.gd` at line 11, Replace the dynamic load
call with a compile-time preload for the static scene reference: change the
declaration of the audio_scene variable that currently uses
load(GamePaths.AUDIO_SETTINGS_SCENE) to use
preload(GamePaths.AUDIO_SETTINGS_SCENE) so the PackedScene is resolved at
script-load time (match other tests that use preload(GamePaths.MAIN_SCENE));
update the variable declaration named audio_scene to use preload accordingly.
files/docs/Development_Guide.md (1)

121-129: Table updates look correct; consider a cleaner alternative to <del> in a pipe table.

Wrapping row cells in <del> within a Markdown pipe table is fragile (some renderers mis-handle HTML-inside-table-cells, and it's the reason MD033 had to be disabled). If the intent is to mark deprecated rows, a note column ("Status: deprecated") or a separate "Removed / deprecated entries" sub-list would render more reliably across GitHub/docs renderers and avoid needing the markdownlint-disable MD033 block entirely.

Non-blocking — surfacing since the PR discussion already raised markdownlint-suppression scope.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@files/docs/Development_Guide.md` around lines 121 - 129, Replace the fragile
<del> HTML in the pipe table by either adding a "Status" column with values like
"deprecated" for rows such as "Logic Observer" (`res://scripts/globals.gd`) and
"Persistence Settings" (`res://scripts/settings.gd`), or move those entries into
a separate "Removed / deprecated entries" subsection below the table; then
remove the markdownlint-disable MD033/enable comments so the table renders
cleanly across renderers and lints normally.
scripts/core/game_paths.gd (2)

10-52: Path coverage is partial — several relocated files are still missing from GamePaths.

The PR relocates many files (bullet.gd, weapon.gd, audio_settings.gd, gameplay_settings_resource.gd, audio_constants.gd, OSWrapper.gd, JavaScriptBridgeWrapper.gd, parallax_manager.gd, etc.), but GamePaths only captures a subset. If the goal is "single source of truth to reduce future refactor brittleness", any res://... literal that still lives in tests/helpers will erode that guarantee the next time those files move.

Consider adding constants for at least the files this PR just relocated, e.g.:

const BULLET: String = "res://scripts/entities/bullet.gd"
const WEAPON: String = "res://scripts/entities/weapon.gd"
const OS_WRAPPER: String = "res://scripts/system/OSWrapper.gd"
const JS_BRIDGE_WRAPPER: String = "res://scripts/system/JavaScriptBridgeWrapper.gd"
const AUDIO_CONSTANTS: String = "res://scripts/resources/audio_constants.gd"
const AUDIO_SETTINGS_RESOURCE: String = "res://scripts/resources/audio_settings.gd"
const GAME_SETTINGS_RESOURCE: String = "res://scripts/resources/game_settings_resource.gd"
const PARALLAX_MANAGER: String = "res://scripts/managers/parallax_manager.gd"

Also, a grouping convention (e.g., PATH_SCRIPT_* / PATH_SCENE_* or nested classes) can prevent name collisions as the set grows.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/core/game_paths.gd` around lines 10 - 52, GamePaths currently defines
only a subset of relocated resource paths (see constants like PLAYER, HUD,
AUDIO_WEB_BRIDGE, GAMEPLAY_SETTINGS_SCENE) so add missing constants for the
files moved in this PR (e.g., BULLET, WEAPON, OS_WRAPPER, JS_BRIDGE_WRAPPER,
AUDIO_CONSTANTS, AUDIO_SETTINGS_RESOURCE, GAME_SETTINGS_RESOURCE,
PARALLAX_MANAGER) using the same String const pattern as existing entries to
ensure tests/helpers use these central values; also apply a simple
naming/grouping convention (e.g., prefix script constants with SCRIPT_ or group
scene constants) to avoid future collisions and keep the file organized.

7-8: Minor: RefCounted is unnecessary for a constants-only container.

Since the class is never instantiated and only exposes consts, extending Object (or keeping RefCounted — both are fine) is equivalent, but it may be worth a short docstring note that instances shouldn't be constructed. Non-blocking.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/core/game_paths.gd` around lines 7 - 8, GamePaths is a constants-only
container but currently extends RefCounted; change it to not imply instantiation
by either replacing "extends RefCounted" with "extends Object" (or removing the
extends line) and/or add a short class docstring/note above the class_name
stating that this class only holds consts and should not be instantiated;
reference the GamePaths class and its const members when making the change.
test/gut/test_pause_menu.gd (1)

37-40: Optional: consider dropping the explanatory comment once the decision is stable.

The note about removed stub() calls is useful context now, but long-term it may become stale. If you want to preserve the rationale, a brief one-liner or a link to the discussion is typically enough.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/gut/test_pause_menu.gd` around lines 37 - 40, Replace the multi-line
explanatory comment about removed stub() calls in test/gut/test_pause_menu.gd
with a concise one-liner (or remove it entirely) that states: "Removed stub()
calls because GUT cannot stub Autoload instances and these methods aren't used
by PM-01–PM-05 pause/resume flows." Keep the reference to stub(), Autoload, and
the PM-01..PM-05 flows so future readers understand the rationale without a
long, potentially stale paragraph.
test/gut/gut_test_helper.gd (1)

63-66: Minor: silently skipping HUD script assignment may mask a real failure.

If load(GamePaths.HUD) returns null (e.g., path regressed during a future move), the mock panel will be built without its HUD script and tests that exercise HUD behavior will fail with confusing downstream errors rather than a clear setup failure. Consider asserting/pushing an error instead of the silent if hud_script: fallback.

Proposed tweak
-	var hud_script := load(GamePaths.HUD)
-	if hud_script:
-		panel.set_script(hud_script)
+	var hud_script: Script = load(GamePaths.HUD)
+	assert(hud_script != null, "Failed to load HUD script from " + GamePaths.HUD)
+	panel.set_script(hud_script)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/gut/gut_test_helper.gd` around lines 63 - 66, The code silently skips
assigning the HUD script when load(GamePaths.HUD) returns null; change the setup
in the test helper to fail fast by checking hud_script and raising/asserting if
it's null so tests don't proceed with a misconfigured mock. Specifically, after
calling var hud_script := load(GamePaths.HUD), replace the silent if hud_script:
panel.set_script(hud_script) behavior with an explicit assertion or error (using
assert, push_error, or a test framework fail) that references hud_script and
GamePaths.HUD before calling panel.set_script to guarantee the HUD script is
present.
test/gut/test_master_volume_control_and_music.gd (2)

11-11: Same optional suggestion as in test_reset_scenarios.gd.

Prefer instantiating audio_scene inside before_each() rather than at script scope to avoid sharing a single PackedScene across tests and to decouple script load from resource availability. Not a blocker.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/gut/test_master_volume_control_and_music.gd` at line 11, Move
instantiation of the audio scene into the test setup by creating/assigning
audio_scene inside before_each() instead of at script scope: replace the
top-level PackedScene load of audio_scene with a local/instance assignment
performed in the before_each() function so each test gets its own instance and
the resource load is decoupled from script evaluation (refer to audio_scene and
before_each()).

354-362: Good fix for the orphan Control.

Wrapping Control.new() in autofree() correctly handles the lifetime of a node that’s never added to the tree and would otherwise leak. Rationale comment is helpful.

One residual concern unrelated to this change: on line 362, audio_instance.queue_free() is invoked while the node is also tracked by add_child_autofree() from before_each(). queue_free() is idempotent in practice, but relying on the double-free being a no-op is fragile — consider removing the explicit queue_free() here and letting autofree handle it, or detaching from autofree tracking. Optional.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/gut/test_master_volume_control_and_music.gd` around lines 354 - 362, The
test currently calls audio_instance.queue_free() while the same node is already
managed by add_child_autofree() in before_each(), which risks fragile
double-free assumptions; remove the explicit audio_instance.queue_free() call
and let GUT's add_child_autofree()/autofree lifecycle management handle cleanup,
keeping the new autofree(Control.new()) for prev_menu as-is (references:
audio_instance, add_child_autofree, before_each, autofree, prev_menu,
queue_free).
test/gut/test_reset_scenarios.gd (1)

12-12: Minor: consider moving the load() into before_each().

Loading the PackedScene at script scope runs during test-script load (before GUT fully sets up), couples test-file parsing to resource availability, and shares a single PackedScene across all tests. Moving it into before_each() (or lazy-initializing it) isolates failures per test and matches how the scene is consumed. Not a blocker.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/gut/test_reset_scenarios.gd` at line 12, The test loads a PackedScene at
script scope via the audio_scene variable which runs during test-file load; move
the load into the GUT before_each() hook (or lazy-initialize audio_scene inside
before_each()) so each test gets its own PackedScene and resource failures are
isolated per-test; update references to audio_scene in tests to use the instance
set in before_each() and remove the top-level load() call.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/gut/test_preserve_other_sections.gd`:
- Around line 99-116: Update the misleading inline comment at the end of the
test to accurately state what's being asserted: instead of saying "Globals
unchanged (not loaded here)", clarify that the test asserts
Globals.settings.current_log_level and Globals.settings.difficulty remain the
values just set while Globals._is_loading_settings was true (DEBUG and 2.0) and
were not modified by AudioManager.load_volumes() /
AudioManager.apply_all_volumes(); reference the Globals._is_loading_settings
guard and the assertions that follow to ensure the comment clearly ties to those
symbols.

---

Outside diff comments:
In `@files/docs/Development_Guide.md`:
- Around line 84-99: Update the docs to use the correct resource path and
reconcile who handles persistence: change the reference from
scripts/game_settings_resource.gd to
res://scripts/resources/game_settings_resource.gd in the "Define the Property"
step, and then clarify whether _save_settings()/_load_settings() in globals.gd
still manage persistence or if that responsibility moved to the resource (or
another class) — update Step 2 to point to the actual current persistence owner
(referencing _save_settings, _load_settings, globals.gd, and
game_settings_resource.gd) and adjust the table entries so the text and table
consistently reflect the single source of truth.
- Around line 11-20: Update the "Key Files" list to match the PR refactor:
change the Engine version from "Godot v4.4" to "Godot v4.5"; replace
`scripts/player.gd` with its new path `res://scripts/entities/player.gd`; and
fix the globals entry from `scripts/Globals.gd` to the autoload path
`res://scripts/globals.gd` (lowercase) so the documented symbols project.godot,
scenes/main_menu.tscn, scripts/main_menu.gd, res://scripts/entities/player.gd,
and res://scripts/globals.gd reflect the repo structure and engine target.

In `@test/gut/test_preserve_other_sections.gd`:
- Around line 42-44: The test resets Globals.settings.current_log_level and
Globals.settings.difficulty directly in before_each(), which triggers
scripts/core/globals.gd::_on_setting_changed and causes _save_settings() disk
I/O; wrap those assignments with Globals._is_loading_settings = true before the
changes and set it back to false after to suppress the auto-save (mirror the
pattern used in test_reset_scenarios.gd::before_each()), ensuring
current_log_level and difficulty are set while loading is guarded so tests do
not write to Settings.CONFIG_PATH.

---

Nitpick comments:
In `@files/docs/Development_Guide.md`:
- Around line 121-129: Replace the fragile <del> HTML in the pipe table by
either adding a "Status" column with values like "deprecated" for rows such as
"Logic Observer" (`res://scripts/globals.gd`) and "Persistence Settings"
(`res://scripts/settings.gd`), or move those entries into a separate "Removed /
deprecated entries" subsection below the table; then remove the
markdownlint-disable MD033/enable comments so the table renders cleanly across
renderers and lints normally.

In `@scripts/core/game_paths.gd`:
- Around line 10-52: GamePaths currently defines only a subset of relocated
resource paths (see constants like PLAYER, HUD, AUDIO_WEB_BRIDGE,
GAMEPLAY_SETTINGS_SCENE) so add missing constants for the files moved in this PR
(e.g., BULLET, WEAPON, OS_WRAPPER, JS_BRIDGE_WRAPPER, AUDIO_CONSTANTS,
AUDIO_SETTINGS_RESOURCE, GAME_SETTINGS_RESOURCE, PARALLAX_MANAGER) using the
same String const pattern as existing entries to ensure tests/helpers use these
central values; also apply a simple naming/grouping convention (e.g., prefix
script constants with SCRIPT_ or group scene constants) to avoid future
collisions and keep the file organized.
- Around line 7-8: GamePaths is a constants-only container but currently extends
RefCounted; change it to not imply instantiation by either replacing "extends
RefCounted" with "extends Object" (or removing the extends line) and/or add a
short class docstring/note above the class_name stating that this class only
holds consts and should not be instantiated; reference the GamePaths class and
its const members when making the change.

In `@test/gut/gut_test_helper.gd`:
- Around line 63-66: The code silently skips assigning the HUD script when
load(GamePaths.HUD) returns null; change the setup in the test helper to fail
fast by checking hud_script and raising/asserting if it's null so tests don't
proceed with a misconfigured mock. Specifically, after calling var hud_script :=
load(GamePaths.HUD), replace the silent if hud_script:
panel.set_script(hud_script) behavior with an explicit assertion or error (using
assert, push_error, or a test framework fail) that references hud_script and
GamePaths.HUD before calling panel.set_script to guarantee the HUD script is
present.

In `@test/gut/test_input_remap_ec.gd`:
- Line 9: Update the constant declaration for InputRemapButton to include the
same Godot type annotation used in the sibling test (i.e., declare const
InputRemapButton: Script = preload(...)) so it matches
test/gut/test_input_remap_button_device_aware.gd; modify the preload line for
the InputRemapButton symbol accordingly to add the : Script type annotation.

In `@test/gut/test_master_volume_control_and_music.gd`:
- Line 11: Move instantiation of the audio scene into the test setup by
creating/assigning audio_scene inside before_each() instead of at script scope:
replace the top-level PackedScene load of audio_scene with a local/instance
assignment performed in the before_each() function so each test gets its own
instance and the resource load is decoupled from script evaluation (refer to
audio_scene and before_each()).
- Around line 354-362: The test currently calls audio_instance.queue_free()
while the same node is already managed by add_child_autofree() in before_each(),
which risks fragile double-free assumptions; remove the explicit
audio_instance.queue_free() call and let GUT's add_child_autofree()/autofree
lifecycle management handle cleanup, keeping the new autofree(Control.new()) for
prev_menu as-is (references: audio_instance, add_child_autofree, before_each,
autofree, prev_menu, queue_free).

In `@test/gut/test_pause_menu.gd`:
- Around line 37-40: Replace the multi-line explanatory comment about removed
stub() calls in test/gut/test_pause_menu.gd with a concise one-liner (or remove
it entirely) that states: "Removed stub() calls because GUT cannot stub Autoload
instances and these methods aren't used by PM-01–PM-05 pause/resume flows." Keep
the reference to stub(), Autoload, and the PM-01..PM-05 flows so future readers
understand the rationale without a long, potentially stale paragraph.

In `@test/gut/test_reset_scenarios.gd`:
- Line 12: The test loads a PackedScene at script scope via the audio_scene
variable which runs during test-file load; move the load into the GUT
before_each() hook (or lazy-initialize audio_scene inside before_each()) so each
test gets its own PackedScene and resource failures are isolated per-test;
update references to audio_scene in tests to use the instance set in
before_each() and remove the top-level load() call.

In `@test/gut/test_sfx_volume_control.gd`:
- Line 11: Replace the dynamic load call with a compile-time preload for the
static scene reference: change the declaration of the audio_scene variable that
currently uses load(GamePaths.AUDIO_SETTINGS_SCENE) to use
preload(GamePaths.AUDIO_SETTINGS_SCENE) so the PackedScene is resolved at
script-load time (match other tests that use preload(GamePaths.MAIN_SCENE));
update the variable declaration named audio_scene to use preload accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c9dbc56a-6f58-4fbb-af8a-795a369c7ae8

📥 Commits

Reviewing files that changed from the base of the PR and between 47e4797 and a20c651.

📒 Files selected for processing (37)
  • files/docs/Development_Guide.md
  • scripts/core/game_paths.gd
  • scripts/core/game_paths.gd.uid
  • test/gut/gut_test_helper.gd
  • test/gut/test_audio_reset_button.gd
  • test/gut/test_audio_web_bridge.gd
  • test/gut/test_blank_key_labels_on_missing_config.gd
  • test/gut/test_decor_layer_transformations.gd
  • test/gut/test_deduplication_on_device_switch.gd
  • test/gut/test_deduplication_on_rapid_remap.gd
  • test/gut/test_deduplication_on_remap.gd
  • test/gut/test_deduplication_on_reset.gd
  • test/gut/test_fuel_additional_edge_cases.gd
  • test/gut/test_fuel_integration.gd
  • test/gut/test_game_settings_resource.gd
  • test/gut/test_gameplay_settings_js.gd
  • test/gut/test_gameplay_settings_lifecycle.gd
  • test/gut/test_gameplay_settings_ui.gd
  • test/gut/test_get_pause_binding_label_for_device.gd
  • test/gut/test_input_remap_button.gd
  • test/gut/test_input_remap_button_device_aware.gd
  • test/gut/test_input_remap_ec.gd
  • test/gut/test_integration_key_mapping.gd
  • test/gut/test_key_mapping_menu.gd
  • test/gut/test_key_mapping_menu_device_aware.gd
  • test/gut/test_main_scene_orphan_nodes.gd
  • test/gut/test_main_scene_parallax_and_performance.gd
  • test/gut/test_master_volume_control_and_music.gd
  • test/gut/test_pause_menu.gd
  • test/gut/test_player_lifecycle.gd
  • test/gut/test_preserve_other_sections.gd
  • test/gut/test_reset_scenarios.gd
  • test/gut/test_settings_unbound_scenarios.gd
  • test/gut/test_sfx_rotor_volume_control.gd
  • test/gut/test_sfx_volume_control.gd
  • test/gut/test_sfx_weapon_volume_control.gd
  • test/gut/test_version_display.gd
✅ Files skipped from review due to trivial changes (17)
  • scripts/core/game_paths.gd.uid
  • test/gut/test_fuel_integration.gd
  • test/gut/test_decor_layer_transformations.gd
  • test/gut/test_fuel_additional_edge_cases.gd
  • test/gut/test_deduplication_on_reset.gd
  • test/gut/test_get_pause_binding_label_for_device.gd
  • test/gut/test_key_mapping_menu.gd
  • test/gut/test_audio_web_bridge.gd
  • test/gut/test_key_mapping_menu_device_aware.gd
  • test/gut/test_deduplication_on_rapid_remap.gd
  • test/gut/test_version_display.gd
  • test/gut/test_audio_reset_button.gd
  • test/gut/test_settings_unbound_scenarios.gd
  • test/gut/test_input_remap_button.gd
  • test/gut/test_deduplication_on_device_switch.gd
  • test/gut/test_player_lifecycle.gd
  • test/gut/test_blank_key_labels_on_missing_config.gd
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Browser Functional Tests / test
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2026-03-30T04:02:23.747Z
Learnt from: ikostan
Repo: ikostan/SkyLockAssault PR: 500
File: test/gut/test_audio_web_bridge.gd:131-145
Timestamp: 2026-03-30T04:02:23.747Z
Learning: In GUT (Godot Unit Test) for Godot 4, when using `assert_called` / `assert_called_count` with parameter matching, include *every* argument the mocked method accepts, including parameters with default values. GUT does not auto-fill default arguments during call matching. For example, if `JavaScriptBridgeWrapper.eval(script: String, global_exec: bool = false)` is invoked as `eval(js_string)`, the actual call recorded by GUT includes the default (`eval(js_string, false)`), so your assertion must match both arguments (e.g., `.bind(js_string, false)`, not `.bind(js_string)`). Apply this rule to GUT assertions in `test/gut` tests.

Applied to files:

  • test/gut/test_sfx_volume_control.gd
  • test/gut/test_deduplication_on_remap.gd
  • test/gut/test_input_remap_ec.gd
  • test/gut/test_input_remap_button_device_aware.gd
  • test/gut/test_gameplay_settings_js.gd
  • test/gut/test_reset_scenarios.gd
  • test/gut/test_sfx_weapon_volume_control.gd
  • test/gut/gut_test_helper.gd
  • test/gut/test_main_scene_parallax_and_performance.gd
  • test/gut/test_gameplay_settings_ui.gd
  • test/gut/test_pause_menu.gd
  • test/gut/test_master_volume_control_and_music.gd
  • test/gut/test_sfx_rotor_volume_control.gd
  • test/gut/test_game_settings_resource.gd
  • test/gut/test_preserve_other_sections.gd
  • test/gut/test_gameplay_settings_lifecycle.gd
  • test/gut/test_integration_key_mapping.gd
  • test/gut/test_main_scene_orphan_nodes.gd
📚 Learning: 2026-02-25T05:50:14.510Z
Learnt from: ikostan
Repo: ikostan/SkyLockAssault PR: 429
File: scripts/input_remap_button.gd:158-162
Timestamp: 2026-02-25T05:50:14.510Z
Learning: In `scripts/input_remap_button.gd`, the keyboard event copying logic (around lines 158-162) intentionally omits `meta_pressed` when transferring modifier states to new_event. Only `shift_pressed`, `ctrl_pressed`, and `alt_pressed` are copied. This is by design.

Applied to files:

  • test/gut/test_deduplication_on_remap.gd
  • test/gut/test_input_remap_ec.gd
  • test/gut/test_input_remap_button_device_aware.gd
  • test/gut/test_integration_key_mapping.gd
📚 Learning: 2026-04-10T00:07:55.427Z
Learnt from: ikostan
Repo: ikostan/SkyLockAssault PR: 534
File: scripts/player.gd:146-149
Timestamp: 2026-04-10T00:07:55.427Z
Learning: In `scripts/globals.gd` and `scripts/player.gd` (GDScript, Godot 4), `current_fuel` is intentionally treated as volatile session data and should NOT be saved to or loaded from `settings.cfg`. Only `max_fuel` (tank capacity) is a persistent setting. `current_fuel` is always reset to `max_fuel` unconditionally in `player._ready()`. Persisting `current_fuel` is considered an architectural mistake by the project maintainer (ikostan). Mid-run fuel state persistence is planned via a separate `SaveGameResource` in PR `#535`.

Applied to files:

  • test/gut/test_gameplay_settings_lifecycle.gd
📚 Learning: 2026-02-25T05:46:55.056Z
Learnt from: ikostan
Repo: ikostan/SkyLockAssault PR: 429
File: scripts/settings.gd:593-601
Timestamp: 2026-02-25T05:46:55.056Z
Learning: In `scripts/settings.gd`, the `events_match` function intentionally omits `meta_pressed` comparison for InputEventKey events. It only compares `physical_keycode`, `shift_pressed`, `ctrl_pressed`, and `alt_pressed`. This is by design.

Applied to files:

  • test/gut/test_integration_key_mapping.gd
🔇 Additional comments (16)
test/gut/test_main_scene_orphan_nodes.gd (1)

14-14: LGTM — path centralization applied correctly.

preload(GamePaths.MAIN_SCENE) is valid because GamePaths.MAIN_SCENE is a compile-time const String from a class_name script. Both call sites (before_each and test_scene_reload_lifecycle) are consistent.

test/gut/test_main_scene_parallax_and_performance.gd (1)

19-19: LGTM.

Consistent with the other GUT tests migrating to GamePaths.MAIN_SCENE.

test/gut/test_input_remap_button_device_aware.gd (1)

11-13: LGTM.

const InputRemapButton: Script = preload(GamePaths.INPUT_REMAP_BUTTON) correctly re-uses the class-style alias so var button: InputRemapButton and the nested enum reference InputRemapButton.DeviceType.KEYBOARD continue to resolve.

test/gut/test_gameplay_settings_js.gd (1)

10-16: LGTM.

Both the script (GAMEPLAY_SETTINGS) and the scene (GAMEPLAY_SETTINGS_SCENE) are resolved via GamePaths, keeping this test aligned with the PR-wide centralization. preload for the script and load for the scene is acceptable since gameplay_menu is declared as Control (no compile-time type dependency on the scene).

scripts/core/game_paths.gd (1)

30-30: No action needed. The constant SETTINGS at line 30 correctly references res://scripts/core/settings.gd, which exists and is actively used in the codebase without issues.

			> Likely an incorrect or invalid review comment.
test/gut/test_deduplication_on_remap.gd (1)

11-11: LGTM — path centralization applied correctly.

Preload now resolves InputRemapButton via GamePaths.INPUT_REMAP_BUTTON, which matches the constant definition in scripts/core/game_paths.gd. No behavioral change.

test/gut/test_integration_key_mapping.gd (1)

18-18: LGTM — consistent migration to GamePaths constants.

All three integration tests now resolve the key-mapping scene and InputRemapButton script through centralized constants, eliminating the hardcoded literals without altering test flow.

Also applies to: 95-95, 115-115, 167-167

test/gut/test_gameplay_settings_ui.gd (1)

10-10: LGTM — GamePaths lookups are equivalent to previous literals.

Both the script preload and the scene load use centralized constants; remaining UI setup and assertions are unchanged.

Also applies to: 19-19

test/gut/test_gameplay_settings_lifecycle.gd (1)

9-9: LGTM — all four resource lookups migrated consistently.

The preload at class scope plus the three scene loads in before_each, test_gs_life_08_web_overlay_cleanup, and test_gs_life_09_unexpected_removal_restoration now go through GamePaths, matching the rest of the suite.

Also applies to: 14-14, 59-59, 96-96

test/gut/test_sfx_weapon_volume_control.gd (2)

11-11: LGTM — scene load centralized.

audio_scene now resolves through GamePaths.AUDIO_SETTINGS_SCENE; behavior preserved.


283-293: Good catch wrapping prev_menu with autofree().

Prevents the orphan-node leak flagged by GUT for the non-parented Control used to simulate the previous menu. Matches the pattern used in the other audio tests.

test/gut/test_pause_menu.gd (1)

14-14: LGTM — PauseMenuScene now preloaded via GamePaths.PAUSE_MENU_SCENE.

test/gut/test_sfx_rotor_volume_control.gd (1)

11-11: LGTM — mirrors the weapon-volume test changes.

GamePaths.AUDIO_SETTINGS_SCENE is used for the scene load and prev_menu is now autofree()-wrapped, matching test_sfx_weapon_volume_control.gd and test_master_volume_control_and_music.gd.

Also applies to: 283-293

test/gut/gut_test_helper.gd (1)

7-7: No action needed. GamePaths.PLAYER is a valid class_name constant that resolves correctly. Six test files successfully load gut_test_helper.gd via preload() and execute without parse errors, confirming that constant initialization works properly in this setup.

test/gut/test_reset_scenarios.gd (1)

40-44: Guarded reset looks correct.

Toggling _is_loading_settings around the Globals.settings mutations matches the pattern in scripts/core/globals.gd::_load_settings and correctly suppresses the auto-save/log side effects in _on_setting_changed during the per-test reset.

test/gut/test_game_settings_resource.gd (1)

13-13: Code verified — no issues found.

GamePaths is correctly declared as a class_name with a const GAMEPLAY_SETTINGS member (not an autoload), making it a compile-time constant suitable for preload().

Comment thread test/gut/test_preserve_other_sections.gd
@ikostan
Copy link
Copy Markdown
Owner Author

ikostan commented Apr 23, 2026

  • In Development_Guide.md, the use of <del> tags inside the markdown table (and disabling MD033) makes the table harder to read and may not render consistently; consider moving deprecated entries to a separate section or marking them as deprecated in plain text instead of using inline HTML strikethroughs.

Won't fix

@ikostan
Copy link
Copy Markdown
Owner Author

ikostan commented Apr 23, 2026

  • GamePaths is a good centralization point, but it currently only covers a subset of scripts/scenes; if the intent is to eliminate fragile string paths, consider incrementally adding remaining frequently used paths (e.g., resources like game_settings_resource.gd) and updating callers to use the constants for consistency.

@ikostan ikostan closed this Apr 23, 2026
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Sky Lock Assault Project Apr 23, 2026
@ikostan ikostan reopened this Apr 23, 2026
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@ikostan
Copy link
Copy Markdown
Owner Author

ikostan commented Apr 23, 2026

  • GamePaths is a good centralization point, but it currently only covers a subset of scripts/scenes; if the intent is to eliminate fragile string paths, consider incrementally adding remaining frequently used paths (e.g., resources like game_settings_resource.gd) and updating callers to use the constants for consistency.

A new task is created: [FEATURE] [Tech Debt] Complete GamePaths centralization across the codebase #584

ikostan added 3 commits April 23, 2026 11:42
….md so that the documentation accurately reflects this relationship

Observer-pattern steps contradict the deleted table rows.

Two issues in this block:

Line 90 still points to scripts/game_settings_resource.gd, but the resource was relocated to res://scripts/resources/game_settings_resource.gd (as correctly reflected in the updated table on line 124).

Step 2 instructs updating _save_settings() / _load_settings() in globals.gd, yet the Logic Observer row for globals.gd was struck out in the table on line 125 (suggesting those responsibilities moved). Either the table deletion or this instruction is wrong — please reconcile.
…ios.gd.

Because of the Observer Pattern implemented in the architecture refactor, assigning values directly to Globals.settings.current_log_level and Globals.settings.difficulty during test setup in before_each() will immediately trigger _on_setting_changed(). This causes an unwanted _save_settings() disk I/O operation before the test even begins.
@ikostan ikostan merged commit 7eb7e8c into main Apr 23, 2026
14 checks passed
@ikostan ikostan deleted the migrate-resources-entities-and-system-scripts branch April 23, 2026 18:54
@ikostan ikostan changed the title Refactor Phase 4: Migrate Resources, Entities, and System scripts Refactor Phase 4: Migrate Resources, Path Centralization, Test Suite Stabilization, and Docs Alignment Apr 23, 2026
ikostan added a commit that referenced this pull request Apr 23, 2026
Having reviewed the details of Release v0.9.18 and PR #582, there are definitely a few key areas in your README.md that need to be updated to stay aligned with the current state of the project.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment