NBT TileEntity. Проблема с сохранением данных

Версия Minecraft
1.16.5
API
Forge
10
0
Добрый день. Столкнулся с такой проблемой, как загрузка NBT. Тайл вроде бы работает, генерирует энергию, но в тот же тик она исчезает из него. На разбор я потратил около дня и так и не понял в чем суть данной проблемы. Буду рад любой помощи.
TileGenerationEnergy сам тайл:
public class TileGenerationEnergy extends EnergyTileMI implements ITickableTileEntity, IEnergyEUTile {

     public TileGenerationEnergy() {
        super(RegisterMod.TILE_GENERATION_ENERGY.get());
     }


    @Override
    public long getGeneration(TileEntity tile) {
        return getVariant().gen;
    }

    @Override
    public long getTransfer(TileEntity tile) {
        return getVariant().transfer;
    }

    @Override
    public long getMaxEnergyStored(TileEntity tile) {
        return getVariant().cap;
    }

    @Override
    public void tick() {
        generation();
    }


    public void transfer(){
        assert this.world != null;

        if(this.world.isRemote) {
            if (getEnergyStored(this.getTileEntity()) <= 0) {
                for (BlockPos nearbyPos : BlockPos.getAllInBoxMutable(pos.add(-3, 0, -3), pos.add(3, 0, 3))) {
                    if (nearbyPos.equals(pos)) {
                        continue;
                    }
                    TileEntity nearbyState = world.getTileEntity(nearbyPos);
                    //if (nearbyState instanceof EnergyReceiverBlock) {
                        //EnergyReceiverBlock receiver = (EnergyReceiverBlock) nearbyState;
                        //receiver.transferEnergy(this.getTileEntity(), nearbyPos, energyToTransfer);
                    }
                }
            }
    }

    public void generation(){
        assert world != null;
        if(world.isRemote) {
            if (world.canSeeSky(this.pos)) {
                if (world.isDaytime()) {
                    generationEnergy(this.getTileEntity(), getGeneration(this.getTileEntity()), false);
                }else{
                    long genNight = getGeneration(this.getTileEntity()) / 2;
                    generationEnergy(this.getTileEntity(), genNight, false);
                }
            }
        }
    }
    @Override
    public boolean isFull(TileEntity tile){
        return getEnergyStored(this.getTileEntity()) >= getMaxEnergyStored(this.getTileEntity());
    }

    public BlockGenerationEnergy.Variant getVariant() {
        Block b = this.getBlockState().getBlock();
        return b instanceof BlockGenerationEnergy ? ((BlockGenerationEnergy)b).var : BlockGenerationEnergy.Variant.ADVANCED;
    }
}

IEnergyEUTile - подкласс тайлов использующие энергию:
public interface IEnergyEUTile extends IForgeTileEntity {

    default CompoundNBT getOrCreateEnergyTag(TileEntity entity) {
        return entity.getTileData();
    }

    default long getEnergyStored(TileEntity tile) {
        CompoundNBT tag = this.getOrCreateEnergyTag(tile);
        return Math.min(tag.getLong("Energy"), this.getMaxEnergyStored(tile));
    }

    long getGeneration(TileEntity tile);

    long getTransfer(TileEntity tile);

    long getMaxEnergyStored(TileEntity tile);

    boolean isFull(TileEntity tile);

    default void setEnergyStored(TileEntity tile, long energy) {
        CompoundNBT tag = this.getOrCreateEnergyTag(tile);
        tag.putLong("Energy", (long) MathHelper.clamp(energy, 0, this.getMaxEnergyStored(tile)));
    }

    default long transferEnergy(TileEntity tile, long maxTransfer, boolean simulate) {
        if(!simulate && getEnergyStored(tile) > 0) {
            setEnergyStored(tile,getEnergyStored(tile) - maxTransfer);
        }
        return maxTransfer;
    }

    default void generationEnergy(TileEntity tile, long maxGen, boolean simulate) {
        if(!simulate && !isFull(tile)) {
            setEnergyStored(tile,getEnergyStored(tile) + maxGen);
        }
    }
}

PS пробовал вводить чтение и внесение данных через read и write, но успеха все так же не оказалось, а получилось даже хуже.
 
assert world != null; if(world.isRemote) {
1) assert здесь нежелателен (уж точно не такой). Можешь пропустить NullPointer при случае, уж лучше обычная проверка на null. Да и в целом, эта вещь используется для тестов.
2) world.isRemote - клиент. Ты тикаешь на клиенте.
Вообще, далеко не всегда нужно разделять тиканье на клиенте и сервере, зачастую наоборот, ты хочешь чтоб оно было синхронно. А пересылка пакетов и загрузка/чтение тиков всегда занимает некоторое время, потому когда ты разделяешь в тиках на сторону - получаем рассинхрон.

Теперь мнение касательно архитектуры (и кода в целом):
1) IEnergyEUTile лучше разделить на несколько интерфейсов: IEUGeneratorTile, IEUStorageTile и IEUConsumerTile (или что-то в таком духе). Иначе, в конечном итог, у тебя выйдет антипаттерн god class (interface), по крайней мере, при добавлении новых функций точно перетечёт в него.
Ну и в целом, если честно, IEnergyEUTile выглядит несколько... странно? Хотя мб это просто я.
2) Пусть IEnergyEUTile#generationEnergy имеет ещё один аргумент - модификатор генерации. Тогда будет гораздо удобнее управлять этим балаганом, и не надо будет прописывать long genNight = getGeneration(this.getTileEntity()) / 2;. Тут, кстати. непонятно зачем используется long. Да и вообще, вместо выделения памяти каждый тик, можно было бы вынести переменную за метод. В общем, простор для улучшения достаточно объёмный.
3) Не уверен, что TileGenerationEnergy#generation должен быть публичным.
 
Так, я тут попытался другим способом пойти
Java:
@Override
    public long getEnergyStored(TileEntity tile) {
        return energy;
    }

Java:
@Override
    public void tick() {
        energy++;
        generation();
    }

Он стал генерировать энергию, тобишь все это время проблема была у меня перед носом
 
Назад
Сверху