From Datapack to Katton
If you already know vanilla datapacks, Katton should feel familiar: you still reload quickly, you can still call command-like helpers, and you can keep existing .mcfunction files while moving the parts that need real code into Kotlin.
The big difference is that Katton lets you stop encoding all logic as command strings. You can write functions, store values in variables, react to events, work with real entity objects, and use hot-reloadable APIs that reach far beyond vanilla datapacks.
NOTE
Paper supports server-side datapack-style APIs and events, but it cannot register custom items, blocks, entities, or client features because a vanilla client cannot receive those registry entries.
Migration Map
| Datapack habit | Katton replacement | Start here |
|---|---|---|
data/<namespace>/function/*.mcfunction | .kt files with @ServerScriptEntrypoint functions | Project Structure |
| Long command chains | Kotlin functions, loops, and command helpers | Translating mcfunction to Kotlin |
| Vanilla commands | top.katton.api.dpcaller helpers | Calling Vanilla Commands |
@e[...], @a[...] | EntitySelectorBuilder and real entity objects | Selectors and Entity Access |
| Scoreboards, tags, NBT, storage | Scoreboards when useful, Kotlin values for logic, NBT APIs for data access | Scoreboards, Tags, NBT, and Storage |
#load, #tick, schedule function | Server lifecycle and tick events | Replacing Load, Tick, and Schedule |
| Recipe and loot JSON edits | modifyRecipe, modifyLootTable, and related APIs | Recipes, Loot Tables, and Datapack Mutations |
| Existing datapack libraries | Keep them and call runFunction while migrating gradually | Keeping Existing Datapacks |
| Datapack limitations | Events, registries, client rendering, injection, pack UI | Going Beyond Datapacks |
A Good First Migration
Start with a small utility function, not your entire datapack. Pick something that is annoying in .mcfunction, such as a selector-heavy loop, a scoreboard calculation, or a command chain that needs branching.
- Create a script pack.
- Add one
@ServerScriptEntrypointfunction. - Recreate the behavior in Kotlin.
- Reload with
/katton reload. - Keep the rest of the datapack unchanged until the new script feels solid.
