Compatibility
Minecraft: Java Edition
Platforms
Supported environments
Links
Creators
Details
Burning
Burning is a library mod that adds a unified interface for managing the amount of burning fuel within most, if not all, furnace-like blocks from vanilla Minecraft and other mods.
Uses Fabric's Lookup and Transaction APIs.
Documentation
Burning revolves around the BurningStorage interface, which manages the insertions and extractions of burning fuel, and the Burning class, which represents the burning fuel itself.
You may read the documentation or the source code to learn more.
Getting Started (for regular users)
Install it as you'd with any other mod, and without further configuration, every block which entity extends the AbstractFurnaceBlockEntity
(Mojang mappings' name) abstract class, be them the vanilla Furnace, Blast Furnace, or Smoker, or any third-party block, will get a BurningStorage
automatically and thus will be ready to interop with every other mod using this library.
Blacklisting Blocks (for advanced users)
You may not want some blocks extending AbstractFurnaceBlockEntity
(Mojang mappings' name) to get a BurningStorage
, whether because it doesn't work or because of your preference.
By tagging any such block under the #burning:blacklist
block tag, you can prevent it from automatically getting a BurningStorage.
To do so, and for every such block, you must figure out the name of that block, which is usually mod_name:block_name
.
Then you must create a data pack like the one in the following example.
Expand
<datapack_name>.zip
├── data
│  └── <datapack_name>
│  └── burning
│  └── tags
│ └── blocks (before 1.21) or block (after 1.21)
│   └── blacklist.json
├── pack.mcmeta
└── pack.png (optional)
Where the blacklist.json
file shall look something like this:
Expand
{
"replace": false,
"values": [
"mod_name:block_name_1",
"mod_name:block_name_2",
...
]
}
Dynamic Storages (for experienced users)
Some mods add block entities that can burn fuel, but that, for one reason or another, don't extend the AbstractFurnaceBlockEntity
abstract class, and thus, they won't automatically get a BurningStorage
.
Fret not, for Burning offers the burning:dynamic_storage
dynamic registry, which, through data packs and a bit of reflection, resolves this specific problem.
How to do so.
For every such block entity, you must figure out a couple of things beforehand, that is:
- The name of that block entity's type.
- The name of the field of that block entity that is functionally equivalent to
AbstractFurnaceBlockEntity.litTimeRemaining
(Mojang mappings' name,litTime
before 1.21.4). - The name of the field of that block entity that is functionally equivalent to
AbstractFurnaceBlockEntity.litTotalTime
(Mojang mappings' name,litDuration
before 1.21.4).
Then you must create a data pack like the one in the following example.
Expand
<datapack_name>.zip
├── data
│  └── <datapack_name>
│  └── burning
│  └── dynamic_storage
│  └── <block_entity_type_1>.json
│  └── <block_entity_type_2>.json
│  └── ...
├── pack.mcmeta
└── pack.png (optional)
Where each *.json
file shall look something like this (comments are for illustration only, remove them in actual JSON):
Expand
{
// The name of that block entity's type
"type": "example_mod:custom_furnace_entity_type",
// The name of the field of that block entity that is functionally equivalent to `litTimeRemaining`
"lit_time": "burnTime",
// The name of the field of that block entity that is functionally equivalent to `litTotalTime`
"lit_duration": "fuelTime"
}
Add Dependencies (for mod developers)
Add the following to your gradle.build
.
repositories {
// Add Modrinth maven repository
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
filter {
includeGroup "maven.modrinth"
}
}
}
dependencies {
// Add Burning dependency
modImplementation "maven.modrinth:burning:<burning_version>"
}
For more information about the Modrinth maven repository read here.
Basic Usage (for mod developers)
Most of the time, as a mod developer using this library, you will only need to access already registered burning storages and transfer burning fuel between them. Here's how to do it.
Get a burning storage:
import niv.burning.api.BurningStorage;
// What you need
Level world;
BlockPos pos;
// How to
@Nullable
BurningStorage storage = BurningStorage.SIDED.find(world, pos, null);
Note: for most use cases, find
's third argument, which should be a Direction
, is ignored by the underlying implementation, so it's safe to pass null.
Transfer burning fuel between two storages:
import niv.burning.api.Burning;
import niv.burning.api.BurningStorage;
// What you need
Level level;
BurningStorage source, target;
// Before 1.21.2, create a burning context, you can use the SimpleBurningContext class or implement one yourself
BurningContext context = ...;
// After 1.21.2, you can also use the FuelValuesBurningContext wrapper class
BurningContext context = new FuelValuesBurningContext(level.fuelValues());
// Create the maximum amount of burning fuel to transfer, for instance, half a COAL worth of burning fuel
Burning burning = Burning.of(Items.COAL, context).withValue(800, context);
// or if you are using COAL, BLAZE_ROD, or LAVA_BUCKET
Burning burning = Burning.COAL.withValue(800, context);
// How to
Burning transferred = BurningStorage.transfer(
source, // transfer from this storage
target, // to this storage
burning, // up to this amount of burning fuel
context, // with this burning context
null); // creating a new transaction in doing so
// `transferred` will have the same fuel as `burning`
Transfer an exact amount or nothing:
import niv.burning.api.Burning;
import niv.burning.api.BurningStorage;
Level level;
BurningStorage source, target;
BurningContext context;
Burning burning = Burning.COAL.withValue(800, context);
try (Transaction transaction = Transaction.openOuter()) {
Burning transferred = BurningStorage.transfer(source, target, burning, context, transaction);
if (burning.equals(transferred)) {
transaction.commit();
}
}
Read the Fabric's Transaction API to understand the last example better.
Use a burning storage in your block entity (for mod developers)
Instead of implementing the two fields functionally equivalent to AbstractFurnaceBlockEntity
's litTimeRemaining
and litTotalTime
, do the following:
import niv.burning.api.BurningStorage;
import niv.burning.api.BurningStorageHelper;
import niv.burning.api.BurningStorageListener;
import niv.burning.api.base.SimpleBurningStorage;
public class MyBlockEntity extends BlockEntity implements BurningStorageListener {
// Add a simple burning storage to the entity
public final SimpleBurningStorage simpleBurningStorage = new SimpleBurningStorage();
public MyBlockEntity(...) {
// ...
// Add this to register this entity for changes in the simpleBurningStorage
this.simpleBurningStorage.addListener(this);
}
// Add this as a callback
@Override
public void burningStorageChanged(BurningStorage burningStorage) {
// Update this entity LIT property (if any) so to match if the given burningStorage is burning
BurningStorageHelper.tryUpdateLitProperty(this, burningStorage);
this.setChanged();
}
// And don't forget to add the following for saving and loading the simpleBurningStorage state
@Override
protected void loadAdditional(ValueInput valueInput) {
super.loadAdditional(valueInput);
// ...
valueInput
.read("Burning", SimpleBurningStorage.SNAPSHOT_CODEC)
.ifPresent(this.simpleBurningStorage::readSnapshot);
}
@Override
protected void saveAdditional(ValueOutput valueOutput) {
super.saveAdditional(valueOutput);
// ...
valueOutput
.store("Burning", SimpleBurningStorage.SNAPSHOT_CODEC, this.simpleBurningStorage.createSnapshot());
}
}
Don't forget to register it:
import niv.burning.api.BurningStorage;
// What you need
BlockEntityType<MyBlockEntity> MY_BLOCK_ENTITY = ...;
// How to
BurningStorage.SIDED.registerForBlockEntity((myBlockEntity, direction) -> myBlockEntity.simpleBurningStorage, MY_BLOCK_ENTITY);
Then you can access the equivalent litTimeRemaining
and litTotalTime
like:
this.simpleBurningStorage.getCurrentBurning(); // as the `litTimeRemaining` equivalent
this.simpleBurningStorage.setCurrentBurning(800);
this.simpleBurningStorage.getMaxBurning(); // as the `litTotalTime` equivalent
this.simpleBurningStorage.setMaxBurning(1600);