PulseCore

Chapter 10 · Section 3

Start

  1. The player presses Start (start()).
  2. The core spins up to its full rate.
  3. The genesis is locked: the panel can no longer change it, and the universe is saved as a new record.
  4. The epoch becomes "singularity": the Pulsecore is now a pinpoint filling with data. A Zinf genesis of one lit cell at level 0 is collected as a find.
  5. The pinpoint is sealed: the painted field is kept as frame 0 (genesisFrame0), any brush ripple still running is dropped, and the whole genesis is written into a Universe Packet so the run can be replayed exactly.
  6. The loop starts at the chosen pace (startLoop()). In the paced mode a tick comes every 50 ms; the filling is paced to about 400 ticks and the life to about 2,000, and after each step the page waits as long as the step took, so the physics never takes more than half the time and the scene draws between.
  7. The first flip only starts the clock: the counter goes from 0 to 1, the state line reads "Pulsing", and nothing in the field changes yet.

The method, in plain steps:

on Start:
    lock the genesis, save the universe
    epoch ← "singularity"
    frame 0 ← the painted field
    repeat every tick (paced: 50 ms):
        run as many steps as the pace owes, never more than half the wall time

The code:

// public/game-v8.4/app.js:4801 start()
lockGenesis(true);
if (typeof universeId !== 'number') saveUniverse('new', genesisPayload());
if (epoch === 'pre') {
    setEpoch('singularity');
    …
}
doStart();   // genesisFrame0 = copyGrid(grid); pulses = []; … running = true; … startLoop();

// public/game-v8.4/app.js:4850 startLoop(), the paced mode
const TICKS_FILL = 400, TICKS_LIFE = 2000;
let rate = 1;
if (epoch === 'singularity' && uni) rate = Math.max(1, (2 * novaTempo(uni.Lm)) / TICKS_FILL);
else if (epoch === 'universe' && uni) rate = Math.min(4, (2 * lifeEndTempo()) / TICKS_LIFE);
owed += rate;
…
finally { skipDraw = false; nextAt = performance.now() + (performance.now() - tNow); }