Skip to content

initial files for furnace block#14

Merged
The-Code-Monkey merged 8 commits into1.21from
feat/add-furnace-block-basics
Jan 28, 2026
Merged

initial files for furnace block#14
The-Code-Monkey merged 8 commits into1.21from
feat/add-furnace-block-basics

Conversation

@The-Code-Monkey
Copy link
Copy Markdown
Contributor

@The-Code-Monkey The-Code-Monkey commented Jan 28, 2026

Summary by CodeRabbit

  • New Features

    • Added a Furnace Workbench with UI, server-side smelting, auto-pull from nearby chests, progress display, and menu/screen.
  • Improvements

    • Introduced a tiered workbench framework with nearby-inventory scanning and a recycling hook; Campfire Workbench migrated into the new framework and multi-block master/anchor interactions enabled.
    • Client now registers workbench menus/screens for proper UI integration.
  • Chores

    • Build/tooling updates: increased Gradle heap and bumped loader/loom/fabric API version properties.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 28, 2026

📝 Walkthrough

Walkthrough

Adds a Furnace Workbench feature (2×2 block, block entity with smelting/ticking and nearby-inventory pulling), menu and client screen; refactors workbench base to use AbstractWorkbenchEntity with master-anchor logic; updates build/Gradle properties and registrations.

Changes

Cohort / File(s) Summary
Build Configuration
build.gradle, gradle.properties
Switched Fabric API dependency to use ${project.fabric_api_version}; increased JVM heap to -Xmx4G; bumped loader_version and loom_version; added fabric_api_version and removed old fabric_version.
Core Init / Client
src/main/java/com/tcm/MineTale/MineTale.java, src/client/java/com/tcm/MineTale/MineTaleClient.java
Calls ModMenuTypes.initialize() on startup; registers FurnaceWorkbenchScreen client-side via MenuScreens.register.
Abstract Workbench Infra
src/main/java/com/tcm/MineTale/block/workbenches/AbstractWorkbench.java, src/main/java/com/tcm/MineTale/block/workbenches/entity/AbstractWorkbenchEntity.java
Tightened generic to AbstractWorkbenchEntity; added master-anchor logic (getMasterPos), conditional newBlockEntity, interaction handling (useWithoutItem) to open menus, and new AbstractWorkbenchEntity implementing MenuProvider with tier, scanRadius, nearby-inventory scanning and recycle hook.
Campfire Workbench
src/main/java/com/tcm/MineTale/block/workbenches/CampfireWorkbench.java, src/main/java/com/tcm/MineTale/block/workbenches/entity/CampfireWorkbenchEntity.java
Migrated to AbstractWorkbench<CampfireWorkbenchEntity>/AbstractWorkbenchEntity; added CODEC, constructors, shape and master-pos logic; entity sets tier/scanRadius and provides createMenu stub.
Furnace Workbench Block
src/main/java/com/tcm/MineTale/block/workbenches/FurnaceWorkbench.java
New FurnaceWorkbench (2×2 footprint) with CODEC, constructors, MODEL render, server-side ticker delegating to master block entity, and codec override.
Furnace Workbench Entity
src/main/java/com/tcm/MineTale/block/workbenches/entity/FurnaceWorkbenchEntity.java
New FurnaceWorkbenchEntity: 7-slot container (fuel, inputs, outputs), ContainerData sync, tick logic (fuel consumption, canSmelt, smelt, tier speed), pulls items from nearby inventories, persistence for tier/scanRadius, and createMenu implementation.
Menu / Client UI
src/main/java/com/tcm/MineTale/block/workbenches/menu/FurnaceWorkbenchMenu.java, src/client/java/com/tcm/MineTale/block/workbenches/screen/FurnaceWorkbenchScreen.java
Added FurnaceWorkbenchMenu (slots, quick-move, progress data) and FurnaceWorkbenchScreen (texture rendering, title centering, tooltips).
Registries
src/main/java/com/tcm/MineTale/registry/ModBlockEntities.java, src/main/java/com/tcm/MineTale/registry/ModBlocks.java, src/main/java/com/tcm/MineTale/registry/ModMenuTypes.java
Registered FURNACE_WORKBENCH_BLOCK and FURNACE_WORKBENCH_BE; added ModMenuTypes exposing FURNACE_WORKBENCH_MENU and initialize() helper.

Sequence Diagram(s)

sequenceDiagram
    actor Player
    participant Client as Client
    participant Block as FurnaceWorkbench (Block)
    participant Server as Server
    participant Entity as FurnaceWorkbenchEntity (BlockEntity)
    participant Chests as Nearby Containers

    Player->>Client: Right-click workbench
    Client->>Block: useWithoutItem(state,pos,player,hit)
    Block->>Block: getMasterPos(state,pos)
    Block->>Server: request master BlockEntity at masterPos
    Server->>Entity: getBlockEntity(masterPos)
    alt Entity implements MenuProvider
        Server->>Entity: createMenu(syncId, playerInventory, player)
        Server->>Client: open menu (FurnaceWorkbenchScreen)
    else
        Server-->>Client: interaction PASS
    end

    rect rgba(100,150,200,0.5)
        Note over Server,Entity: Server-side ticking loop
        Server->>Entity: tick()
        Entity->>Entity: canSmelt? / consumeFuel() / advance cookTime
        alt Inputs empty
            Entity->>Chests: pullFromNearbyChests()
            Chests-->>Entity: supply items
        end
        Entity->>Client: sync cook & burn progress via ContainerData
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hop through lines, a tiny code-smitten chap,
I stitch two-by-two blocks into a furnacey lap.
Menus swing open, chests spill their ore—
Sparks and tiers hum, the smelter roars.
Hop! MineTale gleams with each new crafted map.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: it introduces initial implementation files for a furnace block feature, which is supported by the addition of FurnaceWorkbench, FurnaceWorkbenchEntity, FurnaceWorkbenchMenu, FurnaceWorkbenchScreen, and related supporting changes.
Docstring Coverage ✅ Passed Docstring coverage is 91.30% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/com/tcm/MineTale/block/workbenches/CampfireWorkbench.java (1)

34-35: Fix CODEC to use the proper block entity supplier, not null.

Lines 34-35 instantiate CampfireWorkbench with () -> null instead of the correct block entity supplier. Use the single-argument constructor via method reference, which properly supplies ModBlockEntities.CAMPFIRE_WORKBENCH_BE:

🔧 Proposed fix
-    public static final MapCodec<CampfireWorkbench> CODEC = simpleCodec((properties) -> 
-        new CampfireWorkbench(properties, () -> null));
+    public static final MapCodec<CampfireWorkbench> CODEC = simpleCodec(CampfireWorkbench::new);
🤖 Fix all issues with AI agents
In
`@src/main/java/com/tcm/MineTale/block/workbenches/entity/AbstractWorkbenchEntity.java`:
- Around line 33-53: The getNearbyInventories method can NPE when accessing
level.getBlockEntity(...) because the inherited level may be null; update
getNearbyInventories to early-return an empty List if level is null (or
otherwise guard uses of level), i.e., check the BlockEntity.level field at the
start of getNearbyInventories and only run BlockPos.betweenClosed(...) and
level.getBlockEntity(pos) when level != null, then continue with the existing
proximity sort on inventories before returning.

In
`@src/main/java/com/tcm/MineTale/block/workbenches/entity/CampfireWorkbenchEntity.java`:
- Around line 21-25: CampfireWorkbenchEntity currently implements MenuProvider
but createMenu throws UnsupportedOperationException; fix by either implementing
createMenu to return a proper AbstractContainerMenu instance (constructing your
workbench container with the provided syncId, playerInventory and this block
entity) so menu-opening via player.openMenu() works, or remove MenuProvider from
CampfireWorkbenchEntity and any calls to player.openMenu() (e.g., in
CampfireWorkbench.useWithoutItem) to ensure no menu is ever opened; as a
temporary safe placeholder you may have createMenu return null instead of
throwing, but prefer adding a concrete menu class and returning its instance
from CampfireWorkbenchEntity.createMenu.

In
`@src/main/java/com/tcm/MineTale/block/workbenches/entity/FurnaceWorkbenchEntity.java`:
- Around line 32-44: The UI always receives a fixed cookTimeTotal (200) from
ContainerData.get(3) which causes progress drift when tier changes; in
FurnaceWorkbenchEntity ensure the effective total used for the current tier is
exposed to clients by either updating the field cookTimeTotal whenever you
compute currentTotal (so cookTimeTotal reflects tier speed) or change the
ContainerData.get implementation (the anonymous data instance) to return the
computed currentTotal instead of the hardcoded 200; locate the computation that
adjusts currentTotal for tier speed and sync that value to cookTimeTotal (or
return it directly from data.get(3)) before the container state is sent to the
client.
- Around line 67-105: The entity's slot indexing is wrong: update tick and
related methods (tick, pullFromNearbyChests(), canSmelt(), consumeFuel(),
smeltItem()) to use fuel slot 0, input slots 1 and 2, and output slots 3–6; read
fuel from inventory.getItem(0) and inputs from inventory.getItem(1)/getItem(2),
prevent pullFromNearbyChests() from depositing into slot 0, and when smelting
use a helper that writes the result into the first valid output slot among 3–6
while checking item type/stack limits (merge with same item or ensure room)
instead of writing to slot 2; also adjust canSmelt/consumeFuel/smeltItem to
accept input slot indices and guard cookTimeTotal logic accordingly (preserve
tier speedBoost computation).
- Around line 160-174: The loadAdditional method in FurnaceWorkbenchEntity is
forcing scanRadius back to 5.0 when the NBT key is absent, overriding the
constructor default (8.0); update loadAdditional to use the instance's current
value as the fallback (use this.scanRadius instead of 5.0) so the constructor
default is preserved; locate the read call for "ScanRadius" in loadAdditional
and change its orElse(...) to orElse(this.scanRadius) (leave the "WorkbenchTier"
handling as-is).

In `@src/main/java/com/tcm/MineTale/block/workbenches/FurnaceWorkbench.java`:
- Around line 24-25: The CODEC is creating FurnaceWorkbench instances with a
null BlockEntityType supplier; update the CODEC so it uses the proper
constructor reference instead of () -> null. Replace the supplier argument
passed to simpleCodec so CODEC calls the single-argument constructor via
FurnaceWorkbench::new (which will cause instances to be initialized with
ModBlockEntities.FURNACE_WORKBENCH_BE), ensuring the BlockEntityType supplier is
valid when the block entity is created or ticked.

In
`@src/main/java/com/tcm/MineTale/block/workbenches/menu/FurnaceWorkbenchMenu.java`:
- Around line 47-52: The custom Slot's mayPlace() is using a brittle string
match via stack.getItem().toString().contains("log") and duplicates the fuel
logic from isFuel(); replace that string check by using the Minecraft logs tag
(ItemTags.LOGS_THAT_BURN) and, better yet, delegate the entire fuel validation
to the existing isFuel(ItemStack) method to avoid duplication. Update the
anonymous Slot in FurnaceWorkbenchMenu (the slot created with FUEL_SLOT) so
mayPlace(...) returns the same result as isFuel(stack) and remove the
toString-based check; ensure you import/use the ItemTags.LOGS_THAT_BURN symbol
if you keep any explicit tag checks.
- Around line 36-40: The constructor for FurnaceWorkbenchMenu stores the
provided ContainerData without validating its size, so add the standard
ContainerData size guard before assigning this.data; call the helper
checkContainerDataCount(data, 4) (from AbstractContainerMenu) in the
FurnaceWorkbenchMenu constructor (the same place you call
checkContainerSize(container, containerSize)) to validate indices 0–3 match the
expected 4 slots, then store this.data = data only after the check passes.

In
`@src/main/java/com/tcm/MineTale/block/workbenches/screen/FurnaceWorkbenchScreen.java`:
- Around line 1-44: FurnaceWorkbenchScreen uses client-only APIs
(AbstractContainerScreen, GuiGraphics, RenderPipelines) but lives in main; move
the class file for FurnaceWorkbenchScreen into the client source set
(src/client/java) keeping the same package declaration and imports, so the
compiler will exclude it from server/runtime builds; ensure the existing
reference in MineTaleClient.java still points to the same package/class and
remove the file from src/main/java to avoid duplicate symbol errors.
🧹 Nitpick comments (4)
src/main/java/com/tcm/MineTale/block/workbenches/entity/AbstractWorkbenchEntity.java (1)

55-59: Stub method with no implementation.

The attemptRecycle method is currently a no-op. This is fine for initial scaffolding, but consider adding a TODO comment or tracking this in an issue to ensure it doesn't get forgotten.

Would you like me to open an issue to track the implementation of the recycler logic?

src/main/java/com/tcm/MineTale/registry/ModBlocks.java (1)

31-36: Consider using SoundType.STONE for a furnace block.

The furnace workbench uses SoundType.WOOD, but furnaces typically use stone-based sounds. If this is intentional (e.g., a wooden furnace frame), the current setting is fine. Otherwise, consider changing to SoundType.STONE for consistency with vanilla furnace behavior.

♻️ Suggested change if stone sound is preferred
 public static final Block FURNACE_WORKBENCH_BLOCK = register(
 	"furnace_workbench_block",
 	FurnaceWorkbench::new,
-	BlockBehaviour.Properties.of().sound(SoundType.WOOD),
+	BlockBehaviour.Properties.of().sound(SoundType.STONE),
 	true
 );
src/main/java/com/tcm/MineTale/registry/ModMenuTypes.java (1)

20-23: Prefer the mod logger over System.out.

Consider using MineTale.LOGGER for consistent log routing and log-level control.

gradle.properties (1)

11-15: Use a stable Loom release instead of a SNAPSHOT to avoid build drift.

loom_version=1.15-SNAPSHOT is compatible with Loader 0.18.4 and Fabric API 0.141.2+1.21.11 for Minecraft 1.21.11, but SNAPSHOT versions can introduce breaking changes. The latest stable Loom release is 1.14.x (Dec 2025), which is known to work with your target version. Prefer a stable release like 1.14.10 over the SNAPSHOT.

Comment on lines +21 to 25
@Override
public @Nullable AbstractContainerMenu createMenu(int syncId, Inventory playerInventory, Player player) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'createMenu'");
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, find the CampfireWorkbenchEntity file and understand its structure
find . -name "CampfireWorkbenchEntity.java" -type f

Repository: CodeMonkeysMods/MineTale

Length of output: 154


🏁 Script executed:

# Search for CampfireWorkbench-related files and menu invocations
fd 'CampfireWorkbench' -x cat -n {} \; | head -100

Repository: CodeMonkeysMods/MineTale

Length of output: 4659


🏁 Script executed:

# Look for openMenu and createMenu calls across the codebase
rg -n 'openMenu|createMenu' --type java | grep -i campfire | head -20

Repository: CodeMonkeysMods/MineTale

Length of output: 439


🏁 Script executed:

# Check if this class implements MenuProvider and what the parent class is
rg -n 'class CampfireWorkbenchEntity' --type java -A 5

Repository: CodeMonkeysMods/MineTale

Length of output: 878


🏁 Script executed:

# Check AbstractWorkbenchEntity class definition and if it implements MenuProvider
rg -n 'class AbstractWorkbenchEntity' --type java -A 10

Repository: CodeMonkeysMods/MineTale

Length of output: 1468


🏁 Script executed:

# Search for MenuProvider implementations in the codebase
rg -n 'implements.*MenuProvider' --type java

Repository: CodeMonkeysMods/MineTale

Length of output: 247


🏁 Script executed:

# Check if there are other workbench entities and how they implement createMenu
fd 'WorkbenchEntity' --type f -name '*.java' | head -10

Repository: CodeMonkeysMods/MineTale

Length of output: 298


🏁 Script executed:

# Look for any calls to openMenu in the codebase
rg -n 'openMenu' --type java -B 2 -A 2

Repository: CodeMonkeysMods/MineTale

Length of output: 683


🏁 Script executed:

# Check the full useWithoutItem method in AbstractWorkbench
rg -n 'useWithoutItem' --type java -A 30 | grep -A 30 'AbstractWorkbench'

Repository: CodeMonkeysMods/MineTale

Length of output: 5716


🏁 Script executed:

# View the complete AbstractWorkbench.useWithoutItem to see when openMenu is called
sed -n '150,200p' src/main/java/com/tcm/MineTale/block/workbenches/AbstractWorkbench.java

Repository: CodeMonkeysMods/MineTale

Length of output: 1808


Implement createMenu or remove the MenuProvider interface.

CampfireWorkbenchEntity implements MenuProvider but throws an exception in createMenu. Although the current CampfireWorkbench.useWithoutItem() returns PASS (avoiding a menu open), the interface contract declares the method must function. Once you uncomment the menu-opening logic or call player.openMenu() elsewhere, this will crash. Either implement a proper menu, return null and ensure openMenu is never called, or remove MenuProvider from the class hierarchy.

🧯 Safe placeholder (until menu is implemented)
     `@Override`
     public `@Nullable` AbstractContainerMenu createMenu(int syncId, Inventory playerInventory, Player player) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'createMenu'");
+        return null;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Override
public @Nullable AbstractContainerMenu createMenu(int syncId, Inventory playerInventory, Player player) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'createMenu'");
}
`@Override`
public `@Nullable` AbstractContainerMenu createMenu(int syncId, Inventory playerInventory, Player player) {
return null;
}
🤖 Prompt for AI Agents
In
`@src/main/java/com/tcm/MineTale/block/workbenches/entity/CampfireWorkbenchEntity.java`
around lines 21 - 25, CampfireWorkbenchEntity currently implements MenuProvider
but createMenu throws UnsupportedOperationException; fix by either implementing
createMenu to return a proper AbstractContainerMenu instance (constructing your
workbench container with the provided syncId, playerInventory and this block
entity) so menu-opening via player.openMenu() works, or remove MenuProvider from
CampfireWorkbenchEntity and any calls to player.openMenu() (e.g., in
CampfireWorkbench.useWithoutItem) to ensure no menu is ever opened; as a
temporary safe placeholder you may have createMenu return null instead of
throwing, but prefer adding a concrete menu class and returning its instance
from CampfireWorkbenchEntity.createMenu.

Comment on lines +32 to +44
private int cookTime;
private int cookTimeTotal = 200;
private int fuelTime;

protected final ContainerData data = new ContainerData() {
@Override
public int get(int index) {
return switch (index) {
case 0 -> fuelTime;
case 1 -> 100; // Fuel total
case 2 -> cookTime;
case 3 -> cookTimeTotal;
default -> 0;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Tier speed boost doesn’t update the cookTimeTotal sent to UI.

currentTotal changes with tier, but data.get(3) always reports cookTimeTotal=200, so the progress bar will drift for higher tiers. Consider syncing the effective total to cookTimeTotal (or exposing currentTotal) before sending to the client.

🔧 Possible sync tweak
-            int currentTotal = Math.max(20, this.cookTimeTotal - speedBoost);
+            int currentTotal = Math.max(20, this.cookTimeTotal - speedBoost);
+            this.cookTimeTotal = currentTotal;

Also applies to: 82-84

🤖 Prompt for AI Agents
In
`@src/main/java/com/tcm/MineTale/block/workbenches/entity/FurnaceWorkbenchEntity.java`
around lines 32 - 44, The UI always receives a fixed cookTimeTotal (200) from
ContainerData.get(3) which causes progress drift when tier changes; in
FurnaceWorkbenchEntity ensure the effective total used for the current tier is
exposed to clients by either updating the field cookTimeTotal whenever you
compute currentTotal (so cookTimeTotal reflects tier speed) or change the
ContainerData.get implementation (the anonymous data instance) to return the
computed currentTotal instead of the hardcoded 200; locate the computation that
adjusts currentTotal for tier speed and sync that value to cookTimeTotal (or
return it directly from data.get(3)) before the container state is sent to the
client.

Comment on lines +160 to +174
@Override
protected void saveAdditional(ValueOutput valueOutput) {
super.saveAdditional(valueOutput);
// store() uses Codecs for type safety
valueOutput.store("WorkbenchTier", Codec.INT, this.tier);
valueOutput.store("ScanRadius", Codec.DOUBLE, this.scanRadius);
}

@Override
protected void loadAdditional(ValueInput valueInput) {
super.loadAdditional(valueInput);
// read() returns an Optional
this.tier = valueInput.read("WorkbenchTier", Codec.INT).orElse(1);
this.scanRadius = valueInput.read("ScanRadius", Codec.DOUBLE).orElse(5.0);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Default scanRadius on load should match constructor.

loadAdditional falls back to 5.0, overriding the constructor’s 8.0 even when no NBT is present. Use the current value as the fallback to keep defaults consistent.

🔧 Suggested fallback
-        this.scanRadius = valueInput.read("ScanRadius", Codec.DOUBLE).orElse(5.0);
+        this.scanRadius = valueInput.read("ScanRadius", Codec.DOUBLE).orElse(this.scanRadius);
🤖 Prompt for AI Agents
In
`@src/main/java/com/tcm/MineTale/block/workbenches/entity/FurnaceWorkbenchEntity.java`
around lines 160 - 174, The loadAdditional method in FurnaceWorkbenchEntity is
forcing scanRadius back to 5.0 when the NBT key is absent, overriding the
constructor default (8.0); update loadAdditional to use the instance's current
value as the fallback (use this.scanRadius instead of 5.0) so the constructor
default is preserved; locate the read call for "ScanRadius" in loadAdditional
and change its orElse(...) to orElse(this.scanRadius) (leave the "WorkbenchTier"
handling as-is).

Comment thread src/main/java/com/tcm/MineTale/block/workbenches/FurnaceWorkbench.java Outdated
Comment on lines +1 to +44
package com.tcm.MineTale.block.workbenches.screen;

import com.tcm.MineTale.block.workbenches.menu.FurnaceWorkbenchMenu;

import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.RenderPipelines;
import net.minecraft.resources.Identifier;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.network.chat.Component;

// FurnaceBlockEntity
// AbstractFurnaceMenu
// FurnaceMenu
// FurnaceScreen
// AbstractFurnaceScreen

public class FurnaceWorkbenchScreen extends AbstractContainerScreen<FurnaceWorkbenchMenu> {
private static final Identifier TEXTURE =
// Identifier.fromNamespaceAndPath(MineTale.MOD_ID, "textures/gui/container/furnace_workbench.png");
Identifier.withDefaultNamespace("textures/gui/container/furnace.png");

public FurnaceWorkbenchScreen(FurnaceWorkbenchMenu menu, Inventory inventory, Component title) {
super(menu, inventory, title);
}

@Override
protected void init() {
super.init();
this.titleLabelX = (this.imageWidth - this.font.width(this.title)) / 2;
}

protected void renderBg(GuiGraphics guiGraphics, float f, int i, int j) {
int k = this.leftPos;
int l = this.topPos;
guiGraphics.blit(RenderPipelines.GUI_TEXTURED, TEXTURE, k, l, 0.0F, 0.0F, this.imageWidth, this.imageHeight, 256, 256);
}

@Override
public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
renderBackground(graphics, mouseX, mouseY, delta);
super.render(graphics, mouseX, mouseY, delta);
renderTooltip(graphics, mouseX, mouseY);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

fd 'FurnaceWorkbenchScreen.java'

Repository: CodeMonkeysMods/MineTale

Length of output: 151


🏁 Script executed:

rg -n --type=java 'FurnaceWorkbenchScreen' -C2

Repository: CodeMonkeysMods/MineTale

Length of output: 2288


🏁 Script executed:

# Also check for source set configuration files
fd -e 'gradle' -e 'pom.xml' | head -20

Repository: CodeMonkeysMods/MineTale

Length of output: 96


🏁 Script executed:

cat build.gradle

Repository: CodeMonkeysMods/MineTale

Length of output: 2416


🏁 Script executed:

# Check if there are any other references to FurnaceWorkbenchScreen outside client code
rg 'FurnaceWorkbenchScreen' --type=java -l

Repository: CodeMonkeysMods/MineTale

Length of output: 204


Move client-only screen to src/client/java (architectural violation with split source sets).

FurnaceWorkbenchScreen uses client-only APIs (AbstractContainerScreen, GuiGraphics, RenderPipelines) but is placed in src/main/java. The build.gradle declares separate sourceSets.main and sourceSets.client, so client code must live in src/client/java. The class is already referenced only from the client entrypoint (MineTaleClient.java), making it safe to move.

🧰 Tools
🪛 GitHub Actions: build

[error] 1-39: Compilation failed due to missing Minecraft GUI classes and unresolved symbols. Errors include: cannot find symbol for net.minecraft.client.gui.GuiGraphics, net.minecraft.client.gui.screens.inventory.AbstractContainerScreen, net.minecraft.client.renderer.RenderPipelines, and many dependent members (e.g., GuiGraphics, AbstractContainerScreen, RenderPipelines, title/width/font fields). This indicates missing or incompatible Minecraft/LibGraft/Mixin APIs in the project setup.

🤖 Prompt for AI Agents
In
`@src/main/java/com/tcm/MineTale/block/workbenches/screen/FurnaceWorkbenchScreen.java`
around lines 1 - 44, FurnaceWorkbenchScreen uses client-only APIs
(AbstractContainerScreen, GuiGraphics, RenderPipelines) but lives in main; move
the class file for FurnaceWorkbenchScreen into the client source set
(src/client/java) keeping the same package declaration and imports, so the
compiler will exclude it from server/runtime builds; ensure the existing
reference in MineTaleClient.java still points to the same package/class and
remove the file from src/main/java to avoid duplicate symbol errors.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@src/client/java/com/tcm/MineTale/block/workbenches/screen/FurnaceWorkbenchScreen.java`:
- Around line 3-15: The TEXTURE constant in FurnaceWorkbenchScreen points to the
vanilla single-output furnace texture but your menu implements a 2x2 output
grid; add a matching custom GUI texture named furnace_workbench.png in your
mod's resources, change TEXTURE back to use
Identifier.fromNamespaceAndPath(MineTale.MOD_ID,
"textures/gui/container/furnace_workbench.png") (uncomment that line) only after
the texture exists, and remove the unused import RenderPipelines; also ensure
the new texture layout places the four output slots at the menu's coordinates
(116/134 × 21/39).
🧹 Nitpick comments (1)
src/client/java/com/tcm/MineTale/block/workbenches/screen/FurnaceWorkbenchScreen.java (1)

27-31: Consider rendering cook/burn progress bars from the menu data.

FurnaceWorkbenchMenu already exposes getCookProgress() / getBurnProgress(). Drawing those bars here will make the UI responsive to smelting state.

Comment on lines +3 to +15
import com.tcm.MineTale.block.workbenches.menu.FurnaceWorkbenchMenu;

import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.RenderPipelines;
import net.minecraft.resources.Identifier;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.network.chat.Component;

public class FurnaceWorkbenchScreen extends AbstractContainerScreen<FurnaceWorkbenchMenu> {
private static final Identifier TEXTURE =
// Identifier.fromNamespaceAndPath(MineTale.MOD_ID, "textures/gui/container/furnace_workbench.png");
Identifier.withDefaultNamespace("textures/gui/container/furnace.png");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find the FurnaceWorkbenchScreen file
find . -name "FurnaceWorkbenchScreen.java" -type f

Repository: CodeMonkeysMods/MineTale

Length of output: 155


🏁 Script executed:

#!/bin/bash
# Search for furnace_workbench texture asset
find . -name "*furnace_workbench*" -type f 2>/dev/null

Repository: CodeMonkeysMods/MineTale

Length of output: 50


🏁 Script executed:

#!/bin/bash
# Search for MineTale class with MOD_ID constant
find . -name "MineTale.java" -type f

Repository: CodeMonkeysMods/MineTale

Length of output: 114


🏁 Script executed:

#!/bin/bash
# Look at the FurnaceWorkbenchMenu to verify the layout
find . -name "FurnaceWorkbenchMenu.java" -type f

Repository: CodeMonkeysMods/MineTale

Length of output: 149


🏁 Script executed:

#!/bin/bash
cat -n ./src/client/java/com/tcm/MineTale/block/workbenches/screen/FurnaceWorkbenchScreen.java

Repository: CodeMonkeysMods/MineTale

Length of output: 1937


🏁 Script executed:

#!/bin/bash
cat -n ./src/main/java/com/tcm/MineTale/block/workbenches/menu/FurnaceWorkbenchMenu.java

Repository: CodeMonkeysMods/MineTale

Length of output: 6355


🏁 Script executed:

#!/bin/bash
cat -n ./src/main/java/com/tcm/MineTale/MineTale.java | head -50

Repository: CodeMonkeysMods/MineTale

Length of output: 1384


🏁 Script executed:

#!/bin/bash
# Double-check for texture assets in the correct asset directory structure
find . -path "*/assets/*/textures/gui/container/*furnace*" -type f 2>/dev/null

Repository: CodeMonkeysMods/MineTale

Length of output: 50


Custom GUI texture asset must be created to match the 2x2 output slot layout.

The menu defines a 2x2 output grid (slots at coordinates 116/134 × 21/39), but the vanilla furnace texture only has a single output slot. Either create the custom texture asset at src/main/resources/assets/minetale/textures/gui/container/furnace_workbench.png or use a different existing texture. The commented line should only be uncommented once the texture file is in place. Remove the unused import of RenderPipelines while you're at it.

🤖 Prompt for AI Agents
In
`@src/client/java/com/tcm/MineTale/block/workbenches/screen/FurnaceWorkbenchScreen.java`
around lines 3 - 15, The TEXTURE constant in FurnaceWorkbenchScreen points to
the vanilla single-output furnace texture but your menu implements a 2x2 output
grid; add a matching custom GUI texture named furnace_workbench.png in your
mod's resources, change TEXTURE back to use
Identifier.fromNamespaceAndPath(MineTale.MOD_ID,
"textures/gui/container/furnace_workbench.png") (uncomment that line) only after
the texture exists, and remove the unused import RenderPipelines; also ensure
the new texture layout places the four output slots at the menu's coordinates
(116/134 × 21/39).

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 28, 2026

Note

Docstrings generation - SUCCESS
Generated docstrings for this pull request at #17

Docstrings generation was requested by @The-Code-Monkey.

* #14 (comment)

The following files were modified:

* `src/client/java/com/tcm/MineTale/MineTaleClient.java`
* `src/client/java/com/tcm/MineTale/block/workbenches/screen/FurnaceWorkbenchScreen.java`
* `src/main/java/com/tcm/MineTale/MineTale.java`
* `src/main/java/com/tcm/MineTale/block/workbenches/AbstractWorkbench.java`
* `src/main/java/com/tcm/MineTale/block/workbenches/CampfireWorkbench.java`
* `src/main/java/com/tcm/MineTale/block/workbenches/FurnaceWorkbench.java`
* `src/main/java/com/tcm/MineTale/block/workbenches/entity/AbstractWorkbenchEntity.java`
* `src/main/java/com/tcm/MineTale/block/workbenches/entity/CampfireWorkbenchEntity.java`
* `src/main/java/com/tcm/MineTale/block/workbenches/entity/FurnaceWorkbenchEntity.java`
* `src/main/java/com/tcm/MineTale/block/workbenches/menu/FurnaceWorkbenchMenu.java`
* `src/main/java/com/tcm/MineTale/registry/ModBlockEntities.java`
* `src/main/java/com/tcm/MineTale/registry/ModBlocks.java`
* `src/main/java/com/tcm/MineTale/registry/ModMenuTypes.java`
…2cd980

📝 Add docstrings to `feat/add-furnace-block-basics`
@The-Code-Monkey
Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 28, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@src/main/java/com/tcm/MineTale/block/workbenches/entity/FurnaceWorkbenchEntity.java`:
- Around line 179-181: Replace the brittle string check in isWood with a proper
tag membership test: instead of stack.getItem().toString().contains("log"), use
the Minecraft item tag for burnable logs (ItemTags.LOGS_THAT_BURN) to test the
ItemStack (e.g., via stack.isIn(ItemTags.LOGS_THAT_BURN) or
ItemTags.LOGS_THAT_BURN.contains(stack.getItem()) depending on mappings). Update
the isWood method to use that tag-based check; keep isOre as-is or expand
similarly later.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@src/main/java/com/tcm/MineTale/block/workbenches/entity/FurnaceWorkbenchEntity.java`:
- Around line 169-173: canSmelt currently returns true based only on input type
(isOre/isWood) and doesn't verify output capacity, which lets fuel burn with no
room for results; update FurnaceWorkbenchEntity.canSmelt to also compute the
smelting result for the given input and verify the output slots can accept it
(i.e., for each target output slot: if empty allow, if same item ensure
existing.getCount() + result.getCount() <= existing.getMaxStackSize(), and if
different item disallow); use the entity's methods/fields that reference output
inventory slots (the class' output slot getters/fields and the smelting result
helper you already call elsewhere) so fuel only consumes/advances when there is
space to place the produced ItemStack.
🧹 Nitpick comments (2)
src/main/java/com/tcm/MineTale/block/workbenches/entity/AbstractWorkbenchEntity.java (1)

22-22: Consider using int type for scanRadius.

Since scanRadius is always cast to int when used with BlockPos.offset() (lines 62-63), declaring it as int would be clearer and avoid unnecessary casts.

src/main/java/com/tcm/MineTale/registry/ModBlocks.java (1)

50-50: Consider using a logger instead of System.out.println.

Using SLF4J or the Minecraft logger would provide better control over log levels and output formatting. This applies to other registry classes as well.

Comment on lines +169 to +173
private boolean canSmelt(ItemStack input) {
if (input.isEmpty()) return false;
// Logic: Check if it's an ore (Copper to Adamantite) or Logs for Charcoal
return isOre(input) || isWood(input);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Prevent smelting when outputs are full.
canSmelt ignores output capacity, so fuel can burn even with no room for results.

🛑 Gate on output space
     private boolean canSmelt(ItemStack input) {
         if (input.isEmpty()) return false;
-        // Logic: Check if it's an ore (Copper to Adamantite) or Logs for Charcoal
-        return isOre(input) || isWood(input);
+        if (!(isOre(input) || isWood(input))) return false;
+        ItemStack result = isWood(input)
+            ? new ItemStack(Items.CHARCOAL)
+            : new ItemStack(Items.COPPER_INGOT);
+        return findOutputSlot(result) != -1;
     }
🤖 Prompt for AI Agents
In
`@src/main/java/com/tcm/MineTale/block/workbenches/entity/FurnaceWorkbenchEntity.java`
around lines 169 - 173, canSmelt currently returns true based only on input type
(isOre/isWood) and doesn't verify output capacity, which lets fuel burn with no
room for results; update FurnaceWorkbenchEntity.canSmelt to also compute the
smelting result for the given input and verify the output slots can accept it
(i.e., for each target output slot: if empty allow, if same item ensure
existing.getCount() + result.getCount() <= existing.getMaxStackSize(), and if
different item disallow); use the entity's methods/fields that reference output
inventory slots (the class' output slot getters/fields and the smelting result
helper you already call elsewhere) so fuel only consumes/advances when there is
space to place the produced ItemStack.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@gradle.properties`:
- Around line 11-15: Replace the unstable SNAPSHOT value for loom_version with a
stable release: update the property loom_version from "1.15-SNAPSHOT" to
"1.15.3" (or another chosen stable 1.15.x), keeping loader_version and
fabric_api_version as-is; ensure the change is made where the gradle property
loom_version is defined so builds use the pinned stable loom release.

In `@src/main/java/com/tcm/MineTale/block/workbenches/CampfireWorkbench.java`:
- Around line 34-35: The CODEC currently constructs CampfireWorkbench with a
null block entity supplier causing an NPE when newBlockEntity() calls
blockEntityType.get().create(...); update the CODEC to pass a proper supplier
that returns ModBlockEntities.CAMPFIRE_WORKBENCH_BE instead of () -> null so
CampfireWorkbench(blockEntityType) can create its block entity; ensure you
reference the CampfireWorkbench.CODEC constant and the blockEntityType used by
newBlockEntity() so the supplier provides the correct BE type
(ModBlockEntities.CAMPFIRE_WORKBENCH_BE).

In
`@src/main/java/com/tcm/MineTale/block/workbenches/entity/FurnaceWorkbenchEntity.java`:
- Around line 212-222: smeltItem in FurnaceWorkbenchEntity currently writes the
result to a hardcoded slot index 2 instead of the computed outputSlot from
findOutputSlot(result); change the inventory.setItem call to use the outputSlot
variable (e.g., replace inventory.setItem(2, ...) with
inventory.setItem(outputSlot, ...)) so outputs go to the correct slot found by
findOutputSlot(result).
🧹 Nitpick comments (2)
gradle.properties (1)

20-20: Minor: Missing newline at end of file.

The file appears to be missing a trailing newline after the last line. While not critical, most style conventions recommend ending files with a newline character.

src/main/java/com/tcm/MineTale/block/workbenches/CampfireWorkbench.java (1)

117-131: Placeholder code for workbench interaction.

The method contains commented-out logic for handling workbench interactions. Note that CampfireWorkbenchEntity.createMenu() currently throws UnsupportedOperationException, so any attempt to open a menu will crash until that's implemented.

The current behavior (SUCCESS on client, PASS on server) means the interaction will be acknowledged client-side but won't do anything server-side.

Would you like me to help implement the interaction logic or open an issue to track completing this feature?

Comment thread gradle.properties
Comment on lines +11 to +15
loader_version=0.18.4
loom_version=1.15-SNAPSHOT

# Fabric API
fabric_api_version=0.141.2+1.21.11
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify Fabric loader version exists
echo "=== Checking Fabric Loader 0.18.4 ==="
curl -s "https://maven.fabricmc.net/net/fabricmc/fabric-loader/maven-metadata.xml" | grep -o '<version>[^<]*</version>' | grep "0.18.4" || echo "Version 0.18.4 not found in metadata"

# Verify Fabric API version exists for MC 1.21.11
echo "=== Checking Fabric API 0.141.2+1.21.11 ==="
curl -s "https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api/maven-metadata.xml" | grep -o '<version>[^<]*</version>' | grep "0.141.2+1.21.11" || echo "Version 0.141.2+1.21.11 not found in metadata"

# Check for fabric-loom releases
echo "=== Checking Fabric Loom versions ==="
curl -s "https://maven.fabricmc.net/net/fabricmc/fabric-loom/maven-metadata.xml" | grep -o '<version>[^<]*</version>' | tail -20

Repository: CodeMonkeysMods/MineTale

Length of output: 919


Consider replacing loom_version=1.15-SNAPSHOT with a stable release.

All versions are available in Maven repositories:

  • loader_version=0.18.4
  • fabric_api_version=0.141.2+1.21.11
  • loom_version=1.15-SNAPSHOT exists, but stable versions 1.15.1, 1.15.2, and 1.15.3 are also available

Using the SNAPSHOT version introduces build instability unnecessarily when stable releases are available. Pin to 1.15.3 (or the latest stable release appropriate for your build).

🤖 Prompt for AI Agents
In `@gradle.properties` around lines 11 - 15, Replace the unstable SNAPSHOT value
for loom_version with a stable release: update the property loom_version from
"1.15-SNAPSHOT" to "1.15.3" (or another chosen stable 1.15.x), keeping
loader_version and fabric_api_version as-is; ensure the change is made where the
gradle property loom_version is defined so builds use the pinned stable loom
release.

Comment on lines 34 to 35
public static final MapCodec<CampfireWorkbench> CODEC = simpleCodec((properties) ->
new CampfireWorkbench(properties, () -> null));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

CODEC uses null supplier, causing NPE on block entity creation.

The CODEC instantiates CampfireWorkbench with () -> null as the block entity type supplier. When newBlockEntity() is called on a deserialized block (line 98), blockEntityType.get().create(pos, state) will throw a NullPointerException.

Use ModBlockEntities.CAMPFIRE_WORKBENCH_BE in the CODEC:

🐛 Proposed fix
     public static final MapCodec<CampfireWorkbench> CODEC = simpleCodec((properties) -> 
-        new CampfireWorkbench(properties, () -> null));
+        new CampfireWorkbench(properties, () -> ModBlockEntities.CAMPFIRE_WORKBENCH_BE));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static final MapCodec<CampfireWorkbench> CODEC = simpleCodec((properties) ->
new CampfireWorkbench(properties, () -> null));
public static final MapCodec<CampfireWorkbench> CODEC = simpleCodec((properties) ->
new CampfireWorkbench(properties, () -> ModBlockEntities.CAMPFIRE_WORKBENCH_BE));
🤖 Prompt for AI Agents
In `@src/main/java/com/tcm/MineTale/block/workbenches/CampfireWorkbench.java`
around lines 34 - 35, The CODEC currently constructs CampfireWorkbench with a
null block entity supplier causing an NPE when newBlockEntity() calls
blockEntityType.get().create(...); update the CODEC to pass a proper supplier
that returns ModBlockEntities.CAMPFIRE_WORKBENCH_BE instead of () -> null so
CampfireWorkbench(blockEntityType) can create its block entity; ensure you
reference the CampfireWorkbench.CODEC constant and the blockEntityType used by
newBlockEntity() so the supplier provides the correct BE type
(ModBlockEntities.CAMPFIRE_WORKBENCH_BE).

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@src/main/java/com/tcm/MineTale/block/workbenches/CampfireWorkbench.java`:
- Around line 116-129: In CampfireWorkbench.useWithoutItem, the client currently
returns InteractionResult.SUCCESS while the server returns PASS; change the
client-side early return to return InteractionResult.PASS so both sides match
while the workbench logic (commented block interacting with
AbstractWorkbenchEntity) is not implemented; update the early return in the
useWithoutItem method to return PASS on client side to signal the interaction is
unhandled.

In
`@src/main/java/com/tcm/MineTale/block/workbenches/entity/FurnaceWorkbenchEntity.java`:
- Around line 132-134: The tick method calls pullFromNearbyChests() which
mutates the inventory but never marks the block entity changed; update
pullFromNearbyChests() to return a boolean indicating whether items were pulled,
then in FurnaceWorkbenchEntity.tick() (both occurrences around the shown block
and the similar block at lines ~232-243) check the returned value and if true
set changed = true (or call setChanged()/markDirty equivalent) so the entity is
persisted after pulling items. Ensure pullFromNearbyChests() returns false when
no change occurs and true only when inventory mutation happens.
- Around line 217-219: The compilation error is caused by a missing semicolon
after the inventory.setItem(...) call inside FurnaceWorkbenchEntity (in the
block checking output.isEmpty()); open the method containing that fragment in
FurnaceWorkbenchEntity and add the missing semicolon to terminate the statement
(inventory.setItem(outputSlot, result.copy());), then recompile to ensure the
syntax error is resolved.

Comment on lines 116 to +129
@Override
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
return SHAPE;
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hit) {
if (level.isClientSide()) return InteractionResult.SUCCESS;

// BlockPos masterPos = getMasterPos(state, pos);
// BlockEntity be = level.getBlockEntity(masterPos);

// if (be instanceof AbstractWorkbenchEntity) {
// // Open UI or handle Recycling logic here
// // Example: if player is holding a tool, try to recycle it
// return InteractionResult.CONSUME;
// }

return InteractionResult.PASS;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the complete file to understand the context
cat src/main/java/com/tcm/MineTale/block/workbenches/CampfireWorkbench.java

Repository: CodeMonkeysMods/MineTale

Length of output: 6334


🏁 Script executed:

# Search for other uses of InteractionResult in the codebase to see patterns
rg "InteractionResult\.(SUCCESS|PASS|CONSUME)" --context 2 -A 1

Repository: CodeMonkeysMods/MineTale

Length of output: 1931


🏁 Script executed:

# Check if there are other workbench implementations to compare
fd -e java "Workbench" | head -20

Repository: CodeMonkeysMods/MineTale

Length of output: 702


🏁 Script executed:

cat src/main/java/com/tcm/MineTale/block/workbenches/AbstractWorkbench.java | head -200

Repository: CodeMonkeysMods/MineTale

Length of output: 9181


🏁 Script executed:

# Find the useWithoutItem or similar interaction methods in AbstractWorkbench
rg -A 15 "useWithoutItem|use(" src/main/java/com/tcm/MineTale/block/workbenches/AbstractWorkbench.java

Repository: CodeMonkeysMods/MineTale

Length of output: 156


🏁 Script executed:

# Check if there are other similar incomplete implementations or patterns
rg "useWithoutItem" -B 2 -A 8 src/main/java/com/tcm/MineTale/block/workbenches/

Repository: CodeMonkeysMods/MineTale

Length of output: 2607


🏁 Script executed:

# Look at FurnaceWorkbench to see if it has similar pattern
cat src/main/java/com/tcm/MineTale/block/workbenches/FurnaceWorkbench.java

Repository: CodeMonkeysMods/MineTale

Length of output: 4458


Return PASS on client until workbench logic is implemented.

The current code returns SUCCESS on client but PASS on server, creating a mismatch where the client thinks the interaction is handled while the server ignores it. Since the workbench implementation is commented out, the interaction isn't actually being handled. Once the implementation is complete, the server will return CONSUME (as in the parent AbstractWorkbench), so return PASS on both sides now to signal the interaction remains unhandled.

Suggested fix
-        if (level.isClientSide()) return InteractionResult.SUCCESS;
+        if (level.isClientSide()) return InteractionResult.PASS;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Override
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
return SHAPE;
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hit) {
if (level.isClientSide()) return InteractionResult.SUCCESS;
// BlockPos masterPos = getMasterPos(state, pos);
// BlockEntity be = level.getBlockEntity(masterPos);
// if (be instanceof AbstractWorkbenchEntity) {
// // Open UI or handle Recycling logic here
// // Example: if player is holding a tool, try to recycle it
// return InteractionResult.CONSUME;
// }
return InteractionResult.PASS;
`@Override`
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hit) {
if (level.isClientSide()) return InteractionResult.PASS;
// BlockPos masterPos = getMasterPos(state, pos);
// BlockEntity be = level.getBlockEntity(masterPos);
// if (be instanceof AbstractWorkbenchEntity) {
// // Open UI or handle Recycling logic here
// // Example: if player is holding a tool, try to recycle it
// return InteractionResult.CONSUME;
// }
return InteractionResult.PASS;
🤖 Prompt for AI Agents
In `@src/main/java/com/tcm/MineTale/block/workbenches/CampfireWorkbench.java`
around lines 116 - 129, In CampfireWorkbench.useWithoutItem, the client
currently returns InteractionResult.SUCCESS while the server returns PASS;
change the client-side early return to return InteractionResult.PASS so both
sides match while the workbench logic (commented block interacting with
AbstractWorkbenchEntity) is not implemented; update the early return in the
useWithoutItem method to return PASS on client side to signal the interaction is
unhandled.

Comment on lines +132 to +134
if (input.isEmpty() && level.getGameTime() % 20 == 0) {
pullFromNearbyChests();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Mark entity dirty when pulling inputs.

pullFromNearbyChests mutates the inventory but tick never sets changed, so the block entity may not persist the pulled item on save/unload. Return a boolean and set changed = true when a pull succeeds.

🔧 Proposed fix
-        if (input.isEmpty() && level.getGameTime() % 20 == 0) {
-            pullFromNearbyChests();
-        }
+        if (input.isEmpty() && level.getGameTime() % 20 == 0) {
+            if (pullFromNearbyChests()) {
+                changed = true;
+            }
+        }
@@
-    private void pullFromNearbyChests() {
+    private boolean pullFromNearbyChests() {
         List<Container> nearby = this.getNearbyInventories();
         for (Container chest : nearby) {
             for (int i = 0; i < chest.getContainerSize(); i++) {
                 ItemStack stack = chest.getItem(i);
                 if (isOre(stack) || isWood(stack)) {
                     int inputSlot = inventory.getItem(INPUT_1).isEmpty() ? INPUT_1 : (inventory.getItem(INPUT_2).isEmpty() ? INPUT_2 : -1);
-                    if (inputSlot == -1) return;
+                    if (inputSlot == -1) return false;
                     inventory.setItem(inputSlot, stack.split(1));
                     chest.setChanged();
-                    return;
+                    return true;
                 }
             }
         }
+        return false;
     }

Also applies to: 232-243

🤖 Prompt for AI Agents
In
`@src/main/java/com/tcm/MineTale/block/workbenches/entity/FurnaceWorkbenchEntity.java`
around lines 132 - 134, The tick method calls pullFromNearbyChests() which
mutates the inventory but never marks the block entity changed; update
pullFromNearbyChests() to return a boolean indicating whether items were pulled,
then in FurnaceWorkbenchEntity.tick() (both occurrences around the shown block
and the similar block at lines ~232-243) check the returned value and if true
set changed = true (or call setChanged()/markDirty equivalent) so the entity is
persisted after pulling items. Ensure pullFromNearbyChests() returns false when
no change occurs and true only when inventory mutation happens.

@The-Code-Monkey The-Code-Monkey merged commit cab93b0 into 1.21 Jan 28, 2026
2 of 3 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant