Overview › Code › R86
Code · blind round

R86 · Scrolling terrain from value noise

blind round 9/11 local models answered

Every answer below carries the name of the model that wrote it. Blind refers to the scoring: the review was done without knowing which model produced which answer — the published result names them.

2 of the 11 local models delivered nothing through our test harness in this round — for reasons that lie with our setup, not with the models. Those cards are marked DNF like any other, but they are not evidence about those models — the reason is noted on the card itself.

Show task
Create ONE self-contained HTML file (STRICT LIMIT: max 7000 characters in total — this is a budget on characters, not on lines, so removing line breaks does not help) that renders an endlessly scrolling landscape from value noise on a <canvas>: build a noise field by interpolating smoothly between random values at grid points, sum two or three octaves, and draw the result as a height profile coloured by altitude (water, sand, grass, rock, snow). Scroll the world sideways so new terrain is generated on the fly and never repeats visibly. Show the current world offset. Smooth requestAnimationFrame animation, NO user input, starts immediately and keeps running (restart with a fresh random instance when finished). No external libraries, no comments needed. Output ONLY the HTML file content, nothing else.

The answers

Local models (Brain cluster) — identical prompt, shuffled order (the sequence is not a ranking)
qwen3-coder:30bERRBLANKMINIFIED
Show code
<!DOCTYPE html>
<html><head><title>Infinite Noise Landscape</title><style>body{background:#000;margin:0;overflow:hidden}canvas{display:block}</style></head><body><canvas id="c"></canvas><script>let c=document.getElementById('c');let ctx=c.getContext('2d');c.width=window.innerWidth;c.height=window.innerHeight;let offset=0;let seed=Math.random();let lastTime=0;const scale=0.005;const numOctaves=6;function pseudoNoise(x,y,z){let n=Math.sin(x*123.4+seed)*453.1+Math.cos(y*987.6+seed)*453.1+Math.sin(z*543.2+seed)*453.1;return Math.abs((n-0)/453.1);}//Modified trigonometric noise function for speed and simplicity
function getNoise(x,y){let n=pseudoNoise(x*scale, y*scale, 0);return (Math.sin(x*0.1+seed)*0.4+Math.cos(y*0.1+seed)*0.4+Math.sin((x+y)*0.05+seed)*0.2)/1.0;}
function fBM(x,y){let total=0;let amplitude=1;let frequency=1;for(let i=0;i<numOctaves;i++){total+=getNoise(x*frequency, y*frequency)*amplitude;amplitude*=0.5;frequency*=2;}return total/Math.pow(2,numOctaves-1);}
function drawWorld(){const width=c.width;const height=c.height;ctx.clearRect(0,0,width,height);let imageData=ctx.getImageData(0,0,width,height).data;for(let x=0;x<width;x+=2){for(let y=0;y<height;y+=2){const nx=x/2;const ny=y/2;const heightVal=fBM(nx-offset,ny);let h=Math.floor(heightVal*5)+10;let color=0;if(h<=10){color=Math.min(255, Math.max(0, 255*(1-h/10)));}else if(h<=30){color=Math.floor(Math.random()*100+50);}//Sand
else if(h<=60){color=Math.floor(Math.random()*80+100);}//Grass
else if(h<=90){color=40;}//Rock
else{color=255;}//Snow

let r,g,b;if(h<=10){r=g=b=Math.floor(255*(1-h/10));}else if(h<=30){r=Math.max(50, Math.random()*100);g=Math.max(50, Math.random()*100);b=Math.floor((h-10)*2+50);}else if(h<=60){r=Math.min(255, Math.max(80, 150-(h-30)/3));g=Math.min(255, Math.max(100, 150-(h-30)/3));b=Math.floor(100);}(r,g,b);
imageData[x*4]=r;imageData[x*4+1]=g;imageData[x*4+2]=b;imageData[x*4+3]=255;}}ctx.putImageData(imageData,0,0);}
function loop(timestamp){if(!lastTime)lastTime=timestamp;const elapsed=timestamp-lastTime/1000;offset+=elapsed*0.2;drawWorld();lastTime=timestamp;}requestAnimationFrame(loop);window.addEventListener('resize',()=>{(c.width=window.innerWidth;c.height=window.innerHeight;)});
</script></body></html>
mistral-small:24bERRBLANKFORMAT
Show code
```html
<canvas id="landscape" style="border:1px solid #000;"></canvas>
<script>
// Noise generation functions:
function lerp(x,y,a){return x+(y-x)*a;}
function fade(t){return t*t*t*(t*(t*6-15)+10);}
function grad(hash,x,y){let h=hash&3;let u=(h&1)?x:y;let v=(h&2)?y:x;return ((h&1) ? -u : u)+(h&2?v:-v);}
function noise(x,y){const p=[[151, 164, 180, 137], [91, 192, 129, 131],[192, 101, 143, 134],[151, 131, 180, 164]];let X=(x&255)+((y&255)<<8);X=(((p[X&255]|(p[((X>>8)&255)]<<8))|(X<<16)));

	return (grad(p[(X<<13)^X>>7]%4, x,y) + grad(p[((X>>19)^X>>20) * 4], x - y, y))/Math.sqrt(3);}

function fbm(x,y,n){let a=0;let b=1;for(let i=0;i<n;i++){a+=b*noise(x/b,y/b);b/=2}}return a;}
function drawTerrain(){const canvas=document.getElementById('landscape');const ctx=canvas.getContext('2d');
    let width=window.innerWidth;let height=window.innerHeight;
    canvas.width=width;canvas.height=height;
    const imgData=new ImageData(256,1);
    let offsetX=-Math.floor(-scrollPos/4)*4;
    for(let x=0;x<width+4*3;x++){
        let n=fbm((offsetX+x)/16, 0, 3) * 8 + 80;
        let c=255;
        if(n<-10)n=-10;
        else if(n>160){c=Math.floor(255*Math.sin((n-140)/10));}
        imgData.data[x*4]=c;imgData.data[x*4+1]=(c/3)|0;imgData.data[x*4+2]=(c/2)|0;imgData.data[x*4+3]=255;}
    ctx.putImageData(imgData, 4);ctx.fillStyle="black";ctx.font="18px Arial";ctx.fillText(`Offset: ${Math.floor(scrollPos)}`, 10, height-20);
    scrollPos+=scrollSpeed;if(Math.abs(scrollPos)>1e6){location.reload();}}let scrollPos=0;
let scrollSpeed=-1.5;function animate(){drawTerrain();
    requestAnimationFrame(animate);}requestAnimationFrame(animate);
</script>
```
qwen3:14bSTATFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Endless Noise World</title>
    <style>
        body { margin: 0; overflow: hidden; background: #000; }
        canvas { display: block; cursor: default; }
    </style>
</head>
<body>

<canvas id="c"></canvas>

<script>
const c = document.getElementById('c');
const ctx = c.getContext('2d');

let W, H;
let offset = 0;
const MAX_OCTAVES = 6;
const FREQ_BASE = 0.015;
const AMPLITUDE_BASE = 0.8;

function init() {
    W = c.width = window.innerWidth;
    H = c.height = window.innerHeight;
}
window.addEventListener('resize', () => {
    c.width = c.height = W = H = Math.min(window.innerWidth, window.innerHeight); // Keep it square for simplicity if needed, or just use full size
    W = c.width = window.innerWidth;
    H = c.height = window.innerHeight;
});

// Pseudo-noise function using trig functions for smooth gradient simulation
function noise2D(x, y) {
    let n = 0;
    n += Math.sin(x * 13.9 + y * 1.7) * 45;
    n += Math.cos(y * 8.1 - x * 16.3) * 25;
    return (Math.sin(n) / Math.sin(0)) % 1.0; // Normalize to [0, 1] range roughly
}

// Multi-octave noise generator
function getNoiseHeight(x, y) {
    let total = 0;
    let frequency = FREQ_BASE;
    let amplitude = AMPLITUDE_BASE;
    let sum = 0;
    for (let i = 0; i < MAX_OCTAVES; i++) {
        total += noise2D(x * frequency, y) * amplitude;
        sum += amplitude;
        frequency *= 2.0;
        amplitude *= 0.5;
    }
    return total / sum; // Normalize the result to roughly [-1, 1] range
}

// Color mapping based on normalized height (h): -Water to +Snow
function getColor(h) {
    let normalized = Math.max(-1, Math.min(1, h));
    let r = 0, g = 0, b = 0;

    if (normalized < 0.2) { // Water (Deep blue -> Shallow blue)
        r = Math.floor(5 + normalized * 10);
        g = Math.floor(10 + (normalized + 0.2) * 30);
        b = Math.floor(100 - (Math.abs(normalized) * 100));
    } else if (normalized < 0.45) { // Sand/Beach (Yellowish-brown)
        r = Math.floor(200 + (normalized - 0.2) * 80);
        g = Math.floor(190 - (normalized - 0.2) * 50);
        b = Math.floor(100 - (normalized - 0.2) * 30);
    } else if (normalized < 0.65) { // Grass/Forest (Green)
        r = Math.floor(50 + (normalized - 0.45) * 100);
        g = Math.floor(200);
        b = Math.floor(50 + (normalized - 0.45) * 80);
    } else if (normalized < 0.9) { // Rock/Mountain (Grey/Brown)
         r = Math.floor(150);
         g = Math.floor(Math.max(50, 200 - (normalized - 0.65) * 70));
         b = Math.floor(100 + (normalized - 0.65) * 40);
    } else { // Snow (White/Light blue)
        r = g = b = Math.floor(255 - (normalized - 0.9) * 100);
    }

    return `rgb(${Math.max(0, r)}, ${Math.max(0, g)}, ${Math.max(0, b)})`;
}


function draw() {
    // Draw the terrain profile across the entire width
    for (let x = 0; x < W; x++) {
        const currentX = x + offset * 0.5; // Apply scroll offset
        ctx.strokeStyle = '';

        // Iterate y from top to bottom, drawing horizontal slices
        for (let y = 0; y < H; y += 2) {
            // Sample height at the current coordinates
            const h = getNoiseHeight(currentX * 0.1, y * 0.05);
            const color = getColor(h);

            ctx.beginPath();
            ctx.strokeStyle = color;
            ctx.lineWidth = 2;
            ctx.moveTo(x, y);
            // We are drawing the height profile across all columns at a fixed Y level
            // For simplicity and performance, we draw lines representing the altitude change for this column 'x'
             
        }
    }

    // Optimized rendering: Draw vertical strips of constant width (2 pixels)
    ctx.clearRect(0, 0, W, H);
    for (let x = 0; x < W; x += 2) {
        const currentX = x + offset * 0.5;
        
        // Determine the height profile for this column 'x'
        // We iterate through vertical slices of the canvas to draw a gradient/column
        for (let y_level = 0; y_level < H; y_level += 2) {
            const h = getNoiseHeight(currentX * 0.1, y_level * 0.05);
            ctx.fillStyle = getColor(h);
            ctx.fillRect(x, y_level, 2, 2);
        }
    }

    // Display World Offset (Top Left)
    ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
    ctx.font = "16px monospace";
    ctx.fillText(`Offset: ${offset.toFixed(3)}`, 10, 20);

    // Scroll the world and update offset for next frame
    offset += 0.05;
}


function animate() {
    draw();
    requestAnimationFrame(animate);
}

init();
animate();
</script>

</body>
</html>
```
gemma4:26bharness
No answer reached us (THIN) — and the reason lies with our setup, not with the model: reasoning consumed the entire token budget (3 min 28 s, zero characters of answer); larger budgets are refused by the gateway Counted as a did-not-finish, but it is not evidence about this model.
qwen3.5:9bOKFORMAT
Show code
```html
<!DOCTYPE html>
<html>
<head><title>Infinite Noise Landscape</title></head>
<body style="margin:0; overflow:hidden;"><canvas id="c"></canvas><script>
const c = document.getElementById('c');
const ctx = c.getContext('2d');

let W, H;
let offsetX = 0;

function resize() {
    W = window.innerWidth;
    H = window.innerHeight;
    c.width = W;
    c.height = H;
}
window.addEventListener('resize', resize);
resize();

// Simple seeded pseudo-random number generator (for consistent noise generation)
let seed = Math.random() * 10000;
function rand(x, y) {
    let s = x * 34527 + y * 59621 + seed;
    s ^= s >>> 18;
    return (s / 0x100000000);
}

// Interpolation function: smoothstep
function smooth(t) { return t * t * t * (t * (t * 6 - 15) + 10); }

// Perlin/Value Noise implementation for a single point (x, y)
function noise(x, y) {
    let X = Math.floor(x);
    let Y = Math.floor(y);
    let xf = x - X;
    let yf = y - Y;

    // Interpolate 4 corners using randomized values
    return (
        smooth(xf) * (rand(X, Y) * (1 - smooth(yf)) + rand(X + 1, Y) * smooth(yf)) +
        smooth(Math.min(xf, 1 - xf)) * (rand(X + 1, Y) * (1 - smooth(yf)) + rand(X, Y + 1) * smooth(yf))
    ) / 2; // Normalize the range slightly

}

// Fractional Brownian Motion (FBM) using multiple octaves
function fbm(x, y, scale, octaves, persistence, lacunarity) {
    let total = 0;
    let frequency = 1;
    let amplitude = 1;
    let maxValue = 0;

    for (let i = 0; i < octaves; i++) {
        total += noise(x * scale * frequency, y * scale * frequency) * amplitude;
        maxValue += amplitude;
        amplitude *= persistence;
        frequency *= lacunarity;
    }
    return total / maxValue; // Normalize the result roughly to [-1, 1]
}

// Color mapping based on normalized height (0.0 to 1.0)
function getColor(h) {
    h = Math.max(0, Math.min(1, h));
    let r, g, b;

    if (h < 0.2) { // Water (deep blue)
        r = Math.floor(Math.sin(h * 5) * 50 + 100);
        g = Math.floor(Math.sin(h * 3) * 50 + 80);
        b = Math.floor(Math.cos(h * 2) * 50 + 120);
    } else if (h < 0.35) { // Sand/Shallow Water (yellow-brown)
        r = 255; g = Math.floor((h - 0.2) * 400); b = 0;
    } else if (h < 0.5) { // Grass/Dirt (green)
        r = Math.floor(100 + (h - 0.35) * 150); g = 180; b = Math.floor(50 + (h - 0.35) * 100);
    } else if (h < 0.7) { // Rock/Stone (gray)
        r = g = b = Math.floor(100 + (h - 0.5) * 200);
    } else { // Snow/Peak (white)
        r = g = b = Math.floor(255 * (h - 0.7) / 0.3);
    }

    return `rgb(${Math.min(255, r)}, ${Math.min(255, g)}, ${Math.min(255, b)})`;
}

function draw() {
    ctx.clearRect(0, 0, W, H);

    // Draw the world offset indicator (top left)
    ctx.fillStyle = 'rgba(0, 0, 0, 0.6)';
    ctx.fillRect(10, 10, 250, 30);
    ctx.fillStyle = 'white';
    ctx.font = '14px Arial';
    ctx.fillText('Offset X: ' + offsetX.toFixed(Math.floor(offsetX % 100)) + ' px', 15, 28);

    // Landscape rendering parameters
    const SCALE = 0.003;
    const OCTAVES = 6;
    const PERSISTENCE = 0.5;
    const LACUNARITY = 2.0;

    for (let x = 0; x < W; x++) {
        // Sample height at current X position, using global offset for seamless scroll
        let h_normalized = fbm(
            offsetX + x * 0.1 * SCALE, // Horizontal input uses the scroll offset
            Math.floor(x / 50),       // Vertical input is constant across a row but changes slowly over width
            SCALE, OCTAVES, PERSISTENCE, LACUNARITY
        );

        // Map noise [-1, 1] range to height [0, H]
        let height = h_normalized * 0.5 + 0.5; // Scale to [0, 1]
        height *= (H - 20) / 2; // Max height scale

        // Color the column slice
        ctx.fillStyle = getColor(height);
        ctx.fillRect(x, H - Math.min(height * W/W, H-20), 1, Math.max(1, height * W/W));
    }
}

function animate() {
    // Update offset smoothly (scroll speed)
    offsetX += 1; // Controls horizontal scrolling speed (pixels per frame)
    draw();
    requestAnimationFrame(animate);
}

// Start the animation loop
animate();
</script></body></html>
```
qwen3:8bharness
No answer reached us (ERR) — and the reason lies with our setup, not with the model: reasoning consumed the entire token budget and the answer stayed empty; the gateway rejects budgets above 3000 tokens Counted as a did-not-finish, but it is not evidence about this model.
llama3.1:8bERRSTATFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Noise Landscape Scroller</title>
<style>
body {
  margin: 0;
  padding: 0;
}
canvas {
  display: block;
}
</style>
<script type="text/javascript">
var octaves = 3;
var amplitude = 1.5;
var frequency = 0.05;
var offset = 0;
var canvas = document.createElement("canvas");
document.body.appendChild(canvas);
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var ctx = canvas.getContext('2d');
function generateNoise(x, y) {
  var value = 0;
  for (var i = 0; i < octaves; i++) {
    value += Math.sin((x * frequency + offset) * amplitude) *
             Math.sin(y * 10 * amplitude);
    frequency *= 1.5;
    amplitude /= 2;
  }
  return value;
}
function draw() {
  ctx.fillStyle = "rgba(0, 0, 0, 0)";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  for (var x = -100; x <= 100; x++) {
    for (var y = -50; y <= 50; y++) {
      var height = generateNoise(x + offset, y) * 100;
      if (height > 20 && height < 80) ctx.fillStyle = "rgb(0, 255, 0)";
      else if (height > 10 && height <= 20) ctx.fillStyle = "rgb(128, 128, 0)";
      else if (height > 5 && height <= 10) ctx.fillStyle = "rgb(192, 192, 192)";
      else if (height >= -20 && height < 5) ctx.fillStyle = "rgb(255, 255, 255)";
      else ctx.fillStyle = "rgb(128, 0, 0)";
      var w = 10;
      var h = Math.floor(height);
      ctx.fillRect(x * w + canvas.width / 2 - (canvas.width - w*100) / 2,
                    y * h + canvas.height / 2 - (canvas.height - h*50) / 2, w, h);
    }
  }
  offset += 0.01;
}
var startDraw = function() {
  draw();
  requestAnimationFrame(startDraw);
};
startDraw();
document.addEventListener("visibilitychange", function() {
  if (document.visibilityState === "visible") startDraw();
});
</script>
<script type="text/javascript">
requestAnimationFrame(function(){
  document.title = 'Noise Landscape: ' + Math.round(offset * 100) / 100;
});
</script>
</head>
<body>
</body>
</html>
```
deepseek-r1:14bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html><body style="margin:0;overflow:hidden;">
<canvas id=c></canvas>
<script>
const c=document.getElementById('c'),ctx=c.getContext('2d');
const w=c.width=window.innerWidth,h=c.height=window.innerHeight;
let t=0,offset=0;

function noise(x,y,s) {
    let i=floor(x/s),j=floor(y/s);
    let dx=x-s*i,dy=y-s*j;
    return (1-dx)*(1-dy)*i + dx*(1-dy)*j + (1-dx)*dy*(i+1) + dx*dy*(j+1);
}

function random() {
  return sin(t++) * 255 |0;
}

function draw(offset,scale=1.0) {
  ctx.fillStyle='skyblue';ctx.fillRect(0,0,w,h);
  
  let c=c.getContext('2d');
  const colors=[[0, '#3399ff'],[50, '#00b14e'],[100, '#88dd33'],[150, '#66a533'],[200, '#447f33'],[250, '#225c33'],[300, '#113b33'],[350, '#002f2f']];
  c.fillStyle='rgb(0,0,255)';
  
  for(let x=0;x<w;x++) {
    let nx=(offset +x)/80;
    let n=noise(nx,0.5*16,4)+noise(nx,0.5*8,2)+noise(nx,0.5*4,1);
    let y=h/2+n*3;
    c.lineTo(x,y);
  }
  
  for(let i=0;i<colors.length-1;i++) {
    let min=colors[i][0],max=colors[i+1][0];
    let ymin=min*2.5,yymax=max*2.5;
    if(ymin>yymax) continue;
    ctx.fillStyle=hsl(min/3,70%,40%);if(min>150)ctx.fillStyle='snow';
    for(let x=0;x<w;x++) {
      let nx=(offset +x)/80;
      let n=noise(nx,0.5*16,4)+noise(nx,0.5*8,2)+noise(nx,0.5*4,1);
      let y=h/2+n*3;
      if(y>ymin&&y<yymax) ctx.lineTo(x,y);
    }
  }
  
  c.fill();
  ctx.fillStyle='black';ctx.font='16px sans-serif';
  ctx.fillText(`World Offset: ${offset.toFixed(0)}`,8,30);
}

function animate() {
  offset=(offset +0.2)%512;
  draw(offset);
  requestAnimationFrame(animate);
}

window.onload=()=>{
 t=random();
 setInterval(()=>{
   if(offset>512) t=random();
   animate();
 },1000/60);
}
</script>
</body></html>
```
qwq:32bSTATLIM
Show code
<think>

Okay, let me try to tackle this query. The user wants an HTML file that creates an endless scrolling landscape using noise, specifically value noise. The key points here are using noise to generate a height profile, smooth interpolation between grid points, combining multiple octaves for detail, coloring based on altitude, and infinite scrolling without repetition. Also, it needs to use requestAnimationFrame, no external libraries, and no user input. Got it.

First, I need to structure the HTML file. Since it's self-contained, everything must be in one file. The canvas element is essential here. The basic structure would be the doctype, html, head with a title and style, then the body with a canvas and a div for the offset display.

Starting with the script part. I'll need to create a noise function. Value noise typically uses a grid of random values and interpolates between them. So, first, I should define the grid size. Let's say a grid every 100 units. The noise function will take an x coordinate, determine which grid points it's between, and interpolate using smoothstep.

But wait, the user mentioned two or three octaves. That means multiple layers of noise with different frequencies and amplitudes. Each octave adds detail. The base frequency could be 1, then higher frequencies for the next octaves. So maybe the first octave is base, the second is double the frequency (so 2), and the third 4, with decreasing amplitude. Summing them up will give the height.

For the colors, the user wants water, sand, grass, rock, snow. So I need a function that maps the height to a color. Probably using thresholds. Like, below a certain value is water, then sand, grass, etc., up to snow at the peaks.

Now, the endless scrolling. The idea is to move the world sideways by updating an offset each frame. The offset must be such that new terrain is generated when the camera moves beyond the current grid points. But since it's endless, the noise function must handle any x value, so the grid has to be based on the current offset. Wait, actually, the grid can be infinite, but the noise function uses modulo to get the grid points. Wait, no, maybe the grid points are based on the current offset, but that might not work. Alternatively, perhaps the grid is fixed, but the offset is added so that the same grid points are used each time, but shifted. Hmm, maybe I need to use the offset to shift the x coordinate in the noise function.

Wait, the problem requires that the terrain never repeats visibly. So the noise must be generated in such a way that as you scroll, new terrain is generated. If the grid is fixed, then scrolling would eventually loop, so that's not good. Instead, the grid points should be based on the current offset. So perhaps the grid is offset by the current position, so that each frame, the grid is effectively moving, thus generating new noise values as you go. Wait, but how to do that without repetition?

Alternatively, the grid can be parameterized by the current offset. Wait, perhaps the grid is based on the offset such that the same x coordinate doesn't use the same grid points each time. For example, as you move, the grid is offset in a way that the same x position in the viewport is mapped to different grid points over time. That way, it's always generating new terrain.

Alternatively, the noise function can be made to depend on both the current x and the offset, so that as the offset changes, the noise at the same x position varies, preventing repetition. Hmm, maybe the offset is added to the x in the noise function. Let me think: each frame, the offset increases (or decreases) by some amount. The noise function for a given x position on the screen would have (x + offset) as its input. Then the grid points are based on this combined value. That way, as the offset increases, the grid points for the same x on screen are different, hence new terrain is generated.

Yes, that makes sense. So the noise function uses (x + offset) to compute the position. The offset is incremented (or perhaps scaled) each frame. The key is to have the offset so large that the same x coordinate doesn't repeat, but the scrolling speed is such that it's smooth.

Now, the canvas drawing. The height profile is drawn as a path. Each frame, we calculate the height for each vertical slice (x positions on the canvas) based on the current x and offset. The height is scaled to the canvas height, then colored according to altitude.

The function to generate the noise will need to:

1. Take x (plus the offset) to get the current position in the noise grid.
2. Find the grid cells around that position.
3. Get the random values for those grid points.
4. Interpolate between them using smoothstep.

The smoothstep function is usually something like 3t^2 - 2t^3 for interpolation between two points. So I'll need that.

For multiple octaves, each call to the noise function can be multiplied by a certain factor and summed. Maybe:

function getNoise(x) {
    let total = 0;
    let amplitude = 1;
    let frequency = 1;
    for(let i=0; i < octaves; i++) {
        total += noise(x * frequency) * amplitude;
        amplitude *= 0.5;
        frequency *= 2;
    }
    return total;
}

Wait, but this is a different approach. Alternatively, each octave can be a separate noise call with different parameters.

Alternatively, the code can loop over octaves, each time adding a scaled version of the noise function evaluated at a higher frequency.

Wait, perhaps first define a base noise function that returns a 0-1 value for a given x. Then, the octaves are summed with different frequencies and amplitudes.

So putting it all together:

First, variables for the canvas context, width, height.

Then the noise grid. To generate the grid points, we can use an array of random values. Wait, but since the grid is infinite, we can't precompute all values. So instead, we need to precompute a grid, but since it's endless, perhaps we use a perlin noise approach with a seed. But since we can't precompute all possible points, but can compute the random values on the fly using a hash function based on the grid coordinates.

Ah, right! The random values at each grid point can be generated using a deterministic function of the grid indices. For example, using a simple hash function like (xIndex * 12345 + yIndex * 6789 + someSeed) % something to get a random number between 0 and 1.

But since we're in 1D (the height is vertical?), the grid points are along the x-axis. Let me think: for a given x coordinate, we find the grid cell it's in, which is based on x divided by the grid spacing (let's say cellSize). The grid points are at multiples of cellSize. The random values at each grid x can be generated using a function of their integer index.

So, for grid point at integer i, the random value can be generated using something like (Math.sin(i * 12.9898 + 4.1414) * 43758.5453) % 1, or similar. Alternatively, a simple hash function. The seed can be based on the offset, but that might cause repetition over time. Wait, but the user wants a fresh random instance each time it restarts, so perhaps the seed can be initialized with a random number when the page loads.

Wait, but the user says "NO user input, starts immediately and keeps running (restart with a fresh random instance when finished)". Wait, when finished? Maybe the scrolling is continuous, but how does it know when to restart? Or perhaps the user means that when the animation is stopped, you can refresh the page to get a new instance. Hmm, maybe that part is about making sure that each time the page is reloaded, it's a different terrain.

Okay, to generate the grid points' random values, perhaps using a function like:

function random(i) {
    return (Math.sin(i * 12.98 + 4.453) * 43758.5453) % 1;
}

This uses a pseudo-random function based on the index i, so that each grid point has a deterministic but random-looking value. This way, we don't need to precompute anything; the hash function gives us a random value for any grid index.

Now, putting it all together in code:

First, variables:

- ctx, width, height (from the canvas)
- offset: the current world offset
- cellSize: the spacing between grid points (maybe 100)
- octaves: 3 (as per user's 'two or three')
- seed for the random function (maybe Math.random() * some number when starting)

Wait, but to get a seed that's the same for each reload? No, the user says to restart with a fresh instance, so the seed can be generated each time the page loads. But in JavaScript, when the page is reloaded, it's a new instance. So the seed can be initialized once at the start.

Alternatively, maybe the seed doesn't need to be stored, since the function uses the grid index which is based on the offset and x. Hmm.

Wait, the random function is based on the grid index (x divided by cellSize, floored to get the integer). So for grid point at x = i * cellSize, the random value is random(i). Since i can be any integer (positive or negative), the random function can generate a value for any i. This way, the grid is effectively infinite.

So the noise function steps:

Given a position x (plus offset):

1. cellSize is the spacing between grid points. Let's pick 100.

2. Let’s compute the grid indices:

   let i = Math.floor((x + offset) / cellSize);
   let fractional = (x + offset) / cellSize - i;

3. Get the random values at grid points i and i+1.

   let r0 = random(i);
   let r1 = random(i + 1);

4. Interpolate between r0 and r1 using smoothstep.

The smoothstep function is: t = 3t² - 2t³.

Wait, but interpolation between two points. So the fractional is between 0 and 1, so we can use that.

Wait, the smoothstep function is used for the interpolation. Let me see:

Let’s compute the interpolation factor using smoothstep:

let t = fractional;
let wt = t * t * (3 - 2 * t);

Then the interpolated value is r0*(1 - wt) + r1*wt ?

Wait, or is it r0 + (r1 - r0)*wt ?

Yes, that's correct.

So the noise value at x is:

r0 + (r1 - r0)*wt.

Then, for multiple octaves, we can scale and sum this.

But each octave has a different frequency and amplitude.

So, for example, for three octaves:

total = 0;
let amplitude = 0.5; // starts at 0.5, but maybe adjust
let frequency = 1;
for (let o = 0; o < 3; o++) {
    let n = getNoise(x * frequency);
    total += n * amplitude;
    amplitude *= 0.5; // or some other factor
    frequency *= 2;
}

Wait, but in the base function, the x should be scaled by frequency. Hmm, perhaps:

Wait, for each octave, the frequency is multiplied by 2, so the grid spacing becomes cellSize / frequency. Alternatively, the frequency scales the x input to the noise function.

Alternatively, perhaps the octave's frequency is a scaling factor on the x parameter.

Hmm, perhaps I need to rework the noise function to take a scale parameter.

Let me re-define the noise function as:

function noise(x, scale) {
    let cellSize = 100;
    let i = Math.floor(x * scale);
    let fractional = x * scale - i;
    let r0 = random(i);
    let r1 = random(i + 1);
    let t = fractional;
    let wt = t * t * (3 - 2 * t);
    return r0 + (r1 - r0) * wt;
}

Wait no, perhaps better to separate the parameters.

Alternatively, the base noise function uses the grid spacing, and each octave has a different grid spacing (frequency).

Wait, maybe it's simpler to define the base cellSize as 100, and for each octave, the cellSize is divided by 2^{octave}.

Hmm, not sure. Let's think of it step by step.

The main noise function (without octaves) would be:

function getNoise(x) {
    let cellSize = 100;
    let actualX = (x + offset) % (cellSize * 2); // Not sure, but perhaps the offset is added.
    Wait, no. The actual x coordinate passed to the function is offset-adjusted.

    Wait, perhaps the noise function should take into account the offset. Or the offset is part of the x parameter.

    Let me think differently: the noise function is calculating the noise at position x, which is the x coordinate on the screen, but the world is moving. The offset is added to x so that as the world moves, the x coordinate relative to the world is x + offset.

    So the noise function's input is (x + offset). Let's say the main function is:

    function noiseValue(xPos) {
        // xPos is the position in the world (x + offset)
        let cellSize = 100;
        let i = Math.floor(xPos / cellSize);
        let fractional = (xPos / cellSize) - i;
        let r0 = random(i);
        let r1 = random(i + 1);
        let t = fractional;
        let wt = t * t * (3 - 2 * t);
        return r0 + (r1 - r0) * wt;
    }

    Then, for the octaves:

    function getHeight(x) {
        let total = 0;
        let amplitude = 1;
        let frequency = 1;
        for (let o = 0; o < 3; o++) {
            let scaledX = x * frequency;
            total += noiseValue(scaledX) * amplitude;
            amplitude *= 0.5;
            frequency *= 2;
        }
        return total;
    }

Wait, but this way, the scaledX is the x coordinate scaled by the frequency. But the offset needs to be added inside the noiseValue function. Wait, no, the x here is the screen coordinate, but the offset is added to the world position before being passed into the noise function.

Hmm, perhaps I need to clarify the parameters. The screen's x position (from 0 to canvas.width) maps to a world position (xScreen + offset). The noise function takes the world position.

Wait, so for each x position on the screen:

worldX = xScreen + offset;

Then, the noise function is called with worldX.

But in the octaves, the scaledX would be worldX * frequency?

Wait, perhaps the correct approach is:

function getNoise(x) {
    let cellSize = 100;
    let i = Math.floor(x / cellSize);
    let fractional = (x / cellSize) - i;
    let r0 = random(i);
    let r1 = random(i + 1);
    let t = fractional;
    let wt = t * t * (3 - 2 * t);
    return r0 + (r1 - r0) * wt;
}

Then, getHeight for multiple octaves:

function getHeight(x) {
    let total = 0;
    let amplitude = 1;
    let frequency = 1;
    for (let o = 0; o < 3; o++) {
        let scaledX = x * frequency;
        total += getNoise(scaledX) * amplitude;
        amplitude *= 0.5;
        frequency *= 2;
    }
    return total * 0.5; // normalize?
}

Wait, but the amplitude starts at 1, so the total could be up to 1 + 0.5 + 0.25 = 1.75. Maybe divide by 2 to make it 0-1?

Alternatively, adjust the amplitudes so that the total is between 0 and 1.

Alternatively, the random function already returns 0-1, so the sum would be up to 1*(1 + 0.5 + 0.25) = 1.75. To clamp between 0 and 1, maybe divide by the sum of amplitudes.

Alternatively, just scale the result so that it's normalized. But perhaps for simplicity, multiply by a factor.

Anyway, the exact scaling can be adjusted in the code.

Now, the drawing:

Each frame, we need to loop through all x positions on the canvas and compute their height. But doing this for every frame and every pixel would be too slow. Wait, the canvas's width is, say, 800 pixels. If we draw vertical lines (each x pixel) with the height calculated, that might be manageable with requestAnimationFrame.

Alternatively, draw a filled path that represents the terrain. Let's use a path where each point is (x, y) where y is the height.

The steps for the draw function:

1. Clear the canvas.

2. Begin a path.

3. For each x from 0 to canvas.width:

   let worldX = x + offset;

   let h = getHeight(worldX);

   // map h to a height between 0 and canvas.height.

   let y = canvas.height - h * canvas.height * someScale;

   So the higher the noise value, the higher the terrain.

   Wait, but we need to adjust the scale so that the terrain isn't too flat or too high.

4. The path starts at the first point, and each new point is connected to form the terrain.

After drawing the path, fill it with a gradient? Or color each segment based on the height.

Wait, the user wants the height colored by altitude (water, sand, grass, rock, snow). So each segment's color depends on its height.

Alternatively, draw the path and then fill it with a gradient based on height. But perhaps it's better to draw each vertical line with a color corresponding to the height.

Alternatively, use a loop over each x, and for each x, draw a line from the bottom to the terrain height, with the color determined by the height.

But since this is per-pixel, maybe using a gradient would be better.

Alternatively, here's a plan:

- The terrain is drawn as a path.

- Then, create a gradient that depends on the y-coordinate (height).

Wait, but gradients can be linear or radial. A linear gradient might not work because the coloring depends on the actual height.

Alternatively, the height can be mapped to a color based on elevation.

Each point's y (height) can choose between colors:

- Below sea level (e.g., <0.2) → water (blue)

- Between 0.2 and 0.5 → sand (yellow)

- Between 0.5 and 0.8 → grass (green)

- Above 0.8 → snow (white)

But how to do this in canvas without individual pixels?

Perhaps using a pixel buffer (getImageData) but that might be slow.

Alternatively, draw the path and then use a loop to fill each vertical column with the appropriate color.

But even that would be slow for 800 columns.

Alternative approach:

1. Draw the terrain path.

2. Create a clipping region with the path.

3. Draw the color layers (e.g., a blue rectangle for water, then a yellow rectangle over it, etc., each clipped by the terrain path).

But this might be tricky.

Alternatively, use a gradient that's based on the height of the terrain.

Wait, here's a possible approach inspired by:

- Draw the path as the outline of the terrain.

- Create a clipping path with the terrain's shape.

- Then draw layers (water, sand, grass, etc.) from bottom to top:

   - Draw a blue rectangle from bottom to water level.

   - A yellow rectangle above that up to sand level.

   - And so on, each clipped by the terrain path.

But this requires knowing the height of each point, which complicates things.

Alternatively, maybe the easiest way is to loop over each x position, compute the height, and set the color for each vertical column.

Here's the plan:

- Clear the canvas.

- For each x from 0 to width:

   compute worldX = x + offset

   compute h = getHeight(worldX)

   map h to elevation between 0 (ground level) and max_height (say 1).

   determine color based on elevation.

   draw a vertical line at x from bottom of canvas to the height y.

But doing this for each x pixel (if width is 800) would require 800 vertical lines per frame.

Each line is 1 pixel wide. That might be manageable.

Alternatively, use a path and fill it with color based on height.

Alternatively, use a gradient that's based on Y position.

Wait, maybe a gradient from bottom to top, but the terrain's height would modulate it.

Hmm, not sure.

Alternatively, here's the code outline:

function draw() {

    var c = document.getElementById("canvas");
    var ctx = c.getContext("2d");
    ctx.clearRect(0, 0, c.width, c.height);

    ctx.beginPath();
    ctx.moveTo(0, c.height);

    var maxHeight = some value; // maybe 3?

    // determine the max height from the noise function (maybe arbitrary)

    for (var x = 0; x < c.width; x++) {

        var worldX = x + offset;
        var h = getHeight(worldX);
        // normalize h to 0-1
        var normalizedHeight = h / (maxHeight); // assuming max is around 2?

        // calculate color based on normalizedHeight
        var color;
        if (normalizedHeight <= 0.2) {
            color = 'blue';
        } else if (normalizedHeight <= 0.5) {
            color = 'yellow';
        } else if (normalizedHeight <= 0.8) {
            color = 'green';
        } else {
            color = 'white';
        }

        // calculate y position on canvas
        var y = c.height - (normalizedHeight * c.height * 0.5); // adjust scaling
        ctx.lineTo(x, y);
        // ctx.fillStyle = color;
        // ctx.fillRect(x, y, 1, c.height - y); // fill down to bottom?

    }

    ctx.fillStyle = 'black';
    ctx.fill();

    // Also draw the bottom?

    ctx.strokeStyle = 'black';
    ctx.stroke();

}

Wait, but this would draw a black filled path, which is not the color. Hmm, need to think differently.

Alternatively, perhaps using a gradient:

But maybe let's try a different approach where the color is applied per column.

Wait, here's a possible code structure:

function draw() {

    var ctx = this.ctx;
    ctx.clearRect(0, 0, this.width, this.height);

    for (var x = 0; x < this.width; x++) {

        var worldX = x + this.offset;
        var h = this.getHeight(worldX);
        h = (h + 1) / 2; // assuming noise ranges from -1 to 1? Or maybe not.

        // Normalize h to between 0 and 1, assuming the getHeight function returns a certain range.

        // Adjust scaling to fit the canvas height.

        var y = this.height - h * this.height * 0.5;

        // Determine color based on h.

        var color;
        if (h < 0.2) color = '#0000ff'; // water
        else if (h < 0.5) color = '#ffff00'; // sand
        else if (h < 0.8) color = '#00ff00'; // grass
        else color = '#ffffff'; // snow

        ctx.fillStyle = color;
        ctx.fillRect(x, y, 1, this.height - y);
    }

    // Move offset for next frame
    this.offset += 0.1; // or some speed

    requestAnimationFrame(draw.bind(this));
}

But this loops through 800 pixels each frame, which might be slow. However, in practice, with the noise function being simple, it might work.

Alternatively, precompute the heights for a strip and then draw, but probably not needed.

Now, the random function:

The random function needs to generate a value between 0 and 1 for any integer i.

The user defined random function (using perlin noise or something else?) but since we don't have perlin, perhaps use a simple hash-based approach.

For example, a function that takes an integer i and returns a pseudo-random value between 0 and 1.

Here's a possible implementation:

function random(i) {
    // Simple pseudo-random function
    let n = i * 3747613;
    n = Math.imul(n, 12741261);
    return (n - (n | 0)) * 2 + 0.5; // or something
}

Wait, but perhaps a better way:

We can use a hash function like this:

function random(i) {
    // A simple pseudo-random function based on i
    // Using a hash from https://stackoverflow.com/a/6127354/3042019
    let n = (i * 343291835 + 1) % 257;
    return (n / 256);
}

This would give a value between 0 and 1. The exact implementation may vary as long as it's consistent for the same i.

Alternatively, use the XORShift algorithm:

But for simplicity, maybe just use:

function random(i) {
    return (Math.sin(i * 1013) * 10000) % 1;
}

But the key is that for a given i, the value is deterministic.

Testing this function is important, but for the purpose here, we can proceed.

Putting it all together:

Now, in code structure:

The canvas is initialized, and requestAnimationFrame loops.

The variables:

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var offset = 0;

// The cellSize for the base noise
var cellSize = 100;

// The function to get noise value at a given position (worldX)
function noiseValue(worldX) {
    let i = Math.floor(worldX / cellSize);
    let fractional = (worldX / cellSize) - i;
    let r0 = random(i);
    let r1 = random(i + 1);
    let t = fractional;
    let wt = t * t * (3 - 2 * t);
    return r0 + (r1 - r0) * wt;
}

// Function to get the height (with octaves)
function getHeight(x) {
    let total = 0;
    let amplitude = 1;
    let frequency = 1;
    let octaves = 3;
    for (let o = 0; o < octaves; o++) {
        let scaledX = x * frequency;
        let n = noiseValue(scaledX);
        total += n * amplitude;
        amplitude *= 0.5;
        frequency *= 2;
    }
    return total;
}

// The random function (simple)
function random(i) {
    let n = (i * 343291835 + 1) % 257;
    return (n / 256);
}

function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    for (var x = 0; x < canvas.width; x++) {
        var worldX = x + offset;
        var h = getHeight(worldX);
        // Normalize h to 0-1. Assuming the maximum possible value is 2 (since octaves=3, sum 1 + 0.5 + 0.25 = 1.75? Maybe not)
        // Need to determine the max possible h.

        // Let's compute max possible h with 3 octaves:
        // Each octave contributes up to amplitude. So total max is 1 + 0.5 + 0.25 = 1.75
        // So h ranges from -1.75 to 1.75?
        // Wait, the noiseValue returns between 0 and 1, right?

        // Wait in noiseValue, the function returns a value between 0 and 1 because r0 and r1 are between 0 and 1, and the interpolation also is between them.

        // So each octave's contribution is between 0 and amplitude.

        // So with amplitude starting at 1, then 0.5, then 0.25, the max h is 1 + 0.5 + 0.25 = 1.75, and min is 0.

        // So to map h from 0 to 1.75 to 0-1:

        // Let's normalize it to 0-1 by dividing by 1.75

        h = h / 1.75;

        // Now h is between 0 and 1

        // Determine color based on h
        let color;
        if (h < 0.2) color = '#0000ff'; // water
        else if (h < 0.5) color = '#ffff00'; // sand
        else if (h < 0.8) color = '#00ff00'; // grass
        else color = '#ffffff'; // snow

        // Determine the y position: higher h means higher y (since y grows downward)
        // Let's say the maximum height is at the top of the canvas (y=0)

        // So y = (1 - h) * canvas.height 

        // Wait, perhaps:

        // We want h=0 to be at the bottom (y=canvas.height), and h=1 at the top (y=0)

        let y = canvas.height * (1 - h);

        // Draw a vertical line from y to the bottom (canvas.height)
        ctx.fillStyle = color;
        ctx.fillRect(x, y, 1, canvas.height - y);
    }

    // animate
    offset += 0.1;
    requestAnimationFrame(draw);
}

draw();

Wait, but in the noiseValue function, we might have to adjust the cellSize.

Wait, in noiseValue, worldX is divided by cellSize. The cellSize here is 100, but that affects the frequency of the noise.

If cellSize is 100, then the noise repeats every 100 units.

But since the offset increments by 0.1 each frame, perhaps the speed is okay.

Testing this code in a browser would be needed, but here's the approach.

Potential issues:

1. The random function's implementation may give values that are too regular, leading to visible patterns.

2. The scaling of h may not be correct.

3. The color transitions may be too abrupt.

4. Performance: looping through 800 pixels (assuming 800px width) each frame might be acceptable in modern browsers, but could be slow on mobile.

To optimize:

- Precompute the heights for a larger buffer and then draw it, but that may complicate things.

- Use a canvas pixel buffer to update all pixels at once.

Alternatively, here's a simplified version using a pixel buffer:

function draw() {
    var ctx = this.ctx;
    var canvas = this.canvas;
    var width = canvas.width;
    var height = canvas.height;
    var pixels = new Uint8ClampedArray(width * height * 4);
    for (var x = 0; x < width; x++) {
        var worldX = x + this.offset;
        var h = this.getHeight(worldX);
        h = h / 1.75; // normalized to 0-1
        var y = height * (1 - h); // y position
        // Fill from y to bottom with the color
        // For each pixel from y to height in column x:
        for (var yy = Math.floor(y); yy < height; yy++) {
            var index = (x + yy * width) * 4;
            var color;
            if (h < 0.2) color = [0, 0, 255, 255];
            else if (h < 0.5) color = [255, 255, 0, 255];
            else if (h < 0.8) color = [0, 255, 0, 255];
            else color = [255, 255, 255, 255];
            pixels[index] = color[0];
            pixels[index + 1] = color[1];
            pixels[index + 2] = color[2];
            pixels[index + 3] = color[3];
        }
    }
    ctx.putImageData(new ImageData(pixels, width, height), 0, 0);
}

But this would require setting all pixels in a column for each x, which is O(width*height) operations, which is 800*600 = 480,000 operations each frame. Probably too slow.

Hence, the initial approach of looping through each x and drawing vertical 1px columns with fillRect may be better.

Another possible optimization is to use ctx.fillStyle and ctx.fillRect for each color region in a column.

For example, for each column x:

- Compute the color based on h.

- Draw a rectangle from y down to the bottom with that color.

This is exactly what the first approach does, and it's O(width) operations.

Each fillRect is a single draw call per column, but since it's per pixel in width, it could be slow.

Alternatively, since the color is the same for the entire column below y, we can do:

ctx.fillStyle = color;

ctx.fillRect(x, y, 1, height - y);

Which is efficient because fillRect is a single operation per column.

Hence, this should be manageable.

Another consideration is that the noiseValue and getHeight functions are called per x, which may be quick since they are straightforward.

Testing the code, one might adjust the cellSize, the random function, and the color thresholds.

Potential adjustments:

- Increasing octaves to 4 or more for more detail.

- Adjusting the cellSize to make the noise more or less detailed.

- Tweaking the random function for better distribution.

- Changing the color thresholds and palette.

Final note: The code above may not be perfect but illustrates the approach. The user can test and adjust parameters like cellSize, octaves, color thresholds, and the random function to achieve the desired effect.
command-r:35bSTAT
Show code
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Endless Noise Landscape</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
        canvas {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }
        .offset {
            font-family: monospace;
            color: #fff;
            background: rgba(0, 0, 0, 0.7);
            padding: 4px;
            position: absolute;
            top: 10px;
            left: 10px;
        }
    </style>
</head>
<body>
    <canvas id="world"></canvas>
    <div class="offset">Offset: 0</div>

    <script>
        const canvas = document.getElementById('world');
        const ctx = canvas.getContext('2d');

        let offset = 0;       // Horizontal scroll offset
        let octaves = [      // Noise field octave values
            { freq: 1, amp: 0.7 },
            { freq: 3, amp: 0.5 },
            { freq: 9, amp: 0.2 }
        ];

        function noise(x, y) {    // Generate value noise at a point
            let total = 0;       // Sum up octaves
            for (let o of octaves)
                total += Math.cos((o.freq * x + offset) / 18347 + o.freq * y / 26597) * o.amp;  // Use magic numbers as seeds

            return total;
        }

        function render() {
            const width = canvas.width, height = canvas.height;    // Get canvas size
            offset += 0.1;                                     // Increment scroll offset

            ctx.fillStyle = '#0c2f48';                          // Set water color
            for (let y = 0; y < height / 3; y++)                // Draw height profile
                ctx.fillRect(y * width / height, y, 1, 1);

            const step = Math.min(width, height) / octaves[octaves.length - 1].freq;    // Determine interpolation step
            for (let x = 0; x < width; x += step) {
                let prev = noise(x, 0);                          // Interpolate between grid points
                for (let y = step; y < height; y += step) {
                    const next = noise(x + step, y + step);       // Get adjacent values

                    ctx.fillStyle = `hsl(${Math.round((prev + next) / 2 * 100)}, 50%, ${Math.min(80 + (next - prev) * 30, 100)}%)`;
                    ctx.fillRect(x, y, step, step);               // Render height profile pixel

                    prev = next;                                 // Update previous value
                }
            }

            requestAnimationFrame(render);                       // Continue animation
        }

        canvas.width = window.innerWidth;                        // Resize canvas to viewport
        canvas.height = window.innerHeight;

        render();                                              // Start animation
    </script>
</body>
</html>
deepseek-r1:32bERRBLANKMINIFIEDFORMAT
Show code
```html
<!DOCTYPE html><html><head><style>canvas{margin:0;padding:0;display:block;background:#182d45}#offset{position:absolute;top:20px;left:20px;color:white;font-family:sans-serif}</style></head><body><canvas id=c></canvas><div id=offset>Offset: 0</div><script>
"use strict";const canvas=document.getElementById("c"),ctx=canvas.getContext("2d");let width,height,seed=Math.random(),octaves=3,persistence=0.5,lacunarity=2,scale=0.01,minX=0,maxX=100;function noise(n,x,y){let s=n.toString().replace(/\./g,"").length;x=x*s/1e4|0;y=y*s/1e4|0;n=Math.sin(x+x*y*73+n.length+97)*12583*x^Math.cos(y+313*y+z*n.length);return n/568+.5}function generate(){width=canvas.width=window.innerWidth;height=canvas.height=window.innerHeight;let band=[{h:0,c:"#001b4d"},{h:.1,c:"#eab74f"},{h:.2,c:"#93c14a"},{h:.4,c:"#865e44"},{h:1,c:"#ffffff"}];seed=Math.random();let scroll=0;function draw(){ctx.fillStyle="#001b4d";ctx.fillRect(0,0,width,height);let x=minX+offset/2;x-=width*3;for(let y=height;y>=0;y--){let h=0,t=scale;for(let k=0;k<octaves;k++){h+=noise(seed,x*t,y*t)*Math.pow(persistence,k);t*=lacunarity}h=(h+1)/2;let c=h>band[4].h?band[4].c:h>band[3].h?band[3].c:h>band[2].h?band[2].c:h>band[1].h?band[1].c:band[0].c;ctx.fillStyle=c;ctx.fillRect(width-1,height-y,1,1)}offset+=.1;if(offset>maxX){minX=offset;generate()}requestAnimationFrame(draw)}draw()}window.onload=generate;
</script></body></html>
```
Outside the Brain cluster — same task, same character budget, collected through their own tooling (response times not comparable)
Claude Opus 5frontier referenceOK
Show code
<!doctype html>
<html><head><meta charset="utf-8"><title>Scrolling value-noise terrain</title>
<style>
html,body{margin:0;height:100%;background:#070b16;overflow:hidden}
canvas{display:block;width:100vw;height:100vh}
#hud{position:fixed;left:12px;top:11px;font:13px ui-monospace,monospace;color:#d6e6ff;
background:rgba(6,10,22,.6);padding:5px 9px;border-radius:5px;letter-spacing:.02em}
</style></head><body>
<canvas id="c"></canvas><div id="hud">offset 0</div>
<script>
const cv=document.getElementById('c'),g=cv.getContext('2d'),hud=document.getElementById('hud');
let W=0,H=0;
function fit(){W=cv.width=innerWidth;H=cv.height=innerHeight}
fit();addEventListener('resize',fit);

function hash(i){const s=Math.sin(i*127.1+11.7)*43758.5453;return s-Math.floor(s)}
function smooth(t){return t*t*(3-2*t)}
function vnoise(p){const i=Math.floor(p),f=smooth(p-i);return hash(i)*(1-f)+hash(i+1)*f}
function fbm(p){
  let amp=.5,freq=1/260,sum=0,norm=0;
  for(let o=0;o<4;o++){sum+=amp*vnoise(p*freq+o*97.3);norm+=amp;amp*=.5;freq*=2.13}
  return sum/norm;
}

const SEA=.42;
function band(h){
  if(h<SEA-.10) return '#123a63';
  if(h<SEA) return '#1b5285';
  if(h<SEA+.04) return '#cdb887';
  if(h<SEA+.18) return '#3d7a48';
  if(h<SEA+.30) return '#2f5f3c';
  if(h<SEA+.42) return '#6b6d74';
  return '#e8eef6';
}

let off=0,last=0;
function frame(t){
  const dt=Math.min(48,t-(last||t));last=t;
  off+=dt*.055;

  const sky=g.createLinearGradient(0,0,0,H);
  sky.addColorStop(0,'#0a1730');sky.addColorStop(.55,'#20406e');sky.addColorStop(1,'#4b6a94');
  g.fillStyle=sky;g.fillRect(0,0,W,H);

  const base=H*.94;
  for(let x=0;x<W;x++){
    const h=fbm(off+x);
    const y=base-h*H*.72;
    g.fillStyle=band(h);
    g.fillRect(x,y,1,base-y);
    if(h<SEA){
      g.fillStyle='rgba(70,150,220,.35)';
      g.fillRect(x,base-SEA*H*.72,1,(SEA-h)*H*.72);
    }
  }

  hud.textContent='offset '+Math.round(off)+'  ·  octaves 4';
  requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
</script></body></html>
GPT-5.5 (Codex)frontier referenceOK
Show code
<!doctype html><html><head><meta charset="utf-8"><title>Noise Landscape</title><style>html,body{margin:0;height:100%;overflow:hidden;background:#79a7d8;font:16px monospace;color:white}canvas{display:block;width:100%;height:100%}#o{position:fixed;left:14px;top:12px;text-shadow:0 1px 3px #000}</style></head><body><canvas id="c"></canvas><div id="o"></div><script>
let c=document.getElementById("c"),x=c.getContext("2d"),o=document.getElementById("o"),W,H,dpr,seed=Math.random()*1e9,off=0,last=0;
function R(n){let s=Math.sin(n*127.1+seed)*43758.5453;return s-Math.floor(s)}
function S(t){return t*t*t*(t*(t*6-15)+10)}
function N(p,sc){p/=sc;let i=Math.floor(p),f=p-i,a=R(i),b=R(i+1);return a+(b-a)*S(f)}
function Ht(p){let v=.58*N(p,170)+.29*N(p,70)+.13*N(p,25);v=(v-.5)*1.75+.5;return Math.max(0,Math.min(1,v))}
function col(v){return v<.34?"#22699b":v<.38?"#d9c889":v<.62?"#3e8f45":v<.82?"#77736b":"#f2f5f6"}
function size(){dpr=devicePixelRatio||1;W=innerWidth;H=innerHeight;c.width=W*dpr;c.height=H*dpr;x.setTransform(dpr,0,0,dpr,0,0)}
onresize=size;size();
function draw(t){if(!last)last=t;let dt=Math.min(.05,(t-last)/1e3);last=t;off+=dt*70;if(off>1e7){seed=Math.random()*1e9;off=0}
let sky=x.createLinearGradient(0,0,0,H);sky.addColorStop(0,"#6fa4dc");sky.addColorStop(1,"#d8efff");x.fillStyle=sky;x.fillRect(0,0,W,H);
x.fillStyle="#74b5e0";x.globalAlpha=.55;for(let i=0;i<7;i++){let y=70+i*42+N(off+i*600,500)*22;x.beginPath();x.ellipse((i*210-off*.08)%(W+260)-130,y,120,18,0,0,7);x.fill()}x.globalAlpha=1;
let base=H*.82,amp=H*.55,prev=base-Ht(off)*amp;x.lineWidth=2;for(let px=0;px<W;px+=2){let v=Ht(off+px),y=base-v*amp;x.strokeStyle=col(v);x.beginPath();x.moveTo(px,Math.max(prev,y));x.lineTo(px,H);x.stroke();prev=y}
x.fillStyle="rgba(255,255,255,.75)";x.fillText("offset "+Math.floor(off),14,40);o.textContent="offset "+Math.floor(off);requestAnimationFrame(draw)}
requestAnimationFrame(draw)
</script></body></html>
Claude Sonnet 5frontier referenceOK
Show code
<!DOCTYPE html><html><head><meta charset="utf-8"><title>Noise Landscape</title>
<style>html,body{margin:0;background:#87ceeb;overflow:hidden;height:100%}canvas{display:block}
#h{position:fixed;top:8px;left:10px;color:#111;font:14px monospace;text-shadow:0 0 4px #fff}</style>
</head><body><canvas id="c"></canvas><div id="h"></div>
<script>
const cv=document.getElementById('c'),x=cv.getContext('2d');
let W,H;function rz(){W=cv.width=innerWidth;H=cv.height=innerHeight;}
rz();addEventListener('resize',rz);
let seed;
function hash(i){
  const v=Math.sin(i*127.1+seed*311.7)*43758.5453;
  return v-Math.floor(v);
}
function noise1(t){
  const i0=Math.floor(t),i1=i0+1,f=t-i0;
  const u=f*f*(3-2*f);
  return hash(i0)*(1-u)+hash(i1)*u;
}
function fbm(t){
  let s=0,amp=0.55,freq=1,norm=0;
  for(let o=0;o<3;o++){
    s+=noise1(t*freq)*amp;
    norm+=amp;
    amp*=0.5;freq*=2.1;
  }
  return s/norm;
}
let offset,skyGrad;
function init(){
  seed=Math.random()*1000;
  offset=Math.random()*500;
  const g=x.createLinearGradient(0,0,0,H*0.6);
  g.addColorStop(0,'#3a7bd5');g.addColorStop(1,'#a8d8ff');
  skyGrad=g;
}
init();
const scale=0.006,speed=1.4;
const seaLevel=0.34,sandT=0.4,grassT=0.62,rockT=0.82;
function colorFor(e){
  if(e<sandT)return[214,197,140];
  if(e<grassT){const t=(e-sandT)/(grassT-sandT);return[Math.round(90-t*30),Math.round(150+t*20),Math.round(60-t*20)];}
  if(e<rockT){const t=(e-grassT)/(rockT-grassT);return[Math.round(120-t*30),Math.round(110-t*30),Math.round(105-t*25)];}
  const t=Math.min(1,(e-rockT)/(1-rockT));
  return[Math.round(210+t*40),Math.round(210+t*40),Math.round(215+t*40)];
}
function draw(){
  x.fillStyle=skyGrad;x.fillRect(0,0,W,H*0.62);
  const seaY=H*0.75-seaLevel*H*0.55;
  const waterGrad=x.createLinearGradient(0,seaY,0,H);
  waterGrad.addColorStop(0,'#1c6fa8');waterGrad.addColorStop(1,'#0a3a5c');
  for(let X=0;X<W;X++){
    const wt=(X+offset)*scale;
    const e=fbm(wt);
    const groundY=H*0.75-e*H*0.55;
    if(e<seaLevel){
      x.fillStyle=waterGrad;
      x.fillRect(X,seaY,1,H-seaY);
    }else{
      const c=colorFor(e);
      x.fillStyle=`rgb(${c[0]},${c[1]},${c[2]})`;
      x.fillRect(X,groundY,1,H-groundY);
      const c2=[Math.max(0,c[0]-40),Math.max(0,c[1]-40),Math.max(0,c[2]-40)];
      x.fillStyle=`rgb(${c2[0]},${c2[1]},${c2[2]})`;
      x.fillRect(X,groundY+ (H-groundY)*0.7,1,(H-groundY)*0.3);
    }
  }
  offset+=speed;
  document.getElementById('h').textContent=`world offset: ${offset.toFixed(0)}`;
  if(offset>1e7)init();
}
function loop(){draw();requestAnimationFrame(loop);}
loop();
</script></body></html>
Claude Fable 5frontier referenceOK
Show code
<!DOCTYPE html><html><head><meta charset="utf-8"><title>Value Noise Terrain</title><style>html,body{margin:0;height:100%;overflow:hidden;background:#000}canvas{display:block}#h{position:fixed;top:10px;left:10px;color:#fff;font:14px monospace;background:rgba(0,0,0,.45);padding:6px 10px;border-radius:6px}</style></head><body><canvas id="c"></canvas><div id="h"></div><script>
const cv=document.getElementById("c"),g=cv.getContext("2d"),hud=document.getElementById("h");
let W,H;function rs(){W=cv.width=innerWidth;H=cv.height=innerHeight}onresize=rs;rs();
let seed=0,off=0,runT=0;
function reset(){seed=(Math.random()*1e9)>>>0;off=0;runT=0}
reset();
function hash(i){let t=(i+seed)|0;t=Math.imul(t^t>>>15,2246822519);t=Math.imul(t^t>>>13,3266489917);return((t^t>>>16)>>>0)/4294967296}
function vnoise(p,o){const i=Math.floor(p),f=p-i,u=f*f*(3-2*f);return hash(i+o*1013904)*(1-u)+hash(i+1+o*1013904)*u}
function elev(wx){let e=0,a=1,fr=.0035,s=0;for(let o=0;o<3;o++){e+=vnoise(wx*fr,o)*a;s+=a;a*=.5;fr*=2.17}return e/s}
let last=0;
function frame(t){requestAnimationFrame(frame);const dt=Math.min(.05,(t-last)/1000||0);last=t;
off+=dt*90;runT+=dt;
if(runT>150)reset();
const sky=g.createLinearGradient(0,0,0,H);sky.addColorStop(0,"#0b1e3d");sky.addColorStop(.55,"#4a7db0");sky.addColorStop(.62,"#c78a5a");g.fillStyle=sky;g.fillRect(0,0,W,H);
g.fillStyle="rgba(255,240,210,.9)";g.beginPath();g.arc(W*.78,H*.16,26,0,7);g.fill();
const waterY=H*.62+Math.sin(runT*.7)*2;
const snowY=H*.16,rockY=H*.32,grassY=H*.47,sandY=waterY-8;
for(let x=0;x<W;x++){
const wx=off+x,e=elev(wx);
let top=H*.99-e*H*.85;
const sh=.82+.18*Math.min(1,Math.max(0,(elev(wx-3)-e)*40+.5));
if(top>=waterY){
const d=Math.min(1,(top-waterY)/(H*.35));
g.fillStyle=`rgb(${30-20*d|0},${90-55*d|0},${160-80*d|0})`;
g.fillRect(x,waterY,1,H-waterY);
}else{
let y=top;
const bands=[[snowY,[245,248,252]],[rockY,[128,124,132]],[grassY,[76,142,64]],[sandY,[214,192,138]],[H,[110,90,62]]];
for(const[lim,c]of bands){if(y<lim){const y2=Math.min(lim,H);g.fillStyle=`rgb(${c[0]*sh|0},${c[1]*sh|0},${c[2]*sh|0})`;g.fillRect(x,y,1,y2-y);y=y2}}
}}
hud.textContent="world offset: "+Math.floor(off)+"  seed: "+seed;
}
requestAnimationFrame(frame);
</script></body></html>
Claude Haiku 4.5frontier referenceOKMINIFIED
Show code
<!DOCTYPE html><html><head><meta charset="utf-8"><style>body{margin:0;background:#000;overflow:hidden}#c{display:block}#i{position:absolute;top:5px;left:5px;color:#0f0;font-family:monospace;font-size:12px}</style></head><body><canvas id="c"></canvas><div id="i"></div><script>const c=document.getElementById('c'),ctx=c.getContext('2d'),i=document.getElementById('i');c.width=800;c.height=400;const W=800,H=400;let p={};function pn(x){let xi=Math.floor(x),xf=x-xi;let i0=xi%256,i1=(xi+1)%256;if(!p[i0])p[i0]=Math.random();if(!p[i1])p[i1]=Math.random();let u=xf*xf*(3-2*xf);return p[i0]*(1-u)+p[i1]*u}function n(x){let v=0,a=1,f=1;for(let j=0;j<3;j++){v+=a*pn(x*f);a/=2;f*=2}return v}function dr(){ctx.fillStyle='#000';ctx.fillRect(0,0,W,H);let t=(Date.now()/30)%256;for(let x=0;x<W;x++){let v=n((x+t)*0.01);let h=Math.floor(v*H);let col;if(v<0.3)col='#00f';else if(v<0.45)col='#d4a574';else if(v<0.7)col='#0a0';else if(v<0.85)col='#888';else col='#fff';ctx.fillStyle=col;ctx.fillRect(x,H-h,1,h)}i.textContent=`Offset: ${Math.floor(t)}`}setInterval(dr,50);</script></body></html>
Results at a glance— every model in this round with score, response time and status.

Who wrote what

ModelBlind scoreLatencyStatus
qwen3-coder:30b —18.7 sOK
mistral-small:24b —84.5 sOK
qwen3:14b —27.5 sOK
gemma4:26b ——harness
qwen3.5:9b —25.6 sOK
qwen3:8b ——harness
llama3.1:8b —9.3 sOK
deepseek-r1:14b —151.6 sOK
qwq:32b —259.4 sOK
command-r:35b —18.6 sOK
deepseek-r1:32b —59.0 sOK