# Contributing to EU-Utility First off, thank you for considering contributing to EU-Utility! It's people like you that make this tool better for the entire Entropia Universe community. ## Table of Contents - [Code of Conduct](#code-of-conduct) - [Getting Started](#getting-started) - [How Can I Contribute?](#how-can-i-contribute) - [Development Setup](#development-setup) - [Plugin Development](#plugin-development) - [Style Guidelines](#style-guidelines) - [Commit Messages](#commit-messages) - [Pull Request Process](#pull-request-process) - [Reporting Bugs](#reporting-bugs) - [Suggesting Enhancements](#suggesting-enhancements) - [Community](#community) --- ## Code of Conduct This project and everyone participating in it is governed by our commitment to: - **Be respectful** - Treat everyone with respect. Healthy debate is encouraged, but harassment is not tolerated. - **Be constructive** - Provide constructive feedback and be open to receiving it. - **Be inclusive** - Welcome newcomers and help them get started. - **Focus on what's best** - Consider what is best for the community and the project. --- ## Getting Started ### Prerequisites - Python 3.11 or higher - Git - A GitHub account - Entropia Universe (for testing game integration features) ### Quick Setup ```bash # 1. Fork the repository on GitHub # 2. Clone your fork git clone https://github.com/YOUR_USERNAME/EU-Utility.git cd EU-Utility # 3. Add upstream remote git remote add upstream https://github.com/ImpulsiveFPS/EU-Utility.git # 4. Create virtual environment python -m venv venv # 5. Activate it # Windows: venv\Scripts\activate # Linux/Mac: source venv/bin/activate # 6. Install dependencies pip install -r requirements.txt # 7. Run tests python -m pytest # 8. Start EU-Utility python -m core.main ``` --- ## How Can I Contribute? ### ๐Ÿ› Report Bugs Before creating a bug report, please check the [existing issues](https://github.com/ImpulsiveFPS/EU-Utility/issues) to avoid duplicates. When creating a bug report, include: - **Clear title** - Summarize the issue - **Steps to reproduce** - Detailed steps to recreate the bug - **Expected behavior** - What should have happened - **Actual behavior** - What actually happened - **Screenshots** - If applicable - **System info:** - OS and version - Python version - EU-Utility version - Error messages/logs ### ๐Ÿ’ก Suggest Enhancements Enhancement suggestions are welcome! Please provide: - **Clear description** - What would you like to see? - **Use case** - Why would this be useful? - **Proposed implementation** - How could it work? (optional) ### ๐Ÿ”Œ Create Plugins Plugins are the heart of EU-Utility! Create and share your own: - Check the [Plugin Development Guide](./docs/PLUGIN_DEVELOPMENT_GUIDE.md) - Submit to the Plugin Store - Share on community forums ### ๐Ÿ“ Improve Documentation Documentation improvements are always welcome: - Fix typos and grammar - Add examples and clarifications - Translate to other languages - Update outdated information ### ๐Ÿงช Write Tests Help improve code quality by adding tests: - Unit tests for core functionality - Integration tests for plugins - Performance benchmarks ### ๐Ÿ”ง Fix Issues Look for issues labeled: - `good first issue` - Great for newcomers - `help wanted` - Extra attention needed - `bug` - Something isn't working - `enhancement` - New features --- ## Development Setup ### Project Structure ``` EU-Utility/ โ”œโ”€โ”€ core/ # Core services โ”‚ โ”œโ”€โ”€ main.py # Application entry point โ”‚ โ”œโ”€โ”€ plugin_manager.py # Plugin management โ”‚ โ”œโ”€โ”€ event_bus.py # Event system โ”‚ โ”œโ”€โ”€ nexus_api.py # Nexus integration โ”‚ โ””โ”€โ”€ ... โ”œโ”€โ”€ plugins/ # Plugin directory โ”‚ โ”œโ”€โ”€ base_plugin.py # Base plugin class โ”‚ โ”œโ”€โ”€ dashboard/ # Dashboard plugin โ”‚ โ”œโ”€โ”€ loot_tracker/ # Loot tracker plugin โ”‚ โ””โ”€โ”€ ... โ”œโ”€โ”€ docs/ # Documentation โ”œโ”€โ”€ tests/ # Test suite โ”œโ”€โ”€ data/ # User data (not in repo) โ””โ”€โ”€ assets/ # Images, icons, sounds ``` ### Development Workflow ```bash # 1. Sync with upstream git fetch upstream git checkout main git merge upstream/main # 2. Create feature branch git checkout -b feature/my-feature # 3. Make changes # ... edit files ... # 4. Test changes python -m pytest python -m core.main # 5. Commit changes git add . git commit -m "feat: add my feature" # 6. Push to fork git push origin feature/my-feature # 7. Create Pull Request on GitHub ``` --- ## Plugin Development ### Creating a New Plugin 1. **Create plugin directory:** ```bash mkdir plugins/my_plugin touch plugins/my_plugin/__init__.py touch plugins/my_plugin/plugin.py ``` 2. **Implement the plugin:** ```python # plugins/my_plugin/plugin.py from plugins.base_plugin import BasePlugin class MyPlugin(BasePlugin): name = "My Plugin" version = "1.0.0" author = "Your Name" description = "What it does" def initialize(self): pass def get_ui(self): # Return QWidget pass ``` 3. **Test thoroughly:** - Test UI rendering - Test hotkey functionality - Test data persistence - Test error handling 4. **Add documentation:** - Plugin README.md - Code comments - Usage examples ### Plugin Guidelines โœ… **Do:** - Use existing core services - Follow naming conventions - Add proper error handling - Clean up resources in `shutdown()` - Use background tasks for heavy operations - Follow the style guide โŒ **Don't:** - Block the main thread - Access game files directly - Hardcode paths - Ignore errors silently - Duplicate existing functionality --- ## Style Guidelines ### Python Code Style We follow [PEP 8](https://www.python.org/dev/peps/pep-0008/) with some additions: ```python """ EU-Utility - Module Name Short description of the module. Features: - Feature 1 - Feature 2 """ from typing import Optional, Dict, Any, List from dataclasses import dataclass # Constants MAX_RETRIES = 3 DEFAULT_TIMEOUT = 30 @dataclass class Config: """Configuration data class.""" name: str value: int enabled: bool = True class MyClass: """ Brief description of the class. Longer description with usage examples. Attributes: name: The name attribute value: The value attribute Example: >>> obj = MyClass("test", 42) >>> obj.process() """ def __init__(self, name: str, value: int) -> None: """Initialize the class.""" self.name = name self.value = value self._private_var = None def process(self, data: Dict[str, Any]) -> Optional[str]: """ Process the data. Args: data: Input data dictionary Returns: Processed string or None if invalid Raises: ValueError: If data is invalid """ if not data: raise ValueError("Data cannot be empty") return f"{self.name}: {self.value}" ``` ### UI Style Guide Use the EU-Utility theme: ```python # Colors BG_DARK = "#1a1a1a" # Main background BG_PANEL = "#2a2a2a" # Panel background ACCENT_ORANGE = "#ff8c42" # Accent color TEXT_WHITE = "#ffffff" # Primary text TEXT_MUTED = "rgba(255,255,255,150)" # Secondary text # Apply to widgets widget.setStyleSheet(f""" QWidget {{ background-color: {BG_DARK}; color: {TEXT_WHITE}; }} """) ``` ### Documentation Style - Use clear, concise language - Include code examples - Document all public methods - Use type hints - Keep line length under 100 characters --- ## Commit Messages We follow [Conventional Commits](https://www.conventionalcommits.org/): ``` ():