API Usage

This page provides examples and explanations for common Multiverse-Portals API usages. See the developer API starter for general Multiverse API conventions and the Javadocs for the complete API.

Adding Multiverse-Portals to your project

Replace VERSION with the Multiverse-Portals version used by your server.

Gradle

repositories {
    maven { url = "https://repo.onarandombox.com/content/groups/public/" }
}

dependencies {
    compileOnly 'org.mvplugins.multiverse.portals:multiverse-portals:VERSION'
}
md

Maven

<repositories>
    <repository>
        <id>onarandombox</id>
        <url>https://repo.onarandombox.com/content/groups/public/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>org.mvplugins.multiverse.portals</groupId>
        <artifactId>multiverse-portals</artifactId>
        <version>VERSION</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
xml

Also add Multiverse-Portals to softdepend or depend in your plugin.yml to ensure it loads before your plugin.

Obtaining the API instance

Using the singleton (recommended)

Note: this method will throw an IllegalStateException if the API is not loaded.

MultiversePortalsApi portalsApi = MultiversePortalsApi.get();
java

For an optional integration that might initialize before Multiverse-Portals, register a callback instead. The callback runs immediately if the API is already ready, or once initialization finishes otherwise:

MultiversePortalsApi.whenLoaded(portalsApi -> {
    PortalManager portalManager = portalsApi.getPortalManager();
    // initialize the integration
});
java

You can check the current state without throwing an exception:

if (MultiversePortalsApi.isLoaded()) {
    MultiversePortalsApi portalsApi = MultiversePortalsApi.get();
}
java

Using the Bukkit ServicesManager

RegisteredServiceProvider<MultiversePortalsApi> provider = Bukkit.getServicesManager().getRegistration(MultiversePortalsApi.class);
if (provider != null) {
    MultiversePortalsApi portalsApi = provider.getProvider();
}
java

Getting a portal by name

getPortal(String) returns null if no portal with that name exists.

MVPortal portal = portalsApi.getPortalManager().getPortal("spawn-hub");
if (portal != null) {
    // portal found
}
java

Getting a portal at a location

The following returns the portal a player is standing in, respecting their access permissions. Returns null if the player is not in any accessible portal.

MVPortal portal = portalsApi.getPortalManager().getPortal(player, player.getLocation());
if (portal != null) {
    // player is standing in a portal they can use
}
java

To check a location without a player (no permission check), use the location-only overload:

MVPortal portal = portalsApi.getPortalManager().getPortal(location);
java

Getting all portals

List<MVPortal> allPortals = portalsApi.getPortalManager().getAllPortals();

// Or only portals a specific player has access to:
List<MVPortal> accessiblePortals = portalsApi.getPortalManager().getPortals(player);
java

Creating a portal

A PortalLocation defines the axis-aligned bounding box of the portal region as two corner vectors inside a Multiverse world. The string format is WORLD:X,Y,Z:X,Y,Z. The API can register and inspect portals whose Multiverse world is currently unloaded.

PortalManager portalManager = portalsApi.getPortalManager();

// Parse a location from a world-prefixed string
PortalLocation location = PortalLocation.parseLocation("world:10,64,10:12,68,10");

MultiverseWorld mvWorld = MultiverseCoreApi.get().getWorldManager().getWorld("world").getOrNull();
if (mvWorld != null && location.isValidLocation()) {
    boolean added = portalManager.addPortal(mvWorld, "my-portal", "ServerOwner", location);
    if (added) {
        // portal successfully created
    }
}
java

Getting a portal's world

Use getMultiverseWorld() when the configured Multiverse world may be unloaded. Use getBukkitWorld() only when you need a live Bukkit World; it returns an empty Option while the world is unloaded.

portal.getMultiverseWorld().peek(mvWorld ->
        getLogger().info("Portal world: " + mvWorld.getName()));

portal.getBukkitWorld().peek(bukkitWorld ->
        getLogger().info("Loaded Bukkit world: " + bukkitWorld.getName()));
java

getWorld() and the LoadedMultiverseWorld portal constructor are deprecated and scheduled for removal in Multiverse 6. Use the optional world getters and the MultiverseWorld constructor instead.

Removing a portal

Pass true as the second argument to also remove the portal from portals.yml. Passing false removes it from memory only (useful for temporary changes during a reload).

MVPortal removed = portalsApi.getPortalManager().removePortal("my-portal", true);
if (removed != null) {
    // portal was removed
}
java

Editing portal properties

Setting the portal action

Since 5.2, portals support three built-in action types:

Action typeDescription
multiverse-destinationTeleport the entity to any Multiverse destination
commandExecute a command when an entity enters the portal
serverSend the player to a BungeeCord/Velocity server
// Teleport to a Multiverse destination
portal.setActionType("multiverse-destination");
portal.setAction("w:nether_world");

// Run a command (as player, or with "op:" / "console:" prefix)
portal.setActionType("command");
portal.setAction("say Hello %player%!");

// Send to a BungeeCord/Velocity server
portal.setActionType("server");
portal.setAction("lobby");
java

You can also set both at once using an ActionHandler obtained from the ActionHandlerProvider:

ActionHandlerProvider handlerProvider = portalsApi.getActionHandlerProvider();

handlerProvider.parseHandler("multiverse-destination", "e:world:0,64,0:0:0")
        .peek(handler -> portal.setActionHandler(handler))
        .onFailure(failure -> {
            // invalid action string
        });
java

Setting the portal owner

portal.setOwner("PlayerName");
String owner = portal.getOwner();
java

Toggling non-player teleportation

portal.setTeleportNonPlayers(true);  // also teleport mobs/vehicles
boolean teleportsEntities = portal.getTeleportNonPlayers();
java

Destination safety checking

portal.setCheckDestinationSafety(false); // skip safe-spawn check at destination
boolean checksSafety = portal.getCheckDestinationSafety();
java

Configuring portal messages

Each portal can send a message after a successful action or when a player lacks access. The values accept literal text, @disabled, @default, or @@<locale-key>. Literal and localized messages support {player} and {portal} replacements.

portal.setActionSuccessMessage("&aWelcome, {player}!");
portal.setNoPermissionMessage("@@myplugin.portal.denied");
java

Both setters return Try<Void>. See Configure Portal Messages for the complete value format. The global permission-message switch is also available through PortalsConfig:

PortalsConfig config = portalsApi.getPortalsConfig();
config.setSendNoPermissionMessages(false);
java

Using StringPropertyHandle

Since 5.1 you can get or set any portal property by its string name — handy for generic editors or config commands:

StringPropertyHandle handle = portal.getStringPropertyHandle();

// Set a property by name
handle.setPropertyString("teleport-non-players", "true");

// Get a property by name
handle.getPropertyString("owner").peek(value -> {
    // use value
});
java

Listening to MVPortalEvent

MVPortalEvent is fired (and cancellable) whenever a player is about to be teleported by a portal. Listen to it like any other Bukkit event:

@EventHandler
public void onPortalUse(MVPortalEvent event) {
    Player player = event.getTeleportee();
    MVPortal portal = event.getSendingPortal();

    if (portal != null && portal.getName().equals("vip-portal")) {
        if (!player.hasPermission("myplugin.vip")) {
            event.setCancelled(true);
            player.sendMessage("You need VIP rank to use this portal!");
        }
    }
}
java

Registering a custom action handler type

Since 5.2 you can extend ActionHandlerType to add your own portal action, such as opening a GUI or granting a reward.

1. Define the handler

public class RewardActionHandler extends ActionHandler<RewardActionHandlerType, RewardActionHandler> {

    private final String rewardId;

    public RewardActionHandler(RewardActionHandlerType type, String rewardId) {
        super(type);
        this.rewardId = rewardId;
    }

    @Override
    public Attempt<Void, ActionFailureReason> runAction(MVPortal portal, Entity entity) {
        if (entity instanceof Player player) {
            MyRewardPlugin.giveReward(player, rewardId);
        }
        return Attempt.success(null);
    }

    @Override
    public Message actionDescription(Entity entity) {
        return Message.of("Gives reward: " + rewardId);
    }

    @Override
    public String serialise() {
        return rewardId;
    }
}
java

2. Define the type

public class RewardActionHandlerType extends ActionHandlerType<RewardActionHandlerType, RewardActionHandler> {

    public RewardActionHandlerType() {
        super("reward");
    }

    @Override
    public Attempt<RewardActionHandler, ActionFailureReason> parseHandler(CommandSender sender, String action) {
        if (action.isEmpty()) {
            return Attempt.failure(ActionFailureReason.INSTANCE, Message.of("Please specify a reward ID."));
        }
        return Attempt.success(new RewardActionHandler(this, action));
    }
}
java

3. Register on plugin enable

@Override
public void onEnable() {
    ActionHandlerProvider handlerProvider = MultiversePortalsApi.get()
            .getActionHandlerProvider();

    handlerProvider.registerHandlerType(new RewardActionHandlerType());
}
java

Now portals can use action-type: reward and action: my-reward-id in their config.

Last update at: 2026/08/21 16:03:04