🛖
Fox Hut
  • Introduction
    • Setting up
    • CommandActor, @Command and @Subcommand
    • Creating your first command
    • Improving our greet command
  • Platforms
    • Bukkit / Spigot / Paper
    • BungeeCord
    • Velocity
    • Sponge
    • Fabric
    • Brigadier
    • Minestom
    • JDA
    • Command line
  • How-to
    • Creating variants of /teleport
    • Custom parameter types
    • Suggestions and auto-completion
    • Context parameters
    • Command permissions
    • Parameter validators
    • Command conditions
    • Response handlers
    • Cooldowns
    • Help commands
    • Annotation replacers
    • Orphan command
    • Exception handling
    • Hooks
    • Dependency injection
    • Visitors
    • Customizing the dispatcher and failure behavior
Powered by GitBook
On this page
  • Creating variants of /teleport
  • /teleport <x> <y> <z>
  • /teleport <target> <x> <y> <z>
  • /teleport <target> here
  • /teleport <to>

Was this helpful?

Edit on GitHub
  1. How-to

Creating variants of /teleport

This page will explain how we can use Lamp to create multiple variants of the /teleport command

The /greet command we built in the last section was relatively simple, and enough to showcase basic command creation in Lamp.

In this section, however, we will build more complicated commands that simulate real-life cases. Tons of fun awaits us!

Creating variants of /teleport

The /teleport command in Minecraft is a good example of a multi-functional command. In these examples, we will build the following:

  • /teleport <x> <y> <z>

  • /teleport <target> <x> <y> <z>

  • /teleport <target> here

  • /teleport <to target>

We will also define them with the /tp as a shorter form.

We will start with implementing the core functionality. To keep things simple for now, we will not add fancy features like ~ and ^ (relative coordinates and angles). We will introduce them in later sections, however.

Let's start by creating a separate class for containing these commands:

public class TeleportCommands {

}
class TeleportCommands {

}

And register it to our Lamp instance:

public final class TestPlugin extends JavaPlugin {

    @Override public void onEnable() {
        var lamp = BukkitLamp.builder(this).build();
        lamp.register(new TeleportCommands());
    }
}
class TestPlugin : JavaPlugin() {

    override fun onEnable() {
        val lamp = BukkitLamp.builder(this).build()
        lamp.register(TeleportCommands())
    }
}

/teleport <x> <y> <z>

This command should be easy to create. Let's define our function:

public class TeleportCommands {

    @Command({"teleport", "tp"})
    public void teleport(Player sender, double x, double y, double z) {
        Location location = new Location(sender.getWorld(), x, y, z);
        sender.teleport(location);
    }
}
class TeleportCommands {
    
    @Command("teleport", "tp")
    fun teleport(sender: Player, x: Double, y: Double, z: Double) {
        val location = Location(sender.world, x, y, z)
        sender.teleport(location)
    }
}

Let's break this down:

  • @Command({"teleport", "tp"}): This command defines our command as /teleport and /tp.

    • Any aliases defined

  • Player sender: This is the argument that represents the player executing the command.

    • Because this is the first parameter in the method, Lamp will implicitly infer it as the command sender

    • Because it is a Player, any non-player entity attempting to execute this command will receive a You must be a player to use this command!-like error. This makes it easy to restrict certain commands to player senders only.

  • double x, double y, double z: These are the arguments that our command will receive. Lamp will automatically parse the user input and parse it into doubles, or emit errors if the user inputs an invalid value.

Let's try our command:

That's one variant down. Let's create another.

/teleport <target> <x> <y> <z>

@Command({"teleport", "tp"})
public void teleport(Player sender, EntitySelector<LivingEntity> target, double x, double y, double z) {
    Location location = new Location(sender.getWorld(), x, y, z);
    for (LivingEntity entity : target)
        entity.teleport(location);
}
@Command("teleport", "tp")
fun teleport(sender: Player, target: EntitySelector<LivingEntity>, x: Double, y: Double, z: Double) {
    val location = Location(sender.world, x, y, z)
    for (entity in target) 
        entity.teleport(location)
}

Note that our commands with similar signatures can co-exist peacefully with no problems.

We can have as many variants of /teleport as we want, as long as Lamp can actually differentiate between them.

When there are multiple candidates for commands, Lamp will try to find the best one. This method is not foolproof and may go wrong in rare cases of real confusion.

At the end of the page, we will go through the criteria Lamp uses to decide the best execution candidate.

/teleport <target> here

Now, we will implement /teleport <target> here. This command is slightly different from the ones above as it involves an argument in the middle of the command.

We noticed that, in previous commands, arguments would always come at the end of the command, in the same order they are defined. However, we can declare the order in the command annotations as needed. And, as expected, if a parameter is not defined in the command path, it will be put at the end of the command.

@Command("teleport <target> here")
public void teleportHere(Player sender, EntitySelector<LivingEntity> target) {
    for (LivingEntity entity : target)
        entity.teleport(sender);
}
@Command("teleport <target> here")
fun teleportHere(sender: Player, target: EntitySelector<LivingEntity>) {
    for (entity in target)
        entity.teleport(sender)
}

When Lamp encounters a name enclosed by <>, it will automatically infer it as a parameter name and look for a parameter with that name.

Let's create the simple /teleport <to>

/teleport <to>

This one is relatively simple too:

@Command({"teleport", "tp"})
public void teleport(Player sender, Entity target) {
    sender.teleport(target);
}
@Command("teleport", "tp")
fun teleport(sender: Player, target: Entity) {
    sender.teleport(target)
}

That's it! We can see how Lamp can work with a single command that has multiple variants, and how we can define arguments that come in different places of the command.

In the next

PreviousCommand lineNextCustom parameter types

Last updated 9 months ago

Was this helpful?

Executing /teleport

To define an argument in the middle of the command, simply declare it in the command annotation, enclosed with <>. For example

Important note: You need to for this, or define an @Named annotation on the method's parameters. Lamp will throw an exception if it cannot find the parameter.

💡
⚠️
Using /teleport <target> here command
enable parameter names