# Nuclear

# 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 **`Inventory`** is 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 **`Reactor`** is 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 **`Assembly`** is 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

```ts
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 (skill `ferret-physics-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

```ts
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.** `setRods` moves them from 0 (out) to 1 (in); `rodsCritical` is where they hold the reactor at nominal power. `scram()` drops them at once, and a `trip` threshold 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](../recipes/loss-of-coolant.md) 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

```ts
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 (skill `ferret-physics-combustion-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 (skill `ferret-physics-heat`): decay heat warms the thing that carries the source. explosions (skill `ferret-physics-combustion-explosions`): a disassembled assembly is a blast. terrain (skill `ferret-physics-terrain`) and liquids (skill `ferret`): soil and water are shields, and fallout lives on the ground grid. links (skill `ferret-physics-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`.
