Skip to main content

Local development stack

Everything runs in Docker, from dev/: PostgreSQL, Redis, server-service, Velocity 4.3.1 and Paper 26.3 with the GrayCore plugins mounted from target/. Connect with a Minecraft client to localhost:25565.

Quick start​

cd dev
./dev.sh up # Windows: .\dev.ps1 up (builds with Maven, then starts the stack)
./dev.sh logs paper # follow a service

Requirements: Docker, JDK 25 and Maven (the plugins are built on the host).

CommandWhat it does
upBuild, then start Velocity and one Paper server (dev-gens-1).
multiSame, plus a second Paper server (dev-gens-2) to test server switching, player locks and crashes.
reloadRebuild and restart Velocity and Paper to pick up new plugin jars.
psqlOpen a SQL shell on the dev database.
console <service> <command>Type a command in a server console, e.g. ./dev.sh console paper op YourName.
sampleRebuild only the RPG sample and restart only the first Paper, which is much faster than reload when only the sample changed (the proxy is not restarted: players have to reconnect to the server).
worldPut the world of DEV_WORLD in place of the Paper servers' world (the old one is kept as world-backup) and start Paper again.
logs [service]Follow the logs.
resetStop everything and wipe dev/data/ (the database is recreated by Liquibase on the next start).

Layout​

  • docker-compose.yml: the stack. Every value has a working default; copy .env.example to .env to override.
  • config/: committed templates, copied into the servers on first start (edits made in data/ are never overwritten). ${CFG_*} placeholders are filled from the compose environment.
  • data/: git-ignored persistent data (PostgreSQL, Redis, Paper and Velocity folders).
ServiceWhat it is
velocityThe proxy, the only one exposed (localhost:25565).
paper, paper-2The game servers dev-gens-1 and dev-gens-2 (the second with multi).
server-serviceThe registry of game servers.
postgres, redisThe shared storage.
resource-packsServes the resource packs published by the RPG sample on localhost:8088.

Testing on a real map​

Set DEV_WORLD to a world folder (one with level.dat), in dev/.env or in the environment. up and multi copy it into data/<server>/world when a server has no world yet, and ./dev.sh world replaces the existing one. The copy is made once: changes you make in the dev world do not go back to the source folder.

Browsing the world: BlueMap​

BlueMap runs on the first Paper server and draws the world in 3D, with the players moving on it, at http://localhost:8100. Its settings are in config/paper/plugins/BlueMap/core.conf (it accepts the download of the Minecraft client files it needs, and renders with 6 threads). Nothing is drawn until you ask:

./dev.sh console paper bluemap update world # the first render of a big map takes minutes; `bluemap` shows the progress

After that, BlueMap keeps the map up to date with the changes made in the world.

Zones for the dev map​

The templates in config/paper/plugins/ hold the zones of the RPG sample for the map used in DEV_WORLD (mmo_rpg_world), in the module's zones.yml, and their markers for BlueMap (BlueMap/maps/world.conf), so a reset does not lose them. They are built from the world's own data by dev/tools/map-zones:

cd dev/tools/map-zones && npm install
npm run build # scan the world, cut the land between the level tiers, write both templates

WORLD_DIR names another world folder (the world of the first Paper server by default). The tiers, their towns, levels and mobs are at the top of zones.mjs and regions.mjs. A server copies a template into data/ only when it is newer than the file there. After a build, delete data/paper/plugins/GrayCorePaper/modules/rpg-sample/zones.yml and data/paper/plugins/BlueMap/maps/world.conf, then restart the servers. Do not overwrite them from the host instead: the server then fails to start, with Operation not permitted.

Admin and debug mode​

The admin group (every plugin permission, including graycore.commands.debug) is created the first time a Paper server starts. Give it to yourself from the console, then use the commands in game:

./dev.sh console paper grayperms player add-group YourName admin

/debug on then shows how your profile is loaded and saved, and which servers the proxy considered when routing you. See Administration.

Notes​

  • The console helper runs mc-send-to-console as user 1000, as the image requires: docker compose exec paper mc-send-to-console ... without -u 1000 fails with "Exec needs to be run with user ID 1000".
  • Velocity runs in online mode: you need a real Minecraft account. Only Velocity is exposed, not the game servers.
  • Third-party plugins (FastAsyncWorldEdit, WorldGuard, PlaceholderAPI, TAB, BetterModel, BlueMap) are downloaded from Modrinth when a server starts. FastAsyncWorldEdit and WorldGuard are pinned to versions that work together: a newer pair once stopped WorldGuard, and GrayCorePaper with it. Move both at once, and check a server starts.
  • Paper and Velocity register through server-service: there are no static servers in velocity.toml.
  • ./dev.sh psql, then select name, lock, lock_expires_at from players;, shows which server owns which player.