Nuclear
Package @ferret/physics-nuclear, capability nuclear.
What it is for#
A cobalt source in a lead container and a counter that clicks faster as you approach. A heap of fallout you have to cross quickly. A reactor you start, hold, scram, or let melt. A lump of fissile material that goes critical when you add the last piece. A sample that becomes radioactive after a night in a neutron flux.
The physics is textbook physics: decay laws, inverse-square dose, half-value layers, point reactor kinetics. The isotope and material tables that ship with the package are sample data; a game replaces them with its own.
The ideas#
Radiation in a game comes down to three levers the player can pull: distance (the dose falls with the square of it), shielding (every half-value layer of lead or concrete halves the dose) and time (the dose is the rate multiplied by the time spent). Everything in the package serves those three.
- Isotopes decay with a half-life into a daughter, releasing energy and particles of some kinds (alpha, beta, gamma, neutron). Part of the energy stays where the atom decayed and becomes heat. A set of ready isotopes (
EXAMPLE_ISOTOPES) covers Co-60, Cs-137, Sr-90, Mo-99, Rn-222, U-238 and a few stable ones. - An
Inventoryis a pile of atoms of several isotopes. Decay is computed exactly, so chains and equilibrium come out right at any time step. A strontium source grows its own daughter, and after a few weeks the two activities match. - Dose is the activity times the particles per decay, times a dose coefficient, times what the shield lets through, spread over
4π r². Between a source and a receiver the capability walks the ray through the scene and takes the slant thickness of every body made of a shield material, so a thick wall seen at an angle shields more than one seen head-on. - A
Reactoris the heart of a plant: neutrons, delayed neutrons that make control possible, temperature and steam feedback, control rods, xenon poisoning, burn-up and the decay heat that goes on after a shutdown. - An
Assemblyis fissile material measured against its critical mass. Below it nothing happens. Above it the chain runs away until the assembly blows itself apart. - Activation turns a stable material into a radioactive one under a flux. Fallout is a ground grid in which every cell holds an inventory that decays like any other, and rain can wash a share away.
Using it#
import { nuclear } from '@ferret/physics-nuclear';
const n = nuclear();
host.register(n);
host.enable('nuclear');
const pig = n.addSource('pig', { entity: pigEntity }); // a source on an entity
pig.addActivity('Co-60', 1e12); // 1 TBq
n.addReceiver('geiger', { entity: playerEntity, sensitivity: 6e9, seed: 1 });
A body whose physics material is a name in the shield library (lead, concrete, water, ...) shields whatever is behind it. A source on an entity that has a heat part warms it with the decay heat, which is how a hot waste drum works.
A receiver with a sensitivity is a counter: it draws random counts at dose rate × sensitivity (a Geiger tube is about 6·10⁹ counts per sievert) and raises radiation:counts. Receivers without it just add up a dose, and radiation:dose fires every doseStep sieverts.
Reactors#
n.addReactor('core', { power: 1e6, generation: 1e-4, rodWorth: 0.05, rodsCritical: 0.5,
fuelHeat: 5e5, coolantHeat: 2e5, exchange: 5e4, flow: 2e4, inlet: 290, fuelCoefficient: -2e-5 });
What matters for play:
- Delayed neutrons make control possible. A small step of reactivity makes the power jump a little and then climb slowly over seconds. A step bigger than the delayed fraction (about 0.65 %) makes it race up in milliseconds, and the capability raises
reactor:prompt. - Feedback. With a negative fuel temperature coefficient the reactor settles by itself at the level the rods allow; with a positive one it diverges. A void coefficient models coolant boiling away.
- Rods.
setRodsmoves them from 0 (out) to 1 (in);rodsCriticalis where they hold the reactor at nominal power.scram()drops them at once, and atripthreshold on power or fuel temperature does it automatically. - Decay heat. After a scram the fuel still produces 6–7 % of nominal power, falling slowly. Without cooling (
flow: 0) it heats up until it melts (reactor:melt, once). That is the whole lesson of a loss-of-coolant accident, and one of the scenarios plays it out. - Xenon. After a shutdown, xenon-135 builds up for hours and can make a restart impossible. Burn-up makes fuel lose reactivity as it is used, until the rods run out.
The reactor has no randomness: the same inputs give the same run.
Critical assemblies#
n.addAssembly('device', { mass: 55, criticalMass: 50, disassemblyEnergy: 2e6 }, { position: [0, 0, 0] });
The assembly compares its mass with the critical mass. A reflector lowers the critical mass; compression lowers it with the square of the compression. Above critical it raises assembly:critical, then runs away until it disassembles (assembly:disassembled { energy, tnt }). The energy released is the fissioned mass times 8·10¹³ J/kg, and the capability passes it to explosions as an air blast.
Fallout#
A Fallout is a ground grid with a cell size. deposit(x, z, isotope, atoms) puts material in a cell; deposit_disc(x, z, radius, isotope, bq) spreads an activity evenly over a disc. decay(dt) ages it, and wash(fraction, at?) removes a share, which is what rain or a hose does. A wide even deposit gives the dose of an infinite plane, and a small patch far away obeys the inverse square.
Events and commands#
Events: decay, radiation:dose, radiation:counts, reactor:scram, reactor:prompt, reactor:melt, assembly:critical, assembly:disassembled.
Commands: nuclear.info, isotope.add { source, isotope, atoms | activity }, radiation.dose { receiver }, radiation.map { min, max, step, y? } (a grid of dose rates, ready for a hazard map), reactor.state, reactor.rods { name, fraction }, reactor.scram, assembly.state. cap.doseAt(receiver) returns the current dose rate by kind of radiation.
Parameters#
| Value | Default | Effect |
|---|---|---|
doseStep | 1e-3 Sv | dose between two radiation:dose events |
cap.coefficients hold the sievert-metres² per particle for each kind; replace them if your numbers differ.
Works with#
heat: decay heat warms the thing that carries the source. explosions: a disassembled assembly is a blast. terrain and liquids: soil and water are shields, and fallout lives on the ground grid. links: a reactor can heat a boiler and a turbine.
Cost#
A small matrix product per inventory (kept between steps, so use a constant dt), a handful of rays for every source-receiver pair, a few operations per reactor. Nuclear is cheap.
When it does not behave#
| Symptom | Cause |
|---|---|
isotope "x" needs a half-life above zero | use Infinity for a stable isotope |
"x" is stable: it has no activity | addActivity needs a decaying isotope; use add(atoms) |
| The counter never clicks | no sensitivity, or the walls have no half-value layer for that kind |
| The dose ignores a wall | the wall's material is not a shield name |
| The reactor will not stay critical | rods are not at rodsCritical |
| Power swings after a step | xenon and temperature feedback; leave maxSubstep alone unless the coast is long |
| An assembly never goes critical | its mass over critical mass (after reflector and compression) is below 1; k shows the value |
Worked numbers (inverse square and half-value layers, equilibrium of a chain, activation, steady reactor power, decay heat, critical assembly energy) are in tests/unit/examples/physics-nuclear.test.ts.
Reference#
nuclear, NuclearCapability, Inventory, IsotopeLibrary, ShieldLibrary, doseRate, Reactor, Assembly, activate, Fallout.