Skip to content

NBTcompat

A RAM and I/O friendly version of Every Compat, using texture pregen, recolors, and UV mapping.

NeoForge
Loaders
NeoForge
Downloads on Modrinth
131
Followers on Modrinth
1
versions
2
Updated
October 13, 2026Oct 13
Published
in 2026

At a glance

Runs on NeoForge
For Minecraft 1.21.1
Needed in the game and on the server
Latest version — 1.1.0 from October 13, 2026
License GPL-3.0-or-later — free
Where it's needed
In gamerequiredOn serverrequired

Needed both in the game and on the server

Game versions1.21.1

This mod takes a different approach to completeness. Instead of one block ID per entry, this mod uses NBT data to store as few blocks in registry as possible and stores the textures within said NBT data or use alpha mapping to recreate the look out of existing textures.

This massivly reduces load on the server and client, only needing the memory to generate the textures. We store block color in the block's NBT and use uv mapping from existing textures. So very little is added to the texture atlas.

At current, this supports:

Vanilla: (crafting tables, bookshelves, cobblestones, gravels, sands)

Create: (casings (metal X wood combos), recipes for millstone and crushing wheels)

Chipped: (non CTM stone blocks, log variants + 2 custom ones with nether woods, planks, compat with dyed wood for the doors)

custom: (dyed wood sets (planks, fences, doors, trapdoors, buttons, and pressure plates), loot table overrides for cobblestones, world gen for gravels, smelting recipes for cobbles)

Macaw's series: (the entirety of the roofs mod at current)

Mekansim: (recipes for the crusher)

You can define custom woods, metals, stones, and dyes with kubeJS like so (startup script):

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', // preferred for trim textures
    nugget: 'createmoremachines:netherite_alloy_nugget',
    name: 'Netherite Alloy'
  })
  // shorthand
  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', // skip NBT cobble when set
    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')
})

You can also edit the recipe generation like in this example. Artisian worktables is optional (server script):

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' }))
})

// Hard-coded minecraft:crafting_table / bookshelf → convention tags (include nbtcompat via mod datapack).
ServerEvents.recipes(event => {
  event.replaceInput({}, 'minecraft:crafting_table', '#c:player_workstations/crafting_tables')
  event.replaceInput({}, 'minecraft:bookshelf', '#c:bookshelves')
})

FAQ

How to install NBTcompat?

Install NeoForge for your Minecraft version, download NBTcompat for the same version and loader, put the file into the mods folder and launch the game with the loader profile.

Which Minecraft versions does NBTcompat support?

NBTcompat has builds for Minecraft 1.21.1.

Is NBTcompat needed on the server?

Needed in the game and on the server

License and source
GNU General Public License v3.0 or laterfree to use and share; changes to the mod itself must be published under the same license
Original — Modrinth↗Files unchanged, verified with SHA-512Is this your mod? For rights holders

The site uses cookies: the necessary ones for sign-in and the theme, plus the Yandex Metrica and LiveInternet visit counters — they show us how the site is used. We have no advertising cookies. More