Realty is a plugin for Paper Minecraft servers that allows you to put up WorldGuard regions for sale or lease. You can collect rent, hold auctions, create subregions to rent out to other players, and place offers on other players' regions through one simple interface.
- Paper 1.21.8+
- Java 21
- MariaDB/MySQL database to store region data
- Vault and a Vault-compatible economy
- WorldGuard amd WorldEdit (required)
- Essentials (optional)
From the repository root:
./gradlew :realty-paper:shadowJarInstall the JAR from realty-paper/build/libs/ whose name ends with -all.jar.
Other artifacts:
./gradlew :realty-paper-plan-extension:shadowJar
./gradlew :realty-areashop-importer:shadowJarPublished artefacts are hosted at https://maven.minecraftcitiesnetwork.com, split into
/releases and /snapshots — a version ending in -SNAPSHOT goes to the latter, everything
else to the former. Three modules are published; realty-paper itself is not.
repositories {
maven("https://maven.minecraftcitiesnetwork.com/releases")
}
dependencies {
compileOnly("io.github.md5sha256:realty-paper-api:1.4.1")
}| Artefact | Contents |
|---|---|
io.github.md5sha256:realty-backend-api |
Domain API: entities, result types, enums |
io.github.md5sha256:realty-backend |
Persistence and business logic |
io.github.md5sha256:realty-paper-api |
Paper-facing API; depends on the two above |
Most integrations only need realty-paper-api, which pulls the backend modules transitively.
Publishing runs from the Deploy Maven workflow on a published GitHub release, or by manual
dispatch. It reads the target URL and credentials from the MAVEN_REPOSITORY_URL,
MAVEN_REPOSITORY_USERNAME and MAVEN_REPOSITORY_PASSWORD repository secrets. Releases are
immutable: republishing a version that already exists fails with a 409, so bump the version in
buildSrc/src/main/kotlin/realty-conventions.gradle.kts instead.
| Module | Role |
|---|---|
realty-api |
Public API surface |
realty-common |
Shared logic and database access |
realty-paper |
Main Paper plugin |
realty-paper-plan-extension |
Optional Plan integration |
realty-areashop-importer |
Optional AreaShop migration helper |
realty-paper-adapters/chat-adapter |
Notification delivery to online players via chat |
realty-paper-adapters/essentials-adapter |
Notification delivery via EssentialsX mail |
realty-paper-adapters/player-notifications-adapter |
Notification delivery via PlayerNotifications |
realty-paper-adapters/query-service |
Private HTTP endpoint serving live WorldGuard geometry and player names to realty-rest |
The adapter modules are not bundled in the plugin jar. Each is published as its own jar; install
the ones you want by placing them in plugins/Realty/modules and restarting the server. Realty
delivers no notifications until at least one delivery module is installed, and logs a warning at
startup while none is.
player-notifications-adapter registers five notification categories with PlayerNotifications —
agents, auctions, offers, leases, and a general catch-all — each one a data type players switch on and
off in /notifications preferences.
You configure them in PlayerNotifications, not here. PlayerNotifications writes every category a
module registered into its generated categories-defaults.yml; copy the blocks you care about into its
categories.yml and edit them there. That is where a label, a description, or a regrouping of Realty's
data types into categories of your own takes effect.
The adapter's own config.yml
(plugins/Realty/modules/player-notifications-adapter/config.yml) holds one setting, expiry-days:
how long an enqueued notification stays in a player's inbox before PlayerNotifications expires it.
Realty also supplies a display name for each of its data types; rename one in PlayerNotifications'
type-names.yml if you want something different.
A Realty message key that no category claims still reaches players, routed to the general category.
essentials-adapter writes a config.yml into its data folder. Setting notifications-enabled: false
stops Realty notifications being delivered as EssentialsX mail — useful when another delivery module
already covers offline players and you do not want the same notification arriving twice. The module's
teleport-safety integration is not affected by the setting and always applies.
realty-rest runs outside the game server and can only read MariaDB, which holds neither
WorldGuard geometry nor player names. query-service answers for both from inside the server over a
private, secret-gated HTTP endpoint. Its config.yml (plugins/Realty/modules/query-service/config.yml):
| Key | Default | Meaning |
|---|---|---|
shared-secret |
(empty) | Required in every request's X-Realty-Secret header. Empty disables the endpoint rather than running it open; set the same value in realty-rest's REALTY_REST_MODULE_SECRET. |
bind-host |
127.0.0.1 |
Localhost by default. Widen only if realty-rest runs on another host, and put a reverse proxy (with TLS) in front if that crosses a network you do not control. |
port |
8123 |
|
request-timeout-ms |
1000 |
Geometry is read on the main thread and names are resolved through it too; a request that cannot get an answer within this budget returns 504. |
Routes (all require the secret; unversioned because both sides ship from this repository):
| Route | Answers |
|---|---|
GET /health |
{"status":"ok"} |
GET /regions/{worldId}/{regionId}/dimensions |
shape (CUBOID/POLYGONAL), minY, maxY, ordered footprint points — read live, never cached. 404 if WorldGuard has no such region. |
GET /players/{uuid}/name |
{"id","name"}, name null when unknown |
POST /players/names {"ids":[…]} |
{"players":[{"id","name"}]} in request order, unknowns kept with null name. At most 256 ids per request; more is 400 BATCH_TOO_LARGE. |
POST /players/uuids {"names":[…]} |
{"players":[{"id","name"}]} in request order, unknowns kept with null id. At most 256 names per request; more is 400 BATCH_TOO_LARGE. A body, not a query string, because Floodgate names like .Cool Guy 123 are not URL-safe. |
Names come from the server's own usercache first, so Bedrock/Floodgate players resolve; Mojang is
only consulted for a UUID the server has never seen. The same lookups are available in-process to
other plugins as the PlayerNameService Bukkit service.
/realty module reload query-service re-reads the config and restarts the endpoint. If the edited
config fails to read or the new server fails to start, the previous configuration keeps running and
the failure is logged. The reload runs on the main thread and waits for the HTTP server to drain, so
it can pause the tick for up to request-timeout-ms if a request is in flight when it happens.
For detailed setup instructions, visit the Installation Guide.
For player, staff, and server-owner guides, visit the GitHub wiki.