Open
Conversation
- disabled some dependencies in build.gradle until they update
- updated 37 or so classes fixing basic syntax errors - fixed Ingredient access transformers - Re enabled lats web dependencies
- More base syntax fixes
…omponent based** tool system Renames: * ItemToolTiers → ItemToolMaterials * ItemToolTierRegistryKubeEvent → ItemToolMaterialRegistryKubeEvent * KubeResourceLocation → KubeIdentifier New: * MutableToolMaterial * ItemToolMaterials * KubeJSRegistries * Tool behavior is now defined via `ToolMaterial` and item components * Painting item names now resolve via `DataComponents.PAINTING_VARIANT` instead of NBT * Internal getOrCreate() method on BuilderBase * BuilderTypeRegistry.of is now more allowing of Registry ResourceKeys to allow our new Server registry key of KubeJSRegistries.ARMOR_MATERIAL Removals: * Removed tier and all Tier based APIs * Removed TieredItem handling * Removed DiggerItemKJS * Removed DiggerItemMixin * Removed NBT-based tool and painting variant parsing
- More various internal fixes - Mass replacement of Ingredient.EMPTY with Ingredient.of() - Added public transformer for ServerPlayer#server - A lot of Optional<>/Holder adaptions
…lItemModelPropertyEvent - Added KubeJSConditionalCallbackProperty as standin for ClampedItemPropertyFunction which no longer exists - Fixed explode method call to the now 'void' return - No more serverPlayer.hasPermission() moved to Commands.LEVEL_GAMEMASTERS.check(serverPlayer.permissions())
- Fixed RenderType assignment in KubeJSClientEventHandler
- ItemTintFunctionWrapper now implements ItemTintSource
Valid model JSON format for adding 2 layers:
```json
{
"model": {
"tints": [
{ "type": "kubejs:tint", "index": 0 },
{ "type": "kubejs:tint", "index": 1 }
]
}
}
```
Note: "kubejs:tint" is our registered ItemTintSources
- RegisterColorHandlersEvent.Item -> RegisterColorHandlersEvent.ItemTintSources
- ItemTintFunctionWrapper now passes a CODEC instead of unpackaged values
- Fixed "kubedex" KeyMapping registration
- RegisterShadersEvent -> RegisterRenderPipelinesEvent
- Added Category registry in KubeJSClientEventHandler
- Moved DebugScreen event handler to mixin target (DebugText was removed from overlay event)
- Fixed RenderLevelStageEvent highlight render events
- Fixed KubeJSErrorScreen - Fixed particle registry type - Began porting HighlightRenderer to the 1.26.1 render pipeline (post-processing + framegraph) - Rendering logic not yet tested - Updated highlight.json to the new post-processing format - Preserved NotificationToast#drawRectangle(GuiGraphics graphics, int x0, int y0, int x1, int y1, int r, int g, int b) with custom fill command.
- Fixed various Block events - Fixed InventoryAttachment related classes - Fixed GameRulesMixin & GameRulesKJS preserving Key - Fixed FluidIngredientKJS and added SizedFluidIngredient override - Fixed 15 other classes
… equivalents - Fixed component function classes - Fixed some base mixin compile erroring - Fixed KubeJSCommands to use new way of getting tags through registry access - Removed getAffectedPlayers from block explosion since Explosion no longer provides it - Updated tag access to use lookupOrThrow(registry).get(tag) - Reworked tag reload hooks to conform with new PendingTags & TagLoader implementations - Preserved tag loading context through new `TagReloadContextKJS` thread
…omponentMap model - Migrated item modification logic to use NeoForge’s ModifyDefaultComponentsEvent - Reworked item component mutation to operate on DataComponentMap.Builder instead of mutating bound components directly - Preserved existing KubeJS scripting APIs (override, nullable removal semantics, tier helpers, burn time overrides, etc) - Revised component removal semantics (set(type, null) instead of a dedicated remove call) - Fixed component related startup crashes caused by invalid or late-bound component mutations - Ensured item modifications occur at the correct lifecycle stage (before components are bound) - Updated item mixins to match current method signatures (use, appendHoverText, releaseUsing, etc.) - Cleaned up and stabilized component, tool, and attribute handling under the new data-driven item system - Split startup modification dispatch into separate item and block paths - Routed item changes exclusively through `ModifyDefaultComponentsEvent` while keeping block changes on FMLLoadCompleteEvent
…(AbstractContainerMenu.clicked signature change) - Updated selected hotbar sync to use the new carried-slot update packet replacing ClientboundSetCarriedItemPacket - Updated spawn-setting helper to use the new setRespawnPosition(RespawnConfig, boolean) signature - Refactored FluidWrapper to 26.1 FluidIngredient API (no empty()/tag()/single(), new of(HolderSet) usage) - Removed reliance on DataComponentPredicate.EMPTY; now treats component predicates as always-valid and applies DataComponentFluidIngredient directly when present
- ImageGenerator and its registry registration - KubeJSEMIPlugin / KubeJSJEIPlugin / KubeJSREIPlugin and related REI events until JEI/EMI/REI update ## Transfer API Migration - Replaced `IFluidHandler` with `ResourceHandler<FluidResource>` and updated `FluidUtil` usages - Replaced `IItemHandler`/`IItemHandlerModifiable` mixin with `ResourceHandler<ItemResource>` mixin ## Recipe - Replaced `Recipe#getResultItem` with direct `result.create()` on shaped/shapeless recipes - Replaced `Recipe#ingredients()` with direct field access on shaped/shapeless recipes - Replaced `ItemStack#hasCraftingRemainingItem`/`getCraftingRemainingItem` with `getCraftingRemainder()` ## Misc API Changes - Replaced `ComponentSerialization.FLAT_CODEC` with `CODEC` - Replaced `Ingredient#getItems()` with `items()` stream - Replaced `ChargedProjectiles.of` and `BundleContents` constructors with new item transfer equivalents - Fixed `ResourceKey.create()` to pass required registry and location arguments
- Replaced `ItemStack.STRICT_CODEC` with `ItemStack.CODEC.flatXmap(ItemStack::validateStrict, ItemStack::validateStrict)` in `ShapedKubeJSRecipe` and `ItemStackComponent` - Replaced `SizedIngredient.FLAT_CODEC` with `NESTED_CODEC` and removed `kjs$toFlatJson` method from `SizedIngredientKJS` ## Registry Tag Binding - Replaced `entry.registry().bindTags()` with cast to `MappedRegistry` since `bindTags` was removed from the `Registry` interface but still exists in `MappedRegistry` ## Render & GUI - Updated `GuiGraphics#blit` calls to new signature requiring `RenderPipeline` and texture dimensions ## Item API - Updated `SmithingTemplateItemBuilder#createObject` to match new `SmithingTemplateItem` constructor (removed title `Component` param, added `Item.Properties` param) - Updated `MinecraftClientKJS` texture atlas methods to use `getAtlasManager().getAtlasOrThrow().getSprite()` ## Misc - Commented out EMIAddInformationKubeEvent/JEIRemoveRecipesKubeEvent/REIRemoveRecipeKubeEvent until they update - We are now past compile errors at this point. We do not get past mixin target errors on runClient at this point
- Added Access Transformer for `Entity#setRot()` ## Food Eaten Event - Replaced removed `LivingEntity#eat()` usage - Injected into `Animal#mobInteract - Triggers `kjs$foodEaten` when animals are fed - Hooked into `ItemStack#finishUsingItem to track Player eating when food items are consumed ## Mixin Fixes - Fixed classes that were turned into interfaces including: NumericTagMixin, CollectionTagMixin, ClickEventMixin - Fixed some targeting/shadow issues
- Moved LootDataTypeMixin logic to LootTableLoadEvent in `KubeJSServerEventHandler` ## Level - moved `getTime` shadow accessor to LevelAccessor ## Other - Various other mixin target/shadow target fixes
- Fixed Shaped/Shapeless custom recipe serializers - Updated AfterRecipesLoadedKubeEvent to use RecipeMap.create() instead of HashMap - Added makeConditionalOps() accessor via `ContextAwareReloadListenerKJS` - Added ExtraCodecsMixin to override stack size limit ## Render - Various compile fixes to HighlightRenderer/KubeJSClientEventHandler ## Entity - `displayClientMessage` -> `sendSystemMessage`/`sendOverlayMessage` - FallingBlockEntityMixin: fallSpeed is no longer inside local (no longer exists in tick) so we calculate it ourselves to retain it in the `BlockStoppedFallingKubeEvent` - Maintained block hit result in `BlockPickedKubeEvent` by doing our own `BlockHitResult` ## Block - Moved setNameKey() override from BlockMixin to BlockBehaviorMixin ## Items - getTags() shadow removed from ItemStackKJS — replaced with typeHolder().tags() - DataComponentsMixin: replaced lambda$static$1 @ModifyConstant with @ModifyArg moved to ExtraCodecsMixin targeting intRange() call with original == 99 guard - ItemStackHandlerMixin: removed @ModifyConstant for intValue = 99 — constant no longer present in ItemStacksResourceHandler/ItemAccessItemHandler, replaced with @Inject at RETURN of `getCapacity` - ItemStackMixin#kjs$maxSlotSize moved to `ExtraCodecsMixin`
- Made dummy empty ingredient to use everywhere in SlotFilter class (subject to move from SlotFilter.EMPTY_INGREDIENT to one of the helper classes) ## Tags - Fixed StringTagMixin ## Level - Moved getEntity(uuid) shadow from ServerLevelMixin to LevelMixin - Fixed WorldLoaderMixin inject targeting ## Misc - Commented out betteradvancedtooltips integration for now until updated (TextIcons/KubeJSErrorScreen/KubeJSCommands) - Updated rei/emi/jei/arch dep to 1.21.11 - Commented out JEI/REI/EMI/Architectury integration classes until they update - Added ModMaven maven to settings.gradle - Added terminal.ansi systemProperty to configureEach runs task in build.gradle
- Commented out shader registries for now ## HighlightRenderer - Commented out shader registries and loadPostChains implementation in kjs$loadPostChains as well as kjs$resizePostChains implementation
- Re added sentinel check for empty fluid ingredient check
- Fixed KubeJSPlugins#loadMod method not detecting our plugins correctly - Fixed BuiltinKubeJSClientPlugin crash ## Items - Moved EMPTY_INGREDIENT to UtilsJS (Dummy empty Ingredient can no longer be empty) - Changed all instances of `Ingredient.of()` to new UtilsJS.EMPTY_INGREDIENT - Fixed /kjs hand command - Fixed ItemStackKey/ItemStackSet/ItemStackComponent ## Schemas - Updated smithing_transform.json recipe schema ## Builders - Fixed block/item registry builders to set missing id through properties.setId()
- Fixed tag-based ingredients failing to encode by applying postponed tags before recipe processing - Fixed item components not being available during recipe parsing by applying pending data components early - Fixed recipe encoding using wrong registry lookup by building `ConditionalOps` from actual registry access instead of patched lookup provider - Fixed crash with NeoForge custom ingredients (`CompoundIngredient`/ `DifferenceIngredient`) by guarding against `getValues()` calls on custom ingredient types in `IngredientComponent.isEmpty()` - Created accessor for `getContext()` from `ContextAwareReloadListener` - Created accessor for `newComponents` from `ReloadableServerResources`
- Removed `ItemBlockRenderTypes.setRenderLayer()` calls from `KubeJSClientEventHandler.setupClient0()` — the class was removed entirely - Render types for fluid blocks, fluids, and custom blocks are now emitted as `"render_type"` in generated block model JSON via `ModelGenerator.custom()` ## Text Component Updates - Replaced `SelectorPattern` usage in `TextWrapper` with `CompilableString<EntitySelector>` via `EntitySelector.COMPILABLE_CODEC` - Updated `ScoreContents` construction to use `Either<CompilableString<EntitySelector>, String>` - Updated `SelectorContents` construction to use `CompilableString<EntitySelector>` ## Lighting API Changes - Removed `getShade(Direction, boolean)` override from `FakeClientWorld` — method no longer exists on `BlockAndTintGetter` - `FakeClientWorld.cardinalLighting()` now returns `CardinalLighting.DEFAULT` instead of `null` ## Misc - Updated to latest available Minecraft/Neoforge (26.1 snap 10)
* Added tintFunction() for callback based fluid tinting with full world context * Added `bucketColor()` for custom bucket item tint separate from in-world fluid * Separated textureTint from runtime tint in FluidTypeBuilder * Added item definition generation for NeoForge 26.1 new model system * Generated bucket item definitions with neoforge:fluid_contents_tint for fluid overlay layer * Bucket asset generation is skipped when scripters customize parentModel, textures, or modelGenerator * Added support for custom fluid textures via block/<id>_still and block/<id>_flow overrides * Fixed FluidBlockBuilder using wrong texture path * Fixed flowing texture check using wrong variable * Registered both source and flowing fluids in RegisterFluidModelsEvent
…been initialized yet
…ble `ConsoleJS.earlyError()` helper method
…oleJS.earlyError()` allowing early startup errors to either throw or not throw to startup error screen when configs throw json exception
- Gradle wrapper version bump
…correct format for "open_uri_format" in `DevProperties` dev.json
…ecipes easier - Fixed recipe schema factory key detection always defaulting to KubeRecipe instead of ShapedKubeRecipe/ShapelessKubeRecipe when specified in the json - neo version bump
…` for documentation/API clarity
…ell as better erroring - Added Fluids binding
…and updated shaped.json/shapeless.json
- Neoforge version bump - Fixed small recipe manager bug
MaxNeedsSnacks
requested changes
Apr 25, 2026
Member
MaxNeedsSnacks
left a comment
There was a problem hiding this comment.
The last set of changes (namely the error screen and custom menu changes) are out of scope for a port like this, please revert them and make another PR just for them
MaxNeedsSnacks
requested changes
Apr 25, 2026
Comment on lines
35
to
71
| @Override | ||
| default boolean matches(RecipeMatchContext cx, FluidIngredient in, boolean exact) { | ||
| if (in == FluidIngredient.empty()) { | ||
| return false; | ||
| } | ||
|
|
||
| try { | ||
| for (var stack : ((FluidIngredient) this).getStacks()) { | ||
| if (in.test(stack)) { | ||
| var fluids = ((FluidIngredient) this).fluids(); | ||
| if (fluids.isEmpty()) { | ||
| return false; | ||
| } | ||
| int probeAmount = FluidType.BUCKET_VOLUME; | ||
| for (var holder : fluids) { | ||
| if (in.test(new FluidStack(holder, probeAmount))) { | ||
| return true; | ||
| } | ||
| } | ||
| } catch (Exception ex) { | ||
| throw new KubeRuntimeException("Failed to test fluid ingredient " + in, ex); | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| @Override | ||
| default boolean matches(RecipeMatchContext cx, SizedFluidIngredient in, boolean exact) { | ||
| try { | ||
| var fluids = ((FluidIngredient) this).fluids(); | ||
| if (fluids.isEmpty()) { | ||
| return false; | ||
| } | ||
| int probeAmount = in.amount(); | ||
| for (var holder : fluids) { | ||
| if (in.test(new FluidStack(holder, probeAmount))) { | ||
| return true; | ||
| } | ||
| } | ||
| } catch (Exception ex) { | ||
| throw new KubeRuntimeException("Failed to test sized fluid ingredient " + in, ex); | ||
| } | ||
| return false; | ||
| } |
Member
There was a problem hiding this comment.
I'm not that well-versed with ReplacementMatches anymore (we really need documentation, but resolving these just to test if they overlap at all feels... wrong)
We might want to look into reworking how replacement works after this PR
Comment on lines
+145
to
+148
| default boolean kjs$hasPermission(int i) { | ||
| var permission = new Permission.HasCommandLevel(PermissionLevel.byId(i)); | ||
| return kjs$self().permissions().hasPermission(permission); | ||
| } |
Member
There was a problem hiding this comment.
TODO (post-port): more granular permission support?
- Removed useless shapeless/shaped recipe checks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
KubeJS 26.1 Primer
1. Overview
This branch is a large-scale migration to NeoForge 26.1+.
Core migration themes:
ModifyDefaultComponentsEventToolMaterial+ component-driven behaviorResourceHandlerTagManagerhooksResourceLocation->Identifiersource migration2. Categorized Change Breakdown
A. Rendering & Client Pipeline
Nature
API migration, refactor, compatibility fixes
Key Changes
RegisterColorHandlersEvent.ItemTintSourcesItemTintFunctionWrappernow implementsItemTintSourceItemBlockRenderTypes.setRenderLayer()is no longer used for generated blocks/fluids"render_type"in generated model JSONKubeJSErrorScreenB. Tool System Migration
Nature
Major rework
Key Changes
ToolMaterialplus item components such as:DataComponents.TOOLDataComponents.WEAPONDataComponents.ENCHANTABLEDataComponents.REPAIRABLEMutableToolMaterialItemToolMaterialsItemToolMaterialRegistryKubeEventKubeJSRegistries.ARMOR_MATERIALItemModificationKubeEvent#setTier()now rebuilds tool-related components instead of relying on old-style direct tier mutationDataComponents.PAINTING_VARIANTKubeJSRegistries.ARMOR_MATERIALMutableToolTiertoolTierfields on handheld buildersDiggerItemBuilder"toolTierRegistry"TieredItem#tierC. Item System & Data Components Migration
Major Changes
ModifyDefaultComponentsEventDataComponentMap.Builderset(component, null)ModifyDefaultComponentsEventRecordDefaultsnow uses:DataComponentExactPredicate.EMPTYDataComponentPredicate.EMPTYbehaviorD. Transfer API & Fluid Migration
Changes
ResourceHandler<FluidResource>ResourceHandler<ItemResource>FluidUtilis now imported from:net.neoforged.neoforge.transfer.fluid.FluidUtilResourceHandlerInventoryWrapperFluidTankAttachment.Wrappednow implements:ResourceHandler<FluidResource>Additional Fluid/Ingredient Notes
DataComponentFluidIngredientis used for component-aware fluid matchingFluidIngredient/SizedFluidIngredientinputs are explicitly treated as unsupportedE. Recipe System & Reload Pipeline
Key Fixes
ModifyRecipeJsonsEventAfterRecipesLoadedKubeEventnow rebuilds recipe maps with:RecipeMap.create()ReloadableServerResourcesStructural Improvements
ConditionalOpsis constructed from actual registry accessReloadableServerResources#newComponentsis wired through mixins/interfacesAPI / Encoding Updates
SizedIngredienthandling now uses:SizedIngredient.NESTED_CODECplacementInfo().ingredients()getCraftingRemainder()items()streamsIngredient/FluidIngredientinputs are no longer treated as validSmithing
minecraft:smithing_transformminecraft:smithing_trimF. Tag System Migration
Changes
TagManager-style mixin logic was replaced withRegistryAccess/HolderLookup/TagLoaderbased hookslookupOrThrow(registry).get(tag)TagLoaderRegistry.PendingTags<?>ReloadableServerResources#postponedTagsMappedRegistryTagReloadContextKJSis not used here; the activeServerScriptManagerand registry are stored directly on the loader/mixin path insteadG. Entity, Messaging & Interaction Changes
Changes
Entity#setRot(float, float)sendSystemMessage()sendOverlayMessage()BlockHitResultmanually using a fresh ray trace inIBlockStateExtensionMixinLootTableLoadEventItemStack#finishUsingItemExplosion#getAffectedPlayersis gone and no longer usedAnimal#mobInteractreplacement work forLivingEntity#eat()is not present hereH. GUI & Container Updates
Changes
ClickTypeContainerInputServerPlayer.RespawnConfigsetRespawnPosition(respawnConfig, boolean)ClientboundSetHeldSlotPacketI. Misc Infrastructure & Compatibility State
Confirmed Project / Build Changes
ResourceLocation->Identifier2601.7.2terminal.ansi=truesettings.gradledependencyResolutionManagementCurrent Compatibility Guards / Temporary Disablement
validateAccessTransformersis currently forced to:falsearchitectury,JEI,REI, andEMIcompile dependencies are still commented out inbuild.gradleKubeJSClientWeb.register()are still commented outRendering & Client
Entity / Messaging
Recipe / Ingredient
Registry & Tags
Tool / Components