Port reactor logic from Forge branch with enhancements and fixes - #42
Open
Giovanniricotta2002 wants to merge 33 commits into
Open
Port reactor logic from Forge branch with enhancements and fixes#42Giovanniricotta2002 wants to merge 33 commits into
Giovanniricotta2002 wants to merge 33 commits into
Conversation
Groundwork required before porting the reactor's logic layer (services, reactorLogic, consumable, snapshot, display) from the Forge branch. None of it compiles without these five prerequisites. - CReactorHeat: new config holding the DANGER heat thresholds per reactor size (5x5 / 7x7 / 9x9), wired into CNCServer. - CRods: add the uranium/graphite/thorium proximity, base and ratio values the heat model reads. Existing key names are kept so current configs are not reset. - RodType: numeric values become Suppliers so they are re-read from the config at runtime instead of being frozen at registration, as on Forge. Adds ratio() (weight used by the fuel/cooler thermal balance), the isFuel/isCooled overloads taking a resolved RodType, and the level-aware tooltipKey. Drops the useConfig machinery: its three switches were fully commented out, so it always returned the default value, and nothing called setRodConfig(). - IHeat.HeatLevel: thresholds now depend on the reactor size, plus isNotDanger() and the BigItemStack overload. - ReactorControllerBlock: add the ACTIVE property, recomputed server-side every tick and synced to the client. It drives the running-sound loop and the lit controller texture (off / standby / on) generated by ReactorControllerGenerator. Also register the RodType of URANIUM_ROD and GRAPHITE_ROD, which had none: resolveRodType() fell back to FALLBACK (type NONE), which the heat calculator skips, so the ported model would have computed zero heat forever without any visible error. THORIUM_ROD switches from hardcoded values to the config-backed ones. PORTAGE_REACTEUR.md documents the full gap analysis and the remaining lots. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ports the reactor's thermal model from the Forge branch. Six of the seven files are byte-identical to their Forge counterpart; DefaultHeatCalculator only differs by the ItemStackHandler import. - DefaultHeatCalculator: per-slot heat from the blueprint pattern, with the adjacency bonus/malus resolved through a precomputed neighbour map. Only rods actually present in the inputs contribute, so a pattern asking for more rods than are loaded no longer over-reports heat. - DefaultOverheatController: overheat escalates while the reactor is out of balance, and the escalation accelerates as overFlowLimiter shrinks. Two independent malus sources: fuel/cooler ratio above the 6:1 equilibrium, and coolant missing or past its maxHeat. - HeatBalance / EquilibriumState: the 6:1 wiki equilibrium, weighted by the RodType ratio introduced in lot 0. - HeatManager: facade resolving the coolant type before delegating. ReactorDisplayState comes along from lot 4: it is a hard dependency of computeHeat(). Its NBT methods take a HolderLookup.Provider because BigFluidStack.write()/read() require one on NeoForge, and item lookup goes through BuiltInRegistries.ITEM.getOptional() so an item removed with its mod is dropped instead of silently resolving to air. Nothing calls HeatManager yet - wiring lands with lot 3 (services) and lot 6 (block entity), which is also when DefaultHeatCalculatorGameTest gets ported to actually exercise this. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ports the consumable cycle from the Forge branch. Four of the five carried files are byte-identical; ConsumptionCycleManager only differs by the registry lookup and the empty-pattern check. - ConsumptionCycleManager: one timer per rod type present in the pattern, persisted in NBT so a cycle survives a reload. Timers are rebuilt when the pattern changes rather than restarted from scratch, so editing a blueprint does not refund the elapsed lifetime. - ItemConsumable / FluidConsumable / ConsumableTimer / IConsumable: unchanged from Forge. PatternReader is rewritten rather than translated. Forge parsed the raw patternAll/pattern NBT elements off the blueprint stack; on NeoForge the blueprint carries a typed ReactorBluePrintData component, so it now reads patternAll() directly, falling back to pattern(). Fixes a divergence in ReactorBluePrintMenu that this exposed: on Forge, pattern is the player's raw grid and patternAll is the normalized view where empty slots AND non-rod items become glass panes. On NeoForge both fields pointed at the same array and kept non-rod items. Any stray item left in the grid would then be counted by PatternReader as a pattern requirement, and since updateHeatOnly() requires every requirement to be present in the inputs, heat would have stayed pinned at 0 with nothing to show for it. saveData now builds the two arrays separately. getItemStorage() keeps reading pattern() (raw), matching the Forge version which reads the raw pattern NBT element. Also drops the duplicated ReactorBluePrintData construction in saveData: both instances were built from identical inputs, so the follow-up equals() check could never fire. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ports the reactor's service layer from the Forge branch. Nine of the ten straight ports are byte-identical; DefaultHeatService differs by one trailing space. - ReactorMeltdownMonitor: 300-tick danger countdown driving the stabilized / overheating / meltdown-flash / critical-failure notifications. - ReactorMeltdownExecutor: spawns the explosion sized from reactor footprint and fuel count (sqrt for diminishing returns), then irradiates the biome. - ReactorAlarmCoordinator: drives the alarm blocks off the danger flag and awards SILENCE_THE_CORE on the rising edge. - ReactorHeatUpdateCoordinator: fuel-only gate for canRun() vs full-pattern gate for updateHeatOnly(). - FluidConsumptionRateCalculator: coolant drain rate per reactor size. Neutralizes the copyTag() trap documented in PORTAGE_REACTEUR.md section 5.1. The Forge code stored heat by mutating configuredPattern.getOrCreateTag() in place. On NeoForge reading that tag back yields a defensive copy, so a literal translation would compile, throw nothing, and leave heat pinned at zero forever. Writing now goes through CNDataComponents.HEAT, which already existed as a DataComponentType<Float>, isolated in writeHeat(). The empty-pattern check moves to isEmptyPattern(), testing for the absence of ReactorBluePrintData. Those are the only non-javadoc differences from Forge. IPersistenceService and DefaultPersistenceService are deferred to lot 6: they call block entity accessors that do not exist yet on the NeoForge controller (Direction vs String facing, BoundingBox vs int[] bounds, inventory serialization, display state). Porting them now would mean rewriting the block entity, which is lot 6 itself. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ports the per-tick input snapshot and the display helpers from the Forge branch. No behavioural adaptation was needed on this lot: the differences are the minecraftforge -> neoforged imports and one renamed FluidStack accessor. - ReactorInputSnapshot: byte-identical to Forge. Immutable per-tick view of the loaded rods, coolants and total tank capacity. - ReactorInputSnapshotBuilder: aggregates the live item handlers and tanks once per tick, so heat, tooltip and client sync all read the same numbers. - ReactorFrameDisplayManager: extracts the frameFluidCache* / frameColumn* fields currently inlined in the block entity. Fluid and fill ratio are recomputed at most once per game tick from the same tanks, so they cannot disagree. The block entity keeps its own copies until lot 6 replaces them. - ReactorGoggleTooltipRenderer: stateless, reads only from a ReactorDisplayState snapshot. Uses getHoverName() since FluidStack lost getDisplayName() in 1.21. Its javadoc example is also corrected: the Forge version showed render() being called with four arguments while the method takes five. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both files are byte-identical to their Forge counterpart: no API adaptation was needed. AbstractTickableSoundInstance is unchanged between 1.20.1 and 1.21, and the already-ported ReactorAlarmSoundInstance confirms the shape. - ReactorRunningSoundInstance: looping client-side sound driven by the ACTIVE blockstate added in lot 0. It stops itself when the block stops being an active controller, so it survives the controller being broken or the block entity's tick no longer driving it. - ReactorDebugDiagnostics: dumps registered vs. currently valid positions for each of the four IO managers. Adds the eight createnuclear.reactor.debug.* lang keys, which were missing from lang/default/reactor.json. The nine notification.reactor.* keys that lot 3's ReactorMeltdownMonitor depends on were already present. runData is needed to propagate the new keys into the generated en_us.json. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replaces the monolithic NeoForge controller with the Forge one and wires it to the 33 files ported in lots 0-5. ReactorControllerBlockEntity goes from 868 lines to 424, and its divergence from Forge from 864 lines to 76 - all of them 1.21 adaptations (HolderLookup.Provider on read/write, DataComponents instead of raw NBT, neoforged imports). The reactor now actually runs: heat model, overheat escalation, meltdown countdown with its notifications, explosion, alarms, coolant consumption, rod consumption cycles, the ACTIVE blockstate driving the running sound and the lit controller texture, and the goggle tooltip fed from the synced snapshot. Carried along: ReactorControllerBlock, ReactorAssembler, CNMultiblock, ReactorPattern, MultiblockHelpers, ReactorOutput(Entity), ReactorOutputManager, ReactorFrame(Renderer), ReactorCasing, ReactorCooler, ReactorCoreEntity, ReactorRodInput, the two persistence services deferred from lot 3, and IMultiblockController (lot 7). Four features turned out to be missing rather than merely reorganized: - Only the 5x5 reactor existed. CNMultiblock registered a single pattern with the rod input and output pinned to fixed positions; Forge registers three (5x5 / 7x7 / 9x9) where IO blocks sit anywhere on the shell. 7x7 and 9x9 were simply impossible to assemble. - ReactorFrameEntity was never registered. The class and its renderer both existed, but no BlockEntityEntry did, so frame blocks had no block entity at all and the fluid could never render in the windows. - Fluid capacity was multiplied by the number of inputs. applyReactorTierCapacity gave every input the reactor's full capacity, so four inputs held four times the intended total. Replaced by applyCapacity(int), with the assembler splitting the total as Forge does. - ReactorOutputEntity drove its speed through a KineticScrollValueBehaviour instead of the manager-driven persisted generatedSpeed, which also kept the DIR interaction on ReactorOutput that Forge had dropped. Note for future syncs: in tick(), `int heat = ...` is deliberately a local shadowing the field, exactly as on Forge. Promoting it to a field assignment would change the previousHeat value fed to the heat calculation. CNShapes.REACTOR_INPUT and CNBlockEntityTypes.REACTOR_INPUT keep their NeoForge names (Forge: REACTOR_ROD_INPUT); renaming them would change the createnuclear:reactor_input registry id and break existing worlds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ports DefaultHeatCalculatorGameTest and ReactorInputFluidManagerGameTest from the Forge branch. `./gradlew runGameTestServer` runs 30 tests: 28 pass, 2 fail by design. The four heat-model tests pass, including threeByThreeDiamond which is cross-checked against the community wiki calculator. This is the first runtime validation of the whole port - everything before this only compiled. The two failures are the *_expectedContract regression markers, which fail on the Forge branch too: extractFluids never decrements fluidNeeded between handlers (over-extraction) and silently drops requests for exactly one unit. Identical behaviour on both sides, which is what these tests are there to verify. Note this makes runGameTestServer exit non-zero, so it should not gate CI until extractFluids is fixed in both repos. Port adaptations: - loadPattern writes a typed ReactorBluePrintData (57 PatternData entries) instead of the raw `pattern` NBT tag, since the blueprint carries a data component on NeoForge. - Capabilities go through level.getCapability(Capabilities.FluidHandler.BLOCK, pos, null) rather than be.getCapability(ForgeCapabilities.FLUID_HANDLER). - BuiltInRegistries.FLUID replaces ForgeRegistries.FLUIDS, and the annotations come from net.neoforged.neoforge.gametest. - empty_platform.nbt lands in data/createnuclear/structure/ - singular, as 1.21 renamed the data folders Forge 1.20.1 spelled `structures`. Also fixes a NeoForge-only bug the suite made obvious: ReactorInputFluidManager read getFluidInTank(handler.getTanks()), an out-of-bounds index, in both getInventory() and extractFluids(). Forge reads index 0. Corrected, and a leftover debug LOGGER.warn in getBlocksPosition() that fired on every call is removed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The previous commit swept in run/world/ (25 region and data files) because the gametest server writes its scratch world there. Untracked and added to .gitignore. run/server.properties stays tracked - it already was - but its gametest-time rewrite is reverted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CNDataComponents.HEAT was registered with ExtraCodecs.POSITIVE_FLOAT, which rejects 0.0. The controller writes the heat on every tick, so a blueprint sitting in an idle or stopped reactor made the chunk save throw "Value must be positive: 0.0" while serializing the stack, and the block entity stopped persisting entirely. Zero is the normal heat of a reactor that is not running, so the codec was simply wrong. 1.21.1 has no ExtraCodecs.NON_NEGATIVE_FLOAT, so this uses plain Codec.FLOAT, matching the Forge branch which stores the value in an NBT double. The non-negative invariant stays enforced upstream in DefaultHeatCalculator#computeHeat, where violating it cannot take a save down: a persistent codec that can refuse a value fails at save time, far from the write that caused it. Introduced in lot 3 when heat storage moved from the blueprint's NBT tag to the typed data component. Adds heatComponent_atZero_survivesSerialization, which saves and re-parses a blueprint carrying heat=0 and would have caught this. The other four components use NON_NEGATIVE_INT and accept zero, so they carry no equivalent trap. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ogen Three defects reported from in-game testing. Frame fluid rendered almost black. The renderer passed fluid.getFluid().defaultFluidState() to renderFluidBox, and the FluidState overload resolves texture and tint from the fluid's block state, losing the stack's tint. It now passes the FluidStack, as the Forge branch does. CatnipServices.FLUID_RENDERER is declared FluidRenderHelper<?>, so the platform type has to be reintroduced with a cast - that wildcard is why the FluidStack overload appeared unavailable during the lot 6 port. Rod input exposed two slots, one hardcoded to uranium and one to graphite. Forge has a single slot accepting any fuel or cooler rod, resolved through RodType, so several rod inputs can be placed around the shell to feed different rods. The inventory drops to one slot, the menu draws one slot at Forge's coordinates, and quickMoveStack comes over as well. Liquid nitrogen was commented out of CNReactorFluidTypes, so no nitrogen.json was generated and the fluid had no registered ReactorFluidType. An unregistered fluid falls back to efficiency -1, which makes fluidMalus permanently true in DefaultOverheatController: overheat then climbs without bound and the reactor always melts down, whatever the rod pattern. Registered with Forge's values (maxHeat 8196, efficiency 100). Regenerated data: nitrogen.json, the 16 controller blockstate variants carrying the ACTIVE property with their off/standby/on models, and the eight reactor.debug lang keys. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…er layers Two defects reported from in-game testing. The reactor output produced 81920 SU where Forge produces 512000. Its stress capacity was registered at 10240.0 instead of Forge's 64000.0 - the 6.25x ratio matches the observed numbers exactly. Restored. The fluid in the frame windows rendered almost black. The frame block was missing noOcclusion(), so it counted as a full opaque block: light stopped propagating through it and the fluid rendered inside the window came out at near-zero light. Passing the FluidStack instead of a FluidState (previous commit) was necessary but not sufficient - this is the other half. While checking that, four more blocks turned out to have lost their render layer relative to Forge, which has five addLayer calls to NeoForge's one: - reactor_frame and reactor_rod_input and reactor_fluid_input: cutoutMipped - reinforced_glass: translucent, without which it renders opaque - enriching_fire: cutout addLayer is deprecated for removal in this registrate version, but it is what Forge uses and PalettesVariantEntry already relies on it here, so switching away from it is left as its own change rather than mixed into a fix. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Marks the port complete: eight lots done, validated in game, 31 gametests with the two intentional failures. Adds lot 9, the six defects found while playing, with which of them the port introduced (one) and which were pre-existing NeoForge divergences (five). Adds section 9, a full inventory of what is still not ported. The raw count is 42 Forge files with no NeoForge counterpart, but six of those exist under another name - two of them only differ by a typo - so the real remainder is 36, listed by feature rather than by file. Also lists the shared files that diverge heavily but were never audited, with the caveat that a large diff is not evidence of a missing feature: most of it is 1.21 API. Lot 9 showed those diffs do hide real bugs though - the stress capacity and the missing render layers were both inside CNBlocks. Records the extractFluids over-extraction bug as present in BOTH versions, so it gets fixed in both, and warns against gating CI on runGameTestServer until then. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
# Conflicts: # src/generated/resources/.cache/35ba5b194a3aa18fb27424c32b9e16e01b900a51 # src/main/java/net/nuclearteam/createnuclear/CNItems.java
It was tracked at the repo root but missing from the working tree, so the merge commit recorded a deletion nobody asked for. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
extractFluids never decremented fluidNeeded between handlers, so the requested amount was treated as a per-input quota instead of a total: a reactor asking for 10 units with two fluid inputs holding 10 each drained both, removing 20. The more inputs the player placed, the faster the coolant vanished. An `if (toExtract > 1)` guard also silently dropped requests for exactly one unit, which is what FluidConsumptionRateCalculator asks for at the low end of the consumption curve, so the smallest reactors leaked their buffer accounting. The loop now tracks what is left to extract, stops once satisfied, and subtracts what the handler actually returned rather than what was asked of it. The Javadoc claimed "true if the full amount was extracted" while the code returned true on any partial extraction. The code's behaviour is the right one - the reactor should consume whatever coolant it can reach rather than refuse to run - so the Javadoc now documents that instead. The two gametests that pinned the buggy behaviour are removed, and extractFluids_returnsTrueEvenWhenNotFullyExtracted_javadocMismatch is renamed now that there is no mismatch. The suite goes from 31 tests with 2 intentional failures to 29 all passing, so runGameTestServer exits 0 and can gate CI. The same fix is applied to the Forge branch, which carries the identical bug. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Section 9.4 described extractFluids as a known bug present in both versions; it is fixed in both now, so it documents what the bug was and what the contract is. runGameTestServer exits 0 on both branches and can gate CI. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Leftover screenshot at the repo root. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PARITE_FORGE_NEOFORGE.md lists every feature still missing from the NeoForge version, with the hook points to wire each one, a difficulty estimate and a suggested order. A raw tree diff reports 42 Forge files with no NeoForge counterpart, which is misleading. Eight exist under another name - two differ only by a typo - and four are deliberately not ported because the 1.21 equivalent is better: the radiation capability plumbing is replaced by NeoForge data attachments, CriterionTriggerBase by vanilla SimpleCriterionTrigger, and the bundled SimplexNoise by vanilla's. Re-porting those would be a regression, so they are called out explicitly. That leaves 30 real gaps, grouped by feature. The document also records what the reactor port taught us: the method that kept ~35 of 50 files byte-identical to Forge, the 1.21 translation table, and the two traps that compile and throw nothing - a CUSTOM_DATA tag read back as a defensive copy, and a persistent codec that fails at world-save time rather than at the write. Section 9 of PORTAGE_REACTEUR.md now points at it; that document stays focused on the reactor. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Chantier 1 de PARITE_FORGE_NEOFORGE.md. Porte les 9 fichiers Forge qui
manquaient, et branche la feature qui etait entierement morte cote NeoForge.
Fichiers portes depuis Forge :
- CNDisplaySources
- content/redstone/displayLink/source/ : AbstractReactorStatDisplaySource,
HeatDisplaySource, FuelDisplaySource, CoolerDisplaySource,
LiquidLevelDisplaySource, ReactorSizeDisplaySource,
ReactorDisplayConstants, ReactorGaugeRenderer
Branchements (aucun display source n'etait attache cote NeoForge, pas meme
REACTOR_SUMMARY : la classe existait mais n'etait referencee nulle part) :
- CreateNuclear.java : CNDisplaySources.register()
- CNBlocks : les 6 .transform(displaySource(...)) sur
REACTOR_CASING et REACTOR_CONTROLLER
ReactorSummaryDisplaySource : fuel / cooler / fluid / heat etaient commentes
faute de ReactorGaugeRenderer. Reactives, ainsi que les branches "gauge" de
formatValue/formatFluid. Le resume n'affichait que statut + taille.
Divergences assumees vs Forge (ne pas les "corriger" a la prochaine synchro) :
- CNDisplaySources : Registrate 1.21 type ses entrees RegistryEntry<R, T>
(registre + entree) la ou 1.20.1 n'avait que RegistryEntry<T>.
- HeatDisplaySource et ReactorSummaryDisplaySource : Forge lit la chaleur via
getConfiguredPattern().getOrCreateTag().getDouble("heat"). En 1.21 elle vit
dans le data component CNDataComponents.HEAT, et relire le tag NBT renvoie
une copie defensive ou la valeur est toujours absente : le resume affichait
donc 0. On passe par controller.getConfiguredPatternHeat().
- AbstractReactorStatDisplaySource, ReactorSizeDisplaySource : imports
net.minecraftforge.api.distmarker -> net.neoforged.api.distmarker.
- LiquidLevelDisplaySource : 8 imports inutilises supprimes (deja morts
cote Forge).
- FuelDisplaySource, CoolerDisplaySource, ReactorGaugeRenderer,
ReactorDisplayConstants : identiques a l'octet.
Toutes les cles de lang display_source.* etaient deja presentes dans
interface.json, identiques a Forge. Aucun ajout de ressource necessaire.
Verifie : compileJava OK, 29/29 gametests passent.
A noter, hors perimetre de ce lot : runGameTestServer logue une
IllegalStateException a la sauvegarde du chunk du controleur
("Value must be within range [1;99]: 0; Item must not be minecraft:air"),
depuis SmartInventory.serializeNBT via ReactorControllerBlockEntity.write.
Verifie preexistante (reproduite sur 9e7aba0 sans ce lot). A traiter a part.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…lueprint
PatternData.CODEC utilisait ItemStack.CODEC, qui refuse la stack vide
("Item must not be minecraft:air" / "Value must be within range [1;99]: 0").
Un motif de reacteur fait 57 slots et n'est presque jamais plein : des qu'un
blueprint se trouvait dans un controleur, ReactorControllerBlockEntity.write
levait a la sauvegarde du chunk, et Minecraft desactivait silencieusement la
persistance du block entity ("It will not persist"). Le controleur perdait
donc son blueprint a chaque rechargement du monde.
Meme defaut sur le chemin reseau : PatternData.STREAM_CODEC utilisait
ItemStack.STREAM_CODEC, qui leve EncoderException("Empty ItemStack not
allowed"). REACTOR_BLUE_PRINT_DATA etant networkSynchronized, l'encodage
echouait des que la stack partait vers un client.
Correctif : ItemStack.OPTIONAL_CODEC et ItemStack.OPTIONAL_STREAM_CODEC.
L'encodage des stacks non vides est inchange entre les deux variantes (seule
la stack vide passe de "refusee" a "{}"), donc les blueprints deja sur disque
se relisent sans migration.
Le flatXmap qui entourait ItemStack.CODEC est supprime : sa condition
(!stack.isEmpty() || stack.is(FUEL) || stack.is(COOLER)) etait morte, le
premier disjoint rendant les deux autres inatteignables, et l'ensemble se
reduisait a l'identite. ItemStack.CODEC refusait de toute facon les stacks
vides avant meme que ce mapping ne les voie.
C'est le piege n2 du paragraphe 6 de PARITE_FORGE_NEOFORGE.md, deja rencontre
sur CNDataComponents.HEAT declare en POSITIVE_FLOAT : un codec persistant qui
peut refuser une valeur fait planter la sauvegarde, tres loin de la cause.
Le code compile, ne leve rien a l'ecriture, et perd les donnees.
Verifie : 2 gametests de regression ajoutes (disque et reseau), qui echouent
avant le correctif avec l'erreur de production exacte. 31/31 passent apres,
et runGameTestServer ne logue plus aucune erreur de sauvegarde (5 avant).
Verifie aussi les autres usages de ItemStack.CODEC/STREAM_CODEC du mod :
CNDataComponents.ClothItemStack n'est ecrit que si l'item est un ClothItem,
donc jamais vide ; les encodages de ReactorBluePrintItem/Menu portent sur le
blueprint tenu en main, jamais vide. Rien d'autre a corriger.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- $3.1 Jauges DisplayLink : marque fait (3f99c87), diagnostic d'origine conserve en <details> et complete par ce qu'il sous-estimait (la feature etait morte, pas incomplete) ainsi que par les deux bugs trouves dans ReactorSummaryDisplaySource et la resolution du doublon ReactorGaugeOverrides. - $6 piege n2 : ajoute le cas PatternData / ItemStack.CODEC (a8d1f1b), et la lecon associee : les gametests ne rechargent pas le monde, l'erreur ne sortait que dans le log sous un 'All 29 tests passed'. - Journal des chantiers, compte de fichiers et nombre de gametests mis a jour. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Les deux depots portaient 8 fichiers identiques sous des noms differents, ce qui obligeait a les traiter comme des faux positifs a chaque diff d'arborescence (section 1 de PARITE_FORGE_NEOFORGE.md). Ils sont desormais nommes pareil des deux cotes. Sept renommages cote NeoForge, vers le nom Forge : content/rod/CNRodTypes -> content/multiblock/rod/CNRodTypes foundation/damagesTypes/ -> foundation/damageTypes/ CNArmorMaterials -> ArmorMaterials CExplose -> CExplode PlayerInteracteReactorFluidInput -> PlayerInteractReactorFluidInput IrradiatedCatLieOnBedGoal -> CatLieOnBedGoal IrradiatedCatSitOnBlockGoal -> CatSitOnBlockGoal Le cas damagesTypes n'etait pas qu'un nom : le fichier declarait deja "package ...foundation.damageTypes" alors qu'il vivait dans un dossier damagesTypes. Dossier et package se contredisaient ; seul le dossier bougeait. Le huitieme ecart est traite dans l'autre sens, dans le depot Forge : c'est Forge qui ecrivait BiomeIrradationExtractorItem, NeoForge avait deja l'orthographe correcte. Renommer NeoForge aurait propage la faute. Trois des nouveaux noms masquent une classe vanilla homonyme : ArmorMaterials (net.minecraft.world.item), CatLieOnBedGoal et CatSitOnBlockGoal (net.minecraft.world.entity.ai.goal). Les fichiers concernes importent ces packages en wildcard, mais une classe du meme package l'emporte sur un import a la demande, et aucun de ces fichiers n'utilise la classe vanilla homonyme. Forge compile ainsi depuis toujours. A savoir si l'un d'eux a un jour besoin de la version vanilla : il faudra la qualifier completement. Verifie : compileJava passe sur les deux depots, et le diff d'arborescence de la section 7 ne liste plus ces 8 fichiers. Aucune ressource touchee (aucune reference a ces noms hors .java). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Chantier 2 de PARITE_FORGE_NEOFORGE.md (section 3.8) : RodsStats,
RodsTooltipHandler, UraniumOreItem et CNOpenPipeEffectHandlers. Les quatre sont
portes a l'identique de Forge, seule l'API 1.21 change (ItemTooltipEvent passe
sous net.neoforged, ForgeRegistries.ITEMS.getKey -> BuiltInRegistries.ITEM.getKey,
@Mod.EventBusSubscriber -> @EventBusSubscriber sans attribut bus, le bus GAME
etant le defaut en NeoForge et l'attribut etant deprecie).
CNOpenPipeEffectHandlers etait le fichier important. RadiationEffectHandler
existait deja cote NeoForge, complet et correct, mais n'etait reference nulle
part faute de ce point d'enregistrement : un tuyau ouvert Create crachant de
l'uranium n'irradiait donc personne. C'est le meme schema que les jauges
DisplayLink du chantier 1 -- une feature entierement morte plutot qu'incomplete.
Deux cas en deux chantiers : cote NeoForge, chercher systematiquement les
classes jamais referencees.
Deux ecarts avec le diagnostic de la roadmap, trouves en portant :
- trois blocs portent UraniumOreItem cote Forge, pas deux. La roadmap citait
uranium_ore et deepslate_uranium_ore (radiation 3), et oubliait
raw_uranium_block, dont la radiation vaut 27. Les trois sont branches.
- la cle de lang tooltip.ratio manquait cote NeoForge, alors que les cinq
autres cles tooltip.* des barres etaient deja presentes. Sans elle,
RodsStats aurait affiche la cle brute. Ajoutee dans lang/default et
regeneree via runData (en_us et en_ud).
RodsStats et RodsTooltipHandler ne font pas doublon, malgre les apparences :
RodsStats est branche sur setTooltipModifierFactory de Registrate, qui ne couvre
que les items du mod ; RodsTooltipHandler ecoute ItemTooltipEvent et ne sert que
les items externes (autres mods, ou RodType definis par datapack et resolus au
runtime), d'ou son return anticipe sur le namespace createnuclear. Supprimer
l'un des deux ou inverser la condition double le tooltip des barres du mod. Le
commentaire qui le dit est present dans le fichier, des deux cotes.
Verifie : compileJava passe, runData ne produit que la cle de lang ajoutee
(aucune regeneration de modele malgre le passage de .item() a
.item((b, p) -> new UraniumOreItem(...))), et 31/31 gametests passent sans
aucune erreur dans le log complet.
Non verifie -- aucun gametest ne couvre ces trois comportements, ils demandent
un test en jeu :
1. tooltip d'une barre : cinq lignes de stats, type en vert (FUEL) ou cyan ;
2. raw_uranium_block en inventaire : la radiation monte de 27 par item ;
3. tuyau ouvert crachant de l'uranium : irradie les entites de la zone.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Les depots ont ete transferes sous l'organisation Create-Nuclear-Team, mais plusieurs liens pointaient encore sur les comptes personnels d'origine. GitHub redirige, donc rien n'etait casse -- mais une redirection cesse de fonctionner des que quelqu'un recree un depot sous l'ancien nom. Le cas le plus genant n'etait pas le proprietaire mais le depot lui-meme : issueTrackerURL de neoforge.mods.toml pointait sur CreateNuclearForge, pas sur CreateNuclearNeoForge. Les rapports de bug des joueurs NeoForge, ouverts depuis l'ecran de crash du jeu, atterrissaient donc dans le tracker de la version Forge. Corrige en meme temps que le proprietaire. Le README de CreateNuclearForge etait deja correct sur les trois liens : c'est lui qui a servi de reference. Non modifie volontairement : le CHANGELOG (ce sont des liens vers des commits et des PR historiques, les reecrire falsifierait l'historique) et les rapports de crash archives dans run/, qui citent l'URL en vigueur au moment du crash. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Le fichier accumulait le fait et le restant : sections barrees, encadres
"FAIT le ...", diagnostics d'origine replies dans des <details>, journal des
chantiers. A la lecture, il fallait trier avant de savoir quoi faire.
Desormais il ne contient que du travail restant. Ce qui est fait en sort --
l'historique est dans les commits, qui sont plus fiables qu'un journal tenu a
la main.
Supprime : le journal, la section des 8 fichiers renommes (les noms sont
alignes des deux cotes), les chantiers Jauges DisplayLink et Divers, et les
lignes barrees de l'ordre de travail.
Conserve, mais deplace, ce qui n'etait pas "du travail fait" mais du savoir
utile pour la suite :
- la lecon des deux chantiers -- une feature peut etre presente mais morte,
faute de point d'enregistrement -- passe en encadre du paragraphe 0 et en
premiere etape de la methode, avec le grep qui la detecte ;
- le fait que trois classes du mod masquent une classe vanilla homonyme
(ArmorMaterials, CatLieOnBedGoal, CatSitOnBlockGoal) rejoint les pieges du
paragraphe 6 : ce n'est pas une tache faite, c'est une propriete du code
actuel qui peut mordre plus tard ;
- les deux cas de codec persistant trop strict sont fusionnes en un seul
piege, avec les deux exemples.
Ajoute un paragraphe 4 "Verifications en jeu en attente" : la radiation et les
trois comportements livres au chantier 2 ne sont couverts par aucun gametest.
C'est du travail restant, meme si ce n'est pas du portage -- le supprimer avec
le reste du chantier l'aurait perdu.
Renumerotation en 0-7 sans trou. Les messages de commit anterieurs a celui-ci
referencent l'ancienne numerotation (section 1, section 3.1, section 3.8).
Verifie : la somme des fichiers des six chantiers fait bien 17, le diff
d'arborescence en donne 21 (17 + les 4 a ne pas porter), et aucune reference
ne pointe vers une section supprimee.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… HolderSet RodType previously stored a HolderSet<Item> so a rod type could map to multiple items; in practice each type only ever mapped to one, so the API/data model is simplified to a single Holder<Item>. - RodType: replace `items: HolderSet<Item>` with `item: Holder<Item>`, switch codec from RegistryCodecs.homogeneousList to RegistryFixedCodec, and update isNotEmptyItem()/toString()/ getTypeForItem() accordingly - RodType.Builder: replace addItems(ItemLike...) with item(ItemLike), add explicit type(TypeRod) setter, drop the redundant *Set boolean flags in favor of null checks in build(), default type to NONE - TypeRodPredicate: drop the non-level-aware IS_FUEL/IS_COOLED predicates and tag shortcuts; isFuel/isCooled now always resolve the rod type through the level's registries - ItemRodTypesValue: build DEFAULT_ROD_TYPE from Items.AIR's holder instead of an empty HolderSet, update setRodTypeInfos() to use builder.item(item) instead of addItems(item) - ReactorInputManager: switch fuel/cooler checks to the level-aware isFuel(stack, level)/isCooled(stack, level) methods - Regenerate fallback.json rod-type data to use "item": "minecraft:air" instead of "items": []
…FluidType Following the RodType refactor, apply the same "one item per type" simplification to ReactorFluidType, and centralize the fallback registry keys. - ReactorFluidType: replace `fluids: HolderSet<Fluid>` with `fluid: Holder<Fluid>`; switch codec from RegistryCodecs.homogeneousList to RegistryFixedCodec; simplify getTypeForFluid()/isNotEmptyFluid()/toString() accordingly - ReactorFluidType.Builder: single fluid(Fluid)/fluid(FluidStack) setters instead of accumulating a list; drop the unused setRodConfig()/useConfig runtime-config override in maxHeat()/ efficiency() (build() now always requires maxHeat and efficiency) - CreateNuclearRegistries: introduce FALLBACK_ROD and FALLBACK_FLUID ResourceKey constants, replacing the ones previously declared in CNRodTypes.FALLBACK and CNReactorFluidTypes.FALLBACK - CNRodTypes / CNReactorFluidTypes: remove the now-relocated FALLBACK ResourceKey fields - RodType: point resolveRodType() at CreateNuclearRegistries.FALLBACK_ROD instead of CNRodTypes.FALLBACK - ReactorFluidTypesValue: build DEFAULT_REACTOR_FLUID_TYPE from Fluids.EMPTY's holder instead of an empty HolderSet - MultiBlockManagerBeta: widen findStructure()'s parameter from the concrete ReactorControllerBlockEntity to the IMultiblockController interface - Regenerate fluid-type data (fallback.json, nitrogen.json, water.json) to use the singular "fluid" field instead of "fluids"
…ult bus @EventBusSubscriber previously pinned the class to the GAME bus explicitly; switch to the default bus argument so the class's listeners register on NeoForge's default mod event bus instead. - RadiationCapability: drop `bus = EventBusSubscriber.Bus.GAME` from the @EventBusSubscriber annotation, keeping only `modid`
… foundation to the api package Relocate the addon-facing recipe generator base classes into the `api.data.recipe` package (mirroring how other API surfaces of the mod are organized), restore EnrichedRecipeGen's full StandardProcessingRecipeGen<EnrichedRecipe> implementation, and wire up the new camera/renderer client mixins for the radiation-effect rendering hook. Staged: - Move SnowPowderRecipeGen from foundation/data/recipe → api/data/recipe (package updated) - Delete the old foundation/data/recipe/EnrichedRecipeGen.java (now superseded by the moved/rewritten api/data/recipe/EnrichedRecipeGen.java) Not staged: - EnrichedRecipeGen (api): extend StandardProcessingRecipeGen<EnrichedRecipe> again instead of the raw ProcessingRecipeGen, restoring the convert(...) helper methods, CNRecipeTypes.ENRICHED wiring, and class-level Javadoc pointing at CNEnrichedRecipeGen/CNRecipeProvider - CNEnrichedRecipeGen / CNSnowPowderRecipeGen: update imports to reference the relocated api.data.recipe base classes - CNRecipeProvider: drop now-unused imports (Create, ProcessingRecipe, ProcessingRecipeBuilder, CreateRecipeProvider, IRecipeTypeInfo, CatnipServices, ResourceLocation, Ingredient, ItemLike, CreateNuclear, Supplier, UnaryOperator) left over from the recipe gen cleanup - createnuclear.neoforge.mixins.json: register the two new client mixins, client.CameraAccessor and client.GameRendererMixin, alongside the existing RadiationHeartMixin and AntiRadiationArmorTextureMixin - PARITE_FORGE_NEOFORGE.md: update the Forge→NeoForge parity notes — mark CriterionTriggerBase as resolved (now tracks Create's own evolution instead of vanilla SimpleCriterionTrigger), note that the Alex's Caves compat hook doesn't apply since that mod isn't available on 1.21.1, and note that comparing mixins.json is mandatory given Minecraft's internal changes between 1.20.1 and 1.21.1 Untracked (new files, not yet staged): - compat/Mods.java and compat/alexscave/AlexscaveCompat.java: initial mod-compat scaffolding (mod-loaded checks and an Alex's Caves compatibility handler) - foundation/mixin/client/CameraAccessor.java and foundation/mixin/client/GameRendererMixin.java: new client mixins backing the mixins.json registration above, for camera/renderer access per the radiation-effect rendering parity notes
… dose/contagion model Radiation damage sources (campfire, fan enriching, the RADIATION mob effect) previously applied the effect/damage directly; they now go through RadiationCapability's dose-based contagion system, and the fan_radiation damage type (previously commented out) is wired up and tagged as NO_KNOCKBACK alongside RADIATION. - RadiationEffect: extend the new VicinityEffect base instead of MobEffect directly, adding a contagion radius/duration and an onContaminate(...) hook that calls RadiationCapability.applyContagion(...) on nearby entities; applyEffectTick() now defers to super, computes damage from RadiationCapability.getRadiationResistance(...), and deals it via CNDamageSources.radiation(...) instead of livingEntity.damageSources().magic() - EnrichingCampfireBlock: entityInside() now calls RadiationCapability.applyContagion(livingEntity, CAMPFIRE_DOSE, 100) instead of directly adding a RADIATION MobEffectInstance - CNFanProcessingTypes.EnrichedType: affectEntity() now applies a contagion dose via RadiationCapability.applyContagion(...) and separately deals 1 point of fan_radiation damage via CNDamageSources.fanRadiation(level), instead of only adding a RADIATION MobEffectInstance - CNDamageSources: un-comment and enable fanRadiation(Level), which was previously dead code - CNDamageTypes: clean up radiation(Level) to use imported DamageSource/ Level types instead of fully-qualified names (no behavior change) - Add CNDamageTypeTagsProvider: a plain TagsProvider<DamageType> (not a Registrate dynamic tag generator, since DamageType entries only resolve through the datapack-registry HolderLookup.Provider) tagging RADIATION and FAN_RADIATION under DamageTypeTags.NO_KNOCKBACK - CreateNuclearDatagen: register the new CNDamageTypeTagsProvider as a server data provider - CameraAccessor: widen callMove(...)'s parameters from double to float, matching the updated Camera#move signature - GameRendererMixin: update the @Inject target from the old render(FJZ)V signature to the current render(Lnet/minecraft/client/DeltaTracker;Z)V signature, and read the partial tick via deltaTracker.getGameTimeDeltaPartialTick(false) instead of a raw float parameter
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.
No description provided.