Commands And Events
Register simple commands and common tick callbacks through the mc adapter.
Some APIs may still change or behave unevenly because they do not have enough real-world use cases and test coverage yet.
Commands And Events
Commands and events sit on the boundary between stable mod setup and native Minecraft runtime objects. Nows gives simple stable helpers first, plus native escape hatches when you need full control.
Simple Commands
Use CommandSpec when a command has one literal, simple arguments and a straightforward callback.
CommandSpec command = CommandSpec.literal("mydebug")
.requiresPermission(2)
.executes(() -> LOGGER.info("Debug command ran"))
.build();
MinecraftApi.commands(context).register(command);
Add stable arguments with CommandArgumentSpec.
CommandSpec command = CommandSpec.literal("setheat")
.argument(CommandArgumentSpec.integer("amount"))
.executes(commandContext -> {
int amount = commandContext.integer("amount").orElse(0);
MyDebugState.heat = amount;
commandContext.reply(McText.literal("Heat set to " + amount));
return 1;
})
.build();
Use stable command specs for generated or boring commands. Use Brigadier directly when a command needs custom parsers, suggestions, redirects or advanced permission behavior.
Brigadier Escape Hatch
CommandApi.register(Consumer<CommandDispatcher<CommandSourceStack>>) lets advanced code register native Brigadier commands.
MinecraftApi.commands(context).register(dispatcher -> {
dispatcher.register(Commands.literal("my_native_command")
.requires(source -> source.hasPermission(2))
.executes(ctx -> {
ctx.getSource().sendSuccess(() -> Component.literal("Done"), false);
return 1;
}));
});
This is version-specific code. Keep it close to the Minecraft target or behind your own compatibility layer.
Client Ticks
Use clientTick when you need the native client object.
MinecraftApi.events(context).clientTick(client -> {
if (client.player == null) return;
MyClientState.update(client.player);
});
Use stableClientTick when a snapshot is enough.
MinecraftApi.events(context).stableClientTick(tick -> {
tick.player().ifPresent(player -> LOGGER.debug(player.name()));
});
Server And Level Ticks
Use native server ticks for world mutation or scheduling.
MinecraftApi.events(context).serverTick(server -> {
if (server.getTickCount() % 20 == 0) {
MyMachines.flushQueue(server);
}
});
Use level ticks for per-world work.
MinecraftApi.events(context).serverLevelTick((server, level) -> {
MyChunkCache.tick(level);
});
The stable tick contexts are intentionally lightweight. They are good for status checks, counters and generator-friendly callbacks; native overloads are better for real world mutation.