HBM's NTM Graphite Pile Calculator

Formulas from the HBM's Nuclear Tech Mod 1.7.10-1.0.27 source

Paint a graphite pile, block by block, and the page runs the mod's own neutron transport: every reacting rod casts 12 rays in random directions, marching 0.5 blocks at a time out to range 5 — concrete quarters the flux, boron eats it, empty space kills it dead. Heat self-damps (hot rods go quiet), rods transmute at 50,000 progress, lithium breeds tritium. Seeded Monte-Carlo over 2,000 ticks, exactly the mod's tick loop, transcribed from PileNeutronHandler and the pile tile entities.

—
Y 3 / 3

Drag to rotate. Right-drag, Shift-drag or two-finger drag to pan. Scroll or pinch to zoom. Click a block face to place the selected block there; click a block with the Empty brush to remove it.

Pile painter

The slice preview tracks the layer the slicer is on — click a cell to paint it too. Rows run front to back (Z), columns left to right (X). Air stops a neutron ray instantly — a ray that steps into an empty cell dies there, so leave no gaps between the rods. Rod end-faces glow as progress burns toward plutonium; Neutrons tints every block by the neutrons it received in the first tick.

Mod preset

Edit pile constants (NTM ships these in code, not in a config file)

Pile shape & RNG

Same seed + same pile = the exact same run; reroll to sample a new set of random ray directions. The loop is a per-tick Monte-Carlo — a full 15×15×5 core takes a few seconds. 528 mode retargets plutonium to 75,000 progress and tritium to 50,000.

Result

median fuel rod progressmedian rod heatPu targetheat cap 1,000

    2,000 game ticks = 100 s. The chart tracks the fuel rod nearest the pile centre. A pile has no meltdown — the heat cap means radon, not a blast.

    Share this design

    The link opens this exact pile with this exact seed. Paste a design code above to load one.

    What the code actually says

    Twelve rays, no fixed directions

    There is no fixed set of 12 vectors in 1.0.27. Every cast starts from (1,0,0) and rotates it by three independent random full turns — rotateX, rotateY, rotateZ (TileEntityPileBase.castRay, lines 34-37). On (1,0,0) rotateX does nothing, so each ray's exact direction is (cos a·cos b, cos a·sin b, −sin a) with a,b uniform on [0,2π) — a true Monte-Carlo over the sphere. The stream walks it with i from 1.0 to 5.0 in 0.5 steps, hopping to floor(pos+0.5+v·i) (PileNeutronHandler.runStreamInteraction, lines 47-54).

    12 casts: fuel reaction, source rod
    2 casts: lithium with neutrons > 0
    range 5, step 0.5, per-ray flux:
    fuel max(reaction×0.25, 1) · source 1 (isotope 2)
    TileEntityPileBase.castRay · PileNeutronHandler.range=5

    Hot rods go quiet

    Every neutron budget is scaled by (1 − heat/1000 × 0.5): a rod at 1,000 heat converts only half its neutrons, at 2,000 none at all — and with reaction ≤ 0 the function returns early, so a cold-started lone fuel rod casts zero rays. Heat feeds back into itself: equilibrium lands at 20× the reaction rate (dry sleeve). The pile can't melt down; it throttles.

    reaction = (int)(neutrons × (1 − heat/1000 × 0.5))
    progress += reaction; heat += reaction
    heat −= heat × (0.065 water | 0.05)
    if (reaction <= 0) return   // no rays at all
    TileEntityPileFuel.react · dissipateHeat

    Concrete is the control rod

    Every concrete variant a ray crosses — concrete, smooth, asbestos, colored, brick concrete — multiplies its flux by 0.25. Receivers get floor(flux) and swallow the ray, so one concrete layer in front of a rod delivers floor(0.25) = zero neutrons. Boron blocks absorb the ray outright. Stack concrete plates between rods and you carve a neutron shadow into the pile.

    concrete · flux ×= 0.25 (keeps going)
    boron    · return (absorbed)
    receiver · receive(floor(flux)); return
    detector with meta bit 8 · passes through
    PileNeutronHandler.runStreamInteraction, lines 70-96

    50,000 progress = plutonium

    A fuel rod adds its reaction to progress every tick; at maxProgress the block is replaced by a plutonium block (528 mode: 75,000). It stops being a pile tile — no TE, rays pass through. Lithium breeding rods add raw neutrons (no heat) to 30,000 (528: 50,000) and become a tritium block, casting 2 rays per active tick on the way.

    fuel: maxProgress = enable528 ? 75000 : 50000
    Li:   maxProgress = enable528 ? 50000 : 30000
    at max → block swap, tile entity gone
    TileEntityPileFuel · TileEntityPileBreedingFuel

    Empty sleeves absorb — build order matters

    A ray resolves the block position to a tile entity first: air (no TE) ends the stream instantly, and a graphite rod sleeve without a rod (meta bit 8 clear) absorbs it too. The source rod is a pile tile but not a receiver, so rays sail straight through it. Neutrons only cross the pile where solid, transparent material (graphite) connects the rods.

    tile == null             → return (air)
    graphite_rod (meta&8)==0 → return
    graphite · source rod    → pass through
    PileNeutronHandler, lines 60-88 · TileEntityPileSource

    Radon cap, trip detector, water sleeves

    At heat ≥ 1000 the rod spawns dense radon gas and smoke — the cap is a radiation hazard, not a meltdown. Neutron detectors trip their rod control at 10 neutrons/tick and, when powered (meta bit 8), stop absorbing beams. Water-cooled sleeves (meta bit 4) shed 6.5% of their heat per tick instead of 5% — a 30% better equilibrium. Anything living standing in a stream takes flux/4 rads per pass.

    heat >= 1000        → gas_radon_dense
    neutrons >= 10       → detector triggerRods
    meta bit 4          → dissipation 0.065
    stream entity        → contaminate(flux/4)
    TileEntityPileFuel · TileEntityPileNeutronDetector · PileNeutronHandler, line 104