Architecture Overview

This document describes the system architecture of Pilaf, a YAML story-driven testing framework for Minecraft plugins.

System Overview

Pilaf follows a layered architecture with clear separation of concerns:

┌─────────────────────────────────────────────────────────────────────┐
│                      Pilaf TEST FRAMEWORK                           │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌───────────────────────────────────────────────────────────────┐ │
│  │                    TEST LAYER (YAML Stories)                   │ │
│  │  ┌──────────────────────┐  ┌──────────────────────┐           │ │
│  │  │ Story Files          │  │ Configuration Files  │           │ │
│  │  │ • test-*.yaml        │  │ • pilaf.yaml         │           │ │
│  │  │ • *.yaml             │  │ • config-*.yaml      │           │ │
│  │  └──────────┬───────────┘  └──────────┬───────────┘           │ │
│  └─────────────┼─────────────────────────┼───────────────────────┘ │
│                │                         │                         │
│                ▼                         ▼                         │
│  ┌───────────────────────────────────────────────────────────────┐ │
│  │                   ORCHESTRATION LAYER                          │ │
│  │  ┌──────────────────────┐  ┌──────────────────────┐           │ │
│  │  │ TestOrchestrator     │  │ YamlStoryParser      │           │ │
│  │  │ (Timeline Replay)    │  │ (YAML DSL Parser)    │           │ │
│  │  │ • Story execution    │  │ • Parse YAML stories │           │ │
│  │  │ • Action sequencing  │  │ • Create Action objs │           │ │
│  │  │ • Result aggregation │  │ • Validation         │           │ │
│  │  └──────────┬───────────┘  └──────────┬───────────┘           │ │
│  └─────────────┼─────────────────────────┼───────────────────────┘ │
│                │                         │                         │
│                ▼                         ▼                         │
│  ┌───────────────────────────────────────────────────────────────┐ │
│  │                     BACKEND LAYER                              │ │
│  │  ┌──────────────┐  ┌──────────────┐  ┌────────────────────┐   │ │
│  │  │ PilafBackend │◀─┤ Backend      │  │ PilafBackendFactory│   │ │
│  │  │ (Interface)  │  │ Factory      │  │ (creates backends) │   │ │
│  │  │ • Player ops │  │ • Config mgmt│  │ • Backend selection│   │ │
│  │  │ • Entity ops │  │ • Creation   │  │ • Initialization   │   │ │
│  │  │ • Server cmds│  │ • Validation │  │ • Dependency inject │   │ │
│  │  └──────┬───────┘  └──────────────┘  └────────────────────┘   │ │
│  │         │                                                       │ │
│  │         ├─────────────────┬─────────────────┬────────────────┐  │ │
│  │         ▼                 ▼                 ▼                │  │ │
│  │  ┌──────────────┐  ┌──────────────┐  ┌────────────────────┐   │ │ │
│  │  │ Mineflayer   │  │ HeadlessMc   │  │ Docker/RCON        │   │ │ │
│  │  │ Backend      │  │ Backend      │  │ Backend            │   │ │ │
│  │  │ • Player sim │  │ • Self-cont. │  │ • Server commands  │   │ │ │
│  │  │ • HTTP API   │  │ • CI/CD opt  │  │ • RCON protocol    │   │ │ │
│  │  │ • Bridge     │  │ • Auto-launch│  │ • Full server acc  │   │ │ │
│  │  └──────┬───────┘  └──────┬───────┘  └──────────┬───────────┘   │ │ │
│  └───────────────────────────┼─────────────────────┼───────────────┘ │ │
│                              │                     │                  │ │
└──────────────────────────────┼─────────────────────┼──────────────────┘
                               │                     │
                               ▼                     ▼
┌──────────────────────────────────────────────────────────────────────┐
│                      COMMUNICATION LAYER                              │
│                                                                       │
│  ┌───────────────────────┐          ┌──────────────────────────────┐ │
│  │      RconClient       │          │  MineflayerBridge (Node.js)  │ │
│  │    (Java, TCP)        │          │  HTTP/WebSocket Server       │ │
│  │    Port: 25575        │          │  Port: 3000                  │ │
│  └───────────┬───────────┘          └───────────┬──────────────────┘ │
│              │                                  │                    │
│              │                                  │                    │
│              │                                  ▼                    │
│              │                  ┌──────────────────────────────┐    │
│              │                  │  PilafMineflayerClient       │    │
│              │                  │  (Java HTTP Client)          │    │
│              │                  │  • REST API calls            │    │
│              │                  │  • JSON responses            │    │
│              │                  └───────────────┬──────────────┘    │
│              │                                  │                    │
└──────────────┼──────────────────────────────────┼────────────────────┘
               │                                  │
               ▼                                  ▼
┌──────────────────────────────────────────────────────────────────────┐
│                     MINECRAFT SERVER LAYER                            │
│                                                                       │
│  ┌────────────────────────────────────────────────────────────────┐  │
│  │  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────┐  │  │
│  │  │ PaperMC Server   │  │ RCON Interface   │  │ Minecraft    │  │  │
│  │  │ (Docker/Local)   │  │ Port: 25575      │  │ Game Port:   │  │  │
│  │  │ • Version 1.20.4+│  │ • Command exec   │  │ 25565        │  │  │
│  │  │ • Plugins        │  │ • Query support  │  │ • Multiplayer│  │  │
│  │  │ • World data     │  │ • Auth required  │  │ • Player act │  │  │
│  │  └──────────────────┘  └──────────────────┘  └──────────────┘  │  │
│  │                                                                   │  │
│  └──────────────────────────────────────────────────────────────────┘  │
│                                                                       │
└───────────────────────────────────────────────────────────────────────┘

Source Code Structure

Main Application Layer

src/main/java/org/cavarest/pilaf/
├── cli/                          # Command Line Interface
│   ├── PilafCli.java             # Main CLI entry point
│   ├── ConfigLoader.java         # Configuration file loader
│   └── StoryDiscoverer.java      # Story file discovery
├── orchestrator/                 # Test Orchestration
│   ├── TestOrchestrator.java     # Main orchestration logic
│   └── StoryExecutor.java        # Story execution engine
├── parser/                       # YAML Parsing
│   └── YamlStoryParser.java      # YAML story parser
├── backend/                      # Backend Abstraction
│   ├── PilafBackend.java         # Backend interface
│   ├── PilafBackendFactory.java  # Backend factory
│   ├── MineflayerBackend.java    # Mineflayer implementation
│   ├── HeadlessMcBackend.java    # HeadlessMc implementation
│   ├── DockerServerBackend.java  # Docker backend
│   └── RconBackend.java          # RCON backend
├── config/                       # Configuration Management
│   ├── TestConfiguration.java    # Configuration model
│   └── ConnectionManager.java    # Connection handling
├── model/                        # Data Models
│   ├── Action.java               # Action model
│   ├── Assertion.java            # Assertion model
│   ├── TestStory.java            # Story model
│   └── TestResult.java           # Result model
├── report/                       # Reporting
│   ├── TestReporter.java         # Main reporter
│   └── HtmlReportGenerator.java  # HTML report generation
├── rcon/                         # RCON Protocol
│   └── RconClient.java           # RCON protocol implementation
├── client/                       # Client Communication
│   └── MineflayerClient.java     # Mineflayer HTTP client
└── testing/                      # Testing Framework
    └── BackendConsistencyTester.java

Backend Implementations

Docker Backend

The Docker backend launches a PaperMC server in a Docker container and communicates via RCON.

  • Container Image: itzg/minecraft-server:java21

  • RCON Port: 25575

  • Minecraft Port: 25565

  • Network: Custom bridge network (172.20.0.0/16)

backend:
  type: docker
docker:
  server_image: "itzg/minecraft-server:java21"
  network_name: "pilaf-network"

Mineflayer Backend

The Mineflayer backend uses a Node.js bridge server to control a headless Minecraft client.

  • Runtime: Node.js 16+

  • Framework: Express.js

  • Library: Mineflayer v4.33.0

  • Communication: HTTP/REST API on port 3000

backend:
  type: mineflayer
client:
  host: "localhost"
  port: 3000

HeadlessMc Backend

The HeadlessMc backend is a self-contained Java implementation for CI/CD environments.

  • Runtime: Java 21

  • Server Management: Self-contained PaperMC launcher

  • RCON: Fallback mechanism for server commands

  • CI/CD: Optimized for GitHub Actions

backend:
  type: headlessmc
server:
  minecraft_version: "1.20.4"

Key Design Patterns

1. Backend Abstraction Pattern

Pilaf uses an interface-based backend system with factory pattern:

public interface PilafBackend {
    void initialize() throws Exception;
    void cleanup() throws Exception;
    String getType();
    // Core action methods...
}

public class PilafBackendFactory {
    public static PilafBackend create(String type, String... args) {
        switch (type.toLowerCase()) {
            case "mineflayer": return new MineflayerBackend(...);
            case "headlessmc": return new HeadlessMcBackend(...);
            case "docker": return new DockerServerBackend(...);
            default: throw new IllegalArgumentException("Unknown backend: " + type);
        }
    }
}

2. YAML Story DSL Design

Pilaf uses a declarative YAML format with structured action definitions:

name: "Test Story"
setup:
  - action: "execute_rcon_command"
    command: "op test_player"
steps:
  - action: "give_item"
    player: "test_player"
    item: "diamond_sword"
    count: 1
cleanup:
  - action: "execute_rcon_command"
    command: "deop test_player"

3. Multi-Layer Communication

Pilaf separates communication layers for different use cases:

  • RCON: Direct server commands (reliable, fast)

  • HTTP/WebSocket: Player simulation (realistic, event-driven)

  • Local API: Development and testing

Data Flow

  1. Story Loading: YAML → Parser → Action objects

  2. Action Execution: Orchestrator → Backend → Communication → Server

  3. State Management: Actions → Variables → Storage → Retrieval

  4. Result Aggregation: Actions → Results → Reporter → Output

State Management

Pilaf provides centralized state management with variable storage:

public class TestOrchestrator {
    private Map<String, Object> storedStates = new HashMap<>();

    public void storeState(String variableName, Object value) {
        storedStates.put(variableName, value);
    }

    public Object getState(String variableName) {
        return storedStates.get(variableName);
    }
}

This enables complex test scenarios with state comparison and dynamic test flow based on runtime state.

Error Handling Strategy

  • Graceful Degradation: Fallback mechanisms for backend limitations

  • Comprehensive Logging: Detailed logs for debugging and analysis

  • Health Monitoring: Service availability checking and reporting

Next Steps


Back to top

Copyright © 2025 Pilaf Contributors. Open source under the MIT license.

This site uses Just the Docs, a documentation theme for Jekyll.