Create Structures

Create structure definitions with KubeJS server scripts.

Server script

MMEvents.createStructures(event => {
  event.create('expert:coke_oven')
    .name('Coke Oven')
    .controllerId('mm:coke_oven')
    .layout(l => {
      l.layer(['AAA', 'ACA', 'AAA'])
      l.key('A', { block: 'minecraft:bricks' })
      l.key('C', { block: 'mm:coke_oven' })
    })
})

Unlike startup-generated controllers, ports, and extra blocks, structures are datapack/resource ids. event.create(...) should use a full resource location such as expert:coke_oven.

The controller block generated by event.create('coke_oven') in registerControllers is mm:coke_oven, not mm:coke_oven_controller.

Builder methods

MMEvents.createStructures(event => {
  event.create('mypack:my_structure')
    .name('My Structure')
    .controllerId('mm:my_controller')
    .maxParallelRecipes(-1)
    .layout(l => {
      l.layer(['AAA', 'ACA', 'AAA'])
      l.key('A', { block: 'minecraft:bricks' })
      l.key('C', { block: 'mm:my_controller' })
      l.key('I', { port: 'mm:my_item_port', input: true })
      l.key('O', { portType: 'mm:item', input: false, minTier: 1, maxTier: 1 })
      l.portsAnywhere(false)
    })
})
Method Meaning
create(id) Full structure resource location, for example expert:coke_oven.
name(text) Display name for the formed structure.
controllerId(id) Full generated controller id, for example mm:coke_oven. Can be called more than once.
maxParallelRecipes(int) Optional structure-level cap. -1 means no structure override.
layout(builder => ...) Layout builder containing layer, key, and portsAnywhere.

layer(...) is added to the builder in a way that preserves top/bottom ordering after build. When in doubt, verify in-game with JEI/blueprint/debug output.