diff --git a/AI-Car-Racer/buttonResponse.js b/AI-Car-Racer/buttonResponse.js index dc1c5a3..f28471a 100644 --- a/AI-Car-Racer/buttonResponse.js +++ b/AI-Car-Racer/buttonResponse.js @@ -8,6 +8,20 @@ function pauseGame(){ btn.classList.remove('start-cta'); } window.__firstStart = false; + + // Gentle first-time onboarding hint (only shown once) + if (!localStorage.getItem('seenFirstStartHint')) { + localStorage.setItem('seenFirstStartHint', '1'); + setTimeout(() => { + try { + const hint = document.createElement('div'); + hint.style.cssText = 'position:fixed;bottom:12px;left:50%;transform:translateX(-50%);background:rgba(0,0,0,0.78);color:#ddd;padding:6px 14px;border-radius:4px;font-size:12px;z-index:9999;white-space:nowrap;'; + hint.innerHTML = 'Demo running — cars are evolving. Use “✏️ Customize Track” or 🧪 Experiments for more options.'; + document.body.appendChild(hint); + setTimeout(() => { if (hint && hint.parentNode) hint.parentNode.removeChild(hint); }, 7000); + } catch (_) {} + }, 1400); + } // Halt / resume the worker's AI step loop too. Without this, sim-worker // would keep burning CPU while the user has paused — and on resume the // accumulator would stampede a huge backlog of physics steps at once. diff --git a/AI-Car-Racer/car.js b/AI-Car-Racer/car.js index 778e0e8..e867aa3 100644 --- a/AI-Car-Racer/car.js +++ b/AI-Car-Racer/car.js @@ -125,7 +125,14 @@ class Car{ // distance cue; see docs/plan/ruvector-proof/arch-a1/PROOF.md. const cpList = checkPointList; let lf = 0, lr = 0; - if (cpList && cpList.length){ + + // When pureLocalSensors is active, we deliberately give the brain + // ZERO information about where the next checkpoint is. + // This is the "embodied local signals only" mode for comparison. + // Guard works in both main thread (window) and Web Worker (self). + const isPureLocal = (typeof window !== 'undefined' && window.pureLocalSensors) || + (typeof self !== 'undefined' && self.pureLocalSensors); + if (!isPureLocal && cpList && cpList.length){ const passed = this.checkPointsPassed; const nextIdx = passed.length === 0 ? 0 @@ -139,11 +146,7 @@ class Car{ const s = Math.sin(this.angle), c = Math.cos(this.angle); const lfRaw = dx * s + dy * c; const lrRaw = dx * c - dy * s; - // Canvas diagonal as track-invariant scale. `road` is a - // global populated by main.js (or handleInit in the - // worker); both paths set `right` and `bottom` = canvas - // dims. Fallback constant guards the very-early frame - // before handleInit lands. + // Canvas diagonal as track-invariant scale. const W = (typeof road !== 'undefined' && road && road.right) ? (road.right - road.left) : 3200; const H = (typeof road !== 'undefined' && road && road.bottom) ? (road.bottom - road.top) : 1800; const D = Math.hypot(W, H); diff --git a/AI-Car-Racer/eli15/chapters/lineage.js b/AI-Car-Racer/eli15/chapters/lineage.js index e02dd92..05b6b7a 100644 --- a/AI-Car-Racer/eli15/chapters/lineage.js +++ b/AI-Car-Racer/eli15/chapters/lineage.js @@ -6,12 +6,12 @@ export default { oneLiner: 'parentIds + getLineage() reconstruct a brain\'s family tree on demand.', body: [ '

When a generation ends, the best car\'s brain gets archived — but we don\'t just', - 'save the 92 weights. We also save which brains it came from. Each', + 'save the 244 weights. We also save which brains it came from. Each', 'archive entry carries a parentIds: string[]: the ids of the seeds the GA', 'warm-started this batch from. Those parents have their own parents stored', 'alongside their weights. String enough of those together and you have a family', 'tree of neural networks.

', - '

ruvectorBridge.js:200 exposes getLineage(id, maxDepth = 6).', + '

ruvectorBridge.js:1338 exposes getLineage(id, maxDepth = 6).', 'Starting from any brain id, it walks parentIds backwards. When a brain has', 'multiple parents (the batch was seeded from multiple retrievals), it picks the parent', 'with the highest fitness — "the line of descent we credit this genome to". The', diff --git a/AI-Car-Racer/eli15/chapters/neural-network.js b/AI-Car-Racer/eli15/chapters/neural-network.js index c5af0fa..ad3f364 100644 --- a/AI-Car-Racer/eli15/chapters/neural-network.js +++ b/AI-Car-Racer/eli15/chapters/neural-network.js @@ -1,28 +1,28 @@ // eli15/chapters/neural-network.js -// The 92-weight 6→8→4 feed-forward network that decides W/A/S/D. +// The 244-weight 10→16→4 feed-forward network that decides W/A/S/D. export default { id: 'neural-network', - title: 'A brain made of 92 numbers', - oneLiner: 'Six sensor inputs → eight hidden neurons → four pedal/steer outputs.', + title: 'A brain made of 244 numbers', + oneLiner: 'Ten sensor inputs → sixteen hidden neurons → four pedal/steer outputs.', body: [ '

Every car carries a tiny neural network. It is almost comically small:', - '6 inputs → 8 hidden neurons → 4 outputs. See it in', + '10 inputs → 16 hidden neurons → 4 outputs. See it in', 'network.js (the Level and NeuralNetwork classes) and', - 'car.js:37-38 where the car wires it up.

', + 'car.js:41-42 where the car wires it up.

', '

"A neuron" here is just a weighted sum with a threshold. It multiplies each input', 'by a weight, adds them all up, and compares the total to a bias.', 'If the sum beats the bias, the neuron fires a 1. Otherwise a 0. That\'s it — no fancy', 'activation function, no backprop, no gradients. The whole network can be serialised', - 'as a flat Float32Array(92) — see brainCodec.js:2:', - 'FLAT_LENGTH = 92. Where does 92 come from? For each layer with in', + 'as a flat Float32Array(244) — see brainCodec.js:5:', + 'FLAT_LENGTH = 244. Where does 244 come from? For each layer with in', 'inputs and out outputs you need in × out weights plus out biases:', - '(6×8 + 8) + (8×4 + 4) = 56 + 36 = 92.

', + '(10×16 + 16) + (16×4 + 4) = 176 + 68 = 244.

', '

The four outputs are Boolean: forward, reverse, left, right.', - 'The car presses the pedals whose neuron fired a 1. Combine that with the 5 rays', - '(plus 1 bias) from sensors and you get the whole perception-to-action pipeline', + 'The car presses the pedals whose neuron fired a 1. Combine that with the 7 rays + 3 features', + ' from sensors + car and you get the whole perception-to-action pipeline', 'in ~50 lines of JS.

', '

No learning happens inside the brain itself — the brain is just a lookup function.', - 'Learning happens across generations, by the genetic algorithm tweaking those 92', + 'Learning happens across generations, by the genetic algorithm tweaking those 244', 'numbers.

', '

Try it yourself

', '