Plugin Architecture
How the flagship is layered — services over repositories over jOOQ — and the cross-cutting concerns that shape every feature.
Medieval Factions has a consistent internal shape, and once you have seen one feature you have seen them all. This map describes that shape.
The three layers
- Commands parse player input and delegate immediately.
- Services own the in-memory state and the business rules — Service Layer.
- Repositories are interfaces that hide storage — Repository Pattern — implemented against jOOQ Persistence.
A new feature is almost always: a data class, an ID value class (Value Class Identifier), a repository interface, a jOOQ implementation, a service, and a command.
Cross-cutting concerns
- Optimistic Locking — every mutable record carries a version; a stale write is rejected rather than silently overwriting.
- Main Thread Safety — Bukkit state is not thread-safe, so anything doing I/O must snapshot on the main thread and act off it.
- Faction Events — the plugin fires cancellable Bukkit events, which is the supported extension point for other plugins.
- Legacy Data Migration — flat files from version 4 are read once and written into the database.
- Spatial Value Types — the
areapackage's world-UUID records, which are what makes a position storable and safe to carry off the main thread. - Player Interaction Status — the per-player mode that lets a command take a block as an argument, by consuming the player's next click.
Where to attach
If you are writing an Expansion Plugin, the seams that matter are Faction Events (react to things) and the Service Layer (read and change things). If you are integrating an external system, look at how Notification and Map Integration define an interface and swap in an implementation at startup — that is the pattern to copy.