Skip to content

NeoForge 1.21.1 Port#277

Open
theShroo wants to merge 22 commits intoigentuman:1.21-testfrom
theShroo:port/neoforge-1.21.1
Open

NeoForge 1.21.1 Port#277
theShroo wants to merge 22 commits intoigentuman:1.21-testfrom
theShroo:port/neoforge-1.21.1

Conversation

@theShroo
Copy link
Copy Markdown

@theShroo theShroo commented Mar 4, 2026

Summary

Full port of NuclearCraft Neoteric from Forge 1.20 to NeoForge 21.1.219 / Minecraft 1.21.1 / Java 21.

Note: This PR targets 1.20 because there is no 1.21 branch yet. Please consider creating a 1.21 branch and retargeting this PR before merging.

Migration completed:

  • Build system — Gradle 8.10, NeoGradle, NeoForge 21.1.219
  • Package renamesnet.minecraftforgenet.neoforged.neoforge
  • Registration systemDeferredRegister / DeferredHolder with typed factory methods
  • Capability systemRegisterCapabilitiesEvent + IItemHandler/IFluidHandler/IEnergyStorage
  • NetworkingCustomPacketPayload records via RegisterPayloadHandlersEvent
  • ItemStack dataDataComponents.CUSTOM_DATA via NCItemStacks / NCFluidStacks platform layer
  • Blocks/Items/FluidsLiquidBlock(FlowingFluid), burn time semantics, ArmorMaterial registry
  • RecipesRecipeHolder unwrapping, MapCodec/StreamCodec, RecipeInput
  • Client-sideRegisterColorHandlersEvent, RegisterClientExtensionsEvent, normalized UV coords
  • Compat modules — JEI (NeoForgeTypes), Mekanism (unified Chemical), AE2 (19.2.17), EMI, GregTech, KubeJS (2101.7.2)
  • Data generation — Tag renames (c: namespace), RecipeOutput, holder-based loot/enchantment APIs
  • Mixins — All active, including ParticleStackKubeJSMixin (KubeJS particle binding)
  • World gen — Ore generation, biome modifiers, wasteland biome
  • Entities — Wasteland boss, feral ghoul, projectiles, renderers
  • Platform abstractionigentuman.api.platform package with 15+ wrapper classes

KubeJS integration (new):

NC's internal KubeJS plugin has been fully ported to the KubeJS 2101.x API. KubeJS 1.21.1 exists and is actively maintained; the plugin was re-enabled and rewritten from the ground up against the new API surface.

What works:

  • Recipe schema registration — Five per-recipe-type schemas covering all NC recipe types (generic processors, fission_boiling/turbine with heatRequired, fusion_coolant/accelerator_coolant with coolingRate, fusion_core with temperature, and target_chamber with particle components)
  • Reading NC recipes from JSevent.forEachRecipe({mod: "nuclearcraft"}, ...) iterates all NC recipes with full field access via the Gson JSON API
  • Creating NC recipes from JSevent.custom({type: "nuclearcraft:manufactory", input: [...], output: [...]}) creates new NC recipes that the NC runtime loader accepts
  • Cross-mod recipe mirroring — Verified with manufactory↔Mekanism crusher mirror (315 recipes) and alloy smelter mirror across NC/Extended Industrialization/EnderIO/Oritech foundry (344 recipes), zero failures
  • Custom fission fuel registrationNCKJSEvents.registerFissionFuel startup event for script-defined fuels with automatic recipe generation
  • Black hole player eventNCKJSEvents.playerEnterBlackhole server event for script-controlled responses
  • Particle recipe components — Custom RecipeComponent records for InputParticle/OutputParticle with full 4-field codecs (particle/amount/meanEnergy/focus) for target chamber round-trip fidelity
  • Plugin discoverykubejs.plugins.txt gates class loading on KubeJS mod presence; NC runs without KubeJS with zero overhead

What was removed:

  • NCRecipeJS.java — Dead workaround that collapsed fluid tags to concrete fluids (lost tag fidelity). NeoForge's native FluidIngredient handles tags correctly now.
  • KubeJSRecipesEventJSMixin.java — Target class RecipesEventJS no longer exists in KubeJS 2101.x. Diagnostic-only mixin that never worked per its own source comment.

Phase 16 fixes (multiblock formation + testing):

  • Multiblock formation — Fix mutable BlockPosInstance corrupting dimension probes; use immutable BlockPos snapshots for all resolution methods
  • Multiblock validation — Remove pre-reset of outerValid/innerValid/isFormed before validation; validate() sets state from actual results
  • Client sync — Replace all 51 sendBlockUpdated calls with direct syncToTrackingClients() (sends ClientboundBlockEntityDataPacket directly, bypasses ChunkHolder dirty flag system)
  • Port containers — Always add fuel slots with dummy handler fallback to prevent server/client slot count mismatch
  • Port sync — Add sendBlockUpdated to all port setMultiblock() methods; remove early return before connected-state sync in FissionPortBE
  • Cache invalidationinvalidateCache() only sets hasToRefresh flag, no longer resets controller BE fields
  • Fluid tags — Migrate all fluid tags from neoforge: to c: namespace (1.21.1 convention); regenerate 9500+ datagen recipe JSONs
  • Mekanism chemicals — Register CHEMICAL capability on all NC block entities; Chemical2FluidConverter maps chemicals to NC fluids via direct registry lookup
  • Fluid tank colors — Use FluidEntry.color() directly in tank renderer (same fix as bucket colors)
  • Push/pull slots — Fix early return in pushItems/pushFluids that skipped remaining output slots
  • Tag-based fluid validationisValidSlotFluid checks shared c: tags, not just exact fluid match
  • Radiation packets — Snapshot HashMap on construction to prevent ConcurrentModificationException on Netty thread
  • pack_format — Updated from 15 (1.20) to 34 (1.21.1)
  • Block tag lookup — Use BlockState.is(TagKey) for NeoForge 1.21.1 tag resolution
  • Datagen fixNcRecipeBuilder now skips empty NcIngredient entries when serializing output arrays, fixing the non-standard output:[[]] shape that broke downstream consumers

Compat module status:

Module Status
Mekanism Migrated (Gas/Slurry → unified Chemical, CHEMICAL capability registered)
AE2 Re-enabled (19.2.17) with mod-loaded guards
JEI Migrated (ForgeTypes → NeoForgeTypes)
EMI Migrated (bumped 1.1.21 → 1.1.22 for KubeJS compat)
KubeJS Migrated (2101.7.2 — full plugin rewrite, 5 recipe schemas, particle components, event bridges)
ComputerCraft Migrated
GregTech Migrated
The One Probe Migrated
Patchouli Migrated
OC2, TIS-3D, Refined Storage Excluded (no 1.21.1 ports)

Testing done:

  • Server + client launch clean (no NC errors)
  • All 25+ processors tested — energy delivery, recipe processing working
  • Fission reactor multiblock — forms correctly, UI syncs immediately, power production works
  • Mekanism oxygen → NC fluid enricher — chemical conversion and recipe matching verified
  • Isotope separator multi-output push to AE2 interface — all slots eject correctly
  • Fluid tank colors render correctly in machine GUIs
  • Battery blocks render correctly with side configuration
  • Bucket fluid colors render correctly
  • AE2 compat loads without errors
  • EMI recipe categories display correctly
  • Tested with SpeedChunk parallel ticking — no threading issues
  • KubeJS plugin — Zero schema warnings across all NC recipe types on FTB Evolution modpack; 659 cross-mod recipes created via mirror scripts (0 failures)

Remaining work:

  • Extended playtesting of other multiblocks (fusion, turbine, accelerator)
  • Fusion reactor testing
  • Production deployment

Test plan

  • Install into FTB Evolution (1.21.1 NeoForge) for integration testing
  • Test multiblock structures (fission reactor — forms and produces power)
  • Test Mekanism chemical conversion recipes (oxygen verified)
  • Test multi-output push to AE2 interfaces
  • Test KubeJS plugin — recipe reading, creation, cross-mod mirroring
  • Test fusion reactor multiblock
  • Test turbine multiblock
  • Verify world generation (ores, structures)
  • Production deployment

🤖 Generated with Claude Code

Russell Harland and others added 7 commits March 3, 2026 15:27
Migrated NuclearCraft Neoteric from Forge 1.20 to NeoForge 21.1.219 (MC 1.21.1).
562 files changed across all mod systems: registration, capabilities, networking,
blocks, items, fluids, recipes, client rendering, data generation, world gen,
entities, and compat modules.

Key architectural changes:
- Platform translation layer at igentuman/api/platform/ (25+ wrappers)
- DeferredRegister/DeferredHolder replaces RegistryObject throughout
- DataComponents replaces NBT for ItemStack/FluidStack metadata
- Capability system rewritten (RegisterCapabilitiesEvent)
- Attachments replace capability providers (NCAttachments)
- CustomPacketPayload records replace SimpleChannel networking
- NcIngredient no longer extends Ingredient (final in 1.21.1)
- Recipe system uses MapCodec/StreamCodec via NCRecipeSerializerFactory
- Mekanism compat: Gas/Slurry unified to Chemical API

Compat modules excluded (no 1.21.1 ports): OC2, TIS-3D, KubeJS,
Refined Storage, AE2. BFR integration stubbed out.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add TODO markers to all disabled compat call sites (TiC, BFR, KubeJS,
  AE2, RS) indicating we're waiting on those mods to port to NeoForge 1.21.1
- Annotate build.gradle exclusions with mod names and TODO header
- Verify Mekanism 10.7.18 API against JAR: split MekRadiationManager mixin
  into MekRadiationManager + MekRadiationUtil (getRadiationResistance moved
  to RadiationUtil in 10.7.x); register both in nuclearcraft.mixins.json
- Remove stale TODO from MekInteractions (Capabilities.CONFIGURABLE confirmed)
- Fix client crash: ScreenEvent.KeyPressed/KeyReleased are abstract in 1.21.1,
  use .Pre subclasses
- Fix client crash: ColorHandler.register() was adding MOD bus events to game
  bus (already registered via @EventBusSubscriber)
- Fix client crash: TickHandler.onTick @SubscribeEvent on static method
  rejected by NeoForge instance-based bus registration
- Fix client crash: rendertype_blackhole.vsh remove IViewRotMat (removed in
  1.20.5) and update fog_distance to 2-arg signature (Position, FogShape)
- Fix client crash on join: WorldEvents.onLevelTick add isClientSide() guard
  to prevent ClassCastException (ClientLevel -> ServerLevel)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t check

- Fix barrier items in generated recipes: use NcIngredient.toJson() instead
  of asIngredient() which resolves tags at datagen time (empty → barrier)
- Fix solar panel/dimensional blend recipes using dustIngredient().asIngredient()
- Fix blockItem() loop bug checking wrong variable in AbstractRecipeProvider
- Fix forgeFluid() namespace (forge → neoforge) and forgeIngredient() (c: tags)
- Comment out chemical reactor recipes for materials without fluid forms
  (coal, graphite, chromium, osmium, silicon, niobium, titanium, etc.)
- Fix xenorium fusion recipe typo (xenorium298 → xenorium/298)
- Skip xenorium/quantite _ox/_ni/_za variants in chemical reactor
- Fix Item.toString() returning namespaced IDs in 1.21.1 breaking HashMap
  lookups in TurbineCoilBlock, TurbineCoilBE, TurbineBladeBE, CommonConfig
- Fix negative burn time crash: burnTime default -1 → 0 in MultitoolItem,
  NCBaseItem, RadShieldingItem (NeoForge 1.21.1 throws on negative)
- Fix ItemStackIngredient.copy() crash: RegistryAccess.EMPTY → built-in
  registries (stream codecs need item registry for serialization)
- Add 7 missing sound subtitle translations (boss, blackhole, laser)
- Add black_hole blockstate JSON with powered variants
- Add 19 missing EMI c: namespace tag translations
- Fix RuntimeFuelModelGenerator missing parent directory
- Add EMI particle_source_info category translation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…anslations

- Fix battery block UV coordinates (0-16 → 0-1) for NeoForge 1.21.1 normalized sprites
- Migrate 523 bucket model JSONs from forge: to neoforge: (fluid_container loader + parent)
- Migrate fluid color system from deprecated FluidType.initializeClient() to RegisterClientExtensionsEvent
- Implement direct FluidEntry item-identity bucket color lookup (bypasses broken IClientFluidTypeExtensions resolution)
- Re-enable AE2 compat module (AE2 19.2.17 for NeoForge 1.21.1) with mod-loaded guards
- Fix empty Fuel Reprocessor EMI category translation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adapted for NeoForge 1.21.1:
- Kept useWithoutItem() signatures (NeoForge API)
- Added onPlace/onRemove multiblock tracking for accelerator ports
- Added isAcceleratorTooHot() method
- Dropped getOCDevice() (OC2 not ported, LazyOptional removed in NeoForge)
- Removed redundant ParticleSources.init() from onConstruction

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…f List for validators

The TOML config system was stuck in an infinite correction loop because:
1. Enum config values used define() instead of defineEnum(), causing type
   mismatch on deserialization (String vs enum)
2. List validators used instanceof ArrayList, but TOML reader returns
   generic List implementations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@igentuman igentuman changed the base branch from 1.20 to 1.21-test March 5, 2026 13:10
Russell Harland and others added 15 commits March 25, 2026 01:09
- Fix mutable BlockPosInstance corrupting dimension probes: use immutable
  BlockPos for all resolution and helper methods (getSidePos, getForwardPos, etc.)
- Remove async multiblock validation: runs synchronously on server thread now,
  compatible with SpeedChunk's parallel BE ticking model
- Remove direct chunk section reads: all block reads go through Level.getBlockState()
  so SpeedChunk can properly handle cross-chunk access
- Remove chunk cache, CompletableFuture, and MultiblockExecutorManager dependencies
- Fix invalidateCache() eagerly resetting isCasingValid/isInternalValid on the
  controller BE, causing client to briefly see "incomplete" during re-validation
- Fix all 8 port BEs missing sendBlockUpdated() in setMultiblock(), causing client
  to not receive formation state updates
- Fix FissionPortBE early return before connected-state sync when no recipe loaded
- Fix all 5 port containers conditionally adding fuel slots, causing server/client
  slot count mismatch and IndexOutOfBoundsException
- Fix tag lookup: use BlockState.is(TagKey) for NeoForge 1.21.1 tag resolution
- Add diagnostic logging for multiblock dimension resolution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
NC was using Level.sendBlockUpdated() to sync block entity data to clients.
This interfered with vanilla's ChunkHolder dirty flag system, causing
cross-chunk update failures when combined with SpeedChunk's parallel ticking.

- Add syncToTrackingClients() to NuclearCraftBE: sends
  ClientboundBlockEntityDataPacket directly to tracking players via Netty,
  completely bypassing ChunkHolder's section tracking
- Replace all 51 sendBlockUpdated calls across all NC block entities
  with syncToTrackingClients()
- Fix PacketWorldRadiationData ConcurrentModificationException: snapshot
  HashMap on construction instead of holding live reference
- Fix pack_format: 15 → 34 for 1.21.1
- Remove validate() pre-reset of outerValid/innerValid/isFormed: validate
  sets these based on actual results, no pre-clearing needed
- Remove dead canTick field from AbstractMultiblock

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
NeoForge 1.21.1 uses the common "c:" namespace (shared with Fabric)
for cross-mod tags instead of "neoforge:". NC was registering all fluid
tags under neoforge:oxygen, neoforge:hydrogen, etc. which didn't match
Mekanism or other mods using c:oxygen, c:hydrogen.

- Add commonRl() helper for c: namespace ResourceLocations
- Change forgeFluid() default from "neoforge" to "c" (recipe ingredients)
- Change NCFluids tag registration from neoforgeRl() to commonRl()
- Fix Chemical2FluidConverter tag lookup to use c: namespace
- Fix MekChemicalConversionRecipe tag lookup to use c: namespace
- Fixes cross-mod fluid compatibility (Mekanism oxygen in NC recipes, etc.)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Register Mekanism CHEMICAL capability on all NC block entities,
  enabling chemical pipes to push into NC machines
- Chemical2FluidConverter: prefer nuclearcraft: fluid by direct registry
  lookup before falling back to c: tag
- Fix fluid tank renderer: use FluidEntry.color() directly instead of
  broken IClientFluidTypeExtensions resolution (same fix as buckets)
- Fix push methods: iterate ALL output slots instead of returning after
  first slot (items and fluids). Fixes multi-output machines like
  isotope separator not ejecting from all slots
- Regenerate all datagen: 9500+ recipe JSONs updated from neoforge: to
  c: fluid tag namespace
- Add tag-based fluid validation in isValidSlotFluid (sharesFluidTag)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ities

- Port BEs share controller's energyStorage and contentHandler instances
  directly on multiblock formation — no more reflection delegation
- invalidateCapabilities() on formation so cables re-query after reactor forms
- Register Mekanism CHEMICAL capability on all NC block entities
- Skip NC player radiation effects when Mekanism radiation integration is
  active — let Mekanism handle all player effects, avoid double-dosing
- Fix fluid tank renderer colors: use FluidEntry.color() directly
- Fix sound crash: wrap playSound/stopSound in try-catch for
  TileTickableSound NoClassDefFoundError
- Fix push methods: iterate ALL output slots instead of returning after first
- Chemical2FluidConverter: prefer NC fluid by direct registry lookup
- Add tag-based fluid validation (sharesFluidTag) in isValidSlotFluid

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nged guard

- Always serialize side map in item/fluid capability handlers (removed
  sideMapUpdated gate that caused PUSH mode to be lost on chunk reload)
- Fix hasPush/hasPull overwrite: onLoad() now ORs flags instead of
  overwriting, toggleSideConfig recalculates from both handlers
- Make hasPush()/hasPull() public on SidedContentHandler
- Fix MOX fuel isotope resolution: getIsotope() explicitly resolves
  "mixed" group secondary (238) to uranium, primary to plutonium
- Rename "Mixed MIX-" display names to "MOX-" in lang file
- Guard MultiblockControllerBE.setChanged() with isClientSide check
  to prevent NoClassDefFoundError on client block placement

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
getIsotope fix correctly resolves mixed/238 → uranium_238 instead of
plutonium_238. MOX fuel is now properly Pu + U (Mixed Oxide) as intended.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix ProcessorBlockItem tooltip: use registry path instead of toString()
  which included namespace prefix, breaking translation key lookup
- Fix ChamberBlock tooltip: same issue for kugelblitz chamber blocks
  (Quantum Flux Regulator, etc.)
- Add missing fusion block translations: fusion_core, fusion_reactor_casing,
  fusion_reactor_casing_glass, fusion_reactor_connector

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- fluidIngredient() now creates tag-based inputs (c:hydrogen, c:oxygen, etc.)
- fluidStackIngredient() restored as specific-fluid for outputs
- moltenFuelIngredient() uses forgeFluid() tags for inputs
- NcRecipeBuilder resolves tag-based outputs to specific fluids at serialization
- 828 generated recipes updated: inputs use c: tags, outputs use specific fluid IDs
- Remove NC-DIAG diagnostic logging

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move hand-written recipes from recipes/ to recipe/ (1.21.1 singular path)
- Move advancements/ to advancement/, loot_tables/ to loot_table/
- Remove stale duplicate plural-path directories
- Fix datagen: output fluids resolve tag to specific fluid ID at serialization
- Fix datagen crash: avoid config access during data generation (TagUtil)
- Regenerated 828 recipe files with c: tag inputs and specific fluid outputs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… handling

- Remove all spurious molten_ fluid tags (c:boron not c:molten_boron)
- Rename aluminum → aluminium throughout (Materials, textures, configs, recipes)
- Keep aluminum tag aliases for backward compat with other mods
- Fix output fluid namespace: minecraft:water no longer becomes nuclearcraft:minecraft:water
- Regenerated all datagen with correct fluid outputs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tag names use slashes (c:uranium/233) but fluid registry names use
underscores (nuclearcraft:uranium_233). The datagen builder now converts
slashes to underscores when resolving tag-based outputs to specific
fluid IDs. Fixes all melter/centrifuge/ingot former recipes for isotopes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Re-enable NC's KubeJS integration (excluded since the NeoForge port began)
against the completely rewritten KubeJS 2101.x API. The plugin registers
five per-recipe-type schemas covering all NC recipe types, allowing pack
scripts to read, create, remove, and replace NC recipes from JS.

Plugin changes:
- NuclearCraftKubeJSPlugin: new KubeJSPlugin interface, 5 schemas
  (generic/heatRequired/coolingRate/fusion_core/target_chamber),
  particle component registration, beforeRecipeLoading fuel injection
- NCKubeJsEvents: KubeEvent/KubeStartupEvent interfaces, EventGroup
  registration, fuel recipe injection writes to JSON map directly
- ParticleComponents: RecipeComponent records with full 4-field codecs
  (particle/amount/meanEnergy/focus) for round-trip fidelity
- InputParticle/OutputParticle: rewritten with Codec, dropped removed
  APIs (InputReplacement, OutputReplacement, IngredientJS, ItemStackJS)
- ParticleMatch: import path update for moved ReplacementMatch
- NCRecipeJS: deleted (dead workaround that collapsed fluid tags)
- KubeJSRecipesEventJSMixin: deleted (target class removed in 2101.x)
- ParticleStackKubeJSMixin: registered in nuclearcraft.mixins.json
- kubejs.plugins.txt: created for plugin discovery, gated on kubejs mod

Build/dependency changes:
- build.gradle: KubeJS exclusions removed, localRuntime added for dev
- gradle.properties: EMI bumped 1.1.21 → 1.1.22 (KubeJS minimum)

Datagen fix:
- NcRecipeBuilder: skip empty NcIngredient entries in output arrays,
  fixing the non-standard output:[[]] shape that broke downstream
  consumers (KubeJS codecs, JEI integrations)

Bridge wiring:
- BlackHoleBE: PlayerEnterBlackhole event forwarded to KubeJS scripts
- FissionFuel: RegisterFissionFuel event forwarded to KubeJS scripts
  (both guarded by ModList.isLoaded("kubejs"))

Verified on ramdisk server with full FTB Evolution modpack:
- Zero KubeJS schema warnings across all NC recipe types
- 45 manufactory + 47 alloy_smelter recipes read cleanly
- 659 cross-mod recipes created via mirror scripts (0 failures)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The irradiator processor block (nuclearcraft:irradiator) was never
recognized during fission reactor formation. This is a pre-existing
bug in the original Forge 1.20 codebase — the irradiator feature
has never worked in NuclearCraft Neoteric.

Root cause: three independent issues compounding:

1. isIrradiator() checked `instanceof IrradiationChamberBlock` — an
   unused structural block — instead of the actual processor block
   that players place in the reactor wall.

2. The irradiator check was only in processInnerBlock(), but the
   irradiator is a WALL block (in the casing tag), so it's scanned
   by processOuterBlock() which had no irradiator detection.

3. No processOuterBlock() override existed in FissionReactorMultiblock
   to add wall-placed irradiators to the irradiators set or call
   attachMultiblock() to connect them to the controller.

Fixes:
- isIrradiator() now checks by registry identity against the actual
  processor block (NCProcessors.PROCESSORS.get("irradiator"))
- Added processOuterBlock() override that detects irradiators during
  wall scanning, adds them to the irradiators set, and attaches them
  to the multiblock
- IrradiatorBE.controller() now resolves fresh from the live multiblock
  each call to avoid stale references after reactor reform
- Added diagnostic logging during formation and periodic tick stats
  (to be removed once stable)

Also includes fission reactor sound error logging (playSound try-catch).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix fission port cycling through MODERATOR mode permanently zeroing
  moderationLevel: reset targetModerationLevel to 1.0 when leaving
  MODERATOR mode (FissionPortBE)
- Fix radiation TOCTOU race: use ConcurrentHashMap and single get()
  instead of containsKey()+get() pattern (WorldRadiation)
- Fix PacketWorldRadiationData constructor to accept Map instead of
  HashMap for ConcurrentHashMap compatibility
- Remove verbose debug logging from IrradiatorBE, FissionControllerBE,
  and FissionReactorMultiblock (irradiator diagnostics, periodic tick
  logging, outer block processing logging)
- Add aluminum cooler and heat sink assets

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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