Skip to content

Command Permissions

Commands integrate with Hytale’s permission system to control who can execute them. See Permissions for the full permission system reference.

When you register a command, the server automatically generates a permission string based on where the command comes from.

For commands registered by mods via getCommandRegistry(), the permission is:

{group}.{modname}.command.{commandname}

The group and modname come from your mod’s manifest.json:

{
"Group": "MyGroup",
"Name": "MyMod",
...
}

This produces the base permission mygroup.mymod (lowercased), and commands get .command.{name} appended.

Example: A mod with group Survival and name Economy registering a command balance:

  • Permission: survival.economy.command.balance

For subcommands, the parent name is included:

survival.economy.command.shop.buy
survival.economy.command.shop.sell

When a player runs a subcommand, the server checks permissions up the entire parent chain. The player needs permission for the subcommand AND every parent above it.

For example, with /shop buy:

  1. Check survival.economy.command.shop.buy (the subcommand)
  2. Check survival.economy.command.shop (the parent)

If either check fails, the command is denied. This means granting shop.buy alone isn’t enough — the player also needs shop (or a wildcard like survival.economy.command.*).

For deeply nested subcommands, every level is checked:

/admin config set <key> <value>
# checks (bottom-up):
survival.economy.command.admin.config.set
survival.economy.command.admin.config
survival.economy.command.admin

This is handled by AbstractCommand.hasPermission(), which walks up the parent chain calling hasPermission() on each ancestor.

Hytale’s built-in mods use Hytale as the group. For example, TeleportPlugin:

  • Group: Hytale
  • Name: TeleportPlugin
  • Command: teleport
  • Permission: hytale.teleportplugin.command.teleport

Commands registered directly by the server (via CommandManager) use:

hytale.system.command.{commandname}

Example: /stop has permission hytale.system.command.stop

Override the auto-generated permission with requirePermission():

public class MyCommand extends CommandBase {
public MyCommand() {
super("mycommand", "desc.key");
this.requirePermission("custom.permission.here");
}
}

For built-in style permissions, use HytalePermissions:

hytale.command.mycommand
this.requirePermission(HytalePermissions.fromCommand("mycommand"));

Permission groups let you assign permissions based on game mode.

  1. Commands declare which groups they belong to via setPermissionGroup():
public class FlyCommand extends CommandBase {
public FlyCommand() {
super("fly", "desc.key");
this.setPermissionGroup(GameMode.Creative);
}
}
  1. At startup, the server collects all permissions tagged with each group into “virtual groups”
  2. When a player is in a matching game mode, they automatically have those permissions
GroupDescription
AdventureAvailable to all players in Adventure mode
CreativeAvailable to players in Creative mode - includes building/editor commands

The Creative group also grants hytale.editor.builderTools by default.

Many player-targeting commands need different permissions for targeting yourself vs. others.

The easiest way is to extend AbstractTargetPlayerCommand. It automatically:

  1. Adds an optional player argument
  2. Checks hytale.command.{basepermission}.other when targeting another player (via HytalePermissions.fromCommand())
  3. Allows self-targeting with just the base permission
public class HealCommand extends AbstractTargetPlayerCommand {
public HealCommand() {
super("heal", "commands.heal.desc");
}
@Override
protected void execute(CommandContext context, Ref<EntityStore> sourceRef,
Ref<EntityStore> targetRef, PlayerRef playerRef,
World world, Store<EntityStore> store) {
// heal the target player
}
}

With base permission mymod.command.heal:

  • /heal - requires mymod.command.heal
  • /heal --player=OtherPlayer - requires hytale.command.mymod.command.heal.other

Note: The .other check uses HytalePermissions.fromCommand(), which adds the hytale.command. prefix.

@Override
protected void executeSync(CommandContext context) {
if (context.getSender().hasPermission("mymod.admin")) {
// admin-only logic
}
}

CommandSender implements PermissionHolder, providing:

boolean hasPermission(String permission);
boolean hasPermission(String permission, boolean defaultValue);