Chapter 10 · Section 4
Every Flip: The Cell Rule
Every step of the run, before the Pulsecore's novas and after them, begins with the same rule on the field (stepField(), engine.js; Part 2.2). It has three parts and no thresholds to set.
- Perpetual reversal. Every pulser flips, 0 → 1 or 1 → 0. Once a cell has pulsed it never stops (Information-Driven Perpetuation).
- Bifurcation. A null cell, one that has never pulsed, gathers exposure from its lit neighbours, one eighth of a pulse for each lit neighbour each flip (weighted by direction when the universe spins). When its exposure reaches one whole pulse it bifurcates, ∅ → (0 ⥂ 1), and lights (Law of Binary Emergence). Exposure is never lost.
- Fold. A pulser whose eight neighbours are all pulsers in its own phase carries no contrast: it folds back to null (The First Fold). What folds is counted into the void; after the Data Nova a fold can seed a well.
- The neighbourhood wraps, because the field is the skin of a torus.
- The step is kept for Back: the last fields are stored so the player can step backward, up to 200 steps on a small field and fewer on a large one (about 4 million cells in all; Part 2.13).
The method, in plain steps:
for every cell:
if it pulses:
if all eight neighbours pulse in its phase → fold it to null
else flip it
else (null):
exposure += (lit neighbours, spin-weighted) / 8
if exposure ≥ 1 → it lights and starts pulsing, taking a lit neighbour's colour
The code:
// public/game-v8.4/engine.js:53 stepField()
if (pulser[r][c]) {
pulsers++;
// the fold: eight pulser neighbours, all in this cell's phase
let same = 0;
for (let k = 0; k < 8; k++) {
const rr = (r + OFFS[k][0] + rows) % rows, cc = (c + OFFS[k][1] + cols) % cols;
if (pulser[rr][cc] && lit[rr][cc] === lit[r][c]) same++; else break;
}
if (same === 8) { lr[c] = 0; pr[c] = 0; exposure[r][c] = 0; folded.push([r, c]); continue; }
lr[c] = lit[r][c] ? 0 : 1; pr[c] = 1; flips++;
} else {
const n = exposureAt(lit, r, c, rows, cols, weights);
if (n > 0) exposure[r][c] += n / 8;
if (exposure[r][c] >= 1) {
lr[c] = 1; pr[c] = 1; exposure[r][c] = 0; born.push([r, c]); flips++;
…
} else { lr[c] = 0; pr[c] = 0; }
}