Showcase

Boat game, built by Flint

NVFP4via DaBenchllama.cpp
Running live in your browserNew tab
Speed
114tok/s
First token included
Written
19.6Ktokens
Time to build
2m 53s
Flint's builds and scores
Show the code the model wrote
HTML7,572 characters
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ultra Realistic Water - Boat</title>
<style>
  html, body { margin: 0; padding: 0; overflow: hidden; background: #001122; }
  canvas { display: block; width: 100vw; height: 100vh; }
</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
let W = canvas.width = innerWidth;
let H = canvas.height = innerHeight;
window.addEventListener('resize', () => { W = canvas.width = innerWidth; H = canvas.height = innerHeight; });

// Input
const keys = { w: false, s: false, a: false, d: false, arrowup: false, arrowdown: false, arrowleft: false, arrowright: false };
let mouseX = W / 2, mouseY = H / 2;
canvas.addEventListener('mousemove', e => { mouseX = e.clientX; mouseY = e.clientY; });
canvas.addEventListener('mousedown', e => { if (e.button === 0) firing = true; });
canvas.addEventListener('mouseup', e => { if (e.button === 0) firing = false; });
let firing = false;

// Water
const water = {
  gridRes: 50,
  worldSize: 50,
  amp1: 0.8, freq1: 0.08, amp2: 0.6, freq2: 0.06, amp3: 0.4, freq3: 0.05,
  getHeight(x, z, t) {
    return Math.sin(x * this.freq1 + t) * this.amp1 + Math.cos(z * this.freq2 - t) * this.amp2 + Math.sin((x + z) * this.freq3 + t) * this.amp3;
  }
};

// Boat
const boat = {
  pos: { x: 0, z: 0 },
  vel: { x: 0, z: 0 },
  yaw: 0,
  pitch: 0,
  roll: 0,
  health: 100,
  throttle: 0,
  turn: 0,
  angularVel: 0,
  width: 3,
  length: 6,
  mass: 100,
};

// Enemies
let enemies = [];
let projectiles = [];
let enemyTimer = 0;
let gameOver = false;
let time = 0;
let shake = 0;

// Camera & scale
const scale = Math.min(W, H) / 60;
let camX = 0, camZ = 0;

function updateCamera() {
  camX = boat.pos.x;
  camZ = boat.pos.z;
}

// Physics update
function update(dt) {
  if (gameOver) return;
  let throttle = (keys.w ? 1 : 0) - (keys.s ? 1 : 0);
  let turn = (keys.d ? 1 : 0) - (keys.a ? 1 : 0);
  boat.throttle = throttle;
  boat.turn = turn;

  const thrustForce = throttle * 30;
  boat.vel.x += Math.cos(boat.yaw) * thrustForce * dt;
  boat.vel.z += Math.sin(boat.yaw) * thrustForce * dt;
  boat.vel.x *= Math.max(0, 1 - 0.5 * dt);
  boat.vel.z *= Math.max(0, 1 - 0.5 * dt);

  boat.angularVel = turn * 2;
  boat.yaw += boat.angularVel * dt;

  boat.pos.x += boat.vel.x * dt;
  boat.pos.z += boat.vel.z * dt;
  boat.pos.x = Math.max(-20, Math.min(20, boat.pos.x));
  boat.pos.z = Math.max(-20, Math.min(20, boat.pos.z));

  const h = water.getHeight(boat.pos.x, boat.pos.z, time);
  const slopeF = (water.getHeight(boat.pos.x + 0.1, boat.pos.z, time) - water.getHeight(boat.pos.x - 0.1, boat.pos.z, time)) / 0.2 * Math.cos(boat.yaw);
  const slopeR = (water.getHeight(boat.pos.x, boat.pos.z + 0.1, time) - water.getHeight(boat.pos.x, boat.pos.z - 0.1, time)) / 0.2 * Math.sin(boat.yaw);
  boat.pitch += (slopeF * 2 - boat.pitch) * 0.1;
  boat.roll += (slopeR * 2 - boat.roll) * 0.1;
}

// Enemy logic
function spawnEnemy() {
  const angle = Math.random() * Math.PI * 2;
  const dist = 15 + Math.random() * 10;
  enemies.push({
    x: boat.pos.x + Math.cos(angle) * dist,
    z: boat.pos.z + Math.sin(angle) * dist,
    health: 30,
    fireTimer: 0,
  });
}

function updateEnemies(dt) {
  enemyTimer -= dt;
  if (enemyTimer <= 0 && enemies.length < 5) {
    spawnEnemy();
    enemyTimer = 2 + Math.random() * 3;
  }
  for (let i = enemies.length - 1; i >= 0; i--) {
    const e = enemies[i];
    const dx = boat.pos.x - e.x;
    const dz = boat.pos.z - e.z;
    const dist = Math.hypot(dx, dz);
    if (dist < 5) {
      // shoot
      e.fireTimer -= dt;
      if (e.fireTimer <= 0) {
        projectiles.push({
          x: e.x, z: e.z, vx: dx * 2, vz: dz * 2, life: 2,
        });
        e.fireTimer = 1;
      }
    } else {
      e.x += (dx / dist) * 2 * dt;
      e.z += (dz / dist) * 2 * dt;
    }
  }
  // update projectiles
  for (let i = projectiles.length - 1; i >= 0; i--) {
    const p = projectiles[i];
    p.life -= dt;
    p.x += p.vx * dt;
    p.z += p.vz * dt;
    const dx = boat.pos.x - p.x;
    const dz = boat.pos.z - p.z;
    const dist = Math.hypot(dx, dz);
    if (dist < 2) {
      boat.health -= 10;
      projectiles.splice(i, 1);
      if (boat.health <= 0) gameOver = true;
    }
    if (p.life <= 0) projectiles.splice(i, 1);
  }
}

// Render water
function renderWater(t) {
  const cell = water.worldSize / (water.gridRes - 1);
  for (let i = 0; i < water.gridRes; i++) {
    for (let j = 0; j < water.gridRes; j++) {
      const x = -water.worldSize / 2 + i * cell;
      const z = -water.worldSize / 2 + j * cell;
      const h00 = water.getHeight(x, z, t);
      const h10 = water.getHeight(x + cell, z, t);
      const h01 = water.getHeight(x, z + cell, t);
      const h11 = water.getHeight(x + cell, z + cell, t);
      const h0 = h00 + (h10 - h00) * 0.5;
      const h1 = h01 + (h11 - h01) * 0.5;
      const h = h0 + (h1 - h0) * 0.5;
      const sx0 = W / 2 + (x - camX) * scale;
      const sy0 = H / 2 - (z - camZ) * scale;
      const sx1 = W / 2 + (x + cell - camX) * scale;
      const sy1 = H / 2 - (z - camZ) * scale;
      const sx2 = W / 2 + (x - camX) * scale;
      const sy2 = H / 2 - (z + cell - camZ) * scale;
      const sx3 = W / 2 + (x + cell - camX) * scale;
      const sy3 = H / 2 - (z + cell - camZ) * scale;
      ctx.beginPath();
      ctx.moveTo(sx0, sy0);
      ctx.lineTo(sx1, sy1);
      ctx.lineTo(sx3, sy3);
      ctx.lineTo(sx2, sy2);
      ctx.closePath();
      const col = h > 0.4 ? '#2a7a9a' : h > 0.2 ? '#1a5a7a' : '#0a2a4a';
      ctx.fillStyle = col;
      ctx.fill();
    }
  }
}

// Render boat
function renderBoat() {
  const sx = W / 2 + (boat.pos.x - camX) * scale;
  const sy = H / 2 - (boat.pos.z - camZ) * scale;
  ctx.save();
  ctx.translate(sx, sy);
  ctx.rotate(boat.yaw);
  // hull
  ctx.fillStyle = '#1a3a5a';
  ctx.beginPath();
  ctx.ellipse(0, 0, boat.length / 2, boat.width / 2, 0, 0, Math.PI * 2);
  ctx.fill();
  // deck
  ctx.fillStyle = '#2a5a7a';
  ctx.beginPath();
  ctx.ellipse(0, 0, boat.length / 2 - 1, boat.width / 2 - 1, 0, 0, Math.PI * 2);
  ctx.fill();
  // mast
  ctx.strokeStyle = '#5a3a2a';
  ctx.lineWidth = 2;
  ctx.beginPath();
  ctx.moveTo(0, -boat.length / 2);
  ctx.lineTo(0, boat.length / 2);
  ctx.stroke();
  // turret
  ctx.fillStyle = '#888';
  ctx.beginPath();
  ctx.arc(0, -boat.length / 2 + 2, 2, 0, Math.PI * 2);
  ctx.fill();
  // health bar
  ctx.fillStyle = '#0f0';
  ctx.fillRect(-boat.length / 2, -boat.width / 2 - 5, boat.length * boat.health / 100, 3);
  ctx.restore();
}

// Render enemies
function renderEnemies() {
  for (const e of enemies) {
    const sx = W / 2 + (e.x - camX) * scale;
    const sy = H / 2 - (e.z - camZ) * scale;
    ctx.save();
    ctx.translate(sx, sy);
    ctx.fillStyle = '#a00';
    ctx.beginPath();
    ctx.arc(0, 0, 4, 0, Math.PI * 2);
    ctx.fill();
    ctx.restore();
  }
}

// Render projectiles
function renderProjectiles() {
  for (const p of projectiles) {
    const sx = W / 2 + (p.x - camX) * scale;
    const sy = H / 2 - (p.z - camZ) * scale;
    ctx.fillStyle = '#ff0';
    ctx.fillRect(sx - 1, sy - 1, 2, 2);
  }
}

// Main loop
function loop() {
  let dt = 1 / 60;
  time += dt;
  update(dt);
  updateCamera();
  updateEnemies(dt);
  renderWater(time);
  renderBoat();
  renderEnemies();
  renderProjectiles();
  if (gameOver) {
    ctx.fillStyle = '#fff';
    ctx.font = '30px Arial';
    ctx.fillText('GAME OVER', W / 2 - 100, H / 2);
  }
  requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
</script>
</body>
</html>

Same prompt, other models

10 more
Compare side by side

One email when a new model lands on the board or in the showcase. Unsubscribe anytime.