Overview
Paper uses a structured configuration system based on theConfigurationPart pattern. This system provides type-safe configuration with automatic serialization, validation, and per-world customization.
ConfigurationPart Pattern
TheConfigurationPart class is a marker interface for configuration sections:
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
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
World-specific configuration is preferred whenever possible to allow different settings per dimension.
Configuration Structure
Both configuration classes use nested inner classes extendingConfigurationPart to organize settings:
- 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
Adding New Configuration Options
Adding to GlobalConfiguration
Adding to WorldConfiguration
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:IntOr.Default- Use vanilla default or specify custom valueIntOr.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:Collections (Maps and Lists)
Nested Configuration Objects
Configuration File Versioning
Both configuration classes track versions:- Increment
CURRENT_VERSIONwhen 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
Configuration Location
Global configuration:- File:
config/paper-global.yml - One file for entire server
- 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
Prefer World Configuration
Prefer World Configuration
When possible, add settings to
WorldConfiguration to allow different values per dimension. Only use GlobalConfiguration for truly server-wide settings.Provide Sensible Defaults
Provide Sensible Defaults
Always initialize fields with appropriate default values. This ensures the config works even if the file is missing.
Use Descriptive Names
Use Descriptive Names
Field names should clearly indicate what the setting controls. Avoid abbreviations unless they’re industry-standard.
Add Comments for Complex Settings
Add Comments for Complex Settings
Use
@Comment annotations to explain what settings do and what values are acceptable.Group Related Settings
Group Related Settings
Use Type-Safe Wrappers
Use Type-Safe Wrappers
Prefer
Duration, IntOr.Default, etc. over raw primitives for better validation and readability.