Skip to main content

Migrating to KubeJS 6

This page is still being worked on, so if some info is missing, please check back later!

What's changed in the new KubeJS 6 (1.19.2+)?

onEvent()

onEvent('event', e => {}) syntax was replaced by SomeEventGroup.someEventName(e => {})

// Before
onEvent('block.right_click', e => {
  if(e.block.id === 'minecraft:dirt') console.info('Hi!')
})

// After
BlockEvents.rightClicked(e => {
  if(e.block.id === 'minecraft:dirt') console.info('Hi!')
})

Not only that, but new events also support extra parameters for IDs and other things! You can now choose to make each id have its own event handler:

// Before
onEvent('block.right_click', e => {
  if(e.block.id === 'minecraft:dirt') console.info('Hi!')
  else if(e.block.id === 'minecraft:stone') console.info('Bye!')
})

// After
BlockEvents.rightClicked('minecraft:dirt', e => {
  console.info('Hi!')
})

BlockEvents.rightClicked('minecraft:stone', e => {
  console.info('Bye!')
})

Some events require ID, such as registry and tag events:

// Before
onEvent('item.registry', e => {})

// After
StartupEvents.registry('item', e => {})
// Before
onEvent('tags.items', e => {})

// After
ServerEvents.tags('item', e => {})

Using parameters is actually faster on the CPU than checking some event.id == 'id'

You can find the full list of new events here.

onForgeEvent()

onForgeEvent('package.ClassName', e => {}) has been replaced by ForgeEvents.onEvent('package.ClassName', e => {})

// Before
onForgeEvent('net.minecraftforge.event.level.BlockEvent$PortalSpawnEvent', e => {})

// After
ForgeEvents.onEvent('net.minecraftforge.event.level.BlockEvent$PortalSpawnEvent', e => {})

New! It now supports generic events:

ForgeEvents.onGenericEvent('net.minecraftforge.event.AttachCapabilitiesEvent', 'net.minecraft.world.entity.Entity', e => {})

Server settings

settings.log... properties have been removed from server scripts, and instead, moved to local/kubejsdev.properties file. By default, it won't be shipped with the pack, but you can change saveDevPropertiesInConfig to true to instead save the file in kubejs/config/dev.properties.

java()

java('package.ClassName') has been replaced by Java.loadClass('package.ClassName')

// Before
const CactusBlock = java('net.minecraft.world.level.block.CactusBlock')

// After
const CactusBlock = Java.loadClass('net.minecraft.world.level.block.CactusBlock')

There might be some more reflective helper methods later in the Java util class, such as listing all fields and methods in a class, etc.

Bye Bye Wrapper classes

None of the vanilla classes are wrappers anymore - EntityJS, LevelJS, ItemStackJS, IngredientJS, and others are gone. This may introduce some bugs, but in general, should make it significantly easier to interact with Minecraft and other mods. Almost all old methods are still supported by core-modding vanilla. This should also significantly boost performance, as it doesn't need to constantly wrap and unwrap classes.

Version 6.1 Changes

For pack developers

  • Massive backend rewrites, improved performance a lot - recipes should now load faster with KJS than they do with vanilla!
  • Registries have been fixed on both Forge and Fabric - you should now be able to properly register Fluids, modded registries, etc.
  • Fixed tags not working properly on first world load - you no longer need /reload hacks to fix this, so please remove them if you had that!
  • Renamed kubejs/logs files from .txt to .log - So you can now have formatting in VSCode, etc.
  • Fixed resource and data pack order - User added resource packs and datapacks will now be above KJS generated packs, so you should be able to change textures and other things with them.
  • Added .zip loading formfrom kubjes/data and kubejs/assets - You simply drop a .zip file in that folder and it will force-load it (above KJS, under user packs)
  • Event .cancel() now exits event block - This may be a small change but it may affect some scripts. Previously it would only mark event as cancelled and didn't do anything, but now it will act as return; call too. On top of that, some events will now support more than just cancelling - .deny(), .allow() and other methods have been added.
  • Moved debugInfo config from kubejs/config/common.properties to local/kubejsdev.properties. No idea why it was in common properties in first place, its a debug config for devs.
  • Moved Platform.mods.modid.name = 'Custom Name' to Platform.setModName('modid', 'Custom Name'). It also now supports any mod id, not just existing. So if your pack was adding items with custom namespace like ftbstoneblock:custom_block you can now use Platform.setModName('ftbstoneblock', 'FTB StoneBlock 3') for custom name under items. Currently has integration with ModNameTooltip and REI, JEI soon.
  • Better recipe integration with ProbeJS - Because of new schema system in KJS, probe is able to much better display what ingredients go where, with less hacks!
  • Fixed flowing fluid textures on Fabric and other fluid related issues.
  • Fixed errors being way too long in logs - Believe or not, KJS was not supposed to spit out 150 lines of errors for each recipe.
  • Added custom toast notifications - You can use player.notify(title), (title, subtitle) or (Notification.make(...)).
  • Added /kubejs reload config command - No longer you have to restart the game to update configs!
  • Added /kubejs packmode [mode] command - Same as above, but you don't have to mess with files at all.
  • Added /kubejs help command - Useful links directly in-game.
  • Removed /kjs_hand command - Instead added /kjs hand (with space) redirect. Some might hate this change, but _ is much harder to reach than space, and I'm sure you'll get used to it quickly and like it better.
For addon mod developers
  • Complete rewrite of recipe system - Now uses schemas. More on that here. (add link)
  • Events now can have results for more precise control over cancellation and hasListeners() check for performance
  • Fixed datagen issue - KJS should no longer keep datagens from closing game forever in dev environment

Other questions

If you have any other questions, feel free to ask them on my Discord Server.