Task 5 of 5
Everything from this module, running as one machine. The three kernels below are your last three tasks — softened O(n²) acceleration, the velocity tick, the position tick. What's missing is the conductor: a JavaScript loop that runs ten full ticks, feeding each kernel's output into the next and carrying the new state into the next tick.
Notice who does what: JavaScript never touches a single interaction — it just passes arrays around. The GPU grinds through 128 × 128 = 16,384 interactions per tick, 163,840 across the run. Swap 128 for 100,000 and this exact structure is a galaxy simulator; the loop you're about to write wouldn't change by a character.
accel → stepVel → stepPos, carrying the new arrays forward each time.await accel(px, py, mass, SOFT)await stepVel(vx, vy, ax, ay, DT), then await stepPos with the new velocities — awaited one after another, because each reads the one before itpx, py, vx, vy so the next tick starts from the new stateSTEPS ticks, then log body 0's final positionInside the loop: await accel, unpack its pairs into
ax, ay arrays (the unpack helper is right there),
await stepVel, unpack, await stepPos, unpack. One at a
time — the next call needs the previous one's numbers.
End every tick by overwriting the state:
vx = newVx;
vy = newVy;
px = newPx;
py = newPy;
— next tick's
accel must see the moved bodies, or time never advances.
for (let step = 0; step < STEPS; step++) {
const [ax, ay] = unpack(await accel(px, py, mass, SOFT));
const [nvx, nvy] = unpack(await stepVel(vx, vy, ax, ay, DT));
const [npx, npy] = unpack(await stepPos(px, py, nvx, nvy, DT));
px = npx; py = npy; vx = nvx; vy = nvy;
}This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.