Skip to main content

Overview

Paper uses a structured configuration system based on the ConfigurationPart pattern. This system provides type-safe configuration with automatic serialization, validation, and per-world customization.

ConfigurationPart Pattern

The ConfigurationPart class is a marker interface for configuration sections:
All configuration classes extend ConfigurationPart, enabling:
  • Automatic serialization/deserialization
  • Nested configuration sections
  • Type safety and validation
  • IDE autocomplete support
The ConfigurationPart marker enables the configuration framework to identify and process configuration sections automatically.

GlobalConfiguration vs WorldConfiguration

Paper has two primary configuration classes with different scopes:

GlobalConfiguration

Settings that apply server-wide and must remain consistent across all worlds. Location: io.papermc.paper.configuration.GlobalConfiguration Use cases:
  • Proxy settings (BungeeCord, Velocity)
  • Console configuration
  • Watchdog settings
  • Packet rate limiting
  • Player auto-save configuration
  • Message templates
Accessing global config:
Global configuration is accessed via the static get() method and returns a singleton instance.

WorldConfiguration

Settings that can differ between worlds (Overworld, Nether, End, custom dimensions). Location: io.papermc.paper.configuration.WorldConfiguration Use cases:
  • Entity spawning limits
  • Mob behavior settings
  • Anti-cheat configuration (anti-xray)
  • Chunk loading settings
  • Environment settings (thunder, ice, snow)
  • Tick rates for various systems
Accessing world config:
World-specific configuration is preferred whenever possible to allow different settings per dimension.

Configuration Structure

Both configuration classes use nested inner classes extending ConfigurationPart to organize settings:
Key features:
  • Nested sections - Related settings grouped in inner classes
  • Default values - Field initializers provide defaults
  • Type safety - Compile-time checking of setting types
  • Clear hierarchy - Configuration path matches code structure
The configuration file path is automatically generated from field names using snake-case conversion: maxNumOfPlayers becomes misc.max-num-of-players.

Adding New Configuration Options

Adding to GlobalConfiguration

Access in code:

Adding to WorldConfiguration

Access in code:
Always use fully qualified class names for GlobalConfiguration since it’s not imported in most Minecraft classes. Avoid adding imports to vanilla files.

Configuration Annotations

@Setting

Override the configuration key name:

@Comment

Add explanatory comments to the configuration file:

@Required

Mark a field as required (must be present in config):

@PostProcess

Execute validation or transformation after loading:
@PostProcess methods are called after deserialization, allowing validation and computed fields.

Advanced Configuration Types

IntOr.Default and IntOr.Disabled

Optional integer values with special handling:
Use cases:
  • IntOr.Default - Use vanilla default or specify custom value
  • IntOr.Disabled - Allow disabling feature with -1 or special value

DoubleOr.Default and DoubleOr.Disabled

Same pattern for double values:

Duration and DurationOrDisabled

Type-safe duration values:
Supported formats: ”10s”, “5m”, “2h”, “3d”
Using Duration instead of raw integers makes configuration files more readable and less error-prone.

Collections (Maps and Lists)

Nested Configuration Objects

Configuration File Versioning

Both configuration classes track versions:
Version management:
  • Increment CURRENT_VERSION when adding/changing settings
  • Update the comment explaining the change
  • Migrations handle upgrading old configs
The version comment should describe the change so merge conflicts are detected during rebases.

Example: Complete Configuration Section

Access in code:

Configuration Location

Global configuration:
  • File: config/paper-global.yml
  • One file for entire server
World configuration:
  • File: config/paper-world-defaults.yml (defaults for all worlds)
  • Per-world: world/paper-world.yml (overrides for specific world)
World configurations inherit from paper-world-defaults.yml and can override specific settings per world.

Best Practices

When possible, add settings to WorldConfiguration to allow different values per dimension. Only use GlobalConfiguration for truly server-wide settings.
Always initialize fields with appropriate default values. This ensures the config works even if the file is missing.
Field names should clearly indicate what the setting controls. Avoid abbreviations unless they’re industry-standard.
Use @Comment annotations to explain what settings do and what values are acceptable.
Prefer Duration, IntOr.Default, etc. over raw primitives for better validation and readability.