Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/hbmmods/hbm-s-nuclear-tech-git/llms.txt

Use this file to discover all available pages before exploring further.

NTM uses a fully custom power unit called HE (High Energy), stored as Java long values with no standardised conversion factor to RF, FE, or any other energy system. The power network is managed by PowerNetMK2, a node-based distribution system built on top of NTM’s UNINOS (Universal Node Space) framework. Each cable tile registers a PowerNode into the global Nodespace, provider and receiver tiles subscribe themselves to those nodes every tick, and the network redistributes energy proportionally — honouring per-receiver priority levels — before debiting providers. Implementing the right interface from the api.hbm.energymk2 package is all that is required to participate in this network; no event registration or IMC handshake is needed.

Interface Hierarchy

The energy API is a small, well-layered hierarchy. Choose the interface that matches what your tile does:
IEnergyConnectorMK2          ← base: "can this side connect?"
├── IEnergyHandlerMK2        ← adds getPower / setPower / getMaxPower  (DO NOT implement directly)
│   ├── IEnergyProviderMK2   ← your tile SENDS power into the network
│   └── IEnergyReceiverMK2   ← your tile CONSUMES power from the network
└── IEnergyConductorMK2      ← your tile is a cable/wire (no storage)
IEnergyHandlerMK2 carries the Javadoc comment “DO NOT USE DIRECTLY!” — it is a common ancestor that unifies providers and receivers but excludes conductors. Always implement IEnergyProviderMK2 or IEnergyReceiverMK2 rather than IEnergyHandlerMK2 itself.

Interface Reference

Every energy-network participant implements this interface (directly or via a descendant). Its single method controls sided connectivity.
package api.hbm.energymk2;

import net.minecraftforge.common.util.ForgeDirection;

public interface IEnergyConnectorMK2 {
    /**
     * Whether the given side can be connected to.
     * dir refers to the side of THIS block, not the connecting block.
     */
    public default boolean canConnect(ForgeDirection dir) {
        return dir != ForgeDirection.UNKNOWN;
    }
}
The default implementation accepts all six cardinal directions. Override it to restrict which faces expose the power port on your tile.
Extends IEnergyConnectorMK2 and ILoadedTile. Declares the three state accessors shared by providers and receivers, plus an optional debug particle position helper and the EnergyControl integration hook.
package api.hbm.energymk2;

import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Vec3;

public interface IEnergyHandlerMK2 extends IEnergyConnectorMK2, ILoadedTile {

    public long getPower();
    public void setPower(long power);
    public long getMaxPower();

    /** Returns the world-space position used for debug energy particles. */
    public default Vec3 getDebugParticlePosMK2() {
        TileEntity te = (TileEntity) this;
        Vec3 vec = Vec3.createVectorHelper(te.xCoord + 0.5, te.yCoord + 1, te.zCoord + 0.5);
        return vec;
    }

    /** Populates an NBTTagCompound for EnergyControl mod display. */
    public default void provideInfoForECMK2(NBTTagCompound data) {
        data.setLong(CompatEnergyControl.L_ENERGY_HE, this.getPower());
        data.setLong(CompatEnergyControl.L_CAPACITY_HE, this.getMaxPower());
    }
}
Extend this interface on tile entities that generate or store power and push it into the network. Each tick, call tryProvide(world, x, y, z, dir) for every face adjacent to a cable or receiver.
package api.hbm.energymk2;

import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;

public interface IEnergyProviderMK2 extends IEnergyHandlerMK2 {

    /** Removes power from internal storage. Default has no sanity check. */
    public default void usePower(long power) {
        this.setPower(this.getPower() - power);
    }

    /**
     * Maximum HE that can be pushed per tick.
     * Defaults to getMaxPower() — override for throttled generators.
     */
    public default long getProviderSpeed() {
        return this.getMaxPower();
    }

    /**
     * Call once per adjacent face every update tick.
     * Registers this tile as a provider on any connected PowerNetMK2,
     * or directly transfers to an adjacent IEnergyReceiverMK2.
     */
    public default void tryProvide(World world, int x, int y, int z, ForgeDirection dir) { ... }
}
Extend this interface on tile entities that consume power from the network. Call trySubscribe(world, x, y, z, dir) every tick for each adjacent face.
package api.hbm.energymk2;

import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;

public interface IEnergyReceiverMK2 extends IEnergyHandlerMK2 {

    /** Called by the network to deposit power. Returns the overshoot (unaccepted amount). */
    public default long transferPower(long power) { ... }

    /**
     * Maximum HE accepted per tick from the network.
     * Defaults to getMaxPower().
     */
    public default long getReceiverSpeed() {
        return this.getMaxPower();
    }

    /** If true, adjacent providers may bypass the cable network and push power directly. */
    public default boolean allowDirectProvision() { return true; }

    /** Subscribe to a PowerNetMK2 via the cable at (x,y,z) on face dir. Call every tick. */
    public default void trySubscribe(World world, int x, int y, int z, ForgeDirection dir) { ... }

    /** Unsubscribe from the net at (x,y,z). Call on tile invalidation/chunk unload. */
    public default void tryUnsubscribe(World world, int x, int y, int z) { ... }

    /** Priority relative to other receivers on the same network. */
    public default ConnectionPriority getPriority() {
        return ConnectionPriority.NORMAL;
    }

    public enum ConnectionPriority {
        LOWEST, LOW, NORMAL, HIGH, HIGHEST
    }
}
Higher-priority receivers are filled first. When supply is insufficient to satisfy all demand, HIGHEST receivers receive their full share before NORMAL or LOW receivers are considered.
Implement this on tiles that route power but do not store it. The only required method is createNode(), which has a full default implementation that registers a six-way connected PowerNode.
package api.hbm.energymk2;

import api.hbm.energymk2.Nodespace.PowerNode;

public interface IEnergyConductorMK2 extends IEnergyConnectorMK2 {

    /**
     * Creates a PowerNode centred on this tile with connections to all six
     * cardinal neighbours. Override to limit connectivity (e.g. axis-locked cables).
     */
    public default PowerNode createNode() { ... }
}
PowerNetMK2 is instantiated internally and should not be constructed by addon code. However, its public fields are useful for monitoring:
package api.hbm.energymk2;

public class PowerNetMK2 extends NodeNet<IEnergyReceiverMK2, IEnergyProviderMK2, PowerNode> {

    /** Total HE transferred through this net since last reset. */
    public long energyTracker = 0L;

    /**
     * Per-tick distribution: sums provider supply, sums receiver demand
     * (split by ConnectionPriority), then distributes proportionally.
     * Stale entries older than 3000 ms are pruned automatically.
     */
    @Override
    public void update() { ... }

    /**
     * Diode variant: pushes a fixed amount of power into the net's receivers
     * without drawing from registered providers. Returns the remainder.
     */
    public long sendPowerDiode(long power) { ... }
}
Nodespace is a compatibility shim over UNINOS. Use the static helpers to interact with registered nodes:
package api.hbm.energymk2;

public class Nodespace {

    /** Retrieve the PowerNode at a world position, or null if none exists. */
    @Deprecated
    public static PowerNode getNode(World world, int x, int y, int z) { ... }

    /** Register a PowerNode into the global node space. */
    @Deprecated
    public static void createNode(World world, PowerNode node) { ... }

    /** Remove the PowerNode at a position (call when a cable is broken). */
    @Deprecated
    public static void destroyNode(World world, int x, int y, int z) { ... }
}
These methods are marked @Deprecated because UNINOS now manages nodes directly. The methods remain functional — the deprecation is a signal that they may be consolidated in a future release, not that they are broken.

IBatteryItem — Chargeable Items

Items that act as portable power storage (batteries, capacitor packs, power cores) implement IBatteryItem.
package api.hbm.energymk2;

import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;

public interface IBatteryItem {

    /** Adds HE to the stack's stored charge. */
    public void chargeBattery(ItemStack stack, long i);

    /** Sets the exact stored charge. */
    public void setCharge(ItemStack stack, long i);

    /** Removes HE from the stack's stored charge. */
    public void dischargeBattery(ItemStack stack, long i);

    /** Returns the currently stored HE. */
    public long getCharge(ItemStack stack);

    /** Returns the maximum storable HE. */
    public long getMaxCharge(ItemStack stack);

    /** Returns the max HE added per charge operation. */
    public long getChargeRate(ItemStack stack);

    /** Returns the max HE removed per discharge operation. */
    public long getDischargeRate(ItemStack stack);

    /** Returns the NBT tag name used to store the charge long. Defaults to "charge". */
    public default String getChargeTagName() { return "charge"; }

    /** Static helper: returns the charge tag name for the item held in the given stack. */
    public static String getChargeTagName(ItemStack stack) {
        return ((IBatteryItem) stack.getItem()).getChargeTagName();
    }

    /** Utility: returns a zero-charge copy of the stack, or null if not a battery. */
    public static ItemStack emptyBattery(ItemStack stack) { ... }

    /** Utility: returns a zero-charge stack from the given Item, or null if not a battery. */
    public static ItemStack emptyBattery(Item item) { ... }
}

Full Implementation Example: Simple Power Generator

The following example shows a minimal tile entity that generates HE every tick and pushes it into any connected cable or adjacent receiver. It is intentionally verbose so every required element is visible.
package com.example.mymod.tile;

import api.hbm.energymk2.IEnergyProviderMK2;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;

public class TileEntityMyGenerator extends TileEntity
        implements IEnergyProviderMK2 {

    // --- Internal state ---
    private long power    = 0L;
    private long maxPower = 100_000L; // 100 kHE buffer
    private long genRate  = 500L;     // 500 HE per tick

    // -------------------------------------------------------
    // IEnergyHandlerMK2 — required storage accessors
    // -------------------------------------------------------

    @Override public long getPower()             { return power; }
    @Override public void setPower(long power)   { this.power = power; }
    @Override public long getMaxPower()          { return maxPower; }

    // -------------------------------------------------------
    // IEnergyProviderMK2 — optional speed throttle
    // -------------------------------------------------------

    @Override
    public long getProviderSpeed() {
        return 2_000L; // push up to 2 kHE per tick regardless of buffer size
    }

    // -------------------------------------------------------
    // IEnergyConnectorMK2 — restrict connection to top face only
    // -------------------------------------------------------

    @Override
    public boolean canConnect(ForgeDirection dir) {
        return dir == ForgeDirection.UP;
    }

    // -------------------------------------------------------
    // TileEntity lifecycle
    // -------------------------------------------------------

    @Override
    public void updateEntity() {
        if (worldObj.isRemote) return;

        // 1. Generate power (cap at buffer max)
        power = Math.min(power + genRate, maxPower);

        // 2. Attempt to push power upward into the network
        tryProvide(worldObj, xCoord, yCoord + 1, zCoord, ForgeDirection.UP);
    }

    // -------------------------------------------------------
    // NBT persistence
    // -------------------------------------------------------

    @Override
    public void writeToNBT(NBTTagCompound tag) {
        super.writeToNBT(tag);
        tag.setLong("power", power);
    }

    @Override
    public void readFromNBT(NBTTagCompound tag) {
        super.readFromNBT(tag);
        power = tag.getLong("power");
    }
}
Always guard your updateEntity() logic with if (worldObj.isRemote) return;. Energy network calls are server-side only; executing them on the client will cause NullPointerExceptions inside Nodespace.

EnergyControl Mod Integration

NTM’s IEnergyHandlerMK2 includes a default implementation of provideInfoForECMK2(NBTTagCompound data) that writes the current stored HE and maximum capacity into the compound using NTM’s EnergyControl key constants:
// Executed automatically by the default implementation:
data.setLong(CompatEnergyControl.L_ENERGY_HE,   this.getPower());
data.setLong(CompatEnergyControl.L_CAPACITY_HE, this.getMaxPower());
If the EnergyControl mod is present and your tile block is right-clicked with an EC probe, this data is used to render an in-world power readout. No additional action is needed unless you want to expose extra custom fields, in which case you can override provideInfoForECMK2 and call super first.

Key Facts & Gotchas

NTM’s HE unit is self-contained. There is no official conversion rate to Redstone Flux or Forge Energy. Do not attempt to bridge the two systems via a fixed multiplier — the power magnitudes are chosen for NTM’s own balance and would not be meaningful in an RF context.
The PowerNetMK2 prunes stale entries after 3 000 ms (about 60 ticks at 20 TPS). Providers and receivers must re-register themselves each tick by calling tryProvide or trySubscribe on every relevant adjacent position. Failing to do so causes the tile to silently drop off the network.
IEnergyConductorMK2 tiles only need to call Nodespace.createNode() when they are placed and Nodespace.destroyNode() when they are broken. The node persists in world data between chunk loads; conductors do not re-register every tick.
All storage fields and method parameters use long. Be careful with literals — write 100_000L not 100_000 — to avoid accidental integer truncation at large values.
Both IEnergyProviderMK2 and IEnergyReceiverMK2 extend ILoadedTile through IEnergyHandlerMK2. ILoadedTile is a marker interface with no methods to implement, but it must be satisfied by the hierarchy. Since you are implementing these interfaces on a TileEntity subclass, this is automatically satisfied by the Forge tile loading mechanism.

Build docs developers (and LLMs) love