Contributing
Set up, build, test, and contribute to Endstone.
Thank you for your interest in contributing to Endstone! This document provides guidelines and information to help you get started.
Table of Contents
- Getting Started
- Development Setup
- Building
- Testing
- Code Style
- Submitting Changes
- Project Structure
- Architecture Overview
Getting Started
Endstone is a plugin API for Minecraft Bedrock Dedicated Servers (BDS) that supports both Python and C++ plugins. It hooks into the BDS binary to expose a high-level Bukkit-like API for plugin development.
Prerequisites
Windows:
- MSVC 2017+ (Visual Studio 2022 recommended)
- CMake
- Ninja
- Conan 2.0+
Linux:
- Clang 20+ with libc++
- CMake
- Ninja
- Conan 2.0+
Development Setup
1. Install Dependencies
First, install Conan and set up your profile:
pip install conan
conan profile detect2. Install Project Dependencies with Conan
Windows:
conan install . --build=missing -s compiler.cppstd=20 -c tools.cmake.cmaketoolchain:generator=NinjaLinux:
conan install . --build=missing -s compiler.cppstd=20 -s compiler.libcxx=libc++ -c tools.cmake.cmaketoolchain:generator=Ninja3. Activate Conan Build Environment
Windows (cmd):
.\build\Release\generators\conanbuild.batWindows (PowerShell):
.\build\Release\generators\conanbuild.ps1Linux:
source ./build/Release/generators/conanbuild.shBuilding
Build with CMake
cmake --preset conan-release
cmake --build --preset conan-releaseInstall from Source (builds Python wheel)
pip install -U .Testing
C++ Tests (GTest)
ctest --test-dir build/ReleasePython Tests
pytestRuntime Tests
Runtime tests verify the API works correctly within a live Bedrock Dedicated Server. These tests are essential for validating functionality that depends on the server environment.
Install the test plugin:
pip install -e tests/endstone_testRun runtime tests:
- Start a Bedrock Dedicated Server with Endstone
- The
endstone_testplugin will load automatically - Run
/testin-game or from the console to execute the test suite
Before submitting a PR, please ensure:
- All C++ tests pass
- All Python tests pass
- Runtime tests pass (if your changes affect the API)
- The project builds successfully on your target platform
Generating Type Stubs
After adding new Python bindings, you need to regenerate the type stub files to ensure IDE support and type checking work correctly.
When to Regenerate Stubs
You should regenerate stubs after:
- Adding new Python bindings in
src/endstone/python/ - Modifying existing C++ classes exposed to Python
- Installing the wheel with
pip install .
Stub Generation Process
-
Install the wheel to make the bindings available:
pip install -U . -
Install endstone-stubgen (if not already installed):
pip install endstone-stubgen -
Run the stubgen script:
python scripts/stubgen.pyThis will:
- Load the
endstone._pythonmodule from the installed wheel - Generate
.pyistub files in a temporarystubs/directory - Process and format the stubs (adjusting imports, removing Registry duplicates, etc.)
- Copy the processed stubs to the
endstone/directory - Run
ruff formatandruff checkto ensure code style compliance
- Load the
-
Verify the generated stubs:
Check the generated
.pyifiles in theendstone/directory to ensure they correctly represent your new bindings. -
Commit the changes:
The generated stub files should be committed along with your binding changes.
Example Workflow
# 1. Make your binding changes
# (e.g., edit src/endstone/python/... )
# 2. Build and install
pip install -U .
# 3. Generate stubs
python scripts/stubgen.py
# 4. Verify
git status # Check the generated .pyi files
# 5. Commit
git add endstone/*.pyi
git commit -m "docs: update type stubs for new bindings"Troubleshooting
If you encounter errors running the stubgen script:
- "endstone-stubgen not installed": Install it with
pip install endstone-stubgen - Module not found errors: Make sure you've installed the wheel with
pip install . - Incomplete stubs: Verify that your bindings are properly exposed in the pybind11 module
Code Style
C++
Endstone uses clang-format and clang-tidy for code quality enforcement.
Style Guidelines:
- Based on Microsoft style with Stroustrup braces
- Naming conventions:
- Classes/Structs/Enums:
CamelCase - Methods:
camelBack - Private/protected members:
lower_case_(trailing underscore) - Local variables/parameters:
lower_case - Macros:
UPPER_CASE
- Classes/Structs/Enums:
Before submitting C++ code, ensure it passes clang-format and clang-tidy checks.
Python
Endstone uses ruff for Python code quality.
Configuration:
- Line length: 120 characters
- Enabled rules: I (isort), F (pyflakes)
Before submitting Python code, ensure it passes ruff checks.
Submitting Changes
Pull Request Process
- Fork and Branch: Create a feature branch from
main - Make Changes: Follow the code style guidelines
- Test: Run all tests and ensure builds pass
- Commit: Write clear, concise commit messages
- PR: Create a pull request with:
- Clear description of changes
- Reference to any related issues
- Screenshots or examples for UI changes
- Test results
Commit Message Guidelines
Follow conventional commits format:
feat:for new featuresfix:for bug fixesdocs:for documentation changesstyle:for code style changes (formatting, etc.)refactor:for code refactoringtest:for adding or updating testschore:for maintenance tasks
Example:
feat(player): add event for player join
Implement PlayerJoinEvent that fires when a player connects to the server.Project Structure
endstone/
├── include/endstone/ # Public C++ API headers (header-only)
├── src/
│ ├── bedrock/ # Bedrock server type definitions and reverse-engineered structures
│ └── endstone/
│ ├── core/ # Core implementation of the Endstone API
│ │ ├── command/ # Command system
│ │ ├── event/ # Event handling
│ │ ├── inventory/ # Inventory management
│ │ ├── level/ # Level/world management
│ │ ├── plugin/ # Plugin system
│ │ ├── scheduler/ # Task scheduling
│ │ └── scoreboard/ # Scoreboard system
│ ├── runtime/ # Runtime hooks into BDS via funchook
│ │ └── bedrock_hooks/ # Hook files for BDS subsystems
│ └── python/ # Python bindings via pybind11
├── endstone/ # Python package (CLI, plugin loader, metrics)
├── tests/ # Test files
│ ├── bedrock/ # C++ tests for bedrock layer
│ ├── endstone_test/ # Runtime test plugin (pip install -e tests/endstone_test)
│ ├── *.cpp # C++ unit tests
│ └── *.py # Python unit tests
└── conanfile.py # Dependency managementArchitecture Overview
Endstone follows a layered architecture:
1. Runtime Hooks (src/endstone/runtime/bedrock_hooks/)
- Intercepts BDS functions to inject Endstone behavior
- Each hook file corresponds to a BDS class (think of it as a patch file)
2. Bedrock Layer (src/bedrock/)
- Type-compatible structures matching BDS internal types
- Required for ABI compatibility when hooking
3. Core Layer (src/endstone/core/)
- Implements the public API by wrapping bedrock types
- Contains all subsystems: command, event, inventory, level, plugin, scheduler, scoreboard
- Provides the high-level API that plugins use
4. Plugin System
- C++ Plugins: Loaded as shared libraries with
endstone_prefix - Python Plugins: Loaded via
endstone.plugin.plugin_loader - Both inherit from respective base classes and implement required methods
Key Dependencies
Managed via Conan in conanfile.py:
fmt- Formatting libraryboost- Boost librariespybind11- Python bindingsspdlog- Logging frameworknlohmann_json- JSON libraryentt- Entity component systemmagic_enum- Enum reflectionsentry-native- Crash reporting