NBTcompat

NBTcompat

兼容压缩版,占用内存更少

Every Compat 可以填补大型整合包中经常存在的空缺,不过这需要消耗大量内存,因为它会给注册表和你系统带来沉重负担。本模组采用了不同的方式来实现完整性。与其为每个条目分配一个方块 ID,本模组利用 NBT 数据在注册表中尽可能少地存储方块,并将纹理存储在这些 NBT 数据中,或使用 Alpha 映射从现有纹理中重建外观。

这大大减轻了服务器和客户端的负载,仅需要内存来生成纹理。至于这有多省内存,可以参考 Productive Trees 以及本模组为其添加的染色木板支持。注册表中的一个物品或方块约占 2KB RAM。Productive Trees 为游戏增加了约 160 种木材。若每个兼容模组都处理染料,再加上原版 16 种颜色,Productive Trees 最终会在注册表中产生 23040 个方块,占用约 46 MB 内存,而本模组仅需 18KB。本模组仅向游戏注册少量方块,其余均通过 NBT 数据和纹理生成处理。但纹理生成同样会引发其他问题,它可能会导致图集或系统内存超出你设定的限制。为解决此问题,我们将染色木板、圆石、沙子、沙砾和碎石头方块的方块颜色存储在方块的 NBT 中。对于原木、机壳和书架,我们使用现有纹理的 UV 映射。工作台目前不使用这些方法。

目前,本模组支持:

原版:(工作台、书架、圆石、沙砾、沙子)

机械动力(Create):(机壳(金属 X 木材组合),以及石磨和粉碎轮的配方)

Chipped:(非 CTM 石头方块、原木变体 + 2 个使用下界木材的自定义变体、木板、以及针对门的染色木材兼容)

自定义:(染色木材系列(木板、栅栏、门、活板门、按钮和压力板)、圆石的战利品表覆写、沙砾的世界生成、圆石的熔炼配方)

Macaw 系列:(目前支持该系列的全部屋顶模组)

通用机械(Mekanism):(粉碎机的配方)

你可以像这样使用 KubeJS 定义自定义木材、金属、石头和染料(启动脚本):

NbtCompatEvents.defineWoods(event => {
  event.add('modid:wood', 'modid:wood_planks')
  event.add('modid:wood', 'modid:wood_planks', 'Pretty Name')
  event.remove('minecraft:bamboo')
})

NbtCompatEvents.defineMetals(event => {
  event.add('createmoremachines:netherite_alloy', {
    ingot: 'createmoremachines:netherite_alloy',
    block: 'createmoremachines:netherite_alloy_block', // 纹理修剪时优先使用
    nugget: 'createmoremachines:netherite_alloy_nugget',
    name: 'Netherite Alloy'
  })
  // 简写
  event.add('modid:steel', 'modid:steel_ingot', 'modid:steel_block')
  event.remove('minecraft:gold')
})

NbtCompatEvents.defineStones(event => {
  event.add('mymod:slate', 'mymod:slate_rough', 'Slate')
  event.add('mymod:slate', {
    stone: 'mymod:slate_rough',
    cobble: 'mymod:slate_cobbled', // 设置后跳过 NBT 圆石
    gravel: 'mymod:slate_gravel',
    sand: 'mymod:slate_sand',
    name: 'Slate'
  })
  event.remove('minecraft:netherrack')
})

NbtCompatEvents.defineDyes(event => {
  event.add('kubejs:neon', 'kubejs:neon_dye', 0xff00aa, 'Neon')
})

你还可以像下面的示例那样编辑配方生成。工匠工作台(Artisian worktables)是可选的(服务端脚本):

NbtCompatEvents.defineRecipes(event => {
  const hasArtisan = Platform.isLoaded('artisanworktables')

  if (hasArtisan) {
    event.craftingTable()
      .shaped(
        ['AB', 'CA'],
        {
          A: 'wood:planks',
          B: 'artisanworktables:wood_handsaw',
          C: 'minecraft:flint'
        }
      )
  } else {
    event.craftingTable()
      .shaped(['AA', 'AA'], { A: 'wood:planks' })
  }

  const bookshelf = event.bookshelf()
    .shaped(
      ['PPP', 'BBB', 'PPP'],
      {
        P: 'wood:planks',
        B: 'minecraft:book'
      }
    )
  if (hasArtisan) {
    bookshelf.artisan('carpenter').removeCrafting()
  }

  const dyedPlanks = event.dyedPlanks()
    .shaped(
      ['PPP', 'PDP', 'PPP'],
      {
        P: 'wood:planks',
        D: 'dye'
      }
    )
  if (hasArtisan) {
    dyedPlanks
      .artisan('carpenter')
      .tool('#artisanworktables:tools/handsaw', 1)
      .removeCrafting()
  }

  const dyeFurniture = (builder) => {
    if (hasArtisan) {
      builder.artisan('carpenter').removeCrafting()
    }
  }

  dyeFurniture(event.dyedStairs()
    .shaped(['#  ', '## ', '###'], { '#': 'dyed:planks' }))

  dyeFurniture(event.dyedSlab()
    .shaped(['###'], { '#': 'dyed:planks' }))

  dyeFurniture(event.dyedFence()
    .shaped(['W#W', 'W#W'], { W: 'dyed:planks', '#': 'minecraft:stick' }))

  dyeFurniture(event.dyedFenceGate()
    .shaped(['#W#', '#W#'], { W: 'dyed:planks', '#': 'minecraft:stick' }))

  dyeFurniture(event.dyedDoor()
    .shaped(['##', '##', '##'], { '#': 'dyed:planks' }))

  dyeFurniture(event.dyedTrapdoor()
    .shaped(['###', '###'], { '#': 'dyed:planks' }))

  dyeFurniture(event.dyedPressurePlate()
    .shaped(['##'], { '#': 'dyed:planks' }))

  dyeFurniture(event.dyedButton()
    .shaped(['#'], { '#': 'dyed:planks' }))
})

// 硬编码的 minecraft:crafting_table / bookshelf → 约定标签(通过模组数据包包含 nbtcompat)。
ServerEvents.recipes(event => {
  event.replaceInput({}, 'minecraft:crafting_table', '#c:player_workstations/crafting_tables')
  event.replaceInput({}, 'minecraft:bookshelf', '#c:bookshelves')
})