File Details
NuclearCraft-1.21.1-1.4.0.jar
- B
- May 9, 2026
- 17.61 MB
- 65
- 1.21.1
- NeoForge
File Name
NuclearCraft-1.21.1-1.4.0.jar
Supported Versions
- 1.21.1
Curse Maven Snippet
NuclearCraft Fork — Changelog
May 2026
Fission Reactor — Irradiator Rod Slots
- Added
IrradiatorRodSlotBlockandIrradiatorRodSlotBE— a new block that occupies inner reactor core positions alongside fuel cells - Rod slots use the existing moderator → fuel cell line geometry to determine local flux; slots in better positions irradiate faster
- Each slot tracks its own irradiation line count independently (
localIrradiationLines) rather than sharing the global reactor total - Rod slots registered as valid inner reactor blocks and recognized by the multiblock validation system
- Wall irradiator and irradiation chamber blocks unchanged — both irradiator types coexist
IrradiatorRodSlotBlock.defaultProps()— renamed fromproperties()to avoid compiler collision withBlockBehaviour.properties()in NeoForge 1.21.1
Irradiated Rod Item
- New item
IrradiatedRodItem— output of all irradiation processes - Carries
flux_exposure(0–10000),target_isotope, andsource_elementas per-stack data flux_exposureencodes both reactor geometry quality and fuel radiation value viaspeedMultiplier() * 100, clamped to 10000- Per-stack data uses
NCItemStacks(1.21.1 data component API) —getOrCreateTag()/getTag()do not exist in 1.21.1 - Visual color shifts from dark grey through green, cyan, to blue-white based on exposure value;
isFoil()returns true at flux ≥ 6000 - Not stackable — each rod is an individual processing job
- Registered in
NCItemsasIRRADIATED_RODwithONE_ITEM_PROPERTIES - Static helpers:
create(),getFluxExposure(),setFluxExposure(),getTargetIsotope(),setTargetIsotope(),getSourceElement(),setSourceElement()
IrradiatorRodSlotBE — Output Pipeline
handleRecipeOutput()override — intercepts recipe completion to emitIrradiatedRodIteminstead of raw isotope- Reads input item and matches against
FissionFuel.NC_ISOTOPESto resolvetarget_isotopeandsource_element - Computes
fluxExposure = (int) Math.min(speedMultiplier() * 100, 10000)at completion moment - Guard: only overwrites if
targetIsotopewas successfully resolved
Hot Cell Processor
- New standalone processor
HotCellBE— processes irradiated rods into isotope distributions - Registered in
Processors.javaasHOT_CELL— slot config: 0 fluid in, 1 item in, 0 fluid out, 6 item out - First machine in the mod with runtime-computed outputs — quantities calculated from
flux_exposureNBT getRecipe()override: readstarget_isotope, converts"neptunium/237"→"neptunium_237", matches recipe by ID suffixHotCellBE.Recipeinner class storeskScale = 2000.0andceiling = 0.28
Output probability formula:
P_tier_up(x) = 0.28 × (1 - e^(-x / 2000))
| Slot | Content | Weight |
|---|---|---|
| 0 | Primary tier-up | P_tier_up(x) |
| 1 | Secondary tier-up | P_tier_up(x) × 0.4 |
| 2 | Same-tier useful | 0.15 + (1-P) × 0.10 |
| 3 | Same-tier useful | 0.10 + (1-P) × 0.05 |
| 4 | Lower-tier byproduct | (1-sum 0-3) × 0.5 |
| 5 | Fragment dust | always 1, guaranteed |
HotCellRecipes.java
- ~35 entries covering Th-230 through Es-253
- Recipe IDs:
hot_cell/{isotope_key_underscored}—getRecipe()depends on this format exactly - Two concerns separated: recipe defines isotope identities (fixed), formula defines counts (flux function)
Config Auto-Update (v1.4.1)
- Fuel, heat sink, and accelerator cooler configs self-update from JAR on version mismatch
- Config folders check
version.txton startup; newer bundled version triggers copy before loading - Existing user edits on matching version are preserved
Block Color System
New file: client/block/fission/FissionBlockColors.java
FUEL_CELL_COLOR— walks nearby positions forFissionControllerBE, readsgetCurrentFuel()→ItemFuel.group+def.isotopes[0], returns isotope colorIRRADIATOR_ROD_SLOT_COLOR— reads own BE input slot, parses registry path"neptunium_237"viasplit("_(?=\\d)"), returns isotope colorHEAT_SINK_COLOR— readsheat/maxHeatfrom nearest controller, tints white→orange-red as heat risesgetIsotopeColor(element, mass)— lookup table mirroringgenerate_isotope_textures.pyexactly (same base_rgb, light_rgb, lerp formula)- Registered in
ColorHandler.registerBlockColorHandlers()
Fuel Cell & Irradiator Rod Slot — 3D Rod Geometry
- Both block models redesigned from
cube_allto two-element geometry - Frame element: full
[0,0,0]to[16,16,16]cube, no tint - Rod core element: inset
[4,0,4]to[12,16,12],tintindex: 0— receives isotope color rod_core.png: new 16×16 plain white PNG — tint baseIrradiatorRodSlotBlockregistration now includesnoOcclusion()— required to prevent x-ray through adjacent blocks with inset geometry
Casing & Glass Textures
casing.pngredesigned — 32×32, steel blue-grey family (#4A5054), outer border, inner bevel, corner rivets, horizontal weld seam, vertical division, bolt clustercasing_connected.png— new 32×32 tileable panel, same seam language, no borderglass.png— teal tinted, semi-transparent, visible border (unformed state)glass-ctm.png— seamless, nearly clear teal with subtle diagonal shimmer (formed fallback)
Heat Sink Tinted Parent Model
heat_sink_tinted.json— new parent model withtintindex: 0on all faces- All 45 heat sink model JSONs updated to use this parent
- All moved to
src/main/resources/— safe fromrunData
FissionCasingBlock
FORMEDBooleanProperty added — set true on multiblock formation, false on deformation; drives glass texture switching viasetGlassFormed()inFissionReactorMultiblockVARIANTIntegerProperty(0–21) added for connected texture selectionregisterDefaultStateguarded:if (this.getClass() == FissionCasingBlock.class)— prevents crash whenFissionGlassBlockcallssuper()with a different property set; setsFORMED=false,VARIANT=0explicitly- New
fission_reactor_casing.json— plaincube_allusingcasing.pngfor the unformed state; previously missing, causing purple/black missing texture on blocks placed outside a multiblock
Connected casing — 44-variant blockstate (generated by gen_blockstates.py):
formed=false,*→fission_reactor_casing(plain unformed)formed=true,variant=N→fission_reactor_casing_{name}
22 casing variant models (generated by gen_casing_models.py):
- Panel element
[0,0,0]to[16,16,16]: outward faces use#panelwithoutcullface; connected faces use#panelwithcullface - Border strip elements: 1px slab per outward face,
#casingwithcullface panel=casing_connected.png;casing=casing.png
casingVariantIndex() — 22 cases mirroring Extreme Reactors:
| Outward face count | Cases | Indices |
|---|---|---|
| 0 | 1 (interior) | 0 |
| 1 | 1 (face piece) | 1 |
| 2 | 12 (edge/frame) | 2–13 |
| 3 | 8 (corner) | 14–21 |
Outward face detection uses allBlocks.contains(neighbor.asLong()) — more reliable than instanceof checks; a face is outward iff the neighbor position is not in the multiblock's tracked set.
FissionGlassBlock — Connected Glass System
FissionGlassBlock extends FissionCasingBlock- 6
BooleanPropertyface directions: NORTH, SOUTH, EAST, WEST, UP, DOWN DirectionProperty FACING = BlockStateProperties.FACING— encodes which direction is outward (toward air outside the reactor); set bysetGlassFormed()at formation timecreateBlockStateDefinitionaddsFORMED + FACING + 6 dirs— does NOT call super (excludes VARIANT)registerDefaultStatecalled inFissionGlassBlock's own constructor; setsFORMED=false,FACING=NORTH, all direction booleans false — preventsstateDefinition.any()from returning an arbitrary formed stateconnectsTo()matchesinstanceof FissionGlassBlockonly — glass-to-glass edges are seamless; glass-to-casing edges show the border (the gasket between glass and metal must remain visible)updateShape()returns state unchanged whenFORMED=true— prevents neighbor change events from overwriting direction booleans set by the formation hook
Glass blockstate — 480 variants:
- Key order:
down, east, facing, formed, north, south, up, west(strictly alphabetical) - Unformed: 384 variants (6 facings × 64 direction combos) — all route to plain unformed model
- Formed: 96 variants (6 facings × 16 perpendicular connection combos)
- Generated exclusively by
gen_glass_bs.py
Glass model architecture — inset pane:
Single inset pane, 1px from block boundary, 1px thick. Only the outward face renders. Border baked into outward face texture per variant — eliminates coplanar translucent geometry that caused ghosting/doubling artifacts against adjacent casing faces.
Pane geometry by facing:
| Facing | Min | Max |
|---|---|---|
| north | [0,0,1] |
[16,16,2] |
| south | [0,0,14] |
[16,16,15] |
| east | [14,0,0] |
[15,16,16] |
| west | [1,0,0] |
[2,16,16] |
| up | [0,14,0] |
[16,15,16] |
| down | [0,1,0] |
[16,2,16] |
Corrected FACE_EDGES UV mapping (verified empirically):
| Face | Left | Right | Top | Bottom |
|---|---|---|---|---|
| north | east | west | up | down |
| south | west | east | up | down |
| east | south | north | up | down |
| west | north | south | up | down |
| up | west | east | north | south |
| down | west | east | south | north |
Multiblock Validation — Glass Corner Exclusion
FissionReactorMultiblocknow overridesisValidCorner(BlockPos)- Returns false if block at position is
instanceof FissionGlassBlock - Glass is valid on faces only — corners have three outward faces, which breaks the single-outward-face assumption required by the inset pane model
clearStats() — Deformation Fix
clearStats()now savesbottomLeftandtopRightbefore any resetsetGlassFormed(false)uses the saved bounds to iterate the shell- Previously: failed validation with unset bounds caused
setGlassFormedto iteratebetweenClosed(ZERO, ZERO), deforming nothing; formed glass/casing persisted after the multiblock broke
Asset Safety & Duplicate Detection
check_dupes.py— detects and optionally removes duplicate assets betweensrc/main/resources/andsrc/generated/resources/- Hand-authored assets live in
src/main/resources/— safe fromrunDataoverwrite - Running
runDataafter hand-authoring without checking for duplicates will cause a GradleprocessResourcesfailure
Utility Scripts
| Script | Purpose |
|---|---|
check_dupes.py |
Detect/fix duplicate assets between source trees |
gen_blockstates.py |
Generate casing blockstate only (glass section removed) |
gen_glass_bs.py |
Generate glass blockstate (480 variants, with facing) |
gen_glass_textures.py |
Generate 96 glass models + outward/seamless textures |
gen_casing_models.py |
Generate 22 casing variant models |
generate_isotope_textures.py |
Generate isotope item textures |
gen_glass_models.py |
Obsolete — models now generated by gen_glass_textures.py; do not run |
Correct script order: gen_glass_textures.py → gen_glass_bs.py → check_dupes.py --fix → build
Design Documents Produced
NC_Irradiated_Rod_HotCell_Design.md— irradiated rod and hot cell designNC_Transmutation_Pipeline_Design.md— full transmutation pipeline designNC_Multiblock_Texture_Language_Design.md— four-layer texture language (material base → fabrication marks → operational wear → context marks); status: design complete, implementation pending- Isotope process map updated to v2.1
Bug Fixes
FissionReactorRegistration— added missingIrradiatorRodSlotBEimportregisterDefaultStatecrash — calling it unconditionally in a parent constructor causes a crash when a subclass with a different property set callssuper(); fixed with class guard inFissionCasingBlockand explicit call inFissionGlassBlock- VARIANT in glass blockstate —
createBlockStateDefinitioncallingsuperadded VARIANT to glass, causing all glass blockstate keys to includevariant=0with no matching JSON; fixed by not calling super in glass - Blockstate key ordering — vanilla sorts variant keys strictly alphabetically; mismatched order causes all variants to fall back to the default model; all generated blockstates now use alphabetical property order
- Casing variant always 0 — outward face detection using
instanceof FissionCasingBlockmissed controller, port, and other shell blocks; replaced withallBlocks.contains() - Panel not visible on edge/corner variants — outward faces had
cullfaceset, making them invisible against air; fixed by removingcullfacefrom outward faces - Glass UV mapping — single texture applied to all faces used north-face edge mapping for all directions; corrected per-face FACE_EDGES mapping and verified empirically
- Translucent sorting artifacts — border strip elements in the translucent render pass caused ghosting where coplanar with adjacent casing faces; eliminated by baking border into the outward face texture
- Unformed glass showing formed model —
stateDefinition.any()returned an arbitrary state withFORMED=true; fixed by explicitregisterDefaultStateinFissionGlassBlockconstructor - Formed glass persisting after multiblock break —
clearStats()reset bounds beforesetGlassFormed(false)could use them; fixed by saving bounds before reset

