# Code of Conduct - Skelly Project ## Overview Coding standards and development practices for the Skelly project. These guidelines help developers contribute effectively while maintaining code quality and project consistency. ## Core Principles ### 1. Code Clarity Over Cleverness - Write code that is easy to read - Use descriptive variable and function names - Prefer explicit code over "clever" solutions - Comment complex logic and business rules ### 2. Consistency First - Follow existing code patterns - Use same naming conventions throughout - Maintain consistent indentation and formatting - Follow Godot's GDScript style guide ### 3. Incremental Development - Make small, focused commits - Test changes before committing - Don't break existing functionality - Use debug system to verify changes ## GDScript Coding Standards ### Naming Conventions ```gdscript # Variables and functions: snake_case var player_health: int = 100 func calculate_damage() -> int: # Constants: SCREAMING_SNAKE_CASE const MAX_HEALTH := 100 const TILE_SPACING := 54 # Classes: PascalCase class_name PlayerController # Signals: past_tense signal health_changed signal game_started # Private functions: prefix with underscore func _ready(): func _initialize_grid(): ``` ### File Organization ```gdscript # 1. extends statement extends Node2D # 2. class_name (if applicable) class_name Match3Controller # 3. Constants const GRID_SIZE := Vector2i(8, 8) # 4. Signals signal match_found(tiles: Array) # 5. Variables var grid := [] @onready var debug_ui = $DebugUI # 6. Functions (lifecycle first, then custom) func _ready(): func _process(delta): func custom_function(): ``` ### Documentation Requirements ```gdscript # Required for all public functions func set_gem_pool(gem_indices: Array) -> void: """Set specific gem types as the active pool""" _update_all_tiles_gem_pool(gem_indices) print("Set gem pool to: ", gem_indices) # Document complex algorithms func _get_match_line(start: Vector2i, dir: Vector2i) -> Array: """Find all matching tiles in a line from start position in given direction""" var line = [grid[start.y][start.x]] var type = grid[start.y][start.x].tile_type # Implementation... ``` ## Project-Specific Guidelines ### Scene Management - All scene transitions go through `GameManager` - Never use `get_tree().change_scene_to_file()` directly - Define scene paths as constants in GameManager ```gdscript # ✅ Correct GameManager.start_match3_game() # ❌ Wrong get_tree().change_scene_to_file("res://scenes/game.tscn") ``` ### Autoload Usage - Use autoloads for global state only - Don't access autoloads from deeply nested components - Pass data through signals or direct references when possible ```gdscript # ✅ Correct - using signals signal settings_changed SettingsManager.volume_changed.connect(_on_volume_changed) # ✅ Also correct - direct access for global state var current_language = SettingsManager.get_setting("language") # ❌ Wrong - tight coupling func some_deep_function(): SettingsManager.set_setting("volume", 0.5) # Too deep in call stack ``` ### Debug System Integration - Always connect to DebugManager signals for debug UI - Use structured logging instead of plain print statements - Remove temporary debug logs before committing (unless permanently useful) ```gdscript # ✅ Correct debug integration func _connect_to_global_debug() -> void: DebugManager.debug_ui_toggled.connect(_on_debug_ui_toggled) debug_ui.visible = DebugManager.is_debug_ui_visible() # ✅ Good structured logging DebugManager.log_debug("Debug UI toggled to: " + str(visible), "Match3") DebugManager.log_info("Initialized " + str(tiles.size()) + " tiles", "TileSystem") # ❌ Bad logging practices print("test") # Not descriptive, use structured logging print(some_variable) # No context, use proper log level ``` ### Logging Standards - Use `DebugManager.log_*()` functions instead of `print()` or `push_error()` - Choose log levels based on message importance and audience - Include 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 - **Document every asset** in `assets/sources.yaml` - Include source information, license details, and attribution - Document modifications made to original assets - Verify license compatibility before adding assets - Update sources.yaml in same commit as adding 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 - Check if resources loaded successfully - Use `DebugManager.log_error()` for critical failures - Provide fallback behavior when possible - Include meaningful context in error messages ```gdscript # Good error handling with structured logging func load_scene(path: String) -> void: var packed_scene := load(path) if not packed_scene or not packed_scene is PackedScene: DebugManager.log_error("Failed to load scene at: %s" % path, "SceneLoader") return DebugManager.log_info("Successfully loaded scene: %s" % path, "SceneLoader") get_tree().change_scene_to_packed(packed_scene) ``` ## Git Workflow ### Commit Guidelines - Use clear, descriptive commit messages - Start with a verb in imperative mood - Keep first line under 50 characters - Add body if needed for complex changes ```bash # Good commit messages Add gem pool management to match-3 system Fix debug UI visibility toggle issue Update documentation for new debug system # Bad commit messages fix bug update wip ``` ### Branch Management - Create feature branches for new functionality - Use descriptive branch names: `feature/debug-ui`, `fix/tile-positioning` - Keep branches focused on single features - Delete branches after merging ### Before Committing 1. Test your changes in the Godot editor 2. Check that existing functionality still works 3. Use the debug system to verify your implementation 4. Run the project and navigate through affected areas 5. Remove temporary debug code ## Code Review Guidelines ### For Reviewers - Focus on code clarity and maintainability - Check for adherence to project patterns - Verify that autoloads are used appropriately - Ensure debug integration is properly implemented - Test the changes yourself ### For Contributors - Explain complex logic in commit messages or comments - Provide context for why changes were made - Test edge cases and error conditions - Ask questions if project patterns are unclear ## Testing Approach ### Manual Testing Requirements - Test in Godot editor with F5 run - Verify debug UI works with F12 toggle - Check scene transitions work - Test on different screen sizes (mobile target) - Verify audio and settings integration ### Debug System Testing - Ensure debug panels appear/disappear correctly - Test all debug buttons and controls - Verify debug state persists across scene changes - Check debug code doesn't affect release builds ## Common Mistakes to Avoid ### Architecture Violations ```gdscript # Don't bypass GameManager get_tree().change_scene_to_file("some_scene.tscn") # Don't hardcode paths var tile = load("res://scenes/game/gameplays/tile.tscn") # Don't ignore null checks var node = get_node("SomeNode") node.do_something() # Could crash if node doesn't exist # Don't create global state in random scripts # 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 ```gdscript # Don't search nodes repeatedly func _process(delta): var ui = get_node("UI") # Expensive every frame # Cache node references @onready var ui = $UI func _process(delta): ui.update_display() # Much better ``` ### Debug System Misuse ```gdscript # Don't create separate debug systems var my_debug_enabled = false print("debug: " + some_info) # Don't use plain print() # Use the global debug and logging systems if DebugManager.is_debug_enabled(): show_debug_info() DebugManager.log_debug("Debug information: " + some_info, "MyComponent") ``` ## Learning Resources ### Godot-Specific - [GDScript Style Guide](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_styleguide.html) - [Godot Best Practices](https://docs.godotengine.org/en/stable/tutorials/best_practices/index.html) - Project documentation in `docs/map.md` ### General Programming - Clean Code principles - SOLID principles (adapted for game development) - Git best practices ## Getting Help ### When Stuck 1. Check existing code for similar patterns 2. Review project documentation (`docs/`) 3. Use the debug system to understand current state 4. Ask specific questions about project architecture 5. Test your understanding with small experiments ### Code Review Process - Submit pull requests early and often - Ask for feedback on approach before implementing large features - Be open to suggestions and alternative approaches - Learn from review feedback for future contributions ## Summary This code of conduct emphasizes: - **Clarity**: Write code that others can understand - **Consistency**: Follow established patterns - **Integration**: Use the project's systems properly - **Learning**: Continuously improve your skills Remember: It's better to ask questions and write clear, simple code than to guess and create complex, hard-to-maintain solutions. The goal is to contribute effectively to a codebase that will grow and evolve over time.