11 KiB
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
- Getting Started
- How Can I Contribute?
- Development Setup
- Plugin Development
- Style Guidelines
- Commit Messages
- Pull Request Process
- Reporting Bugs
- Suggesting Enhancements
- 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
# 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 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
- 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 newcomershelp wanted- Extra attention neededbug- Something isn't workingenhancement- 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
# 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
- Create plugin directory:
mkdir plugins/my_plugin
touch plugins/my_plugin/__init__.py
touch plugins/my_plugin/plugin.py
- Implement the plugin:
# 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
-
Test thoroughly:
- Test UI rendering
- Test hotkey functionality
- Test data persistence
- Test error handling
-
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 with some additions:
"""
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:
# 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:
<type>(<scope>): <subject>
<body>
<footer>
Types
- feat - New feature
- fix - Bug fix
- docs - Documentation only
- style - Code style (formatting, no logic change)
- refactor - Code refactoring
- perf - Performance improvements
- test - Adding tests
- chore - Maintenance tasks
Examples
feat(plugins): add auction tracker plugin
Add new plugin for tracking auction prices and markups.
Features:
- Real-time price tracking
- Historical data charts
- Markup calculations
Closes #123
fix(ocr): resolve memory leak in capture method
The OCR service was not releasing image buffers,
causing memory usage to grow over time.
Fixes #456
docs(readme): update installation instructions
Add Windows 11 specific steps and troubleshoot
tips for common installation issues.
Pull Request Process
- Update documentation - Update README.md, CHANGELOG.md, or docs/ if needed
- Add tests - Include tests for new functionality
- Update CHANGELOG.md - Add your changes under the
[Unreleased]section - Ensure tests pass - Run
python -m pytest - Fill out PR template - Describe what and why
- Request review - Wait for maintainer review
- Address feedback - Make requested changes
- Merge - Maintainers will merge when ready
PR Checklist
- Code follows style guidelines
- Tests pass locally
- Documentation updated
- CHANGELOG.md updated
- Commit messages follow conventions
- PR description is clear
Reporting Bugs
Before Submitting
- Check existing issues
- Try the latest version
- Check TROUBLESHOOTING.md
Bug Report Template
**Description**
Clear description of the bug.
**To Reproduce**
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected Behavior**
What should have happened.
**Screenshots**
If applicable, add screenshots.
**Environment:**
- OS: [e.g., Windows 11]
- Python: [e.g., 3.11.4]
- EU-Utility: [e.g., 2.0.0]
**Logs:**
Paste relevant log output
**Additional Context**
Any other information.
Suggesting Enhancements
Enhancement Template
**Feature Request**
Clear description of the feature.
**Problem/Motivation**
What problem does this solve?
**Proposed Solution**
How should it work?
**Alternatives**
Other approaches considered.
**Additional Context**
Mockups, examples, etc.
Community
Communication Channels
- GitHub Issues - Bug reports and feature requests
- GitHub Discussions - General discussion and Q&A
- Discord - Real-time chat (link TBD)
Recognition
Contributors will be:
- Listed in CONTRIBUTORS.md
- Mentioned in release notes
- Credited in relevant documentation
Development Tips
Debugging
# Enable debug logging
import logging
logging.basicConfig(level=logging.DEBUG)
# Add to your plugin
self.log_debug("Debug information")
Testing Plugins
# tests/test_my_plugin.py
import pytest
from plugins.my_plugin.plugin import MyPlugin
class TestMyPlugin:
def test_initialization(self):
plugin = MyPlugin()
plugin.initialize()
assert plugin.name == "My Plugin"
Profiling
# Profile plugin performance
import cProfile
import pstats
profiler = cProfile.Profile()
profiler.enable()
# Your code here
profiler.disable()
stats = pstats.Stats(profiler)
stats.sort_stats('cumtime')
stats.print_stats(20)
Questions?
If you have questions:
- Check the documentation
- Search existing issues
- Ask in GitHub Discussions
- Join our Discord
Thank you for contributing to EU-Utility! 🎮✨