1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
LunaticChat is a Minecraft chat plugin supporting Paper, Folia, and Velocity servers. It provides direct messaging, channel chat, romaji-to-Japanese conversion, and cross-server global chat via Velocity proxy.
- **Language**: Kotlin (JVM 25)
- **Build**: Gradle 9+ with Kotlin DSL
- **Tooling**: mise (Java zulu-25, Bun 1.3.11)
## Common Commands
### Build
```bash
./gradlew clean build # Full build
./gradlew :platform-paper:shadowJar # Paper/Folia plugin JAR
./gradlew :platform-velocity:shadowJar # Velocity plugin JAR
```
### Test
```bash
./gradlew test # Run all tests
./gradlew :engine:test # Run engine tests only
./gradlew :platform-paper:test # Run paper tests only
./gradlew :platform-paper:test --tests "*ChannelManagerTest" # Single test class
```
### Lint
```bash
./gradlew ktlintCheck # Check style
./gradlew ktlintFormat # Auto-format
```
### Debug Server (Docker)
```bash
./x start # Velocity + 2 Paper servers
./x folia start # Single Folia server
./x rcon s1 # RCON console to Paper s1
./x help # All available commands
```
## Architecture
### Module Structure
```
engine/ → Platform-agnostic core (models, converters, protocol, exceptions)
platform-paper/ → Paper & Folia plugin (commands, listeners, config, services)
platform-velocity/ → Velocity proxy plugin (message relay between servers)
dokka/ → API documentation aggregator (no Kotlin source)
docs/ → VitePress documentation site
```
**Dependency flow**: `platform-paper` and `platform-velocity` both depend on `engine`. The engine has no Minecraft platform dependencies.
### Key Architectural Patterns
**Service Container** (`platform-paper`): All services are held in an immutable `ServiceContainer` data class. `ServiceInitializer` handles initialization order and conditional feature setup. Optional features (channel chat, Velocity integration, Japanese conversion) are nullable fields.
**Feature Gating**: Features are toggled via `config.yml`. The `ServiceInitializer` conditionally creates services based on config, and the `ServiceContainer` holds them as nullable properties.
**Plugin Messaging Protocol**: Cross-server communication uses a custom `PluginMessageCodec` in the engine module. Paper servers encode/decode messages via this codec, and Velocity relays them between servers.
### Key Packages (engine)
| Package | Purpose |
|---------|---------|
| `chat.channel` | Channel data model and validation |
| `converter` | Google IME API client for romaji conversion |
| `exception` | Custom exception hierarchy (23 types) |
| `protocol` | Plugin messaging codec for Velocity communication |
| `settings` | Player settings models with UUID serialization |
### Key Packages (platform-paper)
| Package | Purpose |
|---------|---------|
| `chat.handler` | DirectMessage, ChannelMessage, ChannelNotification handlers |
| `command` | Command registration and execution |
| `config` | YAML config loading via KAML |
| `i18n` | Language support (EN, JA) |
| `listener` | Event listeners (chat, join/quit, plugin messages) |
| `velocity` | Cross-server integration |
## Code Conventions
- Follows [Kotlin Coding Conventions](https://kotlinlang.org/docs/coding-conventions.html), enforced by Ktlint
- PRs must pass `./gradlew ktlintCheck`
- Tests use JUnit 5 + MockK; coroutine tests use `kotlinx-coroutines-test`
- Shadow JAR output: `LunaticChat-{version}.jar` (Paper), `LunaticChat-{version}-velocity.jar` (Velocity)
- Serialization uses kotlinx-serialization with KAML for YAML config files
|