DEV Community

Cover image for Building NeuroDrive: A Browser-Native Self-Driving Car That Learns by Evolution
Harish Kotra (he/him)
Harish Kotra (he/him)

Posted on

Building NeuroDrive: A Browser-Native Self-Driving Car That Learns by Evolution

If you want to prototype autonomous behavior without cloud inference, GPU clusters, or reinforcement learning frameworks, the browser is enough.

NeuroDrive is a React + p5.js + TensorFlow.js application where a population of simulated cars learns to navigate a noisy, curved race track via neuroevolution.

Why Neuroevolution for This Problem

Instead of differentiable rewards and backprop through time, we use an evolutionary loop:

  • Initialize many random brains
  • Run them in a common environment
  • Score by survival/progress (fitness)
  • Preserve elites + mutate offspring
  • Repeat

This works especially well for simple control tasks where evaluating many candidate policies is cheap.

High-Level Architecture

High-Level Architecture

1) Environment: Procedural Track With Boundaries

The track is built from radial points whose radius is perturbed with Perlin noise. Inner and outer walls are derived from local perpendicular vectors, producing a continuous ribbon-like lane.

Core track generation pattern:

const angle = (i / numPoints) * Math.PI * 2;
const r = baseRadius + p.noise(xoff * 0.5, yoff * 0.5) * 200;
const x = centerX + Math.cos(angle) * r;
const y = centerY + Math.sin(angle) * r;
Enter fullscreen mode Exit fullscreen mode

Each segment also yields:

  • Checkpoint lines (for progress semantics)
  • Optional friction zones (ice patches)

2) Agent Design: Car + Sensors + Physics

Each car has:

  • Position, velocity, heading angle
  • 5 LiDAR-like ray sensors at fixed offsets (-45°, -22.5°, 0°, 22.5°, 45°)
  • A neural model to map sensor/vehicle context into control output

Sensor casting

Each ray is intersected against all wall segments; nearest hit determines normalized reading in [0,1].

Control output

Network outputs:

  • Steering (signed)
  • Acceleration (mapped from [-1,1] to [0,1])

Motion update

Velocity is blended toward heading direction via lateral grip, then damped by friction. Friction zones override these values for surface dynamics.

Neural Network Per Car

Each car has its own model:

  • Input: 8 values (5 sensor + velocity + steering + leader distance)
  • Hidden: 12 (tanh)
  • Output: 2 (tanh)
model.add(tf.layers.dense({ inputShape: [8], units: 12, activation: 'tanh' }));
model.add(tf.layers.dense({ units: 2, activation: 'tanh' }));
Enter fullscreen mode Exit fullscreen mode

This setup is intentionally lightweight so 50 agents can run in real-time in the browser.

Evolution Engine

At extinction of a generation:

  1. Sort by fitness
  2. Keep top elites unchanged (except reset state)
  3. Fill the rest by fitness-proportionate parent sampling
  4. Copy parent brain and mutate weights
  5. Dispose previous generation models

Mutation uses per-weight random perturbation with configurable rate.

Memory Safety in TensorFlow.js

Long-running browser simulations can leak quickly if tensors are not scoped.

NeuroDrive uses:

  • tf.tidy() in inference/mutation/copy paths
  • Explicit car.dispose() at generation rollover

This keeps model lifecycle bounded even at high time-warp speeds.

Dashboard UX for Learning Systems

The right visualization design matters because model behavior is stochastic and often opaque.

The app includes:

  • Generation, top fitness, learning status
  • Live "leader brain" topology panel
  • Time warp and mutation controls
  • Edit mode for inserting custom walls

This tight feedback loop helps developers tune convergence and diagnose failure modes quickly.

What This Demonstrates

  • Evolutionary search can produce competent local driving policy without supervised labels.
  • Browser-native ML is viable for rich interactive simulations.
  • A carefully constrained architecture can keep both performance and readability.

Limitations and Upgrade Paths

Current constraints:

  • No two-parent crossover (mostly mutated cloning)
  • No persistent genome snapshots
  • Fitness does not fully enforce lap completion semantics

Next upgrades:

  1. Add explicit checkpoint progression reward with anti-cheat logic
  2. Add parent crossover matrices (single-point or blend)
  3. Add deterministic seeds for benchmark reproducibility
  4. Add replay + telemetry export (CSV/JSON)

Running It

npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:3000 and watch generation quality improve over time.

NeuroDrive is a practical pattern for engineers building autonomous behaviors in creative coding environments: combine low-cost simulation, simple network topologies, and robust evolutionary iteration.

For product teams, it is also a strong educational artifact: users can see the full loop of sensing, deciding, failing, and adapting in real-time.

Screenshots

How this works

Output 1

Output 2

Output 3

Output 4

Output 5

More info: https://www.dailybuild.xyz/project/122-neurodrive

Top comments (0)