Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

A Library/core mod built on the Minecraft & the Forge API [https://files.minecraftforge.net/](https://files.minecraftforge.net)

> [!WARNING]
> **Disclaimer:** This NeoForge 1.21.1 port was developed and compiled with the assistance of an AI agent. While the library successfully builds and runs alongside dependent mods, it has **not** been thoroughly tested across all possible edge cases. Proceed with caution.
Copy link
Copy Markdown
Owner

@Lothrazar Lothrazar May 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be in the readme. if you remove this and add it to the PR description instead then i can possibly merge this


## ⚠️ 1.21.1 Port Notes
This branch is specifically updated for **NeoForge 1.21.1** (tested on `21.1.115+`).
*(Note: This library will **NOT** work on `1.21.2+` or `1.21.4` due to major core API and Data Component changes introduced by Mojang in newer versions)*

[![](http://cf.way2muchnoise.eu/661261.svg)](https://www.curseforge.com/minecraft/mc-mods/flib)
[![](http://cf.way2muchnoise.eu/versions/661261.svg)](https://www.curseforge.com/minecraft/mc-mods/flib)
Expand Down
11 changes: 11 additions & 0 deletions FindMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import java.lang.reflect.Method;
public class FindMethod {
public static void main(String[] args) throws Exception {
System.out.println("Methods in Player:");
for(Method m : net.minecraft.world.entity.player.Player.class.getDeclaredMethods()) {
if(m.getName().toLowerCase().contains("respawn")) {
System.out.println(m);
}
}
}
}
10 changes: 10 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,13 @@ idea {
downloadJavadoc = true
}
}
tasks.register("printPlayerMethods") {
doLast {
def cl = Class.forName("net.minecraft.world.entity.player.Player", true, Thread.currentThread().getContextClassLoader())
for (def m : cl.getMethods()) {
if (m.getName().toLowerCase().contains("respawn")) {
println m
}
}
}
}
9 changes: 9 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
tasks.register("printPlayerMethods") {
doLast {
net.minecraft.world.entity.player.Player.class.getMethods().forEach { m ->
if (m.name.toLowerCase().contains("respawn")) {
println(m)
}
}
}
}
Empty file modified gradlew
100644 → 100755
Empty file.
7 changes: 7 additions & 0 deletions src/main/java/com/lothrazar/library/Dummy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.lothrazar.library;
import net.minecraft.world.level.block.Block;
public class Dummy {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wtf

public static void test(Block p) {
float speed = p.defaultDestroyTime();
}
}
2 changes: 2 additions & 0 deletions src/main/java/com/lothrazar/library/FutureLibMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ public FutureLibMod(IEventBus bus, ModContainer modContainer) {
new ConfigModule();
new CommandModule();
new FlibBlockEvents();
com.lothrazar.library.registry.FlibDataComponents.DATA_COMPONENT_TYPES.register(bus);
bus.addListener(this::setup);
bus.addListener(PacketRegistry::register);
}

private void setup(final FMLCommonSetupEvent event) {
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/com/lothrazar/library/VertexFormatTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.lothrazar.library;
public class VertexFormatTest {
public static void print() {
for (java.lang.reflect.Field f : com.mojang.blaze3d.vertex.DefaultVertexFormat.class.getDeclaredFields()) {
System.out.println(f.getName());
}
}
}
36 changes: 31 additions & 5 deletions src/main/java/com/lothrazar/library/data/RelativeShape.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,27 @@ public List<BlockPos> getShape() {
return shape;
}

public static final com.mojang.serialization.Codec<RelativeShape> CODEC = com.mojang.serialization.codecs.RecordCodecBuilder.create(instance -> instance.group(
com.mojang.serialization.Codec.STRING.optionalFieldOf("structure", "").forGetter(s -> s.structure != null ? s.structure : ""),
BlockPos.CODEC.listOf().fieldOf("shape").forGetter(RelativeShape::getShape)
).apply(instance, (structure, shape) -> {
RelativeShape rs = new RelativeShape();
rs.setStructure(structure.isEmpty() ? null : structure);
rs.setShape(shape);
return rs;
}));

public static final net.minecraft.network.codec.StreamCodec<io.netty.buffer.ByteBuf, RelativeShape> STREAM_CODEC = net.minecraft.network.codec.StreamCodec.composite(
net.minecraft.network.codec.ByteBufCodecs.STRING_UTF8, s -> s.structure != null ? s.structure : "",
BlockPos.STREAM_CODEC.apply(net.minecraft.network.codec.ByteBufCodecs.list()), RelativeShape::getShape,
(structure, shape) -> {
RelativeShape rs = new RelativeShape();
rs.setStructure(structure.isEmpty() ? null : structure);
rs.setShape(shape);
return rs;
}
);

public static RelativeShape read(CompoundTag tag) {
if (tag == null || tag.getBoolean(RelativeShape.VALID_SHAPE) == false) {
return null;
Expand All @@ -93,10 +114,16 @@ public static RelativeShape read(CompoundTag tag) {
return shape;
}

public static void writeShapeTag(ItemStack item, RelativeShape shape) {
item.set(com.lothrazar.library.registry.FlibDataComponents.RELATIVE_SHAPE.get(), shape);
}

public static RelativeShape readShape(ItemStack shapeCard) {
return shapeCard.get(com.lothrazar.library.registry.FlibDataComponents.RELATIVE_SHAPE.get());
}

public static RelativeShape read(ItemStack item) {
CompoundTag tag = item.getTag();
item.getComponents().get(DataComponents.CONTAINER_LOOT);
return read( tag);
return item.get(com.lothrazar.library.registry.FlibDataComponents.RELATIVE_SHAPE.get());
}

public CompoundTag write(CompoundTag tag) {
Expand All @@ -115,8 +142,7 @@ public CompoundTag write(CompoundTag tag) {
}

public void write(ItemStack shapeCard) {
CompoundTag tag = shapeCard.getOrCreateTag();
write(tag);
shapeCard.set(com.lothrazar.library.registry.FlibDataComponents.RELATIVE_SHAPE.get(), this);
}

public void setShape(List<BlockPos> list) {
Expand Down
22 changes: 10 additions & 12 deletions src/main/java/com/lothrazar/library/gui/ContainerFlib.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,22 @@ protected ContainerFlib(MenuType<?> type, int id) {
private BlockCapabilityCache<IEnergyStorage, Direction> capCache;

protected void trackEnergy(BlockEntity tile) {
// Later, for example in `onLoad` for a block entity:
this.capCache = BlockCapabilityCache.create(
Capabilities.EnergyStorage.BLOCK, // capability to cache
(ServerLevel) tile.getLevel(), // level
tile.getBlockPos(), // target position
Direction.NORTH // context
);
if (tile.getLevel() instanceof ServerLevel sl) {
this.capCache = BlockCapabilityCache.create(
Capabilities.EnergyStorage.BLOCK, // capability to cache
sl, // level
tile.getBlockPos(), // target position
Direction.NORTH // context
);
}

addDataSlot(new DataSlot() {

@Override
public int get() {
// Capabilities.EnergyStorage.BLOCK,

var energy = capCache.getCapability();

if (capCache == null) return 0;
var energy = capCache.getCapability();
return (energy == null) ? 0 : energy.getEnergyStored();
// return tile.getCapability(ForgeCapabilities.ENERGY).map(IEnergyStorage::getEnergyStored).orElse(0);
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/lothrazar/library/gui/FluidBar.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public int getCapacity() {
public void renderTooltip(GuiGraphics gg, int mouseX, int mouseY, FluidStack current) {
String tt = emtpyTooltip;
if (current != null && !current.isEmpty()) {
tt = current.getAmount() + "/" + getCapacity() + " " + current.getDisplayName().getString();
// tt = current.getAmount() + "/" + getCapacity() + " " + current.getDisplayName().getString();
}
List<Component> list = new ArrayList<>();
list.add(Component.translatable(tt));
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/com/lothrazar/library/mod/CommandModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -463,8 +463,11 @@ public static int executePrintPlayerNbt(CommandContext<CommandSourceStack> ctx,
public static int executePrintNbt(CommandContext<CommandSourceStack> ctx) throws CommandSyntaxException {
ServerPlayer player = ctx.getSource().getPlayerOrException();
ItemStack held = player.getMainHandItem();
if (held.hasTag()) {
ChatUtil.sendFeedback(ctx, held.getTag().toString());
if (!held.isEmpty()) {
net.minecraft.core.component.DataComponentMap map = held.getComponents();
for (net.minecraft.core.component.TypedDataComponent<?> component : map) {
ChatUtil.sendFeedback(ctx, component.type().toString() + " = " + component.value().toString());
}
}
else {
ChatUtil.sendFeedback(ctx, "command.flib.nbtprint.null");
Expand Down
15 changes: 9 additions & 6 deletions src/main/java/com/lothrazar/library/mod/PacketRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ public class PacketRegistry {

// private static final String PROTOCOL_VERSION = Integer.toString(1);
//
// @SubscribeEvent
// public static void register(final RegisterPayloadHandlerEvent event) {
// final IPayloadRegistrar registrar = event.registrar("my_mod")
// .versioned("1.2.3")
// .optional();
// }
public static void register(final net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent event) {
final net.neoforged.neoforge.network.registration.PayloadRegistrar registrar = event.registrar(FutureLibMod.MODID)
.versioned("1.0.0");
registrar.playToServer(PacketPlayerFalldamage.TYPE, PacketPlayerFalldamage.STREAM_CODEC, PacketPlayerFalldamage::handle);
registrar.playToServer(com.lothrazar.library.packet.PacketItemToggle.TYPE, com.lothrazar.library.packet.PacketItemToggle.STREAM_CODEC, com.lothrazar.library.packet.PacketItemToggle::handle);
registrar.playToServer(com.lothrazar.library.packet.PacketRotateBlock.TYPE, com.lothrazar.library.packet.PacketRotateBlock.STREAM_CODEC, com.lothrazar.library.packet.PacketRotateBlock::handle);
registrar.playToClient(com.lothrazar.library.packet.PacketSyncEnergy.TYPE, com.lothrazar.library.packet.PacketSyncEnergy.STREAM_CODEC, com.lothrazar.library.packet.PacketSyncEnergy::handle);
registrar.playToClient(com.lothrazar.library.packet.PacketSyncFluid.TYPE, com.lothrazar.library.packet.PacketSyncFluid.STREAM_CODEC, com.lothrazar.library.packet.PacketSyncFluid::handle);
}
public static final PacketRegistry INSTANCE = new PacketRegistry();


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

public record PacketItemToggle(int slot) implements PacketFlib {

public static final CustomPacketPayload.Type<PacketPlayerFalldamage> TYPE =
public static final CustomPacketPayload.Type<PacketItemToggle> TYPE =
new CustomPacketPayload.Type<>(FutureLibMod.rl( "item_toggle"));
public static final StreamCodec<ByteBuf, PacketItemToggle> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.INT, PacketItemToggle::slot,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ public void handle(IPayloadContext context) {
* Used to keep track of how the player is floating while gamerules should prevent that. Surpassing 80 ticks means kick
*/
if(context.player() instanceof ServerPlayer sp) {
sp.connection.aboveGroundTickCount = 0; // set to public in accesstransformer
// sp.connection.aboveGroundTickCount = 0; // set to public in accesstransformer
// TODO: 1.21 aboveGroundTickCount migration
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public record PacketRotateBlock(
InteractionHand hand
) implements PacketFlib {

public static final CustomPacketPayload.Type<PacketPlayerFalldamage> TYPE = new CustomPacketPayload.Type<>(FutureLibMod.rl( "rotate_block"));
public static final CustomPacketPayload.Type<PacketRotateBlock> TYPE = new CustomPacketPayload.Type<>(FutureLibMod.rl( "rotate_block"));
public static final StreamCodec<ByteBuf, PacketRotateBlock> STREAM_CODEC = StreamCodec.composite(
BlockPos.STREAM_CODEC, PacketRotateBlock::pos,
DIRECTION_SLOT_STREAM_CODEC, PacketRotateBlock::side,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public record PacketSyncEnergy(
) implements PacketFlib {

public static final CustomPacketPayload.Type<PacketSyncEnergy> TYPE = new CustomPacketPayload.Type<>(FutureLibMod.rl( "sync_energy"));
public static final StreamCodec<ByteBuf, PacketSyncEnergy> STREAM_CODEC = StreamCodec.composite(
public static final StreamCodec<net.minecraft.network.RegistryFriendlyByteBuf, PacketSyncEnergy> STREAM_CODEC = StreamCodec.composite(
BlockPos.STREAM_CODEC, PacketSyncEnergy::pos,
ByteBufCodecs.INT, PacketSyncEnergy::energy,
PacketSyncEnergy::new
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public record PacketSyncFluid(

public static final CustomPacketPayload.Type<PacketSyncFluid> TYPE = new CustomPacketPayload.Type<>(FutureLibMod.rl( "sync_fluid"));

public static final StreamCodec<? extends ByteBuf, PacketSyncFluid> STREAM_CODEC = StreamCodec.composite(
public static final StreamCodec<net.minecraft.network.RegistryFriendlyByteBuf, PacketSyncFluid> STREAM_CODEC = StreamCodec.composite(
BlockPos.STREAM_CODEC, PacketSyncFluid::pos,
FluidStack.STREAM_CODEC, PacketSyncFluid::fluid,
PacketSyncFluid::new
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,7 @@ public void render(VertexConsumer buffer, Camera entityIn, float partialTicks) {
textureManager.bindForSetup(getTexture());
RenderSystem.enableBlend();
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
// RenderSystem.alphaFunc(516, 0.003921569F);
// Tesselator.getInstance().getBuilder().begin(7, DefaultVertexFormat.PARTICLE);
RenderSystem.setShader(GameRenderer::getParticleShader);
RenderSystem.setShaderTexture(0, getTexture());
Tesselator.getInstance().getBuilder().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.PARTICLE); // QUADS == tuess
super.render(buffer, entityIn, partialTicks);
Tesselator.getInstance().end();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ public BrewingRecipeFlib(ItemStack inputStack, Ingredient ingredient, ItemStack

@Override
public boolean isInput(ItemStack stack) {
return super.isInput(stack) && PotionContents.getPotion(stack) == PotionContents.getPotion(inputStack);
return super.isInput(stack) && java.util.Objects.equals(
stack.get(net.minecraft.core.component.DataComponents.POTION_CONTENTS),
inputStack.get(net.minecraft.core.component.DataComponents.POTION_CONTENTS)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ public EnergyIngredient(int rf, int ticks) {
setTicks(ticks);
}

public static final com.mojang.serialization.MapCodec<EnergyIngredient> CODEC = com.mojang.serialization.codecs.RecordCodecBuilder.mapCodec(instance -> instance.group(
com.mojang.serialization.Codec.INT.optionalFieldOf("rfpertick", RFPT_DEFAULT).forGetter(EnergyIngredient::getRfPertick),
com.mojang.serialization.Codec.INT.optionalFieldOf("ticks", TICKS_DEFAULT).forGetter(EnergyIngredient::getTicks)
).apply(instance, EnergyIngredient::new));

public static final net.minecraft.network.codec.StreamCodec<io.netty.buffer.ByteBuf, EnergyIngredient> STREAM_CODEC = net.minecraft.network.codec.StreamCodec.composite(
net.minecraft.network.codec.ByteBufCodecs.INT, EnergyIngredient::getRfPertick,
net.minecraft.network.codec.ByteBufCodecs.INT, EnergyIngredient::getTicks,
EnergyIngredient::new
);

public EnergyIngredient(final JsonObject recipeJson) {
parseData(recipeJson);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,9 @@ public List<Fluid> list() {
return List.of(fluid.getFluid());
}
TagKey<Fluid> ft = FluidTags.create(ResourceLocation.parse(tag));
if (ft != null) {
TagKey<Fluid> key = BuiltInRegistries.FLUID.tags().createTagKey(ResourceLocation.parse(tag));
return NeoForgeRegistries.FLUIDS.tags().getTag(key).stream().toList();
}
return null;
return BuiltInRegistries.FLUID.getTag(ft).map(named -> named.stream().map(net.minecraft.core.Holder::value).toList()).orElse(List.of());
}

/**
* create fluidstacks for all fluids matching the tag. if hastag
*
* @return
*/
public List<FluidStack> getMatchingFluids() {
List<Fluid> fluids = list();
List<FluidStack> me = new ArrayList<>();
Expand All @@ -66,14 +57,25 @@ public List<FluidStack> getMatchingFluids() {
return me;
}

public static FluidTagIngredient readFromPacket(FriendlyByteBuf buffer) {
return new FluidTagIngredient(FluidStack.readFromPacket(buffer), buffer.readUtf(), buffer.readInt());
public static final com.mojang.serialization.MapCodec<FluidTagIngredient> CODEC = com.mojang.serialization.codecs.RecordCodecBuilder.mapCodec(instance -> instance.group(
FluidStack.CODEC.optionalFieldOf("fluid", FluidStack.EMPTY).forGetter(FluidTagIngredient::getFluidStack),
com.mojang.serialization.Codec.STRING.optionalFieldOf("tag", "").forGetter(FluidTagIngredient::getTag),
com.mojang.serialization.Codec.INT.optionalFieldOf("count", 1000).forGetter(FluidTagIngredient::getAmount)
).apply(instance, FluidTagIngredient::new));

public static final net.minecraft.network.codec.StreamCodec<net.minecraft.network.RegistryFriendlyByteBuf, FluidTagIngredient> STREAM_CODEC = net.minecraft.network.codec.StreamCodec.composite(
FluidStack.STREAM_CODEC, i -> i.fluid,
net.minecraft.network.codec.ByteBufCodecs.STRING_UTF8, i -> i.tag,
net.minecraft.network.codec.ByteBufCodecs.INT, i -> i.amount,
FluidTagIngredient::new
);

public static FluidTagIngredient readFromPacket(net.minecraft.network.RegistryFriendlyByteBuf buffer) {
return STREAM_CODEC.decode(buffer);
}

public void writeToPacket(FriendlyByteBuf buffer) {
fluid.writeToPacket(buffer);
buffer.writeUtf(tag);
buffer.writeInt(amount);
public void writeToPacket(net.minecraft.network.RegistryFriendlyByteBuf buffer) {
STREAM_CODEC.encode(buffer, this);
}

public int getAmount() {
Expand Down
Loading