27:18Gemini 4 Hydrogen: Cheaper Tokens, More Expensive Answers?
Nov 13, 2026 · YouTube
18:40ERNIE 5.5 Flash Preview vs GLM 5.3 Flash: Baidu's new model is very impressive!
Nov 11, 2026 · YouTube
36:22Fable 5.2 robbing me blind, plus: Nex AGI's N2.6 vs GLM 5.3 Flash
Nov 11, 2026 · YouTube
14:03Gemini 4 Carbon: Can it handle my challenges? (First look with one-shot coding tests)
Nov 10, 2026 · YouTube
47:51Ranking major U.S. Open-Weights Models. (Where does Ripple 65B fit in?)
Nov 6, 2026 · YouTube
10:57"Crouton Alpha": the latest super-efficient coding model by Meta?
Nov 3, 2026 · YouTube
38:58Testing Particle-1: a post-trained DeepSeek V4.1 Flash specializing in coding and efficiency
Oct 28, 2026 · YouTube
22:14GPT-6.1 Terra Pro vs Terra: How Much Better Is Pro?
Oct 27, 2026 · YouTube
29:55Kimi K3.1 Pro Looked Incredible. Then I Kept Testing.
Oct 26, 2026 · YouTube
31:28Is this company reselling GPT Sol 6.1 at a loss (for non-agentic/text-only)?🤔 Is this sustainable?
Oct 20, 2026 · YouTube
17:58Nemotron 3.5 Super VL vs Opus 5.5: Testing NVIDIA’s new coding juggernaut
Oct 15, 2026 · YouTube
16:04Testing a *massive* new open-weights model 🤯: Muse Spark Open (vs. Nemotron, Opus 5.5, and more)
Oct 15, 2026 · YouTube
16:43Gemini 4 Argon: Great 🐈 Animation, but a broken escalator. (Coding challenge vs Opus 5.5, Sol 6.1)
Oct 13, 2026 · YouTube
16:37Meta's new "Muse Wonder" AI is impressive... but can it compete with Anthropic's models?
Oct 12, 2026 · YouTube
11:12WOW... Haiku 5.5 is very impressive. RIP OpenAI?
Oct 7, 2026 · YouTube
22:47Mistral Large 4 Is Cheap. But Is It Good Enough to Compete?
Oct 6, 2026 · YouTube
22:02Is Pareto 26.10 Preview Just Routing to GPT Sol? I Tested It Against Sol 6.1 Pro
Oct 1, 2026 · YouTube
11:22I Tested Sonnet 5.5 Against Opus 5.5. Is It Actually Cheaper?
Sep 28, 2026 · YouTube
30:00Did Elon Musk's team "train the gay away"... and make Grok 4.7 worse?
Sep 26, 2026 · YouTube
19:21I Tested the Stealth "Space Bunny Alpha" Model Before It Went Offline
Sep 23, 2026 · YouTube
10:58So... how much better is Claude Opus 5.5 vs. GPT-6 Sol, really?
Sep 23, 2026 · YouTube
9:38Claude Opus 5.5... the BEST new model for coding!! 🤩
Sep 22, 2026 · YouTube
29:00Grok 4.7: improved, but GLM 5.3 FlashX beat it anyway (benchmark against Gemini, Sol, etc.)
Sep 22, 2026 · YouTube
You write simulations where the interesting behavior is supposed to emerge rather than be animated by hand.
Build me a single HTML page: a side-view escalator carrying 15 to 20 people. Then the escalator reverses, at high speed.
data: URIs are fine.localStorage, sessionStorage, cookies or indexedDB — sandboxed frame, they throw.html block.One paragraph, before the file: how a person is represented, what makes one lose balance, and what happens when two of them occupy the same place.
The single fenced html block.
Having written it, what does the page do when the escalator reverses? Name anything you special-cased or nudged. Say what it does badly — I am going to press the button and watch.
Each person is a capsule-like body with a position, velocity, tilt, and angular velocity; gravity, contact with the steps, and collisions update those values every frame. When a person is standing, the moving escalator accelerates their footing, and that acceleration can tip them; when bodies overlap, the simulation separates them and exchanges momentum, so a fallen person can obstruct those behind. A standing balance response and a room-dependent righting response let people recover without assigning falls or recoveries to particular figures.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Escalator — a small physics simulation</title>
<style>
:root { color-scheme: dark; }
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
padding: 22px;
background: #101820;
color: #edf1e9;
font: 15px/1.45 system-ui, sans-serif;
}
main { width: min(100%, 1080px); }
header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin: 0 0 12px;
}
h1 { font-size: clamp(19px, 3vw, 27px); margin: 0; letter-spacing: .01em; }
button {
border: 0;
border-radius: 8px;
padding: 11px 17px;
color: #10212a;
background: #f2bd58;
font: 700 15px system-ui, sans-serif;
cursor: pointer;
box-shadow: 0 3px 0 #b57d26;
}
button:hover { background: #ffd27a; }
button:active { transform: translateY(2px); box-shadow: 0 1px 0 #b57d26; }
button:focus-visible { outline: 3px solid #f5f1d7; outline-offset: 3px; }
.frame {
overflow: hidden;
border: 1px solid #3e5359;
border-radius: 12px;
background: #c4d4d1;
box-shadow: 0 18px 50px #0005;
}
canvas { display: block; width: 100%; height: auto; }
.caption {
display: flex;
justify-content: space-between;
gap: 14px;
margin-top: 10px;
color: #aebdbd;
font-size: 13px;
}
@media (max-width: 600px) {
body { padding: 12px; }
header { align-items: flex-start; flex-direction: column; }
button { padding: 10px 14px; }
.caption { flex-direction: column; gap: 3px; }
}
</style>
</head>
<body>
<main>
<header>
<h1>Escalator: ordinary rules, sudden reversal</h1>
<button id="reverse" type="button">Reverse escalator</button>
</header>
<div class="frame">
<canvas id="scene" width="960" height="540" aria-label="Side-view escalator simulation"></canvas>
</div>
<div class="caption">
<span id="status">Running uphill · 18 riders</span>
<span>Press the button or Space to reverse it again.</span>
</div>
</main>
<script>
(() => {
"use strict";
const canvas = document.getElementById("scene");
const ctx = canvas.getContext("2d");
const button = document.getElementById("reverse");
const status = document.getElementById("status");
const W = 960, H = 540;
const X0 = 116, STEP_W = 28, STEP_H = 8, STEPS = 25;
const X1 = X0 + STEP_W * STEPS;
const BODY_HALF = 17.5, BODY_R = 7.5;
const DT = 1 / 120;
const clamp = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
const wrap = a => Math.atan2(Math.sin(a), Math.cos(a));
function floorY(x) {
if (x <= X0) return 430;
if (x >= X1) return 430 - STEPS * STEP_H;
const i = Math.floor((x - X0) / STEP_W);
return 430 - i * STEP_H;
}
let reversed = false;
let beltV = 48;
let clock = 0;
let lastTime = performance.now();
let accumulator = 0;
const people = [];
const shirtColors = [
"#d55f45", "#416b9a", "#d0a33f", "#73558c", "#419077", "#c56f91",
"#597c45", "#dc8450", "#486f78", "#a55545", "#7279a8", "#b48a42"
];
for (let i = 0; i < 18; i++) {
const x = 148 + i * 35 + ((i % 3) - 1) * 1.3;
people.push({
x, y: floorY(x) - BODY_HALF - BODY_R,
vx: 48, vy: 0, a: 0, w: 0,
color: shirtColors[i % shirtColors.length]
});
}
function toggleReverse() {
reversed = !reversed;
button.textContent = reversed ? "Put it back" : "Reverse escalator";
status.textContent = reversed
? "Reversing downhill · 18 riders"
: "Running uphill · 18 riders";
}
button.addEventListener("click", toggleReverse);
window.addEventListener("keydown", e => {
if (e.code === "Space" && !e.repeat) {
e.preventDefault();
toggleReverse();
}
});
function endpoints(p) {
const sx = Math.sin(p.a), cy = Math.cos(p.a);
// First endpoint is the feet when the person is upright.
return [
{ x: p.x - sx * BODY_HALF, y: p.y + cy * BODY_HALF },
{ x: p.x + sx * BODY_HALF, y: p.y - cy * BODY_HALF }
];
}
function resolveGround(p) {
let touching = false;
const ends = endpoints(p);
for (const e of ends) {
const f = floorY(e.x);
const penetration = e.y + BODY_R - f;
if (penetration > 0) {
p.y -= penetration;
touching = true;
if (p.vy > 0) p.vy *= -0.04;
} else if (f - (e.y + BODY_R) < 2.5) {
touching = true;
}
}
if (touching) {
p.w *= 0.986;
if (Math.abs(p.vy) < 18) p.vy = 0;
}
return touching;
}
function closestSegments(a0, a1, b0, b1) {
const ux = a1.x - a0.x, uy = a1.y - a0.y;
const vx = b1.x - b0.x, vy = b1.y - b0.y;
const wx = a0.x - b0.x, wy = a0.y - b0.y;
const aa = ux * ux + uy * uy;
const bb = ux * vx + uy * vy;
const cc = vx * vx + vy * vy;
const dd = ux * wx + uy * wy;
const ee = vx * wx + vy * wy;
const den = aa * cc - bb * bb;
let sN, sD = den, tN, tD = den;
if (den < 1e-8) {
sN = 0; sD = 1; tN = ee; tD = cc;
} else {
sN = bb * ee - cc * dd;
tN = aa * ee - bb * dd;
if (sN < 0) { sN = 0; tN = ee; tD = cc; }
else if (sN > sD) { sN = sD; tN = ee + bb; tD = cc; }
}
if (tN < 0) {
tN = 0;
sN = clamp(-dd, 0, aa);
sD = aa;
} else if (tN > tD) {
tN = tD;
sN = clamp(-dd + bb, 0, aa);
sD = aa;
}
const s = Math.abs(sN) < 1e-8 ? 0 : sN / sD;
const t = Math.abs(tN) < 1e-8 ? 0 : tN / tD;
return {
ax: a0.x + ux * s, ay: a0.y + uy * s,
bx: b0.x + vx * t, by: b0.y + vy * t
};
}
function collide(a, b) {
const ea = endpoints(a), eb = endpoints(b);
const c = closestSegments(ea[0], ea[1], eb[0], eb[1]);
let dx = c.bx - c.ax, dy = c.by - c.ay;
let d = Math.hypot(dx, dy);
const minD = BODY_R * 2;
if (d >= minD) return;
if (d < 1e-6) {
dx = b.x - a.x; dy = b.y - a.y;
d = Math.hypot(dx, dy) || 1;
}
const nx = dx / d, ny = dy / d;
const overlap = minD - d;
// Equal-mass bodies are separated; the correction is positional, not a scripted shove.
const correction = Math.max(0, overlap - 0.15) * 0.36;
a.x -= nx * correction;
a.y -= ny * correction;
b.x += nx * correction;
b.y += ny * correction;
const rax = c.ax - a.x, ray = c.ay - a.y;
const rbx = c.bx - b.x, rby = c.by - b.y;
const avx = a.vx - a.w * ray, avy = a.vy + a.w * rax;
const bvx = b.vx - b.w * rby, bvy = b.vy + b.w * rbx;
const closing = (bvx - avx) * nx + (bvy - avy) * ny;
if (closing < 0) {
const impulse = -(1.06 * closing) / 2;
a.vx -= impulse * nx;
a.vy -= impulse * ny;
b.vx += impulse * nx;
b.vy += impulse * ny;
// A modest angular response lets a shoulder/hip impact turn a body.
const inertia = 230;
a.w += impulse * (rax * ny - ray * nx) / inertia;
b.w -= impulse * (rbx * ny - rby * nx) / inertia;
}
}
function hasRoom(p) {
for (const q of people) {
if (q === p) continue;
if (Math.hypot(q.x - p.x, q.y - p.y) < 43) return false;
}
return true;
}
function step(dt) {
const target = reversed ? -94 : 48;
beltV += clamp(target - beltV, -1500 * dt, 1500 * dt);
for (const p of people) {
const grounded = resolveGround(p);
let supportAx = 0;
if (grounded) {
supportAx = clamp((beltV - p.vx) * 24, -1900, 1900);
p.vx += supportAx * dt;
// The moving tread pushes at the feet: rapid acceleration tips the body.
const uprightish = Math.abs(wrap(p.a)) < 1.35;
p.w += -supportAx * (uprightish ? 0.095 : 0.018) * dt;
}
const angle = wrap(p.a);
if (Math.abs(angle) < 0.85) {
// Same balance response for every upright rider.
p.w += (-angle * 20 - p.w * 5.8) * dt;
} else if (grounded && Math.abs(p.w) < 4.2 && hasRoom(p)) {
// Righting is only available when nearby bodies leave enough room.
p.w += (-angle * 7.5 - p.w * 3.2) * dt;
}
p.w = clamp(p.w, -12, 12);
p.vy += 900 * dt;
p.x += p.vx * dt;
p.y += p.vy * dt;
p.a += p.w * dt;
if (p.x < 96) { p.x = 96; p.vx = Math.max(0, p.vx); }
if (p.x > 866) { p.x = 866; p.vx = Math.min(0, p.vx); }
resolveGround(p);
}
for (let i = 0; i < people.length; i++) {
for (let j = i + 1; j < people.length; j++) collide(people[i], people[j]);
}
for (const p of people) {
resolveGround(p);
p.w = clamp(p.w, -12, 12);
}
clock += dt;
}
function line(x1, y1, x2, y2, color, width) {
ctx.strokeStyle = color;
ctx.lineWidth = width;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
}
function drawBackground() {
const g = ctx.createLinearGradient(0, 0, 0, H);
g.addColorStop(0, "#d9e5df");
g.addColorStop(1, "#b6c9c5");
ctx.fillStyle = g;
ctx.fillRect(0, 0, W, H);
// Quiet architectural shapes, kept behind the moving figures.
ctx.fillStyle = "#a9bfba";
ctx.fillRect(0, 0, W, 110);
ctx.fillStyle = "#c7d7d1";
ctx.fillRect(0, 110, W, 320);
ctx.fillStyle = "#b1c5c0";
ctx.fillRect(0, 430, W, 110);
ctx.fillStyle = "#dce6dd";
ctx.fillRect(0, 0, 960, 17);
ctx.fillStyle = "#809995";
ctx.fillRect(40, 90, 62, 4);
ctx.fillRect(40, 90, 4, 125);
ctx.fillRect(842, 52, 70, 4);
ctx.fillRect(908, 52, 4, 155);
ctx.fillStyle = "#e7eee8";
ctx.fillRect(68, 173, 36, 47);
ctx.fillRect(857, 123, 44, 45);
ctx.fillStyle = "#93aaa5";
ctx.fillRect(75, 180, 22, 33);
ctx.fillRect(865, 130, 28, 31);
}
function drawEscalator() {
// Lower and upper landings.
ctx.fillStyle = "#708581";
ctx.fillRect(0, 430, X0 + 2, 110);
ctx.fillRect(X1 - 2, 230, W - X1 + 2, 310);
ctx.fillStyle = "#91a6a1";
ctx.fillRect(0, 430, X0, 8);
ctx.fillRect(X1, 230, W - X1, 8);
// Dark casing below the staircase.
ctx.fillStyle = "#405652";
ctx.beginPath();
ctx.moveTo(X0, 430);
ctx.lineTo(X1, 230);
ctx.lineTo(X1, 268);
ctx.lineTo(X0, 468);
ctx.closePath();
ctx.fill();
// Individual visible treads and risers.
for (let i = 0; i < STEPS; i++) {
const x = X0 + i * STEP_W;
const y = 430 - i * STEP_H;
ctx.fillStyle = i % 2 ? "#8fa39e" : "#9aada8";
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + STEP_W, y);
ctx.lineTo(x + STEP_W, y - STEP_H);
ctx.lineTo(x + STEP_W - 3, y - STEP_H);
ctx.lineTo(x + STEP_W - 3, y - 2);
ctx.lineTo(x, y - 2);
ctx.closePath();
ctx.fill();
ctx.fillStyle = "#d4dfd8";
ctx.fillRect(x + 1, y - 3, STEP_W - 4, 2);
ctx.fillStyle = "#536762";
ctx.fillRect(x + STEP_W - 2, y - STEP_H, 2, STEP_H);
}
// Side rails.
line(X0 - 8, 355, X1 + 8, 155, "#526a66", 9);
line(X0 - 8, 350, X1 + 8, 150, "#d7e1db", 3);
line(X0 - 8, 475, X1 + 8, 275, "#536a66", 7);
// Moving direction marks on the tread surface.
const sign = beltV >= 0 ? 1 : -1;
ctx.save();
ctx.strokeStyle = "#e3e9dd";
ctx.lineWidth = 2;
for (let i = 0; i < 5; i++) {
const x = 195 + i * 128 + ((clock * Math.abs(beltV) * sign) % 128);
const y = floorY(x) - 7;
ctx.beginPath();
if (sign > 0) {
ctx.moveTo(x - 7, y - 3); ctx.lineTo(x, y); ctx.lineTo(x - 7, y + 3);
} else {
ctx.moveTo(x + 7, y - 3); ctx.lineTo(x, y); ctx.lineTo(x + 7, y + 3);
}
ctx.stroke();
}
ctx.restore();
// Small motor housing at the foot.
ctx.fillStyle = "#374c48";
ctx.fillRect(93, 416, 42, 29);
ctx.fillStyle = "#d5aa50";
ctx.fillRect(101, 422, 26, 5);
}
function drawPerson(p) {
const s = Math.sin(p.a), c = Math.cos(p.a);
const axis = { x: s, y: -c }; // direction from hips toward head
const side = { x: c, y: s };
const add = (base, u, k, v, m) => ({
x: base.x + u.x * k + v.x * m,
y: base.y + u.y * k + v.y * m
});
const center = { x: p.x, y: p.y };
const shoulder = add(center, axis, -8, side, 0);
const hip = add(center, axis, 8, side, 0);
const head = add(center, axis, 20, side, 0);
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.strokeStyle = "#26363a";
ctx.lineWidth = 6;
line(shoulder.x, shoulder.y, hip.x, hip.y, "#26363a", 6);
line(shoulder.x, shoulder.y, hip.x, hip.y, p.color, 3.5);
const hand1 = add(shoulder, axis, -1, side, -13);
const hand2 = add(shoulder, axis, 4, side, 13);
line(shoulder.x, shoulder.y, hand1.x, hand1.y, "#26363a", 4);
line(shoulder.x, shoulder.y, hand2.x, hand2.y, "#26363a", 4);
line(shoulder.x, shoulder.y, hand1.x, hand1.y, p.color, 2.3);
line(shoulder.x, shoulder.y, hand2.x, hand2.y, p.color, 2.3);
const foot1 = add(hip, axis, 15, side, -6);
const foot2 = add(hip, axis, 15, side, 6);
const shoe1 = add(foot1, axis, 2, side, -3);
const shoe2 = add(foot2, axis, 2, side, 3);
line(hip.x, hip.y, foot1.x, foot1.y, "#26363a", 4);
line(hip.x, hip.y, foot2.x, foot2.y, "#26363a", 4);
line(foot1.x, foot1.y, shoe1.x, shoe1.y, "#26363a", 3);
line(foot2.x, foot2.y, shoe2.x, shoe2.y, "#26363a", 3);
ctx.fillStyle = "#e0ad83";
ctx.strokeStyle = "#26363a";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(head.x, head.y, 5.7, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
}
function draw() {
ctx.clearRect(0, 0, W, H);
drawBackground();
drawEscalator();
// Riders are drawn in consistent depth order; their motion is entirely simulated.
const ordered = [...people].sort((a, b) => a.y - b.y);
for (const p of ordered) drawPerson(p);
ctx.fillStyle = "#263b3b";
ctx.font = "600 13px system-ui, sans-serif";
ctx.fillText("SIDE VIEW", 22, 30);
ctx.fillStyle = "#425956";
ctx.font = "12px system-ui, sans-serif";
ctx.fillText("BELT SPEED " + (beltV >= 0 ? "+" : "") + beltV.toFixed(0), 22, 49);
}
function frame(now) {
const elapsed = Math.min((now - lastTime) / 1000, 0.05);
lastTime = now;
accumulator = Math.min(accumulator + elapsed, 0.12);
while (accumulator >= DT) {
step(DT);
accumulator -= DT;
}
draw();
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
})();
</script>
</body>
</html>
The page starts with 18 evenly spaced riders moving uphill. Pressing the button (or Space) rapidly reverses the belt; press it again to return to uphill motion. The belt’s change in speed pushes through each rider’s footing, and body contact and crowding determine who falls, gets blocked, or finds room to right themselves.
The only deliberate setup is the initial evenly spaced arrangement and shared starting belt speed. All figures use the same movement, collision, balance, and recovery rules; no one is assigned a fall or a recovery time. The escalator is a simplified stepped surface, but the bodies are capsules rather than fully articulated ragdolls: limb motion is drawn from body tilt, so tangled limbs, complex impacts, and detailed stair-by-stair footing are not modeled particularly well.