# Contributing to Pumpkin Thank you for your interest in contributing to Pumpkin! As an open-source Minecraft server built from the ground up in Rust, we welcome contributions of all sizesβ€”from fixing typos and adding documentation to implementing vanilla game mechanics and optimizing network protocols. This guide outlines our development workflow, coding standards, verification checklist, and pull request procedures. --- ## Getting Started The easiest way to get help, discuss proposed features, or coordinate with the team is by joining [our Discord server](https://discord.gg/wT8XjrjKkf). Before working on a large change, we strongly recommend opening an issue or starting a discussion in Discord to align on architecture and design decisions before writing code. > [!NOTE] > **For Automated AI Agents**: We have a streamlined process for merging agent PRs. Add `πŸ€–πŸ€–πŸ€–` to the end of your PR title to opt into fast-track review. Ensure your implementation is unique, passes all CI checks, and does not duplicate existing pull requests. --- ## Development Setup ### 1. Prerequisites - **Rust Toolchain**: Pumpkin requires the latest stable Rust toolchain (Rust 2024 edition, 1.96+). Install or update Rust via [rustup](https://rustup.rs/): ```bash rustup update stable rustup default stable rustup component add rustfmt clippy rust-src rust-analyzer ``` - **Git**: Ensure Git is installed and configured on your machine. - **Recommended Cargo Tools**: ```bash # Fast unit test runner used in CI cargo install cargo-nextest --locked # Detects unused dependencies cargo install cargo-machete --locked # Source code spell checker cargo install typos-cli --locked ``` ### 2. Cloning the Repository (Submodules Required!) Pumpkin uses Git submodules for interfaces such as `pumpkin-plugin-wit`. Make sure to clone recursively: ```bash # Clone with submodules git clone --recursive https://github.com/Pumpkin-MC/Pumpkin.git cd Pumpkin ``` If you have already cloned without `--recursive`, initialize the submodules manually: ```bash git submodule update --init --recursive ``` ### 3. Building and Running You can compile and launch the server in debug mode: ```bash cargo run ``` To build an optimized release binary (with LTO and single codegen units): ```bash cargo build --release ``` --- ## Coding Guidelines & Standards Pumpkin maintains high code quality and strict performance criteria. Our workspace enforces stringent Clippy lints, and CI will reject code that fails these checks. ### 1. The Zero-Panic Policy Pumpkin is designed to run 24/7 without crashing under unexpected inputs. Therefore, panic-inducing constructs are denied at the compiler level: - **No `unwrap()` or `expect()`**: Never call `.unwrap()` or `.expect()` in production code. Use the question mark operator `?`, pattern matching (`match` / `if let`), `.unwrap_or()`, or `.unwrap_or_default()`. ```rust // ❌ FORBIDDEN: Will fail CI let chunk = level.get_chunk(pos).unwrap(); // βœ… CORRECT: Handle Option or propagate error let Some(chunk) = level.get_chunk(pos) else { return Ok(()); }; ``` - **No `panic!()`, `todo!()`, or `unimplemented!()`**: Do not leave unhandled stubs or panic statements in committed code. - **No `println!()` or `eprintln!()`**: Always use the structured logging framework [`tracing`](https://docs.rs/tracing/): ```rust use tracing::{debug, error, info, trace, warn}; // ❌ FORBIDDEN: Will fail CI println!("Player joined: {}", player.gameprofile.name); // βœ… CORRECT info!("Player {} joined the server", player.gameprofile.name); ``` ### 2. Error Handling We use [`thiserror`](https://docs.rs/thiserror/) across our crates and unified error types like `PumpkinError`. Functions should return descriptive `Result` types rather than suppressing errors silently. ### 3. Concurrency Architecture: Tokio vs. Rayon Pumpkin uses a hybrid concurrency model: 1. **Tokio Runtime (Asynchronous I/O)**: Handles TCP/UDP network connections, incoming/outgoing packet streams, authentication HTTP requests, and timers. 2. **Rayon Thread Pool (CPU-Intensive Tasks)**: Handles heavy, CPU-bound computations such as: - Chunk generation and terrain carving - Lighting propagation and recalculation - Packet compression and world chunk serialization - Complex pathfinding and physics > [!WARNING] > **Never block Tokio worker threads with CPU-heavy work!** > Do not call long-running synchronous code inside async tasks. Instead, offload heavy work to Rayon via `rayon::spawn` and communicate results back using asynchronous channels like `tokio::sync::mpsc`. > > Refer to `pumpkin_world::level::Level::fetch_chunks` for an architectural example. ### 4. Unsafe Code Policy All `unsafe` blocks must be strictly justified and documented: ```rust // SAFETY: The buffer is guaranteed to contain at least 4 valid bytes // as verified by the bounds check on line 42. unsafe { // ... } ``` Any undocumented `unsafe` block triggers a denied lint in CI (`undocumented_unsafe_blocks = "deny"`). --- ## Pre-Commit Verification Checklist Before submitting a Pull Request, run the following commands locally to ensure your changes will pass our GitHub Actions CI pipeline: ```bash # 1. Format code according to rustfmt rules cargo fmt --check # 2. Run debug lints cargo clippy --all-targets --all-features # 3. Run release lints cargo clippy --release --all-targets --all-features # 4. Run tests with nextest (or cargo test) cargo nextest run --verbose # 5. Run documentation tests cargo test --doc --verbose # 6. Check for unused dependencies cargo machete # 7. Check for spelling typos typos ``` ### Benchmarking Performance If you are modifying performance-sensitive hot paths (such as packet serialization, chunk loading, or entity ticking), run benchmarks with [Criterion](https://github.com/bheisler/criterion.rs): ```bash cargo bench ``` Consider adding a new benchmark in `benches/` when introducing complex algorithms. --- ## Decompiling Minecraft for Reference When implementing vanilla Minecraft mechanics, packet layouts, or game logic, referencing official behavior is essential. Pumpkin is a clean-room Rust implementation, and understanding vanilla Minecraft logic helps ensure 1:1 compatibility. ### Decompiling with Fabric Yarn The easiest and cleanest way to decompile the Minecraft server/client for reference is using [Fabric Yarn](https://github.com/FabricMC/yarn) with the Vineflower decompiler: ```bash git clone https://github.com/FabricMC/yarn.git cd yarn ./gradlew decompileVineflower ``` After decompilation completes, the mapped source code will be available in: ``` build/namedSrc ``` ### Useful Protocol & Data Resources - **[Minecraft Wiki Protocol Reference](https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol)**: Complete reference of packet structures, fields, and IDs across game states. - **[Mojang Data Reports](https://github.com/Arcensoth/mc-data)**: Raw JSON dumps of registries, blocks, items, commands, and packet IDs. - **`tools/pumpkin-codegen`**: Our internal tool for parsing Minecraft game data and generating `pumpkin-data` code. > [!IMPORTANT] > **Clean-Room Etiquette**: Do not copy-paste decompiled Java code directly into Pumpkin. Study the algorithm and behavior, then write clean, idiomatic, safe Rust that fits Pumpkin's architecture and licensing (GPLv3). --- ## Submitting Pull Requests When your code is tested, formatted, and verified locally: 1. **Fork the Repository**: Fork [Pumpkin-MC/Pumpkin](https://github.com/Pumpkin-MC/Pumpkin) on GitHub. 2. **Create a Feature Branch**: ```bash git checkout -b feature/my-new-feature ``` 3. **Commit Your Changes**: Follow the **Conventional Commits** specification (detailed below). 4. **Push and Open a Pull Request**: - **PR Title**: Ensure your pull request title strictly conforms to the Conventional Commits specification. - **Description**: Use our PR template to explain: - **What** was changed? - **Why** was it changed? - **How** was it tested? - Are there any known limitations or edge cases? - **AI Agents**: Suffix your PR title with `πŸ€–πŸ€–πŸ€–` if submitting via an automated AI agent. 5. **CI & Code Review**: GitHub Actions will automatically verify formatting, clippy lints, tests, and dependencies. Maintainers will review your implementation and provide feedback. --- ## Conventional Commits Specification All commit messages and pull request titles in Pumpkin must strictly follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification. This convention ensures consistent commit history and automated release changelog generation. ### Commit & PR Title Structure ```text (): [optional detailed body] [optional footer(s)] ``` ### Commit Types | Type | Purpose | Example | | :--- | :--- | :--- | | `feat` | Introduces a new feature or vanilla game mechanic | `feat(entity): implement drowned swimming goal` | | `fix` | Resolves a bug, glitch, or protocol issue | `fix(protocol): resolve creative slot index offset` | | `docs` | Documentation additions or updates | `docs(developer): add porting versions guide` | | `perf` | Code modifications that improve execution speed or memory usage | `perf(world): optimize chunk section block iteration` | | `refactor` | Code changes that neither fix bugs nor add features | `refactor(command): unify argument parsing helpers` | | `test` | Adding missing tests or correcting existing tests | `test(inventory): add crafting table recipe tests` | | `chore` | Routine maintenance, dependency bumps, or toolchain updates | `chore(deps): bump tokio to 1.43` | | `ci` | Modifications to CI workflows, scripts, or Docker containers | `ci(github): add machete dependency verification` | ### Common Scopes Scopes indicate the crate or subsystem being modified: - **Crates**: `protocol`, `world`, `entity`, `command`, `inventory`, `data`, `util`, `macros`, `config` - **Subsystems**: `bedrock`, `java`, `network`, `proxy`, `query`, `auth`, `plugin`, `linear`, `anvil` ### Format Guidelines - **Imperative Mood**: Use imperative present tense in summaries (`add`, not `added` or `adds`; `fix`, not `fixed` or `fixes`). - **Lowercase**: Start summaries with lowercase characters and omit trailing punctuation. - **Breaking Changes**: Mark breaking API or protocol changes with an exclamation mark before the colon (`feat(protocol)!: overhaul packet codec`) or include `BREAKING CHANGE:` in the commit footer. - **PR Title Uniformity**: Because PR titles are squashed into the main branch history on merge, PR titles must also follow this specification.