Проблемы с Capability 1.16.5

Версия Minecraft
1.16.5
API
Forge
76
3
5
Cоздал интерфейс
Java:
public interface NewLevelSystem {
        public void setLevel(float pointsLevel);
        public void addExp(float points);

        public float getLevel();
    }

Затем создал методы
Java:
public class Levels implements RpgMod.NewLevelSystem {
    private float level = 0.0f;

    @Override
    public void setLevel(float points) {
        this.level = points;
    }

    @Override
    public void addExp(float points) {
        this.level += points;
    }

    @Override
    public float getLevel() {
        return this.level;
    }
}

И теперь мне нужно их записывать, пытаюсь записать их так
Java:
public class LevelStorage implements Capability.IStorage<RpgMod.NewLevelSystem> {
    @Nullable
    @Override
    public INBT writeNBT(Capability<RpgMod.NewLevelSystem> capability, RpgMod.NewLevelSystem instance, Direction side) {
        return new FloatNBT(instance.getLevel());
    }

    @Override
    public void readNBT(Capability<RpgMod.NewLevelSystem> capability, RpgMod.NewLevelSystem instance, Direction side, INBT nbt) {
        instance.set(((NBTPrimitive) nbt).getFloat());
    }
}

Но как я понял, NBTPrimitive из старых версий форджа.
Ещё ругается на FloatNBT говорит, что он приватный, аналога я не нашёл.

И так, где я ошибся или как сделать правильно?
 
76
3
5
мат запрещен
и вот точно такой же код, но в проекте который создал плагин в IDEA
Java:
@SubscribeEvent
    public static void AddCapabilities(AttachCapabilitiesEvent<Entity> event) {
        if (event.getObject() instanceof PlayerEntity) {
            event.addCapability(new ResourceLocation(RpgMod.MOD_ID, ("level")), new CapabilityProvider());

            PlayerEntity Player = (PlayerEntity) event.getObject();

            final float[] Value = {0};

            Player.getCapability(LevelCapability.PLAYER_LEVEL).ifPresent(Data -> Data.addValue(1));
            Player.getCapability(LevelCapability.PLAYER_LEVEL).ifPresent(Data -> Value[0] = Data.getValue());

            System.out.println("\u001B[32m" + "Test: " + Value[0] + "\u001B[0m");
        }
    }

Переношу его в новый и ничего
 
Последнее редактирование модератором:
76
3
5
мат запрещен
Чтож, я всё сломал при переносе файлов в другой проект...

Вот крашлог
CrashLog:
---- Minecraft Crash Report ----
// Don't be sad, have a hug! <3

Time: 19.11.22 14:14
Description: Ticking memory connection

java.lang.NullPointerException: Ticking memory connection
    at dajestalin.rpgmod.capability.systemlevel.ProviderCapability.<init>(ProviderCapability.java:17) ~[main/:?] {re:classloading}
    at dajestalin.rpgmod.capability.event.ClientEvent.AddCapabilities(ClientEvent.java:21) ~[main/:?] {re:classloading}
    at net.minecraftforge.eventbus.ASMEventHandler_3_ClientEvent_AddCapabilities_AttachCapabilitiesEvent.invoke(.dynamic) ~[?:?] {}
    at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:85) ~[eventbus-4.0.0.jar:?] {}
    at net.minecraftforge.eventbus.EventBus.post(EventBus.java:302) ~[eventbus-4.0.0.jar:?] {}
    at net.minecraftforge.eventbus.EventBus.post(EventBus.java:283) ~[eventbus-4.0.0.jar:?] {}
    at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:583) ~[forge:?] {re:classloading}
    at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:577) ~[forge:?] {re:classloading}
    at net.minecraftforge.common.capabilities.CapabilityProvider.doGatherCapabilities(CapabilityProvider.java:69) ~[forge:?] {re:classloading}
    at net.minecraftforge.common.capabilities.CapabilityProvider.gatherCapabilities(CapabilityProvider.java:64) ~[forge:?] {re:classloading}
    at net.minecraftforge.common.capabilities.CapabilityProvider.gatherCapabilities(CapabilityProvider.java:48) ~[forge:?] {re:classloading}
    at net.minecraft.entity.Entity.<init>(Entity.java:221) ~[forge:?] {re:classloading,pl:accesstransformer:B}
    at net.minecraft.entity.LivingEntity.<init>(LivingEntity.java:207) ~[forge:?] {re:classloading}
    at net.minecraft.entity.player.PlayerEntity.<init>(PlayerEntity.java:160) ~[forge:?] {re:classloading,pl:accesstransformer:B}
    at net.minecraft.entity.player.ServerPlayerEntity.<init>(ServerPlayerEntity.java:182) ~[forge:?] {re:classloading,pl:accesstransformer:B}
    at net.minecraft.server.management.PlayerList.createPlayerForUser(PlayerList.java:420) ~[forge:?] {re:classloading}
    at net.minecraft.network.login.ServerLoginNetHandler.tryAcceptPlayer(ServerLoginNetHandler.java:122) ~[forge:?] {re:classloading}
    at net.minecraft.network.login.ServerLoginNetHandler.tick(ServerLoginNetHandler.java:66) ~[forge:?] {re:classloading}
    at net.minecraft.network.NetworkManager.tick(NetworkManager.java:244) ~[forge:?] {re:classloading}
    at net.minecraft.network.NetworkSystem.tick(NetworkSystem.java:151) ~[forge:?] {re:classloading}
    at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:899) ~[forge:?] {re:classloading,pl:accesstransformer:B}
    at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:821) ~[forge:?] {re:classloading,pl:accesstransformer:B}
    at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:84) ~[forge:?] {re:classloading,pl:runtimedistcleaner:A}
    at net.minecraft.server.MinecraftServer.func_240802_v_(MinecraftServer.java:664) ~[forge:?] {re:classloading,pl:accesstransformer:B}
    at net.minecraft.server.MinecraftServer.lambda$startServer$0(MinecraftServer.java:233) ~[forge:?] {re:classloading,pl:accesstransformer:B}
    at java.lang.Thread.run(Thread.java:750) [?:1.8.0_352] {}


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- System Details --
Details:
    Minecraft Version: 1.16.5
    Minecraft Version ID: 1.16.5
    Operating System: Windows 10 (amd64) version 10.0
    Java Version: 1.8.0_352, Amazon.com Inc.
    Java VM Version: OpenJDK 64-Bit Server VM (mixed mode), Amazon.com Inc.
    Memory: 641261976 bytes (611 MB) / 1236271104 bytes (1179 MB) up to 1895825408 bytes (1808 MB)
    CPUs: 4
    JVM Flags: 2 total; -XX:+IgnoreUnrecognizedVMOptions -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump
    ModLauncher: 8.1.3+8.1.3+main-8.1.x.c94d18ec
    ModLauncher launch target: fmluserdevclient
    ModLauncher naming: mcp
    ModLauncher services:
        /mixin-0.8.4.jar mixin PLUGINSERVICE
        /eventbus-4.0.0.jar eventbus PLUGINSERVICE
        /forge-1.16.5-36.2.39_mapped_snapshot_20210309-1.16.5-launcher.jar object_holder_definalize PLUGINSERVICE
        /forge-1.16.5-36.2.39_mapped_snapshot_20210309-1.16.5-launcher.jar runtime_enum_extender PLUGINSERVICE
        /accesstransformers-3.0.1.jar accesstransformer PLUGINSERVICE
        /forge-1.16.5-36.2.39_mapped_snapshot_20210309-1.16.5-launcher.jar capability_inject_definalize PLUGINSERVICE
        /forge-1.16.5-36.2.39_mapped_snapshot_20210309-1.16.5-launcher.jar runtimedistcleaner PLUGINSERVICE
        /mixin-0.8.4.jar mixin TRANSFORMATIONSERVICE
        /forge-1.16.5-36.2.39_mapped_snapshot_20210309-1.16.5-launcher.jar fml TRANSFORMATIONSERVICE
    FML: 36.2
    Forge: net.minecraftforge:36.2.39
    FML Language Providers:
        [email protected]
        minecraft@1
    Mod List:
        client-extra.jar                                  |Minecraft                     |minecraft                     |1.16.5              |DONE      |Manifest: a1:d4:5e:04:4f:d3:d6:e0:7b:37:97:cf:77:b0:de:ad:4a:47:ce:8c:96:49:5f:0a:cf:8c:ae:b2:6d:4b:8a:3f
        forge-1.16.5-36.2.39_mapped_snapshot_20210309-1.16|Forge                         |forge                         |36.2.39             |DONE      |Manifest: NOSIGNATURE
        main                                              |RpgMod                        |rpgmod                        |NONE                |DONE      |Manifest: NOSIGNATURE
    Crash Report UUID: 4621794f-461b-43a0-bcd5-7be331770cf4
    Player Count: 0 / 8; []
    Data Packs: vanilla, mod:forge, mod:rpgmod
    Type: Integrated Server (map_client.txt)
    Is Modded: Definitely; Client brand changed to 'forge'

Памагите😭😭😭😭
Что это за
 
Последнее редактирование модератором:
76
3
5
мат запрещен
Как я понял, он ругается на это
Java:
package dajestalin.rpgmod.capability.systemlevel;

import net.minecraft.nbt.INBT;
import net.minecraft.util.Direction;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.LazyOptional;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;


public class ProviderCapability implements ICapabilitySerializable<INBT> {

    public static Capability<DataCapability> PLAYER_LEVEL;
    private final DataCapability playerLevel = new DataCapability();
    private final Capability.IStorage<DataCapability> storage = PLAYER_LEVEL.getStorage(); // ругается на это

    @Nonnull
    @Override
    public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
        if (cap.equals(PLAYER_LEVEL)) return LazyOptional.of(() -> playerLevel).cast();
        else return LazyOptional.empty();
    }

    @Override
    public INBT serializeNBT() {
        return storage.writeNBT(PLAYER_LEVEL, playerLevel, null);
    }

    @Override
    public void deserializeNBT(INBT nbt) {
        storage.readNBT(PLAYER_LEVEL, playerLevel, null, nbt);
    }
}

и на это, могу предроложить, что это из-за ("level") вот этой, но что с ней не так, не понятно...
Java:
package dajestalin.rpgmod.capability.event;

import dajestalin.rpgmod.RpgMod;
import dajestalin.rpgmod.capability.systemlevel.ProviderCapability;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

import static dajestalin.rpgmod.capability.systemlevel.ProviderCapability.PLAYER_LEVEL;


@Mod.EventBusSubscriber(modid = RpgMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT)
public class ClientEvent {
    @SubscribeEvent // выдача лвл игроку
    public static void AddCapabilities(AttachCapabilitiesEvent<Entity> event) {
        if (event.getObject() instanceof PlayerEntity) {
            event.addCapability(new ResourceLocation(RpgMod.MOD_ID, ("level")), new ProviderCapability()); // и на это

            PlayerEntity Player = (PlayerEntity) event.getObject();

//            final float[] Value = {0};

            Player.getCapability(PLAYER_LEVEL).ifPresent(Data -> Data.setLevel(1));
//            Player.getCapability(PLAYER_LEVEL).ifPresent(Data -> Value[0] = Data.getLevel());

//            System.out.println("\u001B[32m" + "Test: " + Value[0] + "\u001B[0m");
            System.out.println("\u001B[32m" + "Test123123");
        }
    }
}
 
Последнее редактирование модератором:
76
3
5
Почему, когда я пытаюсь вывести в чат или консоль что-нибудь, оно дублируется?

Java:
@SubscribeEvent
    public static void onJoin(EntityJoinWorldEvent event) {
        if (event.getEntity() instanceof PlayerEntity) {
            PlayerEntity Player = (PlayerEntity) event.getEntity();
            final float[] Value = {0};

            Player.getCapability(PLAYER_LEVEL).ifPresent(Data -> Value[0] = Data.getLevel());

            String message = String.format("You are " + "'" + (int) Value[0] + "'" + " level.");
            Player.sendMessage(new StringTextComponent(message), Player.getUUID());
        }
    }

И дублируется так, что первое сообщение выводит изначальное значение, а затем уже новое
Java:
private float totalLevel = 1.0f;

И при смерти, значение слитает до стандатного(1)
 

Вложения

  • Screenshot_1.png
    Screenshot_1.png
    7.2 KB · Просмотры: 6
Последнее редактирование:
76
3
5
Либо я не панимаю, либо я тупень, другого способа я не нашёл... пока что.
Java:
@SubscribeEvent
    public void onJoin(EntityJoinWorldEvent event) {
        if (event.getEntity() instanceof PlayerEntity) {

            PlayerEntity Player = (PlayerEntity) event.getEntity();
            final float[] Value = {0};

            Player.getCapability(PLAYER_LEVEL).ifPresent(Data -> Value[0] = Data.getLevel());

            String message = String.format("You are " + "'" + (int) Value[0] + "'" + " level.");
//            Player.sendMessage(new StringTextComponent(message), Player.getUUID());

            if (event.getWorld() instanceof ServerWorld) {
                Player.sendMessage(new StringTextComponent(message), Player.getUUID());
                System.out.println("Test123");
            } else {
                System.out.println("Ne Test123");
            }
        }
    }
 
Последнее редактирование:
76
3
5
Такс, ну с этим разобрался, но появилась новая проблема, или нет, не знаю как это назвать.

Получается так, что клиент всегда выводит стандартное значение(1), а у сервера уровень прибавляется.
Прибавляю я его через ивент сна
Java:
@SubscribeEvent // +1 уровень за сон
    public static void onSleepInBed(PlayerSleepInBedEvent event) {
        PlayerEntity Player = (PlayerEntity) event.getEntity();

        Player.getCapability(PLAYER_LEVEL).ifPresent(Data -> Data.addLevel(1));

        System.out.println("Добавление уровня при сне");
    }

И вывожу вот так
Java:
@SubscribeEvent // Вывод в чат нового уровня после сна
    public static void onWakeUpInBed(PlayerWakeUpEvent event) {
        PlayerEntity Player = (PlayerEntity) event.getEntity();

        final float[] Value = {0};

        Player.getCapability(PLAYER_LEVEL).ifPresent(Data -> Value[0] = Data.getLevel());

        String message = String.format("You woke up and your level became " + (int) Value[0]);
        Player.sendMessage(new StringTextComponent(message), Player.getUUID());
    }
Получается первое сообщение от клиента, выводит 1, второе от сервера, там прибавляется +1

Так вот вопрос, нужно ли их синхронизировать между собой, или я просто могу всегда использовать значение сервера?
 
76
3
5
Крашит майн при заходе в мир
CrashLog:
---- Minecraft Crash Report ----
// My bad.

Time: 22.11.22 21:06
Description: Saving entity NBT

java.lang.NullPointerException: Saving entity NBT
    at net.stalin.stalinrpg.capability.experiance.PlayerExperienceCapabilityProvider.lambda$new$0(PlayerExperienceCapabilityProvider.java:18) ~[?:?] {re:classloading}
    at net.minecraftforge.common.util.LazyOptional.getValue(LazyOptional.java:122) ~[forge:?] {re:classloading}
    at net.minecraftforge.common.util.LazyOptional.getValueUnsafe(LazyOptional.java:134) ~[forge:?] {re:classloading}
    at net.minecraftforge.common.util.LazyOptional.map(LazyOptional.java:210) ~[forge:?] {re:classloading}
    at net.stalin.stalinrpg.capability.experiance.PlayerExperienceCapabilityProvider.serializeNBT(PlayerExperienceCapabilityProvider.java:36) ~[?:?] {re:classloading}
    at net.minecraftforge.common.capabilities.CapabilityDispatcher.serializeNBT(CapabilityDispatcher.java:127) ~[forge:?] {re:classloading}
    at net.minecraftforge.common.capabilities.CapabilityProvider.serializeCaps(CapabilityProvider.java:136) ~[forge:?] {re:classloading}
    at net.minecraft.entity.Entity.saveWithoutId(Entity.java:1407) ~[forge:?] {re:classloading,pl:accesstransformer:B}
    at net.minecraft.server.integrated.IntegratedPlayerList.save(IntegratedPlayerList.java:26) ~[forge:?] {re:classloading,pl:runtimedistcleaner:A}
    at net.minecraft.server.management.PlayerList.saveAll(PlayerList.java:637) ~[forge:?] {re:classloading}
    at net.minecraft.server.integrated.IntegratedServer.tickServer(IntegratedServer.java:72) ~[forge:?] {re:classloading,pl:runtimedistcleaner:A}
    at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:642) ~[forge:?] {re:classloading,pl:accesstransformer:B}
    at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:232) ~[forge:?] {re:classloading,pl:accesstransformer:B}
    at java.lang.Thread.run(Thread.java:750) [?:1.8.0_352] {}


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Thread: Server thread
Stacktrace:
    at net.stalin.stalinrpg.capability.experiance.PlayerExperienceCapabilityProvider.lambda$new$0(PlayerExperienceCapabilityProvider.java:18) ~[?:?] {re:classloading}
    at net.minecraftforge.common.util.LazyOptional.getValue(LazyOptional.java:122) ~[forge:?] {re:classloading}
    at net.minecraftforge.common.util.LazyOptional.getValueUnsafe(LazyOptional.java:134) ~[forge:?] {re:classloading}
    at net.minecraftforge.common.util.LazyOptional.map(LazyOptional.java:210) ~[forge:?] {re:classloading}
    at net.stalin.stalinrpg.capability.experiance.PlayerExperienceCapabilityProvider.serializeNBT(PlayerExperienceCapabilityProvider.java:36) ~[?:?] {re:classloading}
    at net.minecraftforge.common.capabilities.CapabilityDispatcher.serializeNBT(CapabilityDispatcher.java:127) ~[forge:?] {re:classloading}
    at net.minecraftforge.common.capabilities.CapabilityProvider.serializeCaps(CapabilityProvider.java:136) ~[forge:?] {re:classloading}
-- Entity being saved --
Details:
    Entity Type: minecraft:player (net.minecraft.entity.player.ServerPlayerEntity)
    Entity ID: 60
    Entity Name: Dev
    Entity's Exact location: 108.50, 4.00, -133.50
    Entity's Block location: World: (108,4,-134), Chunk: (at 12,0,10 in 6,-9; contains blocks 96,0,-144 to 111,255,-129), Region: (0,-1; contains chunks 0,-32 to 31,-1, blocks 0,0,-512 to 511,255,-1)
    Entity's Momentum: 0.00, -0.08, 0.00
    Entity's Passengers: []
    Entity's Vehicle: ~~ERROR~~ NullPointerException: null
Stacktrace:
    at net.minecraft.entity.Entity.saveWithoutId(Entity.java:1407) ~[forge:?] {re:classloading,pl:accesstransformer:B}
    at net.minecraft.server.integrated.IntegratedPlayerList.save(IntegratedPlayerList.java:26) ~[forge:?] {re:classloading,pl:runtimedistcleaner:A}
    at net.minecraft.server.management.PlayerList.saveAll(PlayerList.java:637) ~[forge:?] {re:classloading}
    at net.minecraft.server.integrated.IntegratedServer.tickServer(IntegratedServer.java:72) ~[forge:?] {re:classloading,pl:runtimedistcleaner:A}
    at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:642) ~[forge:?] {re:classloading,pl:accesstransformer:B}
    at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:232) ~[forge:?] {re:classloading,pl:accesstransformer:B}
    at java.lang.Thread.run(Thread.java:750) [?:1.8.0_352] {}


-- System Details --
Details:
    Minecraft Version: 1.16.5
    Minecraft Version ID: 1.16.5
    Operating System: Windows 10 (amd64) version 10.0
    Java Version: 1.8.0_352, Amazon.com Inc.
    Java VM Version: OpenJDK 64-Bit Server VM (mixed mode), Amazon.com Inc.
    Memory: 585940736 bytes (558 MB) / 1052770304 bytes (1004 MB) up to 1895825408 bytes (1808 MB)
    CPUs: 4
    JVM Flags: 2 total; -XX:+IgnoreUnrecognizedVMOptions -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump
    ModLauncher: 8.1.3+8.1.3+main-8.1.x.c94d18ec
    ModLauncher launch target: fmluserdevclient
    ModLauncher naming: mcp
    ModLauncher services:
        /mixin-0.8.4.jar mixin PLUGINSERVICE
        /eventbus-4.0.0.jar eventbus PLUGINSERVICE
        /forge-1.16.5-36.2.34_mapped_official_1.16.5-launcher.jar object_holder_definalize PLUGINSERVICE
        /forge-1.16.5-36.2.34_mapped_official_1.16.5-launcher.jar runtime_enum_extender PLUGINSERVICE
        /accesstransformers-3.0.1.jar accesstransformer PLUGINSERVICE
        /forge-1.16.5-36.2.34_mapped_official_1.16.5-launcher.jar capability_inject_definalize PLUGINSERVICE
        /forge-1.16.5-36.2.34_mapped_official_1.16.5-launcher.jar runtimedistcleaner PLUGINSERVICE
        /mixin-0.8.4.jar mixin TRANSFORMATIONSERVICE
        /forge-1.16.5-36.2.34_mapped_official_1.16.5-launcher.jar fml TRANSFORMATIONSERVICE
    FML: 36.2
    Forge: net.minecraftforge:36.2.34
    FML Language Providers:
        [email protected]
        minecraft@1
    Mod List:
        client-extra.jar                                  |Minecraft                     |minecraft                     |1.16.5              |DONE      |Manifest: a1:d4:5e:04:4f:d3:d6:e0:7b:37:97:cf:77:b0:de:ad:4a:47:ce:8c:96:49:5f:0a:cf:8c:ae:b2:6d:4b:8a:3f
        main                                              |New Mega SUper Duper RPG Mod  |stalinrpg                     |NONE                |DONE      |Manifest: NOSIGNATURE
        forge-1.16.5-36.2.34_mapped_official_1.16.5-recomp|Forge                         |forge                         |36.2.34             |DONE      |Manifest: NOSIGNATURE
    Crash Report UUID: 1e49e04c-a804-48d3-9cce-befd180137b7
    Player Count: 1 / 8; [ServerPlayerEntity['Dev'/60, l='ServerLevel[New World]', x=108.50, y=4.00, z=-133.50]]
    Data Packs: vanilla, mod:stalinrpg, mod:forge
    Type: Integrated Server (map_client.txt)
    Is Modded: Definitely; Client brand changed to 'forge'

Ругается на это, как я понял из-за того, что LEVEL_CAP = null, как это фиксить?
Java:
public class PlayerExperienceCapabilityProvider implements ICapabilitySerializable<INBT> {
    @CapabilityInject(IBaseExperienceCapability.class)
    public static Capability<IBaseExperienceCapability> LEVEL_CAP = null;

    private final LazyOptional<IBaseExperienceCapability> instance = LazyOptional.of(() -> LEVEL_CAP.getDefaultInstance());

    public boolean hasCapability(Capability<?> capability, Direction side) {
        return capability == LEVEL_CAP;
    }

    @Override
    public <T> LazyOptional<T> getCapability(Capability<T> capability, Direction side) {
        return capability == LEVEL_CAP ? instance.cast() : LazyOptional.empty();
    }

    @Override
    public <T> LazyOptional<T> getCapability(Capability<T> capability) {
        return getCapability(capability,null);
    }

    @Override
    public INBT serializeNBT() {
        return instance.map(x -> x.getNBTData()).orElseGet(()-> new CompoundNBT());
    }

    @Override
    public void deserializeNBT(INBT t) {
        instance.ifPresent((cap) -> cap.setNBTData((CompoundNBT) t));
    }
}
 
Сверху