Burning
Burning is a library mod that provides a unified interface for managing fuel levels in most furnace-like blocks - both standard vanilla Minecraft ones and those added by third-party modifications.
The mod utilizes Fabric's Lookup and Transaction technologies.
Operating Principles
The foundation of Burning consists of two key components: the BurningStorage interface, responsible for adding and extracting burning fuel, and the Burning class, representing the burning fuel itself.
More detailed information can be found in the documentation or directly in the source code.
Installation and Usage (for Regular Users)
The installation process is identical to other mods. After installation without additional configuration, any block that extends the AbstractFurnaceBlockEntity abstract class (according to Mojang mappings) - whether it's a standard Furnace, Blast Furnace, or Smoker, as well as any third-party blocks - automatically receives a BurningStorage and becomes ready to interact with other modifications.
Block Exclusion (for Advanced Users)
In some cases, you may need to exclude specific blocks from extended functionality, for example, if they work incorrectly or due to personal preferences.
To do this, simply add the relevant block to the #burning:blacklist block tag. This prevents automatic BurningStorage creation for it.
The procedure requires creating a datapack with the following structure:
<pack_name>.zip
├── data
│ └── <pack_name>
│ └── burning
│ └── tags
│ └── blocks (before version 1.21) or block (after version 1.21)
│ └── blacklist.json
├── pack.mcmeta
└── pack.png (optional)
The blacklist.json file should contain a list of excluded blocks:
{
"replace": false,
"values": [
"mod_name:block_name_1",
"mod_name:block_name_2"
]
}
Dynamic Storage (for Experienced Users)
Some modifications add blocks that can use fuel but for various reasons don't extend the AbstractFurnaceBlockEntity class, so they don't automatically receive BurningStorage.
To solve this problem, Burning offers the burning:dynamic_storage dynamic registry that through datapacks and reflection provides the necessary functionality.
Before configuration, you need to determine:
- Block entity type
- Field similar to
litTimeRemaininginAbstractFurnaceBlockEntity - Field similar to
litTotalTimeinAbstractFurnaceBlockEntity
The datapack should have the following structure:
<pack_name>.zip
├── data
│ └── <pack_name>
│ └── burning
│ └── dynamic_storage
│ └── <block_entity_type_1>.json
│ └── <block_entity_type_2>.json
├── pack.mcmeta
└── pack.png (optional)
Each *.json file is configured as follows:
{
"type": "example_mod:custom_furnace_type",
"lit_time": "burnTime",
"lit_duration": "fuelTime"
}
Developer Integration
Dependency Setup
Add to the gradle.build file:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
filter {
includeGroup "maven.modrinth"
}
}
}
dependencies {
modImplementation "maven.modrinth:burning:<burning_version>"
}
Basic Operations
Retrieving fuel storage:
import niv.burning.api.BurningStorage;
Level world;
BlockPos position;
@Nullable
BurningStorage storage = BurningStorage.SIDED.find(world, position, null);
The third argument of the find method is usually ignored, so it's safe to pass null.
Transferring fuel between storages:
import niv.burning.api.Burning;
import niv.burning.api.BurningStorage;
Level world;
BurningStorage source, target;
BurningContext context = ...;
// Creating fuel amount for transfer
Burning fuel = Burning.COAL.withValue(800, context);
// Transfer
Burning transferred = BurningStorage.transfer(
source,
target,
fuel,
context,
null);
Usage in Custom Block Entities
Instead of implementing fields similar to litTimeRemaining and litTotalTime, it's recommended to:
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 {
public final SimpleBurningStorage simpleBurningStorage = new SimpleBurningStorage();
public MyBlockEntity(...) {
// ...
this.simpleBurningStorage.addListener(this);
}
@Override
public void burningStorageChanged(BurningStorage burningStorage) {
BurningStorageHelper.tryUpdateLitProperty(this, burningStorage);
this.setChanged();
}
@Override
protected void loadAdditional(ValueInput input) {
super.loadAdditional(input);
input.read("Burning", SimpleBurningStorage.SNAPSHOT_CODEC)
.ifPresent(this.simpleBurningStorage::readSnapshot);
}
@Override
protected void saveAdditional(ValueOutput output) {
super.saveAdditional(output);
output.store("Burning", SimpleBurningStorage.SNAPSHOT_CODEC,
this.simpleBurningStorage.createSnapshot());
}
}
Don't forget to register:
BurningStorage.SIDED.registerForBlockEntity((blockEntity, direction) ->
blockEntity.simpleBurningStorage, MY_BLOCK_ENTITY_TYPE);
Access to main field equivalents:
this.simpleBurningStorage.getCurrentBurning(); // litTimeRemaining equivalent
this.simpleBurningStorage.setCurrentBurning(800);
this.simpleBurningStorage.getMaxBurning(); // litTotalTime equivalent
this.simpleBurningStorage.setMaxBurning(1600);