How to Debug Pumpkin-MC/Pumpkin Code: Essential Techniques for Rust Developers

Debug Pumpkin-MC by configuring the RUST_LOG environment variable for granular tracing, attaching LLDB to the async Tokio runtime, and inspecting packet serialization logic in pumpkin-protocol/src/serial/ while ensuring RUST_BACKTRACE=full captures complete panic traces.

Pumpkin-MC is a high-performance Minecraft server implementation written in Rust. Its architecture splits functionality across independent workspace crates—including pumpkin-protocol for network packets and pumpkin-world for chunk simulation—making targeted debugging essential for resolving issues in this asynchronous codebase.

Understand the Crate Architecture

Before debugging, map your issue to the correct crate. Pumpkin-MC organizes functionality into distinct modules:

The server initializes in pumpkin/src/server.rs, loading configurations, initializing the world, and starting the async networking task before entering the tick scheduler.

Configure Logging and Tracing

Pumpkin-MC uses the log crate with env_logger for runtime diagnostics. Control verbosity via the RUST_LOG environment variable:


# Enable debug output for all crates

RUST_LOG=debug cargo run --release

Target specific modules to reduce noise:

RUST_LOG=pumpkin=debug,pumpkin_protocol=debug cargo run

The codebase emits diagnostic messages using macros like log::debug! and log::error!. For example, the protocol crate logs deserialization failures:

log::error!("Failed to deserialize packet: {}", err);

If a module remains silent, verify the crate name uses underscores instead of hyphens in the filter (e.g., pumpkin_protocol not pumpkin-protocol).

Essential Debugging Techniques for Async Rust

Because Pumpkin-MC runs on the Tokio runtime, bugs often surface under concurrent load. Apply these techniques based on the failure mode:

Add debug! statements for quick inspection

Insert temporary logging to inspect values inside functions:

log::debug!("Chunk {} loaded, {} entities", pos, entities.len());

Run targeted unit tests

Isolate components like packet codecs without starting the full server:

cargo test --package pumpkin-protocol

Inspect macro-generated code

Packet definitions use heavy macro codegen. Expand them for inspection:

cargo expand --package pumpkin-codegen

Attach a native debugger

Step through async tasks or watch for panics using LLDB or GDB:

rustup run stable lldb target/debug/pumpkin

Enable full backtraces

Rust backtraces are truncated by default. Capture the full stack on panic:

RUST_BACKTRACE=full cargo run

Profile async performance

Enable the tokio-console feature flag in Cargo.toml to detect task deadlocks or long-running operations in the scheduler.

Use filesystem watches

Detect config reload bugs by auto-rebuilding on changes:

cargo watch -x run

Debug Packet Serialization and Network Issues

Packet handling failures typically originate in pumpkin-protocol. When a client disconnects with a serialization error:

  1. Enable protocol-level logging: RUST_LOG=pumpkin_protocol=debug
  2. Examine raw bytes logged by serializer::write_packet in pumpkin-protocol/src/serial/serializer.rs
  3. Compare the byte sequence against the official Minecraft protocol specification
  4. Check pumpkin-protocol/src/serial/deserializer.rs for offset errors in variable-length integer parsing

If packet structs appear malformed, use cargo expand on the pumpkin-codegen package to verify the generated code in pumpkin-codegen/src/wit/packet_mapping.rs matches your expectations.

Troubleshoot World Ticks and Chunk Loading

World simulation bugs—such as chunks failing to load—stem from the async I/O layer or coordinate calculation errors.

Add debug! statements around the chunk loading path in pumpkin-world/src/world.rs. Verify that ChunkPos calculations in pumpkin/src/world/portal/mod.rs produce valid region file coordinates. If Anvil files fail to parse, inspect the file path construction in pumpkin-world/src/world_info/anvil.rs to ensure region filenames match the expected r.x.z.mca format.

The tick scheduler in pumpkin-world/src/tick/scheduler.rs drives all world updates. If the server hangs, attach a debugger to this module to verify the tick loop isn't blocked by synchronous I/O operations.

Investigate Plugin API Failures

Plugins interact through pumpkin-plugin-api. When a plugin panics or deadlocks:

  1. Check the scheduler logs in pumpkin_plugin_api::scheduler for task execution traces
  2. Verify the plugin's on_tick implementation uses tokio::spawn for long-running work to avoid blocking the main tick thread
  3. Ensure the plugin uses the API logger defined in pumpkin-plugin-api/src/logging.rs rather than standard print statements

Step-by-Step Example: Debugging Player Login Crashes

Consider a crash occurring when players attempt to join. Follow this procedure:

First, enable verbose logging for networking and world systems:

RUST_LOG=pumpkin_protocol=debug,pumpkin_world=debug cargo run --release

Next, add a targeted debug statement in pumpkin/src/player/mod.rs to inspect the login packet fields:

log::debug!(
    "Player {} attempting login from {} (protocol version {})",
    self.username, addr, packet.protocol_version
);

When the server panics, the backtrace points to pumpkin-protocol::packet::handle_login. Cross-reference the logged protocol version and username against the packet specification to identify mismatched field types or incorrect packet IDs in pumpkin-protocol/src/packet.rs.

Summary

  • Structure first: Map your bug to the correct crate—pumpkin-protocol for network issues, pumpkin-world for chunk errors, or pumpkin-plugin-api for extension crashes.
  • Log strategically: Use RUST_LOG=pumpkin_protocol=debug to isolate specific modules without console spam.
  • Handle async complexity: Attach LLDB to the Tokio runtime and enable RUST_BACKTRACE=full to trace panics across task boundaries.
  • Verify generated code: Use cargo expand on pumpkin-codegen when packet structs behave unexpectedly.
  • Inspect serialization: Check pumpkin-protocol/src/serial/serializer.rs and deserializer.rs for protocol mismatches.

Frequently Asked Questions

How do I enable debug logging for specific Pumpkin-MC crates?

Set the RUST_LOG environment variable using the crate name with underscores. For example, use RUST_LOG=pumpkin_protocol=debug for packet handling or RUST_LOG=pumpkin_world=debug for chunk operations. Run the server with RUST_LOG=debug cargo run to capture all crates at once.

Why is my Pumpkin server crashing during player login?

Login crashes typically indicate packet deserialization failures in pumpkin-protocol/src/serial/deserializer.rs. Enable RUST_LOG=pumpkin_protocol=debug to log raw packet bytes, then compare them against the Minecraft protocol specification. Add debug logging to pumpkin/src/player/mod.rs to inspect the protocol version and username fields before the crash occurs.

How can I inspect macro-generated packet code in Pumpkin?

Pumpkin uses macros extensively for packet definitions in the pumpkin-codegen crate. Install cargo-expand and run cargo expand --package pumpkin-codegen to view the generated Rust code in pumpkin-codegen/src/wit/packet_mapping.rs. This reveals the actual struct definitions and trait implementations produced at compile time.

What is the best way to debug async task deadlocks in Pumpkin-MC?

Enable the tokio-console feature flag in the workspace Cargo.toml to monitor task execution in real-time. For post-mortem analysis, run the server under LLDB with rustup run stable lldb target/debug/pumpkin, set breakpoints in pumpkin-world/src/tick/scheduler.rs, and inspect task states when the server hangs. Ensure plugin code in pumpkin-plugin-api uses tokio::spawn for asynchronous operations to avoid blocking the tick loop.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →