promotional bannermobile promotional banner

Dimension Bridge Velocity Plugin

DimensionBridge securely transfers players from Fabric command blocks to registered Velocity backend servers. It is server-side only, supports protocol-restricted destinations, and requires no client mod.

VELOCITY-PLUGIN

needs fabric-minecraft-mod on Minecraft side - Download here

DimensionBridge consists of a Velocity plugin and a matching server-side Fabric mod. A command block can issue an authorized transfer request through /dimensionbridge transfer. Velocity validates the source server, destination, player, client protocol, cooldown, and authorization window before connecting the player.

It is designed for portals, dimension gates, dimension travel, lobby menus, and other immersive server switching. Regular players do not need access to /server or any bridge permission.

So it is a secure way for player teleport from one server to a different one and you can also highly configure which "transport-routes" are available.

For example: A player can move from a lobby-server to any world-server. But from world-server-1 he can only get back to the lobby while from world-server-2 he can back to the lobby-server and to world-server-2a. Like this you can setup complex server structures.

An other filter option is that you can limit access to some servers depending on the Minecraft-protocol. So your lobby-server might be open to any Minecraft version, but it serves like a hub from which players can only connect to servers which suits their active Minecraft version.

Imagine a phone booth where you can enter and it only shows you the numbers which you actually can dial with the minecraft version. A different player with a differen versions sees other numbers.

The options are nearly endless and it is also a security feature, because even if a player gets some informations about your infrastructure and server-setup he will not be able to use the commands, because they are bound to mod / op - level, while normal portals use their commands on user - level.

Please let me know about your ideas to use this.

I got this idea when watching "Bill & Ted's Excellent Adventure" and wanted to have a secure way to switch between servers / timeperiods.

Greetings,

Jan

DimensionBridge – Installation, Configuration and Command Guide

1. Overview

DimensionBridge is a server-side-only bridge between Fabric backend servers and a Velocity proxy. It allows command blocks, the server console and suitably privileged command sources to transfer players to a registered Velocity server.

Players do not need access to Velocity's /server command or to any bridge permission. Protected destination servers can therefore be made accessible only through approved portals, telephone booths or other command-block contraptions.

Architecture

Minecraft client
       │
       ▼
Velocity proxy
└─ DimensionBridge Velocity plugin
       │  Channel: dimensionbridge:transfer
       ▼
Fabric backend
└─ DimensionBridge Fabric mod
   └─ Command block: dimensionbridge transfer <targets> <server>

No client-side mod is required.


2. Supported Versions

A separate JAR is built for every native Fabric server version:

1.20.1  1.20.2  1.20.3  1.20.4  1.20.5  1.20.6
1.21    1.21.1  1.21.2  1.21.3  1.21.4  1.21.5
1.21.6  1.21.7  1.21.8  1.21.9  1.21.10 1.21.11
26.1    26.1.1  26.1.2  26.2

Always use the Fabric JAR that exactly matches the native version of that backend server. The client version translated through ViaVersion is not relevant when selecting the backend JAR.

Runtime Java versions

Minecraft version Java
1.20.1–1.20.4 17
1.20.5–1.21.11 21
26.1–26.2 25
current Velocity plugin 25

3. Requirements

Velocity

  • a Velocity proxy;
  • Java 25;
  • every backend registered in velocity.toml;
  • optionally LuckPerms for permission management.

Fabric backends

  • Fabric Loader matching the Minecraft version;
  • Fabric API matching the Minecraft version;
  • the matching DimensionBridge Fabric JAR;
  • command blocks enabled in server.properties:
enable-command-block=true

A full server restart is required after changing server.properties.


4. Downloading Sourcecode

If you have interrest in participating, reach out for me.


5. Installing the Velocity Plugin

  1. Stop Velocity completely.
  2. Copy the Velocity JAR into:
velocity/plugins/dimensionbridge-velocity-<VERSION>.jar
  1. Start Velocity.
  2. The first start creates:
plugins/dimensionbridge/dimensionbridge.properties
  1. Edit the file. You can then reload it with /dimensionbridge reload.

The proxy console should contain a message similar to:

DimensionBridge loaded. Channel: dimensionbridge:transfer

6. Installing a Fabric Backend Mod

Repeat these steps for every backend server:

  1. Stop the backend completely.
  2. Copy the exact matching Fabric JAR into the mods directory.
  3. Ensure that Fabric API is installed.
  4. Keep only one DimensionBridge JAR in the mods directory.
  5. Start the backend.
  6. The first start creates:
config/dimensionbridge-fabric.properties
  1. Edit the file and restart the backend.

The backend console should contain a message similar to:

DimensionBridge backend <VERSION> loaded. Channel: dimensionbridge:transfer

The Fabric configuration currently has no reload command. Changes to dimensionbridge-fabric.properties require a backend restart.


7. Fabric Configuration

File:

config/dimensionbridge-fabric.properties

Lobby example:

allowed-destinations=hauptwelt,hardcore,vanilla

Game-server example, allowing only a return to the lobby:

allowed-destinations=lobby

Allow every syntactically valid target:

allowed-destinations=*

allowed-destinations

This is the local allowlist of the individual Fabric backend. A transfer payload is sent to Velocity only when the requested target is allowed here.

  • separate multiple names with commas;
  • names are normalized to lowercase;
  • names may contain lowercase letters, numbers, _ and -;
  • * allows every syntactically valid destination that Velocity subsequently accepts.

For security, use a narrow allowlist instead of * whenever possible.


8. Velocity Configuration

File:

plugins/dimensionbridge/dimensionbridge.properties

Complete example using the servers lobby, hauptwelt, hardcore and vanilla:

# Server names must exactly match velocity.toml.
# * allows every source or protocol.

initial-servers=lobby
deny-unlisted-targets=true
cooldown-ms=2500
authorization-window-ms=5000
bypass-permission=dimensionbridge.bypass

destinations=lobby,hauptwelt,hardcore,vanilla

destination.lobby.display-name=Lobby
destination.lobby.protected=false
destination.lobby.allowed-sources=*
destination.lobby.allowed-protocols=*

destination.hauptwelt.display-name=Main World
destination.hauptwelt.protected=true
destination.hauptwelt.allowed-sources=lobby
destination.hauptwelt.allowed-protocols=MINECRAFT_1_20

destination.hardcore.display-name=Hardcore
destination.hardcore.protected=true
destination.hardcore.allowed-sources=lobby
destination.hardcore.allowed-protocols=MINECRAFT_1_20

destination.vanilla.display-name=Vanilla
destination.vanilla.protected=true
destination.vanilla.allowed-sources=lobby
destination.vanilla.allowed-protocols=MINECRAFT_26_2

Global settings

initial-servers

Comma-separated list of servers permitted as initial proxy login servers.

initial-servers=lobby

deny-unlisted-targets

deny-unlisted-targets=true
  • true: servers not listed under destinations are denied;
  • false: unlisted servers remain outside DimensionBridge's protection rules.

Use true for a closed portal network.

cooldown-ms

Delay between two bridge requests from the same player:

cooldown-ms=2500

Allowed range: 0 to 60,000 milliseconds.

authorization-window-ms

Time window during which the Velocity connection request started by DimensionBridge remains authorized:

authorization-window-ms=5000

Allowed range: 500 to 60,000 milliseconds. The value should be longer than a normal proxy-to-backend connection attempt.

bypass-permission

Permission that bypasses all DimensionBridge protection checks:

bypass-permission=dimensionbridge.bypass

Grant it only to trusted administrators.

Destination definitions

Every entry in destinations needs four properties:

destinations=lobby,hauptwelt

destination.hauptwelt.display-name=Main World
destination.hauptwelt.protected=true
destination.hauptwelt.allowed-sources=lobby
destination.hauptwelt.allowed-protocols=MINECRAFT_1_20

display-name

Human-readable name used in player messages.

protected

  • true: entering the target requires a valid DimensionBridge authorization. Direct /server connections are denied unless the player has the bypass permission.
  • false: normal connections are allowed when the protocol rule matches.

The lobby should normally use protected=false so initial login and return travel remain reliable.

allowed-sources

Backend servers from which this destination may be requested:

destination.hauptwelt.allowed-sources=lobby

Multiple sources:

destination.hauptwelt.allowed-sources=lobby,hardcore

Every source:

destination.lobby.allowed-sources=*

allowed-protocols

Velocity client protocol names accepted by this destination:

destination.hauptwelt.allowed-protocols=MINECRAFT_1_20

Multiple protocols:

destination.hauptwelt.allowed-protocols=MINECRAFT_1_20,MINECRAFT_1_21

Every protocol:

destination.lobby.allowed-protocols=*

Minecraft 1.20 and 1.20.1 share the MINECRAFT_1_20 protocol group.

Use this command to obtain the exact Velocity name for a connected client:

/dimensionbridge protocol <player>

9. Permissions

dimensionbridge.admin

Allows a player to use DimensionBridge's administrative Velocity commands.

dimensionbridge.bypass

Bypasses destination, source, protocol and portal-authorization checks. Grant it only to trusted administrators.

velocity.command.server

Controls Velocity's normal /server command. It can be denied to regular players when transfers should only happen through portals:

/lp group default permission set velocity.command.server false

Administrators may retain it:

/lp group admin permission set velocity.command.server true

DimensionBridge does not require velocity.command.server.

Backend command permission

dimensionbridge transfer is available on Fabric only to the console, command blocks and sources with moderator/command level 2. Regular players cannot use it. Do not grant normal players operator or moderator rights.


10. Command Reference

Fabric backend

Transfer players

/dimensionbridge transfer <targets> <Velocity server name>

Omit the leading slash in command blocks:

dimensionbridge transfer @p hauptwelt

Examples:

# Nearest player
dimensionbridge transfer @p hauptwelt

# Nearest player within three blocks
dimensionbridge transfer @p[distance=..3,limit=1,sort=nearest] hauptwelt

# Every player inside a one-block-wide, three-block-high booth
dimensionbridge transfer @a[x=10,y=64,z=5,dx=0,dy=2,dz=0] hauptwelt

# Only players not tagged as being in combat
dimensionbridge transfer @a[x=10,y=64,z=5,distance=..2,tag=!inCombat] hauptwelt

# Return to the lobby
dimensionbridge transfer @p[distance=..3,limit=1,sort=nearest] lobby

Velocity

Help

/dimensionbridge
/db

Reload Velocity configuration

/dimensionbridge reload
/db reload

This reloads only the Velocity configuration.

Show active configuration

/dimensionbridge info
/db info

The output displays the configuration path and loaded destinations.

Show a client protocol

/dimensionbridge protocol
/dimensionbridge protocol <player>

When a player omits the name, the command displays that player's own protocol.


11. Basic Functional Test

Command block settings:

Impulse
Unconditional
Needs Redstone

Command:

dimensionbridge transfer @p[distance=..3,limit=1,sort=nearest] hauptwelt

Stand no more than three blocks from the command block and press the button.

To eliminate the radius as a possible cause:

dimensionbridge transfer @p hauptwelt

The command block's previous output should be similar to:

DimensionBridge: sent 1 transfer request(s) to 'hauptwelt'.

The current mod may display this message in German; the number and destination are the important parts.


12. Example: Lobby Telephone Booths

Booth to the main world

dimensionbridge transfer @p[distance=..3,limit=1,sort=nearest] hauptwelt

Booth to the hardcore world

dimensionbridge transfer @p[distance=..3,limit=1,sort=nearest] hardcore

Booth to the vanilla world

dimensionbridge transfer @p[distance=..3,limit=1,sort=nearest] vanilla

Return booth on every game server

dimensionbridge transfer @p[distance=..3,limit=1,sort=nearest] lobby

The Fabric allowlist on that backend must also permit the destination.


13. Example: Shimmer Effect and Countdown

Run once:

scoreboard objectives add dimensionTarget dummy
scoreboard objectives add dimensionTimer dummy

Main-world start button

Impulse block:

scoreboard players set @p[distance=..3,limit=1,sort=nearest] dimensionTarget 1

Following chain block:

scoreboard players set @p[distance=..3,limit=1,sort=nearest] dimensionTimer 60

60 ticks are approximately three seconds.

Repeating effect block

Repeating, unconditional, always active:

execute as @a[scores={dimensionTimer=1..}] at @s run particle minecraft:portal ~ ~1 ~ 0.3 0.8 0.3 0.1 10 force

Following chain blocks, all always active:

execute as @a[scores={dimensionTimer=1..}] at @s run particle minecraft:reverse_portal ~ ~1 ~ 0.45 0.9 0.45 0.08 5 force
execute as @a[scores={dimensionTimer=1..}] run title @s actionbar {"text":"Opening dimension …","color":"aqua","italic":true}
execute as @a[scores={dimensionTimer=60}] at @s run playsound minecraft:block.beacon.activate master @s ~ ~ ~ 0.8 0.7
execute as @a[scores={dimensionTimer=20}] at @s run playsound minecraft:block.respawn_anchor.charge master @s ~ ~ ~ 0.8 1.3

The transfer must run before timer value 1 is removed:

dimensionbridge transfer @a[scores={dimensionTimer=1,dimensionTarget=1}] hauptwelt

Then:

scoreboard players remove @a[scores={dimensionTimer=2..}] dimensionTimer 1
scoreboard players reset @a[scores={dimensionTimer=1}] dimensionTarget
scoreboard players reset @a[scores={dimensionTimer=1}] dimensionTimer

14. Example: Clickable Chat Menu with /trigger

Run once:

scoreboard objectives add dimension trigger
scoreboard objectives add dimensionTarget dummy
scoreboard objectives add dimensionTimer dummy

Enable the trigger for the player before displaying the menu:

scoreboard players enable @p[distance=..3,limit=1,sort=nearest] dimension

Example using the text-component syntax of a native Minecraft 1.20.1 lobby:

tellraw @p[distance=..3,limit=1,sort=nearest] [{"text":"☎ Select dimension\n","color":"gold","bold":true},{"text":"[ Main World ]","color":"green","clickEvent":{"action":"run_command","value":"/trigger dimension set 1"}},{"text":"\n"},{"text":"[ Hardcore ]","color":"red","clickEvent":{"action":"run_command","value":"/trigger dimension set 2"}},{"text":"\n"},{"text":"[ Vanilla ]","color":"aqua","clickEvent":{"action":"run_command","value":"/trigger dimension set 3"}}]

JSON text-component syntax may change between Minecraft releases. Use the syntax supported by the native version of the server executing the command block.

Store the selected target:

execute as @a[scores={dimension=1}] run scoreboard players set @s dimensionTarget 1
execute as @a[scores={dimension=2}] run scoreboard players set @s dimensionTarget 2
execute as @a[scores={dimension=3}] run scoreboard players set @s dimensionTarget 3
scoreboard players set @a[scores={dimension=1..3}] dimensionTimer 60
scoreboard players reset @a[scores={dimension=1..3}] dimension

Transfers at timer value 1:

dimensionbridge transfer @a[scores={dimensionTimer=1,dimensionTarget=1}] hauptwelt
dimensionbridge transfer @a[scores={dimensionTimer=1,dimensionTarget=2}] hardcore
dimensionbridge transfer @a[scores={dimensionTimer=1,dimensionTarget=3}] vanilla

15. Troubleshooting

The command block does nothing

Verify:

enable-command-block=true

Also:

  • set the block to Impulse, Unconditional, Needs Redstone;
  • ensure that the button powers the block;
  • enable and read the command block's previous output;
  • simplify the selector for testing:
dimensionbridge transfer @p hauptwelt

“Unknown or incomplete command”

Possible causes:

  • wrong Fabric JAR for the native Minecraft version;
  • DimensionBridge did not load;
  • Fabric API is missing;
  • the backend was not fully restarted after installation.

“Target is not locally allowed”

The destination is missing from:

config/dimensionbridge-fabric.properties

Example:

allowed-destinations=hauptwelt,hardcore,vanilla

Restart the backend afterwards.

“Unknown dimension identifier or destination”

The destination is missing from the Velocity destinations list or its destination property block is missing.

“Destination server is not registered in the proxy”

The server name does not exactly match its entry in velocity.toml.

“This portal may not select this destination”

The current backend is missing from destination.<target>.allowed-sources.

Version denied

Check the actual client protocol:

/dimensionbridge protocol <player>

Use the displayed constant in allowed-protocols.

Direct /server is denied

This is expected for targets with protected=true. Use the portal or deliberately grant dimensionbridge.bypass to an administrator.

Configuration changes are not applied

  • Velocity configuration: /dimensionbridge reload
  • Fabric configuration: full backend restart

No payload reaches Velocity

Verify that:

  • the selected player is currently connected to the sending backend;
  • matching DimensionBridge generations are installed on proxy and backend;
  • both sides use the channel dimensionbridge:transfer;
  • no old TelephoneBridge or duplicate DimensionBridge JAR remains installed.

16. Recommended Security Configuration

Velocity:

deny-unlisted-targets=true

Game worlds:

destination.hauptwelt.protected=true
destination.hardcore.protected=true
destination.vanilla.protected=true

Lobby:

destination.lobby.protected=false

LuckPerms:

/lp group default permission set velocity.command.server false

Keep Fabric allowlists narrow:

# Lobby
allowed-destinations=hauptwelt,hardcore,vanilla
# Game worlds
allowed-destinations=lobby

17. Updating

  1. Stop the proxy and all backends.
  2. Remove the old DimensionBridge JARs.
  3. Install the new Velocity JAR.
  4. Install the JAR matching each backend's exact native Minecraft version.
  5. Never load two DimensionBridge versions at the same time.
  6. Back up the configuration files.
  7. Restart proxy and backends.
  8. Test /dimensionbridge info and one basic command-block transfer.

The Dimension Bridge Velocity Plugin Team

profile avatar
Donate

More from jborkenhagen

  • Dimension Bridge project image

    Dimension Bridge

    DimensionBridge securely transfers players from Fabric command blocks to registered Velocity backend servers. It is server-side only, supports protocol-restricted destinations, and requires no client mod.

    • 64
    • July 26, 2026
  • Dimension Bridge project image

    Dimension Bridge

    DimensionBridge securely transfers players from Fabric command blocks to registered Velocity backend servers. It is server-side only, supports protocol-restricted destinations, and requires no client mod.

    • 64
    • July 26, 2026