Understanding the Directory Structure of Pumpkin-MC/Pumpkin: A Rust Workspace Guide

The Pumpkin-MC/Pumpkin repository follows a Rust workspace architecture with 10+ specialized crates, where the pumpkin/ crate contains core server logic, pumpkin-world/ handles chunk systems, and pumpkin-protocol/ manages Minecraft packet serialization.

Pumpkin is a modular, high-performance Minecraft server implementation written in Rust. Understanding the directory structure of Pumpkin-MC/Pumpkin is essential for developers contributing to the codebase or building plugins. The repository uses Cargo workspaces to organize distinct subsystems—ranging from world generation to network protocol handling—into separate, maintainable crates.

Workspace Organization at a Glance

The repository root contains a Cargo.toml workspace definition that coordinates multiple member crates. Each crate follows a consistent pattern with src/ directories containing implementation code and individual Cargo.toml files defining specific dependencies.

The top-level structure includes these primary components:

  • pumpkin/ – Core server engine (entity systems, world ticks, gameplay mechanics)
  • pumpkin-world/ – Low-level world data structures and chunk loading pipeline
  • pumpkin-protocol/ – Minecraft network protocol serialization and packet codecs
  • pumpkin-plugin-api/ – Public API for third-party plugin development
  • pumpkin-nbt/ – Named Binary Tag format handling for player and world data
  • pumpkin-inventory/ – Container abstractions, screen handlers, and slot management
  • pumpkin-data/ – Auto-generated constants for items, sounds, and status effects
  • pumpkin-config/ – Configuration structures parsed from YAML files
  • pumpkin-codecs/ – Generic serialization framework used across crates
  • pumpkin-api-macros/ – Procedural macros supporting the plugin API
  • assets/ – Static resource files including world event definitions

Core Server Logic: The pumpkin Crate

The pumpkin crate serves as the main server executable, importing other workspace members as dependencies. Located at pumpkin/src/, this crate contains the primary Server struct and coordinates entity systems, world ticks, and player interactions.

Key implementation files include:

The server implementation relies on tokio for async runtime management, as evidenced by the initialization patterns found in the source.

World Management with pumpkin-world

The pumpkin-world crate isolates low-level world representation from high-level gameplay logic. This separation allows efficient chunk management independent of entity simulation.

Critical files in this crate include:

The chunk system handles the complex lifecycle of Minecraft chunks, from generation to serialization, without coupling to the main server's tick loop.

Protocol Implementation in pumpkin-protocol

Network communication flows through the pumpkin-protocol crate, which implements Minecraft's binary protocol. This crate manages packet serialization for both Java and Bedrock editions when supported.

Key components reside in:

The protocol layer translates between raw network bytes and Rust data structures, ensuring type-safe packet handling throughout the connection lifecycle.

Plugin Development Architecture

The pumpkin-plugin-api Crate

Third-party extensions integrate through the pumpkin-plugin-api crate. Located in pumpkin-plugin-api/src/, this crate defines the event system, permission hooks, and logging interfaces.

Representative files include:

  • pumpkin-plugin-api/src/lib.rs – Main API surface with Plugin trait and PluginContext
  • Event definitions allowing hooks into PlayerJoinEvent and other server events

Plugins implement the async Plugin trait and register event handlers through the context object.

Supporting Macros: pumpkin-api-macros

The pumpkin-api-macros crate at pumpkin-api-macros/src/lib.rs provides procedural macros that simplify plugin boilerplate. These macros generate glue code for event registration and command parsing at compile time.

Data Serialization and Assets

NBT Handling: pumpkin-nbt

The pumpkin-nbt crate manages Named Binary Tag format used for player inventories, level data, and entity storage. Implementation in pumpkin-nbt/src/lib.rs provides serialization and deserialization utilities compatible with Minecraft's NBT specification.

Generated Game Data: pumpkin-data

The pumpkin-data crate contains auto-generated Rust code derived from vanilla Minecraft data tables. Files like pumpkin-data/src/generated/item_stack/mod.rs export constants for item IDs, sound identifiers, and status effect mappings, ensuring the server remains synchronized with client expectations.

Serialization Framework: pumpkin-codecs

Underpinning many crates is the pumpkin-codecs library in pumpkin-codecs/src/codec/mod.rs. This generic framework provides primitive codecs and builders for maps and lists, standardizing how structured data moves between disk, network, and memory representations.

Configuration and Inventory Systems

Server Configuration: pumpkin-config

Server administrators modify behavior through YAML files parsed by the pumpkin-config crate. Located at pumpkin-config/src/, this crate defines structs for whitelist management, resource pack URLs, and server links. The server_links.rs file specifically handles parsing of server metadata configurations.

Inventory Management: pumpkin-inventory

Player and container inventories are abstracted by the pumpkin-inventory crate. The pumpkin-inventory/src/screen_handler.rs file defines window properties and slot mappings, while pumpkin-inventory/src/lib.rs exposes inventory operations independent of the core game loop.

Practical Code Examples

Starting a Minimal Pumpkin Server

To initialize the server runtime, import the core Server struct and configuration types:

use pumpkin::server::Server;
use pumpkin_config::config::Config;

#[tokio::main]
async fn main() {
    // Load server config with sensible defaults
    let cfg = Config::load().await.unwrap();

    // Instantiate and run the server
    let server = Server::new(cfg).await.unwrap();
    server.run().await.unwrap();
}

This pattern references the pumpkin::server::Server implementation defined in the pumpkin crate's source.

Registering a Plugin Event

Plugins hook into server lifecycle through the API crate:

use pumpkin_plugin_api::events::PlayerJoinEvent;
use pumpkin_plugin_api::plugin::{Plugin, PluginContext};

pub struct WelcomePlugin;

#[async_trait::async_trait]
impl Plugin for WelcomePlugin {
    async fn enable(&self, ctx: PluginContext) {
        ctx.register_event::<PlayerJoinEvent>(|event| async move {
            let player = event.player();
            player.send_message("Welcome to the Pumpkin server!").await;
        });
    }
}

The PlayerJoinEvent and PluginContext types are exported from pumpkin-plugin-api/src/lib.rs.

Reading NBT Data Files

Access player data or schematic files using the NBT utilities:

use pumpkin_nbt::tag::Tag;
use std::fs::File;
use std::io::BufReader;

fn read_player_nbt(path: &str) -> Tag {
    let file = File::open(path).unwrap();
    let mut reader = BufReader::new(file);
    pumpkin_nbt::deserializer::from_reader(&mut reader).unwrap()
}

This functionality is anchored in pumpkin-nbt/src/lib.rs according to the current source tree.

Summary

Frequently Asked Questions

What is the main entry point for running a Pumpkin server?

The primary entry point is the Server struct defined in pumpkin/src/lib.rs within the core pumpkin crate. This struct initializes the configuration system, opens network listeners, and starts the world tick loop. Runtime execution begins by calling Server::new() followed by server.run() in an async context.

How does the Pumpkin codebase handle Minecraft protocol serialization?

Packet serialization is implemented in the pumpkin-protocol crate, specifically within pumpkin-protocol/src/packet.rs and related codec files. This crate translates between Rust data structures and Minecraft's binary wire format, supporting the protocol versions the server targets. The separation into its own crate allows protocol changes without modifying core game logic.

Where are world chunks stored and managed in the Pumpkin repository?

Chunk data structures and loading pipelines are defined in pumpkin-world/src/chunk_system/mod.rs and supporting files under pumpkin-world/src/. This crate handles the low-level block storage, dimension definitions, and chunk I/O operations, while the pumpkin crate coordinates higher-level world mechanics like weather and time.

How do I create a plugin for Pumpkin-MC/Pumpkin?

Develop plugins by implementing the Plugin trait from pumpkin-plugin-api/src/lib.rs. Your plugin must provide an enable method that receives a PluginContext, through which you register event handlers like PlayerJoinEvent. The pumpkin-api-macros crate provides procedural macros to reduce boilerplate when defining commands and event listeners.

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 →