Compare commits

...

2 Commits

Author SHA1 Message Date
dec5d652b4 include info about asset sources file 2025-09-24 11:19:00 +04:00
994ce07a80 add logging 2025-09-24 11:04:16 +04:00
16 changed files with 1044 additions and 54 deletions

424
assets/sources.yaml Normal file
View File

@@ -0,0 +1,424 @@
# Asset Attribution and Source Information
# Every asset in this project must be documented here with complete metadata
# Required fields: source, license, attribution, modifications, usage
audio:
music:
"Space Horror InGame Music (Exploration) _Clement Panchout.wav":
source: "https://clement-panchout.itch.io/yet-another-free-music-pack"
license: "" # TODO: Verify license from source
attribution: "Space Horror InGame Music by Clement Panchout"
modifications: "Converted to WAV format, loop configuration applied in AudioManager"
usage: "Background music for all gameplay scenes and menus"
sfx:
"817587__silverdubloons__tick06.wav":
source: "https://freesound.org/people/SilverDubloons/sounds/817587/"
license: "" # TODO: Verify license from freesound.org
attribution: "Tick06 by SilverDubloons"
modifications: "None"
usage: "UI button click sound effects throughout the application"
sprites:
characters:
skeleton:
"Skeleton Attack.png":
source: "https://jesse-m.itch.io/skeleton-pack"
license: "" # TODO: Verify license from itch.io page
attribution: "Skeleton Pack by Jesse M"
modifications: ""
usage: "Skeleton character attack animation sprite"
"Skeleton Dead.png":
source: "https://jesse-m.itch.io/skeleton-pack"
license: "" # TODO: Verify license from itch.io page
attribution: "Skeleton Pack by Jesse M"
modifications: ""
usage: "Skeleton character death animation sprite"
"Skeleton Hit.png":
source: "https://jesse-m.itch.io/skeleton-pack"
license: "" # TODO: Verify license from itch.io page
attribution: "Skeleton Pack by Jesse M"
modifications: ""
usage: "Skeleton character hit reaction animation sprite"
"Skeleton Idle.png":
source: "https://jesse-m.itch.io/skeleton-pack"
license: "" # TODO: Verify license from itch.io page
attribution: "Skeleton Pack by Jesse M"
modifications: ""
usage: "Skeleton character idle animation sprite"
"Skeleton React.png":
source: "https://jesse-m.itch.io/skeleton-pack"
license: "" # TODO: Verify license from itch.io page
attribution: "Skeleton Pack by Jesse M"
modifications: ""
usage: "Skeleton character reaction animation sprite"
"Skeleton Walk.png":
source: "https://jesse-m.itch.io/skeleton-pack"
license: "" # TODO: Verify license from itch.io page
attribution: "Skeleton Pack by Jesse M"
modifications: ""
usage: "Skeleton character walking animation sprite"
gems:
# Blue gems
"bg_08.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Blue gem sprite for Match-3 gameplay"
"bg_16a.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Blue gem variant sprite for Match-3 gameplay"
"bg_19.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Blue gem variant sprite for Match-3 gameplay"
"bg_26.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Blue gem variant sprite for Match-3 gameplay"
"bg_27.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Blue gem variant sprite for Match-3 gameplay"
"bg_28.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Blue gem variant sprite for Match-3 gameplay"
# Dark/Gray gems
"dg_08.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Dark gem sprite for Match-3 gameplay"
"dg_16a.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Dark gem variant sprite for Match-3 gameplay"
"dg_19.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Dark gem variant sprite for Match-3 gameplay"
"dg_26.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Dark gem variant sprite for Match-3 gameplay"
"dg_27.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Dark gem variant sprite for Match-3 gameplay"
"dg_28.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Dark gem variant sprite for Match-3 gameplay"
# Green gems
"gg_08.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Green gem sprite for Match-3 gameplay"
"gg_16a.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Green gem variant sprite for Match-3 gameplay"
"gg_19.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Green gem variant sprite for Match-3 gameplay"
"gg_26.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Green gem variant sprite for Match-3 gameplay"
"gg_27.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Green gem variant sprite for Match-3 gameplay"
"gg_28.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Green gem variant sprite for Match-3 gameplay"
# Magenta gems
"mg_08.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Magenta gem sprite for Match-3 gameplay"
"mg_16a.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Magenta gem variant sprite for Match-3 gameplay"
"mg_19.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Magenta gem variant sprite for Match-3 gameplay"
"mg_26.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Magenta gem variant sprite for Match-3 gameplay"
"mg_27.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Magenta gem variant sprite for Match-3 gameplay"
"mg_28.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Magenta gem variant sprite for Match-3 gameplay"
# Purple gems
"pg_08.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Purple gem sprite for Match-3 gameplay"
"pg_16a.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Purple gem variant sprite for Match-3 gameplay"
"pg_19.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Purple gem variant sprite for Match-3 gameplay"
"pg_26.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Purple gem variant sprite for Match-3 gameplay"
"pg_27.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Purple gem variant sprite for Match-3 gameplay"
"pg_28.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Purple gem variant sprite for Match-3 gameplay"
# Red gems
"rg_08.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Red gem sprite for Match-3 gameplay"
"rg_16a.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Red gem variant sprite for Match-3 gameplay"
"rg_19.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Red gem variant sprite for Match-3 gameplay"
"rg_26.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Red gem variant sprite for Match-3 gameplay"
"rg_27.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Red gem variant sprite for Match-3 gameplay"
"rg_28.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Red gem variant sprite for Match-3 gameplay"
# Silver gems
"sg_08.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Silver gem sprite for Match-3 gameplay"
"sg_16a.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Silver gem variant sprite for Match-3 gameplay"
"sg_19.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Silver gem variant sprite for Match-3 gameplay"
"sg_26.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Silver gem variant sprite for Match-3 gameplay"
"sg_27.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Silver gem variant sprite for Match-3 gameplay"
"sg_28.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Silver gem variant sprite for Match-3 gameplay"
# Yellow gems
"yg_08.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Yellow gem sprite for Match-3 gameplay"
"yg_16a.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Yellow gem variant sprite for Match-3 gameplay"
"yg_19.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Yellow gem variant sprite for Match-3 gameplay"
"yg_26.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Yellow gem variant sprite for Match-3 gameplay"
"yg_27.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Yellow gem variant sprite for Match-3 gameplay"
"yg_28.png":
source: "https://ilustragm.itch.io/gems-icon-01-free"
license: "" # TODO: Verify license from itch.io page
attribution: "Gems Icon 01 Free by IlustraGM"
modifications: ""
usage: "Yellow gem variant sprite for Match-3 gameplay"
# Referenced in original sources.yaml but file not found:
# textures:
# backgrounds:
# "beanstalk-dark.webp":
# source: "https://www.toptal.com/designers/subtlepatterns/beanstalk-dark-pattern/"
# license: "" # TODO: Verify license and locate file
# attribution: "Beanstalk Dark pattern from Subtle Patterns"
# modifications: ""
# usage: "Background texture (file location TBD)"
# TODO: Verify all license information by visiting source URLs
# TODO: Check for any missing assets not documented here
# TODO: Confirm all attribution text meets source requirements

View File

@@ -1,11 +0,0 @@
---
- fileName: assets/audio/music/Space Horror InGame Music (Exploration) _Clement Panchout.wav
commonUrl: https://clement-panchout.itch.io/yet-another-free-music-pack
- fileName: assets/audio/sfx/817587__silverdubloons__tick06.wav
commonUrl: https://freesound.org/people/SilverDubloons/sounds/817587/
- fileName: assets/textures/backgrounds/beanstalk-dark.webp
commonUrl: https://www.toptal.com/designers/subtlepatterns/beanstalk-dark-pattern/
- fileName: assets/sprites/characters/skeleton
commonUrl: https://jesse-m.itch.io/skeleton-pack
- fileName: assets/sprites/gems
commonUrl: https://ilustragm.itch.io/gems-icon-01-free

View File

@@ -21,6 +21,8 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
- Match-3 debug controls include gem count adjustment and board reroll - Match-3 debug controls include gem count adjustment and board reroll
- Difficulty presets: Easy (3 gems), Normal (5 gems), Hard (8 gems) - Difficulty presets: Easy (3 gems), Normal (5 gems), Hard (8 gems)
- Gameplay mode switching: Space+Enter in game scene switches between match-3 and clickomania modes - Gameplay mode switching: Space+Enter in game scene switches between match-3 and clickomania modes
- Test scripts located in `tests/` directory for system validation
- Use `test_logging.gd` to validate the logging system functionality
### Audio Configuration ### Audio Configuration
- Music: Located in `assets/audio/music/` directory with loop configuration in AudioManager - Music: Located in `assets/audio/music/` directory with loop configuration in AudioManager
@@ -32,6 +34,12 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
- Currently supports English and Russian - Currently supports English and Russian
- New translations: Add to `project.godot` internationalization section - New translations: Add to `project.godot` internationalization section
### Asset Management
- **CRITICAL**: Every asset must be documented in `assets/sources.yaml` before committing
- Include source, license, attribution, modifications, and usage information
- Verify license compatibility with project requirements
- Commit asset files and sources.yaml together in the same commit
## Key Development Guidelines ## Key Development Guidelines
### Scene Management ### Scene Management
@@ -51,11 +59,19 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
- Use F12 key for global debug toggle - Use F12 key for global debug toggle
- Remove debug prints before committing unless permanently useful - Remove debug prints before committing unless permanently useful
### Logging System Usage
- **ALWAYS** use `DebugManager` logging functions instead of `print()`, `push_error()`, etc.
- Use appropriate log levels: INFO for general messages, WARN for issues, ERROR for failures
- Include meaningful categories to organize log output: `"GameManager"`, `"Match3"`, `"Settings"`
- Leverage structured logging for better debugging and production monitoring
- Use `DebugManager.set_log_level()` to control verbosity during development and testing
## Important File References ## Important File References
### Documentation Structure ### Documentation Structure
- **`docs/MAP.md`** - Complete project architecture and structure - **`docs/MAP.md`** - Complete project architecture and structure
- **`docs/CODE_OF_CONDUCT.md`** - Coding standards and best practices - **`docs/CODE_OF_CONDUCT.md`** - Coding standards and best practices
- **`docs/TESTING.md`** - Testing guidelines and conventions
- **This file** - Claude Code specific development guidelines - **This file** - Claude Code specific development guidelines
### Key Scripts to Understand ### Key Scripts to Understand
@@ -72,18 +88,53 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
1. Check `docs/MAP.md` for architecture understanding 1. Check `docs/MAP.md` for architecture understanding
2. Review `docs/CODE_OF_CONDUCT.md` for coding standards 2. Review `docs/CODE_OF_CONDUCT.md` for coding standards
3. Understand existing patterns before implementing new features 3. Understand existing patterns before implementing new features
4. If adding assets, prepare `assets/sources.yaml` documentation
### Testing Changes ### Testing Changes
- Run project with F5 in Godot Editor - Run project with F5 in Godot Editor
- Test debug UI with F12 toggle - Test debug UI with F12 toggle
- Verify scene transitions work correctly - Verify scene transitions work correctly
- Check mobile compatibility if UI changes made - Check mobile compatibility if UI changes made
- Use relevant test scripts from `tests/` directory to validate system functionality
- Run `test_logging.gd` after making changes to the logging system
### Common Implementation Patterns ### Common Implementation Patterns
- Scene transitions: Use `GameManager.start_game_with_mode()` and related methods - Scene transitions: Use `GameManager.start_game_with_mode()` and related methods
- Debug integration: Connect to `DebugManager` signals and initialize debug state - Debug integration: Connect to `DebugManager` signals and initialize debug state
- Logging: Use `DebugManager.log_*()` functions with appropriate levels and categories
- Gameplay modes: Implement in `scenes/game/gameplays/` directory following modular pattern - Gameplay modes: Implement in `scenes/game/gameplays/` directory following modular pattern
- Scoring system: Connect `score_changed` signal from gameplay to main game scene - Scoring system: Connect `score_changed` signal from gameplay to main game scene
- Settings: Use `SettingsManager` for persistent configuration - Settings: Use `SettingsManager` for persistent configuration
- Audio: Use `AudioManager` for music and sound effects - Audio: Use `AudioManager` for music and sound effects
- Localization: Use `LocalizationManager` for language switching - Localization: Use `LocalizationManager` for language switching
### Logging Best Practices
```gdscript
# ✅ Good logging practices
DebugManager.log_info("Scene transition completed", "GameManager")
DebugManager.log_warn("Settings file not found, using defaults", "Settings")
DebugManager.log_error("Failed to load audio resource: " + audio_path, "AudioManager")
# ❌ Avoid these patterns
print("debug") # Use structured logging instead
push_error("error") # Use DebugManager.log_error() with category
```
### Asset Management Workflow
```yaml
# ✅ Required assets/sources.yaml entry format
audio:
music:
"background_music.ogg":
source: "https://freesound.org/people/artist/sounds/123456/"
license: "CC BY 4.0"
attribution: "Background Music by Artist Name"
modifications: "Converted to OGG, adjusted volume"
usage: "Main menu and gameplay background music"
# ✅ Proper commit workflow
# 1. Add asset to appropriate assets/ subdirectory
# 2. Update assets/sources.yaml with complete metadata
# 3. git add both files together
# 4. Commit with descriptive message including attribution
```

View File

@@ -123,8 +123,8 @@ func some_deep_function():
### Debug System Integration ### Debug System Integration
- Always connect to DebugManager signals for debug UI - Always connect to DebugManager signals for debug UI
- Use debug prints with clear prefixes - Use structured logging instead of plain print statements
- Remove debug prints before committing (unless permanently useful) - Remove temporary debug logs before committing (unless permanently useful)
```gdscript ```gdscript
# ✅ Correct debug integration # ✅ Correct debug integration
@@ -132,27 +132,71 @@ func _connect_to_global_debug() -> void:
DebugManager.debug_ui_toggled.connect(_on_debug_ui_toggled) DebugManager.debug_ui_toggled.connect(_on_debug_ui_toggled)
debug_ui.visible = DebugManager.is_debug_ui_visible() debug_ui.visible = DebugManager.is_debug_ui_visible()
# ✅ Good debug prints # ✅ Good structured logging
print("Match3: Debug UI toggled to: ", visible) DebugManager.log_debug("Debug UI toggled to: " + str(visible), "Match3")
print("TileSystem: Initialized ", tiles.size(), " tiles") DebugManager.log_info("Initialized " + str(tiles.size()) + " tiles", "TileSystem")
# ❌ Bad debug prints # ❌ Bad logging practices
print("test") # Not descriptive print("test") # Not descriptive, use structured logging
print(some_variable) # No context print(some_variable) # No context, use proper log level
```
### Logging Standards
- **ALWAYS** use `DebugManager.log_*()` functions instead of `print()` or `push_error()`
- Choose appropriate log levels based on message importance and audience
- Include meaningful categories to organize log output by system/component
- Format messages with clear, descriptive text and relevant context
```gdscript
# ✅ Correct logging usage
DebugManager.log_info("Game scene loaded successfully", "SceneManager")
DebugManager.log_warn("Audio file not found, using default", "AudioManager")
DebugManager.log_error("Failed to save settings: " + error_message, "Settings")
# ❌ Wrong approaches
print("loaded") # Use DebugManager.log_info() with category
push_error("error") # Use DebugManager.log_error() with context
if debug_mode: print("debug info") # Use DebugManager.log_debug()
```
### Asset Management
- **MANDATORY**: Every asset added to the project must be documented in `assets/sources.yaml`
- Include complete source information, license details, and attribution requirements
- Document any modifications made to original assets
- Verify license compatibility with project usage before adding assets
- Update sources.yaml in the same commit as adding the asset
```gdscript
# ✅ Correct asset addition workflow
# 1. Add asset file to appropriate assets/ subdirectory
# 2. Update assets/sources.yaml with complete metadata
# 3. Commit both files together with descriptive message
# Example sources.yaml entry:
# audio:
# sfx:
# "button_click.wav":
# source: "https://freesound.org/people/user/sounds/12345/"
# license: "CC BY 3.0"
# attribution: "Button Click by SoundArtist"
# modifications: "Normalized volume, trimmed silence"
# usage: "UI button interactions"
``` ```
### Error Handling ### Error Handling
- Always check if resources loaded successfully - Always check if resources loaded successfully
- Use `push_error()` for critical failures - Use `DebugManager.log_error()` for critical failures
- Provide fallback behavior when possible - Provide fallback behavior when possible
- Include meaningful context in error messages
```gdscript ```gdscript
# ✅ Correct error handling # ✅ Correct error handling with structured logging
func load_scene(path: String) -> void: func load_scene(path: String) -> void:
var packed_scene := load(path) var packed_scene := load(path)
if not packed_scene or not packed_scene is PackedScene: if not packed_scene or not packed_scene is PackedScene:
push_error("Failed to load scene at: %s" % path) DebugManager.log_error("Failed to load scene at: %s" % path, "SceneLoader")
return return
DebugManager.log_info("Successfully loaded scene: %s" % path, "SceneLoader")
get_tree().change_scene_to_packed(packed_scene) get_tree().change_scene_to_packed(packed_scene)
``` ```
@@ -237,6 +281,26 @@ node.do_something() # Could crash if node doesn't exist
# Use autoloads instead # Use autoloads instead
``` ```
### Asset Management Violations
```gdscript
# ❌ Don't add assets without documentation
# Adding audio/new_music.mp3 without updating sources.yaml
# ❌ Don't use assets without verifying licenses
# Using copyrighted music without permission
# ❌ Don't modify assets without documenting changes
# Editing sprites without noting modifications in sources.yaml
# ❌ Don't commit assets and documentation separately
git add assets/sprites/new_sprite.png
git commit -m "add sprite" # Missing sources.yaml update
# ✅ Correct approach
git add assets/sprites/new_sprite.png assets/sources.yaml
git commit -m "add new sprite with attribution"
```
### Performance Issues ### Performance Issues
```gdscript ```gdscript
# ❌ Don't search nodes repeatedly # ❌ Don't search nodes repeatedly
@@ -253,10 +317,12 @@ func _process(delta):
```gdscript ```gdscript
# ❌ Don't create separate debug systems # ❌ Don't create separate debug systems
var my_debug_enabled = false var my_debug_enabled = false
print("debug: " + some_info) # Don't use plain print()
# ✅ Use the global debug system # ✅ Use the global debug and logging systems
if DebugManager.is_debug_enabled(): if DebugManager.is_debug_enabled():
show_debug_info() show_debug_info()
DebugManager.log_debug("Debug information: " + some_info, "MyComponent")
``` ```
## Learning Resources ## Learning Resources

View File

@@ -15,8 +15,9 @@ skelly/
├── localization/ # Internationalization files ├── localization/ # Internationalization files
├── scenes/ # Godot scenes (.tscn) and scripts (.gd) ├── scenes/ # Godot scenes (.tscn) and scripts (.gd)
├── src/ # Source code organization ├── src/ # Source code organization
├── project.godot # Main Godot project configuration ├── tests/ # Test scripts and validation utilities
── icon.svg # Project icon ── project.godot # Main Godot project configuration
└── icon.svg # Project icon
``` ```
## Core Architecture ## Core Architecture
@@ -48,10 +49,13 @@ Located in `src/autoloads/`, these scripts are automatically loaded when the gam
- Uses translation files in `localization/` - Uses translation files in `localization/`
5. **DebugManager** (`src/autoloads/DebugManager.gd`) 5. **DebugManager** (`src/autoloads/DebugManager.gd`)
- Global debug state management - Global debug state management and centralized logging system
- Debug UI visibility control - Debug UI visibility control
- F12 toggle functionality - F12 toggle functionality
- Signal-based debug system - Signal-based debug system
- Structured logging with configurable log levels (TRACE, DEBUG, INFO, WARN, ERROR, FATAL)
- Timestamp-based log formatting with category support
- Runtime log level filtering for development and production builds
## Scene Hierarchy & Flow ## Scene Hierarchy & Flow
@@ -161,13 +165,46 @@ audio/
### Visual Assets (`assets/`) ### Visual Assets (`assets/`)
``` ```
assets/ assets/
├── audio/
│ ├── music/ # Background music files
│ └── sfx/ # Sound effects
├── sprites/ ├── sprites/
│ ├── characters/skeleton/ # Character artwork │ ├── characters/skeleton/ # Character artwork
│ ├── gems/ # Match-3 gem sprites │ ├── gems/ # Match-3 gem sprites
│ └── ui/ # User interface elements │ └── ui/ # User interface elements
├── textures/ ├── textures/
│ └── backgrounds/ # Background images │ └── backgrounds/ # Background images
── fonts/ # Custom fonts ── fonts/ # Custom fonts
└── sources.yaml # Asset metadata and attribution
```
### Asset Management (`assets/sources.yaml`)
**REQUIRED**: Every asset added to the project must be documented in `assets/sources.yaml` with:
- **Source information** - Where the asset came from (URL, artist, store, etc.)
- **License details** - Usage rights, attribution requirements, commercial permissions
- **Attribution text** - Exact text to use for credits if required
- **Modification notes** - Any changes made to the original asset
- **Usage context** - Where and how the asset is used in the project
**Example format:**
```yaml
audio:
music:
"Space Horror InGame Music (Exploration) _Clement Panchout.wav":
source: "https://freesound.org/people/ClementPanchout/"
license: "CC BY 4.0"
attribution: "Space Horror InGame Music by Clement Panchout"
modifications: "Converted to WAV, loop points adjusted"
usage: "Background music for all gameplay scenes"
sprites:
gems:
"gem_blue.png":
source: "Created in-house"
license: "Project proprietary"
attribution: "Skelly development team"
modifications: "None"
usage: "Match-3 blue gem sprite"
``` ```
## Data & Configuration ## Data & Configuration
@@ -175,11 +212,23 @@ assets/
### Game Data (`data/`) ### Game Data (`data/`)
- `default_bus_layout.tres` - Audio bus configuration for Godot - `default_bus_layout.tres` - Audio bus configuration for Godot
### Documentation (`docs/`)
- `MAP.md` - Project architecture and structure overview
- `CLAUDE.md` - Claude Code development guidelines
- `CODE_OF_CONDUCT.md` - Coding standards and best practices
- `TESTING.md` - Testing guidelines and conventions
### Localization (`localization/`) ### Localization (`localization/`)
- `languages.json` - Available language definitions - `languages.json` - Available language definitions
- `MainStrings.en.translation` - English translations - `MainStrings.en.translation` - English translations
- `MainStrings.ru.translation` - Russian translations - `MainStrings.ru.translation` - Russian translations
### Testing & Validation (`tests/`)
- `test_logging.gd` - DebugManager logging system validation
- `README.md` - Brief directory overview (see docs/TESTING.md for full guidelines)
- Future test scripts for individual components and integration testing
- Temporary test utilities for development and debugging
### Project Configuration ### Project Configuration
- `project.godot` - Main Godot project settings - `project.godot` - Main Godot project settings
- Autoload definitions - Autoload definitions
@@ -213,8 +262,61 @@ Game --> scenes/game/gameplays/match3_gameplay.tscn, clickomania_gameplay.tscn
AudioManager --> assets/audio/music/ AudioManager --> assets/audio/music/
SettingsManager --> localization/languages.json SettingsManager --> localization/languages.json
AudioManager --> data/default_bus_layout.tres AudioManager --> data/default_bus_layout.tres
Asset Management --> assets/sources.yaml (required for all assets)
``` ```
## Logging System
The project uses a centralized logging system implemented in DebugManager for consistent, structured logging throughout the application.
### Log Levels
```
TRACE (0) - Detailed execution tracing (debug mode only)
DEBUG (1) - Development debugging information (debug mode only)
INFO (2) - General application information (always visible)
WARN (3) - Warning messages that don't break functionality
ERROR (4) - Error conditions that may affect functionality
FATAL (5) - Critical errors that may cause application failure
```
### Usage Examples
```gdscript
# Basic logging with automatic categorization
DebugManager.log_info("Game started successfully")
DebugManager.log_warn("Settings file not found, using defaults")
DebugManager.log_error("Failed to load audio resource")
# Logging with custom categories for better organization
DebugManager.log_debug("Grid regenerated with 64 tiles", "Match3")
DebugManager.log_info("Language changed to: en", "SettingsManager")
DebugManager.log_error("Invalid scene path provided", "GameManager")
```
### Log Format
```
[timestamp] LEVEL [category]: message
Example: [2025-09-24T10:48:08] INFO [GameManager]: Loading main scene
```
### Runtime Configuration
```gdscript
# Set minimum log level (filters out lower priority messages)
DebugManager.set_log_level(DebugManager.LogLevel.WARN)
# Get current log level
var current_level = DebugManager.get_log_level()
# Check if a specific level would be logged
if DebugManager._should_log(DebugManager.LogLevel.DEBUG):
# Expensive debug calculation here
```
### Integration with Godot Systems
- **WARN/ERROR/FATAL** levels automatically call `push_warning()` and `push_error()`
- **TRACE/DEBUG** levels only display when debug mode is enabled
- **INFO** and higher levels always display regardless of debug mode
- All levels respect the configured minimum log level threshold
## Development Notes ## Development Notes
### Current Implementation Status ### Current Implementation Status
@@ -233,5 +335,6 @@ AudioManager --> data/default_bus_layout.tres
5. **Data-Driven Configuration** - JSON for settings and translations 5. **Data-Driven Configuration** - JSON for settings and translations
6. **Component Architecture** - Reusable UI and game components 6. **Component Architecture** - Reusable UI and game components
7. **Centralized Scoring System** - Global score management across gameplay modes 7. **Centralized Scoring System** - Global score management across gameplay modes
8. **Structured Logging System** - Centralized logging with level-based filtering and formatted output
This structure provides a clean separation of concerns, making the codebase maintainable and extensible for future features. This structure provides a clean separation of concerns, making the codebase maintainable and extensible for future features.

156
docs/TESTING.md Normal file
View File

@@ -0,0 +1,156 @@
# Tests Directory
This directory contains test scripts and utilities for validating various systems and components in the Skelly project.
## Overview
The `tests/` directory is designed to house:
- System validation scripts
- Component testing utilities
- Integration tests
- Performance benchmarks
- Debugging tools
## Current Test Files
### `test_logging.gd`
Comprehensive test script for the DebugManager logging system.
**Features:**
- Tests all log levels (TRACE, DEBUG, INFO, WARN, ERROR, FATAL)
- Validates log level filtering functionality
- Tests category-based logging organization
- Verifies debug mode integration
- Demonstrates proper logging usage patterns
**Usage:**
```gdscript
# Option 1: Add as temporary autoload
# In project.godot, add: tests/test_logging.gd
# Option 2: Instantiate in a scene
var test_script = preload("res://tests/test_logging.gd").new()
add_child(test_script)
# Option 3: Run directly from editor
# Open the script and run the scene containing it
```
**Expected Output:**
The script will output formatted log messages demonstrating:
- Proper timestamp formatting
- Log level filtering behavior
- Category organization
- Debug mode dependency for TRACE/DEBUG levels
## Adding New Tests
When creating new test files, follow these conventions:
### File Naming
- Use descriptive names starting with `test_`
- Example: `test_audio_manager.gd`, `test_scene_transitions.gd`
### File Structure
```gdscript
extends Node
# Brief description of what this test validates
func _ready():
# Wait for system initialization if needed
await get_tree().process_frame
run_tests()
func run_tests():
print("=== Starting [System Name] Tests ===")
# Individual test functions
test_basic_functionality()
test_edge_cases()
test_error_conditions()
print("=== [System Name] Tests Complete ===")
func test_basic_functionality():
print("\\n--- Test: Basic Functionality ---")
# Test implementation
func test_edge_cases():
print("\\n--- Test: Edge Cases ---")
# Edge case testing
func test_error_conditions():
print("\\n--- Test: Error Conditions ---")
# Error condition testing
```
### Testing Guidelines
1. **Independence**: Each test should be self-contained and not depend on other tests
2. **Cleanup**: Restore original state after testing (settings, debug modes, etc.)
3. **Clear Output**: Use descriptive print statements to show test progress
4. **Error Handling**: Test both success and failure conditions
5. **Documentation**: Include comments explaining complex test scenarios
### Integration with Main Project
- **Temporary Usage**: Test files are meant to be added temporarily during development
- **Not in Production**: These files should not be included in release builds
- **Autoload Testing**: Add to autoloads temporarily for automatic execution
- **Manual Testing**: Run individually when testing specific components
## Test Categories
### System Tests
Test core autoload managers and global systems:
- `test_logging.gd` - DebugManager logging system
- Future: `test_settings.gd` - SettingsManager functionality
- Future: `test_audio.gd` - AudioManager functionality
- Future: `test_scene_management.gd` - GameManager transitions
### Component Tests
Test individual game components:
- Future: `test_match3.gd` - Match-3 gameplay mechanics
- Future: `test_tile_system.gd` - Tile behavior and interactions
- Future: `test_ui_components.gd` - Menu and UI functionality
### Integration Tests
Test system interactions and workflows:
- Future: `test_game_flow.gd` - Complete game session flow
- Future: `test_debug_system.gd` - Debug UI integration
- Future: `test_localization.gd` - Language switching and translations
## Running Tests
### During Development
1. Copy or symlink the test file to your scene
2. Add as a child node or autoload temporarily
3. Run the project and observe console output
4. Remove from project when testing is complete
### Automated Testing
While Godot doesn't have built-in unit testing, these scripts provide:
- Consistent validation approach
- Repeatable test scenarios
- Clear pass/fail output
- System behavior documentation
## Best Practices
1. **Document Expected Behavior**: Include comments about what should happen
2. **Test Boundary Conditions**: Include edge cases and error conditions
3. **Measure Performance**: Add timing for performance-critical components
4. **Visual Validation**: For UI components, include visual checks
5. **Cleanup After Tests**: Restore initial state to avoid side effects
## Contributing
When adding new test files:
1. Follow the naming and structure conventions
2. Update this README with new test descriptions
3. Ensure tests are self-contained and documented
4. Test both success and failure scenarios
5. Include performance considerations where relevant
This testing approach helps maintain code quality and provides validation tools for system changes and refactoring.

View File

@@ -19,7 +19,7 @@ func _ready():
var orig_stream = _load_stream() var orig_stream = _load_stream()
if not orig_stream: if not orig_stream:
push_error("Failed to load music stream: %s" % MUSIC_PATH) DebugManager.log_error("Failed to load music stream: %s" % MUSIC_PATH, "AudioManager")
return return
var stream = orig_stream.duplicate(true) as AudioStream var stream = orig_stream.duplicate(true) as AudioStream

View File

@@ -2,16 +2,26 @@ extends Node
signal debug_toggled(enabled: bool) signal debug_toggled(enabled: bool)
enum LogLevel {
TRACE = 0,
DEBUG = 1,
INFO = 2,
WARN = 3,
ERROR = 4,
FATAL = 5
}
var debug_enabled: bool = false var debug_enabled: bool = false
var debug_overlay_visible: bool = false var debug_overlay_visible: bool = false
var current_log_level: LogLevel = LogLevel.INFO
func _ready(): func _ready():
print("DebugManager loaded") log_info("DebugManager loaded")
func toggle_debug(): func toggle_debug():
debug_enabled = !debug_enabled debug_enabled = !debug_enabled
debug_toggled.emit(debug_enabled) debug_toggled.emit(debug_enabled)
print("Debug mode: ", "ON" if debug_enabled else "OFF") log_info("Debug mode: " + ("ON" if debug_enabled else "OFF"))
func set_debug_enabled(enabled: bool): func set_debug_enabled(enabled: bool):
if debug_enabled != enabled: if debug_enabled != enabled:
@@ -30,6 +40,70 @@ func set_overlay_visible(visible: bool):
func is_overlay_visible() -> bool: func is_overlay_visible() -> bool:
return debug_overlay_visible return debug_overlay_visible
func log_debug(message: String, category: String = "DEBUG"): func set_log_level(level: LogLevel):
if debug_enabled: current_log_level = level
print("[", category, "] ", message) log_info("Log level set to: " + _log_level_to_string(level))
func get_log_level() -> LogLevel:
return current_log_level
func _should_log(level: LogLevel) -> bool:
return level >= current_log_level
func _log_level_to_string(level: LogLevel) -> String:
match level:
LogLevel.TRACE:
return "TRACE"
LogLevel.DEBUG:
return "DEBUG"
LogLevel.INFO:
return "INFO"
LogLevel.WARN:
return "WARN"
LogLevel.ERROR:
return "ERROR"
LogLevel.FATAL:
return "FATAL"
_:
return "UNKNOWN"
func _format_log_message(level: LogLevel, message: String, category: String = "") -> String:
var timestamp = Time.get_datetime_string_from_system()
var level_str = _log_level_to_string(level)
var category_str = (" [" + category + "]") if category != "" else ""
return "[%s] %s%s: %s" % [timestamp, level_str, category_str, message]
func log_trace(message: String, category: String = ""):
if _should_log(LogLevel.TRACE):
var formatted = _format_log_message(LogLevel.TRACE, message, category)
if debug_enabled:
print(formatted)
func log_debug(message: String, category: String = ""):
if _should_log(LogLevel.DEBUG):
var formatted = _format_log_message(LogLevel.DEBUG, message, category)
if debug_enabled:
print(formatted)
func log_info(message: String, category: String = ""):
if _should_log(LogLevel.INFO):
var formatted = _format_log_message(LogLevel.INFO, message, category)
print(formatted)
func log_warn(message: String, category: String = ""):
if _should_log(LogLevel.WARN):
var formatted = _format_log_message(LogLevel.WARN, message, category)
print(formatted)
push_warning(formatted)
func log_error(message: String, category: String = ""):
if _should_log(LogLevel.ERROR):
var formatted = _format_log_message(LogLevel.ERROR, message, category)
print(formatted)
push_error(formatted)
func log_fatal(message: String, category: String = ""):
if _should_log(LogLevel.FATAL):
var formatted = _format_log_message(LogLevel.FATAL, message, category)
print(formatted)
push_error(formatted)

View File

@@ -18,7 +18,7 @@ func start_game_with_mode(gameplay_mode: String) -> void:
pending_gameplay_mode = gameplay_mode pending_gameplay_mode = gameplay_mode
var packed_scene := load(GAME_SCENE_PATH) var packed_scene := load(GAME_SCENE_PATH)
if not packed_scene or not packed_scene is PackedScene: if not packed_scene or not packed_scene is PackedScene:
push_error("Failed to load Game scene at: %s" % GAME_SCENE_PATH) DebugManager.log_error("Failed to load Game scene at: %s" % GAME_SCENE_PATH, "GameManager")
return return
get_tree().change_scene_to_packed(packed_scene) get_tree().change_scene_to_packed(packed_scene)
# Wait one frame for the scene to be ready, then set gameplay mode # Wait one frame for the scene to be ready, then set gameplay mode
@@ -27,14 +27,13 @@ func start_game_with_mode(gameplay_mode: String) -> void:
get_tree().current_scene.set_gameplay_mode(pending_gameplay_mode) get_tree().current_scene.set_gameplay_mode(pending_gameplay_mode)
func save_game() -> void: func save_game() -> void:
print("Game saved (mock)") DebugManager.log_info("Game saved (mock)", "GameManager")
func exit_to_main_menu() -> void: func exit_to_main_menu() -> void:
print("GameManager: Attempting to exit to main menu") DebugManager.log_info("Attempting to exit to main menu", "GameManager")
var packed_scene := load(MAIN_SCENE_PATH) var packed_scene := load(MAIN_SCENE_PATH)
if not packed_scene or not packed_scene is PackedScene: if not packed_scene or not packed_scene is PackedScene:
push_error("Failed to load Main scene at: %s" % MAIN_SCENE_PATH) DebugManager.log_error("Failed to load Main scene at: %s" % MAIN_SCENE_PATH, "GameManager")
return return
print("GameManager: Loading main scene") DebugManager.log_info("Loading main scene", "GameManager")
get_tree().change_scene_to_packed(packed_scene) get_tree().change_scene_to_packed(packed_scene)

View File

@@ -18,7 +18,7 @@ var default_settings = {
var languages_data = {} var languages_data = {}
func _ready(): func _ready():
print("SettingsManager ready") DebugManager.log_info("SettingsManager ready", "SettingsManager")
load_languages() load_languages()
load_settings() load_settings()
@@ -27,10 +27,10 @@ func load_settings():
if config.load(SETTINGS_FILE) == OK: if config.load(SETTINGS_FILE) == OK:
for key in default_settings.keys(): for key in default_settings.keys():
settings[key] = config.get_value("settings", key, default_settings[key]) settings[key] = config.get_value("settings", key, default_settings[key])
print("Settings loaded: ", settings) DebugManager.log_info("Settings loaded: " + str(settings), "SettingsManager")
else: else:
print("No settings file found, using defaults") DebugManager.log_warn("No settings file found, using defaults", "SettingsManager")
print("Language is set to: ", settings["language"]) DebugManager.log_info("Language is set to: " + str(settings["language"]), "SettingsManager")
TranslationServer.set_locale(settings["language"]) TranslationServer.set_locale(settings["language"])
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), linear_to_db(settings["master_volume"])) AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), linear_to_db(settings["master_volume"]))
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Music"), linear_to_db(settings["music_volume"])) AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Music"), linear_to_db(settings["music_volume"]))
@@ -42,7 +42,7 @@ func save_settings():
for key in settings.keys(): for key in settings.keys():
config.set_value("settings", key, settings[key]) config.set_value("settings", key, settings[key])
config.save(SETTINGS_FILE) config.save(SETTINGS_FILE)
print("Settings saved: ", settings) DebugManager.log_info("Settings saved: " + str(settings), "SettingsManager")
func get_setting(key: String): func get_setting(key: String):
return settings.get(key) return settings.get(key)
@@ -65,7 +65,7 @@ func _apply_setting_side_effect(key: String, value) -> void:
func load_languages(): func load_languages():
var file = FileAccess.open(LANGUAGES_JSON_PATH, FileAccess.READ) var file = FileAccess.open(LANGUAGES_JSON_PATH, FileAccess.READ)
if not file: if not file:
print("Could not open languages.json") DebugManager.log_error("Could not open languages.json", "SettingsManager")
return return
var json_string = file.get_as_text() var json_string = file.get_as_text()
@@ -73,12 +73,12 @@ func load_languages():
var json = JSON.new() var json = JSON.new()
if json.parse(json_string) != OK: if json.parse(json_string) != OK:
print("Error parsing languages.json") DebugManager.log_error("Error parsing languages.json", "SettingsManager")
return return
languages_data = json.data languages_data = json.data
if languages_data.has("languages"): if languages_data.has("languages"):
print("Languages loaded: ", languages_data.languages.keys()) DebugManager.log_info("Languages loaded: " + str(languages_data.languages.keys()), "SettingsManager")
func get_languages_data(): func get_languages_data():
return languages_data return languages_data

22
tests/README.md Normal file
View File

@@ -0,0 +1,22 @@
# Tests Directory
This directory contains test scripts and validation utilities for the Skelly project.
## Documentation
For complete testing guidelines, conventions, and usage instructions, see:
**[docs/TESTING.md](../docs/TESTING.md)**
## Current Files
- `test_logging.gd` - Comprehensive logging system validation script
## Quick Usage
```gdscript
# Add as temporary autoload or run in scene
var test_script = preload("res://tests/test_logging.gd").new()
add_child(test_script)
```
See [docs/TESTING.md](../docs/TESTING.md) for detailed usage instructions and conventions.

106
tests/test_logging.gd Normal file
View File

@@ -0,0 +1,106 @@
extends Node
# Test script for the DebugManager logging system
# This script validates all log levels, filtering, and formatting functionality
# Usage: Add to scene or autoload temporarily to run tests
func _ready():
# Wait a frame for DebugManager to initialize
await get_tree().process_frame
test_logging_system()
func test_logging_system():
print("=== Starting Logging System Tests ===")
# Test 1: Basic log level functionality
test_basic_logging()
# Test 2: Log level filtering
test_log_level_filtering()
# Test 3: Category functionality
test_category_logging()
# Test 4: Debug mode integration
test_debug_mode_integration()
print("=== Logging System Tests Complete ===")
func test_basic_logging():
print("\n--- Test 1: Basic Log Level Functionality ---")
# Reset to INFO level for consistent testing
DebugManager.set_log_level(DebugManager.LogLevel.INFO)
DebugManager.log_trace("TRACE: This should not appear (below INFO level)")
DebugManager.log_debug("DEBUG: This should not appear (below INFO level)")
DebugManager.log_info("INFO: This message should appear")
DebugManager.log_warn("WARN: This warning should appear")
DebugManager.log_error("ERROR: This error should appear")
DebugManager.log_fatal("FATAL: This fatal error should appear")
func test_log_level_filtering():
print("\n--- Test 2: Log Level Filtering ---")
# Test DEBUG level
print("Setting log level to DEBUG...")
DebugManager.set_log_level(DebugManager.LogLevel.DEBUG)
DebugManager.log_trace("TRACE: Should not appear (below DEBUG)")
DebugManager.log_debug("DEBUG: Should appear with debug enabled")
DebugManager.log_info("INFO: Should appear")
# Test ERROR level (very restrictive)
print("Setting log level to ERROR...")
DebugManager.set_log_level(DebugManager.LogLevel.ERROR)
DebugManager.log_debug("DEBUG: Should not appear (below ERROR)")
DebugManager.log_warn("WARN: Should not appear (below ERROR)")
DebugManager.log_error("ERROR: Should appear")
DebugManager.log_fatal("FATAL: Should appear")
# Reset to INFO for remaining tests
DebugManager.set_log_level(DebugManager.LogLevel.INFO)
func test_category_logging():
print("\n--- Test 3: Category Functionality ---")
DebugManager.log_info("Message without category")
DebugManager.log_info("Message with TEST category", "TEST")
DebugManager.log_info("Message with LOGGING category", "LOGGING")
DebugManager.log_warn("Warning with VALIDATION category", "VALIDATION")
DebugManager.log_error("Error with SYSTEM category", "SYSTEM")
func test_debug_mode_integration():
print("\n--- Test 4: Debug Mode Integration ---")
# Set to TRACE level to test debug mode dependency
DebugManager.set_log_level(DebugManager.LogLevel.TRACE)
var original_debug_state = DebugManager.is_debug_enabled()
# Test with debug mode OFF
DebugManager.set_debug_enabled(false)
print("Debug mode OFF - TRACE and DEBUG should not appear:")
DebugManager.log_trace("TRACE: Should NOT appear (debug mode OFF)")
DebugManager.log_debug("DEBUG: Should NOT appear (debug mode OFF)")
DebugManager.log_info("INFO: Should appear regardless of debug mode")
# Test with debug mode ON
DebugManager.set_debug_enabled(true)
print("Debug mode ON - TRACE and DEBUG should appear:")
DebugManager.log_trace("TRACE: Should appear (debug mode ON)")
DebugManager.log_debug("DEBUG: Should appear (debug mode ON)")
DebugManager.log_info("INFO: Should still appear")
# Restore original debug state
DebugManager.set_debug_enabled(original_debug_state)
DebugManager.set_log_level(DebugManager.LogLevel.INFO)
# Helper function to validate log level enum values
func test_log_level_enum():
print("\n--- Log Level Enum Values ---")
print("TRACE: ", DebugManager.LogLevel.TRACE)
print("DEBUG: ", DebugManager.LogLevel.DEBUG)
print("INFO: ", DebugManager.LogLevel.INFO)
print("WARN: ", DebugManager.LogLevel.WARN)
print("ERROR: ", DebugManager.LogLevel.ERROR)
print("FATAL: ", DebugManager.LogLevel.FATAL)