agentsclimarketplace

Fabric commands

Skill PSB1234/Fabric-Minecraft-Skill-1.20.1/fabric-commands

Complete reference for Brigadier command system in Fabric Minecraft 1.20.1 — command tree construction, argument types, tab-completion suggestions, permission levels, server/client command registration, and CommandRegistrationCallback. Use this skill whenever the user asks about adding a command, Brigadier, CommandRegistrationCallback, argument types (IntegerArgumentType, StringArgumentType, EntityArgumentType, etc.), command permissions, op level, tab completion, or ServerCommandSource. Triggers on: "command", "brigadier", "CommandRegistrationCallback", "argument type", "tab complete", "command permission", "op level", "/mycommand", "ServerCommandSource", "CommandContext", "literal", "executes", "requires", "suggests". Part of the fabric-mc-modding skill family.From its SKILL.md

Install
npx -y skills add PSB1234/Fabric-Minecraft-Skill-1.20.1 --skill fabric-commands

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

9.9 KB, ~2.0k tokens by cl100k_base, as published. Nobody here has run it

Fabric Commands — 1.20.1 Reference


Registration

All commands are registered via CommandRegistrationCallback in onInitialize():

CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
    // environment = INTEGRATED (single-player), DEDICATED (server), or ALL
    if (environment.dedicated) {
        // only on dedicated server
    }
    MyCommands.register(dispatcher, registryAccess);
});

Basic Command Structure

dispatcher.register(
    CommandManager.literal("hello")           // command name
        .requires(src -> src.hasPermissionLevel(0))  // who can run it (0 = everyone)
        .executes(ctx -> {
            ctx.getSource().sendFeedback(
                () -> Text.literal("Hello, world!"), false); // false = don't log to ops
            return 1; // return 1 = success, 0 = failure
        })
);

Arguments

Integer

.then(CommandManager.argument("count", IntegerArgumentType.integer(1, 64))
    .executes(ctx -> {
        int count = IntegerArgumentType.getInteger(ctx, "count");
        return 1;
    })
)

String

CommandManager.argument("name", StringArgumentType.word())          // single word
CommandManager.argument("msg",  StringArgumentType.string())        // quoted or single word
CommandManager.argument("text", StringArgumentType.greedyString())  // rest of input

Boolean, Float, Double, Long

BoolArgumentType.bool()         BoolArgumentType.getBool(ctx, "flag")
FloatArgumentType.floatArg()    FloatArgumentType.getFloat(ctx, "value")
DoubleArgumentType.doubleArg()  DoubleArgumentType.getDouble(ctx, "value")
LongArgumentType.longArg()      LongArgumentType.getLong(ctx, "value")

Minecraft-specific Arguments

// Player (online players only)
EntityArgumentType.player()
EntityArgumentType.players()     // supports @a, @r, etc.
EntityArgumentType.entity()      // any entity
EntityArgumentType.entities()
// Get value:
ServerPlayerEntity player = EntityArgumentType.getPlayer(ctx, "player");
Collection<ServerPlayerEntity> players = EntityArgumentType.getPlayers(ctx, "players");

// Block position
BlockPosArgumentType.blockPos()
BlockPos pos = BlockPosArgumentType.getBlockPos(ctx, "pos");

// Block state
BlockStateArgumentType.blockState(registryAccess)
BlockStateArgument state = BlockStateArgumentType.getBlockState(ctx, "block");

// Item stack
ItemStackArgumentType.itemStack(registryAccess)
ItemStackArgument item = ItemStackArgumentType.getItemStackArgument(ctx, "item");

// Identifier / ResourceLocation
IdentifierArgumentType.identifier()
Identifier id = IdentifierArgumentType.getIdentifier(ctx, "id");

// Vec3 / Vec2 position
Vec3ArgumentType.vec3()
Vec3d vec = Vec3ArgumentType.getVec3(ctx, "pos");

// Rotation
RotationArgumentType.rotation()

// NBT
NbtCompoundArgumentType.nbtCompound()
NbtTagArgumentType.nbtTag()

Multi-Level Command Tree

dispatcher.register(
    CommandManager.literal("mymod")
        .then(CommandManager.literal("give")
            .then(CommandManager.argument("player", EntityArgumentType.player())
                .then(CommandManager.argument("count", IntegerArgumentType.integer(1, 64))
                    .executes(ctx -> executeGive(ctx, 1))  // optional count
                )
                .executes(ctx -> executeGive(ctx, 1))      // no count → default 1
            )
        )
        .then(CommandManager.literal("reload")
            .requires(src -> src.hasPermissionLevel(4))   // op only
            .executes(ctx -> executeReload(ctx))
        )
        .then(CommandManager.literal("status")
            .executes(ctx -> executeStatus(ctx))
        )
);

Permission Levels

.requires(source -> source.hasPermissionLevel(level))
LevelWho
0All players
1Bypass spawn protection
2Cheats / /gamemode — typical mod commands
3/kick, /ban
4/stop, /op — server admin

Check if source is a player (not console):

.requires(source -> source.getEntity() instanceof PlayerEntity)

Sending Feedback

ServerCommandSource src = ctx.getSource();

// To the command sender only
src.sendFeedback(() -> Text.literal("Done!"), false);

// To the sender and log to ops (true = broadcast to ops)
src.sendFeedback(() -> Text.literal("Reloaded."), true);

// Error message (shown in red)
src.sendError(Text.literal("Something went wrong."));

// Throw a command exception (shown as error, stops execution)
throw new SimpleCommandExceptionType(Text.literal("Invalid arg")).create();

Custom Tab-Completion Suggestions

CommandManager.argument("color", StringArgumentType.word())
    .suggests((ctx, builder) -> {
        // Static list
        Stream.of("red", "green", "blue")
            .filter(s -> s.startsWith(builder.getRemaining()))
            .forEach(builder::suggest);
        return builder.buildFuture();
    })

Or using SuggestionProvider:

private static final SuggestionProvider<ServerCommandSource> MY_SUGGESTIONS =
    (ctx, builder) -> {
        // Dynamic suggestions from server state
        ctx.getSource().getServer().getPlayerManager()
            .getPlayerList().stream()
            .map(p -> p.getName().getString())
            .filter(n -> n.startsWith(builder.getRemaining()))
            .forEach(builder::suggest);
        return builder.buildFuture();
    };

CommandManager.argument("name", StringArgumentType.word())
    .suggests(MY_SUGGESTIONS)

Accessing the Server / World from a Command

ctx.getSource().getServer()          // MinecraftServer
ctx.getSource().getWorld()           // ServerWorld (where the command was run)
ctx.getSource().getPlayer()          // ServerPlayerEntity (throws if console)
ctx.getSource().getPlayerOrThrow()   // same but with exception type
ctx.getSource().getPosition()        // Vec3d position of source
ctx.getSource().getEntity()          // Entity or null (null if console)

Client-Side Commands (Single Player)

Register using ClientCommandRegistrationCallback from Fabric API (client-only):

// In onInitializeClient():
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> {
    dispatcher.register(
        ClientCommandManager.literal("client_cmd")
            .executes(ctx -> {
                MinecraftClient client = MinecraftClient.getInstance();
                // client-side only logic
                return 1;
            })
    );
});

Command Aliases

Register the same handler under multiple names:

LiteralArgumentBuilder<ServerCommandSource> cmd =
    CommandManager.literal("mymod").executes(ctx -> { return 1; });

dispatcher.register(cmd);
dispatcher.register(CommandManager.literal("mm")  // alias
    .redirect(dispatcher.getRoot().getChild("mymod")));

Full Example: /mymod tp <player> <pos>

dispatcher.register(
    CommandManager.literal("mymod")
        .then(CommandManager.literal("tp")
            .requires(src -> src.hasPermissionLevel(2))
            .then(CommandManager.argument("target", EntityArgumentType.player())
                .then(CommandManager.argument("pos", BlockPosArgumentType.blockPos())
                    .executes(ctx -> {
                        ServerPlayerEntity target = EntityArgumentType.getPlayer(ctx, "target");
                        BlockPos pos = BlockPosArgumentType.getBlockPos(ctx, "pos");
                        target.teleport(ctx.getSource().getWorld(),
                            pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5,
                            target.getYaw(), target.getPitch());
                        ctx.getSource().sendFeedback(
                            () -> Text.literal("Teleported " + target.getName().getString()), true);
                        return 1;
                    })
                )
            )
        )
);

Common Mistakes

  • Argument order matters — Brigadier parses greedily; put greedyString last.
  • getPlayer() throws on console — use getEntity() + instanceof check if the command can be run by console.
  • Permission check on wrong node.requires() applies to that node and all children. Put it on the literal root.
  • Suggestions not filtering — always filter with builder.getRemaining() prefix check.
  • Command not registeredCommandRegistrationCallback.EVENT.register(...) must be inside onInitialize().

Further Reading

References

FileWhen to load
references/argument-types.mdComplete Brigadier argument type table (all vanilla types, retrieval methods, custom types, suggestions, dynamic tab-complete, CommandSyntaxException)

Related Skills

  • fabric-mc-modding — project setup
  • fabric-config — exposing config via commands
  • fabric-events — CommandRegistrationCallback is a Fabric event

What ships with it: 1 file

7.0 KB alongside SKILL.md

references/

Keep looking

Skills are one crate of 326,861. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.