Saltar al contenido principal

Proxy Networks (BungeeCord / Waterfall / Velocity)

ResourcePackManager runs on proxy networks. The backend plugin runs on every backend, a separate proxy plugin (Velocity OR BungeeCord, never both) runs on the proxy. The two pieces find each other automatically via the shared plugins/floodgate/key.pem file.

What the Proxy Plugin Does

The proxy plugin's job is Bedrock pack merging and delivery. On a network with several backends, each backend produces its own Bedrock pack (the converted version of its merged Java pack). The proxy plugin:

  1. Polls each backend's small HTTP server every 5 seconds for /bedrock.zip and /mappings.json, using If-Modified-Since so unchanged files cost roughly zero bandwidth.
  2. Waits for the inbox state to stabilize across two consecutive polls.
  3. Merges every backend's Bedrock pack into a single network-wide pack.
  4. Copies the merged Geyser custom-mappings file into plugins/Geyser-*/custom_mappings/ on the proxy.
  5. Serves the merged pack to Bedrock clients on connect via Geyser's SessionLoadResourcePacksEvent.

The proxy plugin is only useful for Bedrock players. Java pack delivery on networks still happens per-backend through the regular setResourcePack / addResourcePack API — Java clients see whichever backend's pack the backend they're on chose to send. If your network is Java-only, you don't need the proxy plugin.

Setup — Two Steps

Step 1: Install Floodgate on the proxy and on every backend

Floodgate is required for Bedrock players to authenticate on the proxy. RSPM piggybacks on Floodgate's plugins/floodgate/key.pem to derive the network identity — that file must be byte-for-byte identical on the proxy AND on every backend. Floodgate already requires this for Bedrock auth, so if Bedrock players currently work across your network, this is already done.

If you don't have Floodgate yet, install it on every component, then copy one canonical key.pem to every other component before continuing.

Step 2: Copy the matching proxy jar from any backend

After the backend RSPM has booted at least once, look in:

plugins/ResourcePackManager/proxy-extension/

That folder will contain:

ResourcePackManager-Velocity.jar
ResourcePackManager-BungeeCord.jar
README.md (plus 9 translated README files)

The backend extracts both jars on every boot regardless of detected topology, so they're always available. Copy exactly one to your proxy's plugins/ folder:

Proxy softwareUse this jar
VelocityResourcePackManager-Velocity.jar
BungeeCordResourcePackManager-BungeeCord.jar
Waterfall (Bungee fork)ResourcePackManager-BungeeCord.jar

Don't install both — only the matching one. Installing both will cause boot errors on whichever platform tries to load the wrong one.

Restart the proxy. That's it.

There is intentionally no config to edit and no key to paste. The proxy plugin reads plugins/floodgate/key.pem on the proxy at boot and derives the network identity from it. Since Floodgate already requires that file to be the same on every backend and on the proxy, the derived key matches every backend's automatically.

First merge typically completes within ~10 seconds of all backends being up.

Verifying It Works

Proxy console

Within ~10 seconds of restart (assuming backends are running) you should see:

[ResourcePackManager] Network-key auto-derived from Floodgate key.pem ✓
[ResourcePackManager] NetworkSync starting (poll interval 5000 ms, ...)
[ResourcePackManager] Merged pack ready at .../merged/Bedrock.zip (sha1 ...)
[ResourcePackManager] Geyser mappings deployed to .../custom_mappings
[ResourcePackManager] ✔ Network resource pack is now ready (... KB, sha1ABCD1234)

/rspm status on the proxy

Prints a snapshot: backend list, per-backend per-path fetch outcomes (200 / 304 / 404 / CONNECT_FAILED), consecutive-empty-poll counter, current merged pack path + size, network-http-offset, and Floodgate / Geyser presence on the proxy. Requires resourcepackmanager.command.status or resourcepackmanager.*. Console always has both; grant one to players via your permission plugin if you want them to run it. The output reveals no secrets (network key is masked, no auth tokens), so liberal grants are safe.

/rspm status on a backend

The Deploy mode line should read network-backend. The Network key line should show a masked key (last 4 chars visible) — match it against the proxy's masked key to confirm both sides agree.

Bedrock client

Connect via Bedrock. You should see the resource-pack download prompt before reaching the world. Custom items render with their intended models instead of plain armor stands.

Configuration Reference

Backend plugins/ResourcePackManager/config.yml

Network mode is auto-detected — there's no networkMode: true flag to set. Detection signals (any one is sufficient):

  1. Floodgate present, Geyser-Spigot absent — strongest signal for the Bedrock-via-proxy case.
  2. spigot.yml: settings.bungeecord: true — legacy BungeeCord / Waterfall IP-forwarding switch.
  3. paper-global.yml: proxies.velocity.enabled: true — modern Velocity forwarding.

The only knob that matters specifically for network mode is networkHttpOffset-v2, which controls the HTTP port the proxy will poll on each backend. Default 1 works on virtually all hosting. See Self-hosting for the full port-resolution story.

Proxy plugins/ResourcePackManager/config.yml

The proxy plugin writes a minimal default config on first boot:

# Force clients to accept the pack (kick on decline). Default: false.
force-resource-pack: false

# Offset added to each backend's Minecraft port to derive the HTTP port
# this proxy will hit for /bedrock.zip and /mappings.json. Default 1.
# Must match each backend's networkHttpOffset-v2.
network-http-offset-v2: 1

There is intentionally no network-key entry — that was retired pre-release because manual paste was a major source of misconfiguration (typos silently broke the proxy↔backend link). The key is auto-derived from plugins/floodgate/key.pem.

Stability and Merge Cadence

The proxy waits for the inbox state to stabilize across two consecutive polls before merging. With the default 5 s poll interval that means the first merge happens ~10 s after the proxy can see at least one backend producing content. Subsequent merges only re-zip when the SHA-1 set of inbox files changes, so a long quiet period costs roughly nothing.

Direct Fetch vs Relay Fallback

The default path is direct fetch: the proxy makes an HTTP GET to http://<backend-host>:<mcPort + offset><path> for each backend.

If the proxy can't reach a backend's HTTP port directly (typical of shared / managed Minecraft hosting where MC ports are exposed but adjacent ports are firewalled), the backend pushes its bedrock.zip and mappings.json to a relay endpoint on magmaguy.com under the network's namespace (derived from the Floodgate key). The proxy lists and downloads from the relay when direct fetch fails hard.

Both paths feed into the same merge step, so the operator never has to choose — direct fetch is preferred (zero bandwidth cost to magmaguy.com), relay kicks in transparently when needed.

The relay has a 30-minute TTL on the server side. Backends push every 25 minutes to keep the entry alive; clean shutdown drops the entry immediately rather than waiting for TTL.

Troubleshooting Common Issues

"Floodgate key.pem missing" on proxy boot

The proxy plugin couldn't find plugins/floodgate/key.pem and idled. RSPM cannot link to any backend without it.

Fix: install Floodgate on the proxy, then make sure plugins/floodgate/key.pem on the proxy is byte-for-byte identical to the same file on every backend. Floodgate auto-generates different keys per install by default — copy one canonical key.pem from any backend to every other component, restart everything.

"No merged pack content" warning after ~20 seconds

After 4 consecutive empty poll cycles, the proxy logs a one-shot multi-line warning listing every backend it polled, the URL it tried, and the outcome. The warning explains the most common fixes:

  • CONNECT_FAILED on every backend — the proxy can't reach the backend HTTP port at all. Check that the address in velocity.toml / config.yml is one the proxy can actually reach (not a Docker-internal name that doesn't resolve from the proxy's network), and that mcPort + networkHttpOffset-v2 is open between proxy and backend. If you have no way to open that port (managed hosting), see the relay fallback section above — the backend should be uploading to the relay automatically.
  • NOT_FOUND_404 on every backend — backends are up but not producing a Bedrock pack. Run /rspm status on each backend; the Bedrock Pack diagnostic block will tell you why (most often: no items definitions in the merged pack, or the first mix cycle hasn't completed yet).

The warning fires once per stuck period. An NetworkSync: recovered line is logged when at least one backend starts returning content again.

Bedrock players see no custom models on first proxy boot

Geyser registers its custom-item table at proxy startup only. If the proxy started before any backend produced a Bedrock pack, Geyser is running with an empty mappings table and stays that way for the rest of the session.

Fix: restart the proxy once after the backend has logged its first Merged Bedrock pack published line. RSPM pre-deploys the previous run's mappings on every proxy boot, so this only ever bites on a brand-new install — subsequent boots have something ready before Geyser scans.

"Duplicate bedrock_identifier" warnings on proxy boot

Two backends emitted the same Bedrock identifier for the same base item. Last-writer-wins; harmless if you only need one backend to provide that item. If both backends should host distinct custom items under the same base item, rename one of the source Java models so the auto-generated hashes differ.

Bedrock player connected but doesn't see the pack

The proxy fires a chat banner to all online Java players when a Bedrock session loads without a usable RSPM pack:

⚠ [RSPM] Bedrock player Alice connected before the resource pack was ready — they're seeing plain armor stands instead of custom models. Tell them to disconnect and reconnect; the pack will load on their next session. (Cause: ...)

The Bedrock player themselves also gets a modal popup, and the proxy console gets a banner. If you need to dig deeper, enable the debug stream (available on both Velocity and BungeeCord):

/rspm debug bedrock on

That turns on verbose [RSPM-BedrockDebug] log lines from GeyserBinder. Reproduce the issue, then turn it off:

/rspm debug bedrock off

The setting resets to off on proxy restart so it can't accidentally be left on.

Updating RSPM on a Network

After bumping the backend RSPM jar, also re-copy the matching proxy jar from plugins/ResourcePackManager/proxy-extension/ on any backend to the proxy and restart the proxy. The backend regenerates these jars on every boot so they're always in sync with the backend version.

What's Not Yet Supported

  • Java packs on networks via the proxy plugin. Java clients receive packs from each backend directly through the regular API. There is no proxy-side Java-pack mixer.
  • Cross-backend Java pack merging. Each backend's Java pack is independent. If a player switches backends, they receive the new backend's pack.
  • Live reconfigure of the network key. The key is bound to Floodgate's key.pem. Changing it requires restarting the proxy AND every backend (which is what you'd do when rotating the Floodgate key anyway).