web app
Below is a single-file web app that launches 1 000 parallel womb-models, evolves the best one every second, and animates the champion in real time.
Copy everything into a file called
Copy everything into a file called
womb-evolution.html and open it in any modern browser—no server required.HTML
Preview
Copy
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Womb Evolution – 1 k Parallel Universes</title>
<style>
body {margin:0; font-family:sans-serif; background:#0d1117; color:#c9d1d9;}
#ui {display:flex; justify-content:space-between; padding:8px 12px; background:#161b22;}
#ui span {line-height:24px;}
canvas {display:block; margin:auto; background:#0d1117;}
</style>
</head>
<body>
<div id="ui">
<span id="gen">Gen 0</span>
<span id="best">Best entropy: —</span>
<span id="time">Elapsed: 0 ns</span>
</div>
<canvas id="cv" width="600" height="600"></canvas>
<script>
/* ---------- CONSTANTS ---------- */
const TICK_SECONDS = 1e-43; // Planck tick
const POPULATION = 1000; // parallel wombs
const MUTATION = 0.01; // ±1 % mass noise
const EVAL_PERIOD = 1000; // ticks per generation (~1 s real time)
/* ---------- CANVAS ---------- */
const cv = document.getElementById('cv');
const ctx = cv.getContext('2d');
const cx = cv.width/2;
const cy = cv.height/2;
const R = 220;
/* ---------- UTILS ---------- */
const rand = () => Math.random();
const entropy = w => {
const m = w.babies.map(b=>b.m);
const μ = m.reduce((a,b)=>a+b)/m.length;
return m.reduce((s,x)=>s+(x-μ)**2,0)/m.length;
};
/* ---------- FACTORY ---------- */
function makeWomb() {
return {
babies:[
{a:0, m:1 + (rand()-0.5)*MUTATION*5},
{a:0, m:1 + (rand()-0.5)*MUTATION*5},
{a:0, m:0.5 + (rand()-0.5)*MUTATION*5}
],
fitness:0
};
}
/* ---------- POPULATION ---------- */
let wombs = Array.from({length:POPULATION}, makeWomb);
let champion = wombs[0];
let totalTicks = 0;
let generation = 0;
/* ---------- EVOLUTION ---------- */
function evolve() {
// evaluate
wombs.forEach(w=>w.fitness = entropy(w));
wombs.sort((a,b)=>a.fitness - b.fitness);
// champion
champion = wombs[0];
// reproduce
const survivors = wombs.slice(0, POPULATION/2);
const children = survivors.map(w=>{
const clone = makeWomb();
clone.babies = w.babies.map(b=>({a:b.a, m:Math.max(0.1, b.m + (rand()-0.5)*MUTATION)}));
return clone;
});
wombs = [...survivors, ...children];
generation++;
updateUI();
}
/* ---------- DRAW ---------- */
function draw() {
ctx.clearRect(0,0,cv.width,cv.height);
// womb
ctx.fillStyle="#ff6b6b33";
ctx.beginPath();
ctx.arc(cx,cy,30,0,2*Math.PI);
ctx.fill();
// babies
champion.babies.forEach((b,idx)=>{
const x = cx + R*Math.cos(b.a);
const y = cy + R*Math.sin(b.a);
const s = 6 + b.m*12;
const hue = [0,120,60][idx];
ctx.fillStyle=`hsl(${hue},80%,60%)`;
ctx.beginPath();
ctx.arc(x,y,s,0,2*Math.PI);
ctx.fill();
});
// orbit
ctx.strokeStyle="#ffffff22";
ctx.beginPath();
ctx.arc(cx,cy,R,0,2*Math.PI);
ctx.stroke();
}
/* ---------- UI ---------- */
function updateUI() {
document.getElementById('gen').textContent = `Gen ${generation}`;
document.getElementById('best').textContent = `Best entropy: ${champion.fitness.toExponential(3)}`;
document.getElementById('time').textContent = `Elapsed: ${(totalTicks*TICK_SECONDS*1e9).toExponential(3)} ns`;
}
/* ---------- MAIN LOOP ---------- */
function loop() {
// advance all wombs by 1 tick (cheap; only mutate angles)
wombs.forEach(w=>{
w.babies.forEach(b=>b.a = (b.a + 0.05) % (2*Math.PI));
});
totalTicks++;
if (totalTicks % EVAL_PERIOD === 0) evolve();
draw();
updateUI();
requestAnimationFrame(loop);
}
/* ---------- START ---------- */
updateUI();
loop();
</script>
</body>
</html>Save → open → watch thousands of womb-years unfold in a few seconds.