Loading
Personal Project
Charming Realm System

Charming Realm is a Minecraft Spigot plugin I built from scratch that provides every player with their own independent private world. The system handles the full lifecycle of realm management through an inventory-based GUI framework, async world generation, MySQL-backed persistence, cross-server synchronization, and a five-tier permission model. I designed the architecture to support Spigot 1.16.5 through 1.20.1, with version-specific NMS implementations for world border rendering and ProtocolLib integration for real-time GUI title updates.

Realm Interface Overview

0:00
/0:00
Main realm management interface where players navigate realm settings, member management, and world configuration through an inventory-based GUI

GUI System

Canvas-Based GUI Framework

I built a custom GUI framework from scratch on top of Spigot’s inventory system. The core abstraction is a Canvas, a personal viewport assigned to each player that manages GUI lifecycle, caching, and state transitions. Every GUI extends CharmGUIBase, which defines a four-phase rendering pipeline: initialization reads button layouts from YAML config, post-initialization injects dynamic data, rendering applies color parsing and placeholder replacement, and display handles the final presentation to the player.

flowchart TD
    subgraph Canvas["Canvas (Per-Player Viewport)"]
        Cache["GUI Cache"]
        State["GUI State"]
    end

    subgraph Handler["CharmGUIHandler"]
        Map["UUID → Canvas Map"]
    end

    subgraph Lifecycle["GUI Rendering Pipeline"]
        A["onCustomGUIInitialize()"] --> B["postCustomGUIInitialize()"]
        B --> C["rendCustomGUI()"]
        C --> D["onCustomGUIDisplay()"]
    end

    subgraph Factory["Button Factory"]
        BF["BaseButtonFactory"]
        WF["WorldCreateButtonFactory"]
    end

    subgraph Config["YAML Config"]
        Matrix["Matrix Layout"]
        Buttons["Button Definitions"]
    end

    Handler --> Canvas
    Canvas --> Lifecycle
    Config --> A
    Factory --> C

The GUI layout is entirely data-driven through YAML configuration files. Each GUI defines a matrix of characters where each character maps to a button definition with its item type, display name, lore, click actions, and sound effects. The BaseButtonFactory and WorldCreateButtonFactory handle button creation with support for multiple button types including LOCKED, UNLOCKED, INVENTORY, MANAGE_MEMBER, and WORLD_CREATE.

0:00
/0:00
Realm creation flow through the setup GUI, where players configure their new world step by step using the inventory-based interface

I also implemented a CrossRealmContainer that allows players to open and manage other players’ realm settings with proper permission validation. The TitleHandler uses ProtocolLib to send raw packets for dynamic GUI title updates without reopening the inventory.

Biome Presets and Custom World Generation

0:00
/0:00
Biome preset selection interface where players choose from predefined world templates before realm creation

I implemented a custom ChunkGenerator that works alongside a template-based world creation system. Players select from preconfigured biome presets through the GUI, and the system copies the corresponding world template to generate their realm. The FirstBorderShaped class handles initial border shape generation, creating the visual boundary that defines the playable area of each new realm.

Realm Creation and World Management

Asynchronous World Creation Pipeline

Realm creation runs entirely off the main server thread to prevent lag spikes. I built a RealmGeneratorManager that maintains a thread pool (3 to 5 threads) with a LinkedHashMap task queue for FIFO processing. Each RealmCreateTask handles world file copying, chunk generation, config YAML creation, game rule application, and border initialization. When a task completes, it fires a RealmFinishCreateEvent back on the main thread so other systems can react safely.

Realm Creation Console Log
Server console output during async realm creation, showing the thread pool processing world generation tasks in the background
flowchart LR
    A["Player Request"] --> B["RealmCreateEvent"]
    B --> C{"Cancelled?"}
    C -->|No| D["Add to Task Queue"]
    D --> E["Thread Pool Executor"]
    E --> F["Copy World Template"]
    F --> G["Generate Chunks"]
    G --> H["Apply Game Rules"]
    H --> I["Initialize Border"]
    I --> J["Write Realm Config"]
    J --> K["RealmFinishCreateEvent\n(Main Thread)"]
    C -->|Yes| L["Abort"]

World Border and Realm Boundary

Realm Boundary
Visual realm boundary rendered in game, defining the playable area for each player’s private world

I implemented a version-adaptive world border system that uses NMS (Net Minecraft Server) code for direct packet manipulation. The WBControl class detects the server version at runtime and delegates to the appropriate implementation, supporting 1.16.3 and above along with Arclight server forks. Players can upgrade their border level to expand their realm’s playable area, with configurable radius increments and upgrade costs. The system also supports hiding and showing the border effect, warning distance configuration, and border damage settings.

Player Management and Social Features

Permission Management and Player Settings

0:00
/0:00
Realm settings panel demonstrating player management, including adding, removing, and resetting player permissions with contextual help

I designed a five-tier permission hierarchy for realm access control:

RoleBuildInteractInviteBanPromoteFull Control
Owner
Operatorto Member
Member
Visitor
Banned

Each realm stores its member list, operator list, and banned player list. The GUI provides dedicated panels for member management (RealmGUIContentMember), banned player management (RealmGUIContentBanned), and role assignment (RealmGUIRoleAssign). All permission checks are enforced through an extensive listener system covering block placement, block breaking, entity interaction, item pickup, item dropping, and portal creation.

Cross-Realm Visiting and Social Features

0:00
/0:00
Teleporting to another player’s realm through the visit interface

I built a social layer on top of the realm system that includes a public realm browser, a flower-based rating system, popularity tracking, and a gift system. Realm owners can toggle their world’s visibility between public and private. Public realms appear in the visit GUI where other players can browse, rate, and teleport to them. The VisitStatistic class tracks visit metrics, and the rating system uses “flowers” as a like mechanism to rank realms by popularity.

Command System with Auto-Complete

0:00
/0:00
Command auto-complete in action, showing tab completion for realm management commands

The /realm command serves as the entry point for all realm operations. I implemented a full tab completion system that dynamically suggests subcommands, player names, and realm names based on context. Commands support operations like creating realms, inviting players, managing permissions, visiting other realms, and administrative functions. The command parser handles nested arguments such as /realm invite <player> from <owner> for cross-realm management.

Database and Cross-Server Architecture

I integrated MySQL with HikariCP connection pooling for persistent realm data storage. The database schema uses two main tables: SelfHomeMain_Users for realm data (owner, members, operators, settings, coordinates, ratings) and SelfHomeMain_Servers for server load tracking. All queries use prepared statements to prevent SQL injection.

flowchart TD
    subgraph Servers["BungeeCord Network"]
        S1["Server 1"]
        S2["Server 2"]
        S3["Server 3"]
    end

    subgraph Proxy["BungeeCord Proxy"]
        LB["Load Balancer"]
        MSG["Plugin Messaging"]
    end

    subgraph Database["MySQL + HikariCP"]
        Users["SelfHomeMain_Users"]
        Stats["SelfHomeMain_Servers"]
    end

    S1 <--> MSG
    S2 <--> MSG
    S3 <--> MSG
    MSG <--> LB
    S1 --> Database
    S2 --> Database
    S3 --> Database
    LB --> Stats

For cross-server support, I implemented BungeeCord plugin messaging with three message types: waitDelayToHome for delayed teleportation, waitToCommand for remote command execution, and waitToLoad for cross-server world loading. The system automatically balances realm creation across servers by tracking player counts and TPS (ticks per second) metrics, directing new realm creation to the least loaded server.

Design Philosophy

Data-Driven Configuration — Every aspect of the plugin is configurable through YAML files. GUI layouts use a matrix-based character mapping system. Realm settings, game rules, border parameters, and entity limits are all externalized. This allows server administrators to customize the entire experience without touching Java code.

Event-Driven Decoupling — The plugin uses over 30 specialized event listeners to handle world protection, player interactions, and realm management. Custom events like RealmCreateEvent and RealmFinishCreateEvent enable loose coupling between the creation pipeline and dependent systems. This architecture makes it straightforward to add new features without modifying existing code.

Async-First Performance — All heavy operations run off the main server thread. World generation uses a dedicated thread pool. Database queries go through HikariCP’s connection pool. Time synchronization runs asynchronously. This ensures the server maintains stable TPS even during peak realm creation periods.

Version-Adaptive Compatibility — Rather than targeting a single Minecraft version, I built abstraction layers that detect the runtime environment and delegate to version-specific implementations. The world border system, packet manipulation, and NMS access all adapt automatically across Spigot 1.16.5 to 1.20.1, including support for Arclight server forks.