Skip to main content

Entity and Player Arguments

The arguments described in this section relate to arguments which you can use to retrieve entities. Their main usage is the selection of command targets. All of these have entity selectors (@a, @e, @n, etc.) as valid inputs, though they require the minecraft.command.selector permission in order to be able to be used. The specific arguments may allow or disallow certain selectors.

Entity Argument

This argument, after resolving its returning EntitySelectorArgumentResolver, returns a list of exactly one, no more and no less, entity. It is safe to call List#getFirst() to retrieve that entity.

Example usage

public static LiteralCommandNode<CommandSourceStack> entity() {
return Commands.literal("entityarg")
.requires(ctx -> ctx.getSender().isOp())
.then(Commands.argument("arg", ArgumentTypes.entity())
.executes(ctx -> {
final EntitySelectorArgumentResolver entitySelectorArgumentResolver = ctx.getArgument("arg", EntitySelectorArgumentResolver.class);
final List<Entity> entities = entitySelectorArgumentResolver.resolve(ctx.getSource());

ctx.getSource().getSender().sendRichMessage("Found a <entitytype>",
Placeholder.unparsed("entitytype", entities.getFirst().getType().name())
);
return Command.SINGLE_SUCCESS;
}))
.build();
}

In-game preview

If the executing player is not opped:

If the executing player is opped:

Entities Argument

In contrast to the single entity argument, this multi entity argument accepts any amount of entities, with the minimum amount of entities being 1. They can, once again, be resolved using EntitySelectorArgumentResolver#resolve(CommandSourceStack), which returns a List<Entity>.

Example usage

public static LiteralCommandNode<CommandSourceStack> entities() {
return Commands.literal("entitiesarg")
.requires(ctx -> ctx.getSender().isOp())
.then(Commands.argument("arg", ArgumentTypes.entities())
.executes(ctx -> {
final EntitySelectorArgumentResolver entitySelectorArgumentResolver = ctx.getArgument("arg", EntitySelectorArgumentResolver.class);
final List<Entity> entities = entitySelectorArgumentResolver.resolve(ctx.getSource());

ctx.getSource().getSender().sendRichMessage("Found the following entities: <entitytypes>",
Placeholder.unparsed("entitytypes", String.join(", ", entities.stream().map(Entity::getType).map(EntityType::name).toList()))
);
return Command.SINGLE_SUCCESS;
}))
.build();
}

In-game preview

Player Argument

The player argument allows you to be given some player input. Running ctx.getArgument return a PlayerSelectorArgumentResolver for player arguments. For the "one player" argument (this one), you can safely get the target player by running PlayerSelectorArgumentResolver.resolve(ctx.getSource()).getFirst(), which returns a Bukkit Player object.

Example usage

This command yeets the targeted player into the air!

public static LiteralCommandNode<CommandSourceStack> playerArgument() {
return Commands.literal("player")
.then(Commands.argument("target", ArgumentTypes.player())
.executes(ctx -> {
final PlayerSelectorArgumentResolver targetResolver = ctx.getArgument("target", PlayerSelectorArgumentResolver.class);
final Player target = targetResolver.resolve(ctx.getSource()).getFirst();

target.setVelocity(new Vector(0, 100, 0));
target.sendRichMessage("<rainbow>Yeeeeeeeeeet");

ctx.getSource().getSender().sendRichMessage("Yeeted <target>!",
Placeholder.component("target", target.name())
);
return Command.SINGLE_SUCCESS;
}))
.build();
}

In-game preview

Players Argument

The "multiple players" argument works similarly to the Player argument, also returning a PlayerSelectorArgumentResolver. Instead of just resolving to exactly one Player, this one can resolve to more than just one player - which you should account for in case of using this argument. PlayerSelectorArgumentResolver.resolve#(ctx.getSource()) returns a List<Player>, which you can just iterate through.

Example usage

Extending the "single player" yeet command to support multiple targets

public static LiteralCommandNode<CommandSourceStack> playersArgument() {
return Commands.literal("players")
.then(Commands.argument("targets", ArgumentTypes.players())
.executes(ctx -> {
final PlayerSelectorArgumentResolver targetResolver = ctx.getArgument("targets", PlayerSelectorArgumentResolver.class);
final List<Player> targets = targetResolver.resolve(ctx.getSource());
final CommandSender sender = ctx.getSource().getSender();

for (final Player target : targets) {
target.setVelocity(new Vector(0, 100, 0));
target.sendRichMessage("<rainbow>Yeeeeeeeeeet");

sender.sendRichMessage("Yeeted <target>!",
Placeholder.component("target", target.name())
);
}
return Command.SINGLE_SUCCESS;
}))
.build();
}

In-game preview

Player Profiles Argument

The player profiles argument is a very powerful argument which can retrieve both offline and online players. It returns the result of the argument as a PlayerProfileListResolver, which resolves to a Collection<PlayerProfile>. This collection can be iterated to get the resulting profile(s). Usually, it only returns a single PlayerProfile if retrieving a player by name, but it can return multiple if using the entity selectors (like @a on online players). Thus it always makes sense to run whatever operation you want to run on all entries in the collection instead of just the first one.

Sometimes, the API call to players, which are currently offline and have no yet logged onto the server, may fail. This is also visible in the in-game preview down below. This weird behavior also explains why the /whitelist add command fails, so now you know 🚀.

Example usage - Player lookup command

public static LiteralCommandNode<CommandSourceStack> playerProfilesArgument() {
return Commands.literal("lookup")
.then(Commands.argument("profile", ArgumentTypes.playerProfiles())
.executes(ctx -> {
final PlayerProfileListResolver profilesResolver = ctx.getArgument("profile", PlayerProfileListResolver.class);
final Collection<PlayerProfile> foundProfiles = profilesResolver.resolve(ctx.getSource());

for (final PlayerProfile profile : foundProfiles) {
ctx.getSource().getSender().sendMessage("Found " + profile.getName());
}

return Command.SINGLE_SUCCESS;
}))
.build();
}

In-game preview