Skip to content

Add part offset support to crafting interfaces, Closes #138, Closes #152 - #215

Open
rubensworks wants to merge 1 commit into
master-1.21-ltsfrom
claude/integrated-crafting-138-4vb3ty
Open

Add part offset support to crafting interfaces, Closes #138, Closes #152#215
rubensworks wants to merge 1 commit into
master-1.21-ltsfrom
claude/integrated-crafting-138-4vb3ty

Conversation

@rubensworks

@rubensworks rubensworks commented Aug 20, 2026

Copy link
Copy Markdown
Member

Closes #138, closes #152.

Crafting interfaces already accepted Part Offset enhancements, but there was no way to configure the offset, and the offset was ignored when interacting with the targeted machine. This implements both halves.

Cause

Two independent problems, matching the three symptoms reported in #152:

  1. No offsets gui. PartTypeCraftingBase extended PartTypeBase rather than PartTypeConfigurable, so getContainerProviderOffsets() returned empty and the offsets gui could never be opened (symptom 1).
  2. Stale target. PartTypeInterfaceCraftingBase.State caches its PartTarget, which was only set on network addition, network re-alive, and priority/channel changes. A changed offset left that cache stale, so the interface kept validating recipes against, and inserting ingredients into, the directly adjacent block (symptoms 2 and 3). This also explains the reported workaround of re-saving the part settings: that path goes through setPriorityAndChannel, which re-registers the target as a side effect.

Changes

  • core/part/PartTypeCraftingBase extends PartTypeConfigurable, so crafting parts expose the part offsets gui. Its writeExtraGuiDataSettings override was dropped, as the new parent already provides an identical one.
  • core/part/PartTypeInterfaceCraftingBase gains a retarget method, called from update whenever the recomputed target differs from the cached one. It unregisters the old recipes from the crafting network before reloading them (removeCraftingInterface iterates getRecipes(), so it needs the old values), sets the new target, reloads recipes, and re-registers. Unlike remove + add, it retains the network and channel, since only the targeted position changes. The target is recomputed inside update rather than reusing the passed one, so variable-driven offsets are picked up in the same tick.
  • A part offsets button is added to the crafting interface gui, and to the crafting interface settings gui. The latter is required for the attuned crafting interface, which shows the settings gui as its main gui. Both reuse the existing gui.integrateddynamics.part_offsets translation key, so no new lang entries are needed.

Tests

New gametest/GameTestsPartOffsets adds three game tests, plus a setPartOffset helper in GameTestHelpersIntegratedCrafting:

  • testItemsCraftChestOffset — interface faces air, reaches the crafting table via an offset.
  • testItemsCraftChestOffsetIgnoresAdjacentMachine — a furnace sits at the adjacent position while the offset points at a crafting table, covering symptom 3 directly.
  • testItemsCraftAttunedPlanksOffset — the attuned interface reads its recipes through an offset.

Each sets the offset after the network is already alive, so they exercise the re-registration path rather than just initial setup.

Verified the tests are meaningful: with the retarget call removed from update, all three fail (Crafting interface has no valid target, Expected Slot 1 item is incorrect to be minecraft:chest, but was minecraft:air, Recipe in crafting interface is not valid). With it in place, ./gradlew build succeeds and ./gradlew runGameTestServer reports all 41 game tests passing.

Known limitation

PartTypeInterfaceCraftingAttuned.onBlockNeighborChange only fires for blocks adjacent to the part. Setting an offset first and then placing the machine at the offset position will therefore not refresh the attuned recipe list until something else re-targets the part. Changing the offset itself (the repro path in #152) does refresh correctly. Left as-is to keep this change scoped.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NHfm2FRdBFfrNNRxJSCPDX



Crafting interfaces already accepted Part Offset enhancements, but there
was no way to configure the offset, and the offset was not taken into
account when interacting with the targeted machine.

* Let PartTypeCraftingBase extend PartTypeConfigurable, so that crafting
  interfaces expose the part offsets gui.
* Add a part offsets button to the crafting interface gui and to the
  crafting interface settings gui. The latter is needed for the attuned
  crafting interface, which shows the settings gui as its main gui.
* Re-target crafting interfaces when their target changes, so that the
  offset is picked up without having to save the part settings first.
  Recipes are reloaded and re-registered in the crafting network for the
  new target, which makes recipe validation, recipe attuning, and
  ingredient insertion happen at the offset position.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NHfm2FRdBFfrNNRxJSCPDX
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@rubensworks
rubensworks changed the base branch from master-26-lts to master-1.21-lts August 20, 2026 18:23
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.

3 participants