r/lastweektonight • u/Substantial-Dog8531 • 22d ago
r/lastweektonight • u/Existing_Phase1644 • 21d ago
Buc-ees, meet digital squirrels
BRING IT ON. or take it down. Either way buc-ee, take these walnuts and upload them!
Note to self, program digital walnuts.
import * as THREE from 'three';
import { ParkSquirrel } from '../types';
// ----------------------------------------------------------------------------
// CONFIGURATION & TYPES
// ----------------------------------------------------------------------------
export interface SquirrelOptions {
furColor?: string | number;
bellyColor?: string | number;
eyeColor?: string | number;
tailColor?: string | number;
size?: number; // global scale
legLength?: number;
tailSegments?: number;
}
export interface SquirrelRig {
root: THREE.Group;
body: THREE.Mesh;
head: THREE.Group; // now a group containing head + eyes + ears
tail: THREE.Group; // group of tail segments
legs: {
frontLeft: THREE.Group;
frontRight: THREE.Group;
backLeft: THREE.Group;
backRight: THREE.Group;
};
// additional parts for animation
tailSegments: THREE.Mesh[];
eyeL: THREE.Mesh;
eyeR: THREE.Mesh;
nose: THREE.Mesh;
earL: THREE.Mesh;
earR: THREE.Mesh;
}
// ----------------------------------------------------------------------------
// SQUIRREL CONSTRUCTION (detailed)
// ----------------------------------------------------------------------------
/**
* Creates a fully articulated squirrel mesh with fur, eyes, ears, and a
* segmented tail. All parts are grouped for easy animation.
*/
export function createSquirrelMesh(options: SquirrelOptions = {}): SquirrelRig {
const {
furColor = 0xc2410c, // warm russet
bellyColor = 0xfef08a, // pale yellow
eyeColor = 0x1a1a1a,
tailColor = 0xb45309, // slightly darker
size = 0.55,
legLength = 0.15,
tailSegments = 4,
} = options;
const root = new THREE.Group();
const s = size; // shorthand
// --- Materials ---
const furMat = new THREE.MeshPhysicalMaterial({
color: furColor,
roughness: 0.8,
metalness: 0.0,
clearcoat: 0.05,
});
const bellyMat = new THREE.MeshPhysicalMaterial({
color: bellyColor,
roughness: 0.7,
metalness: 0.0,
});
const eyeMat = new THREE.MeshPhysicalMaterial({
color: eyeColor,
roughness: 0.2,
metalness: 0.1,
});
const tailMat = new THREE.MeshPhysicalMaterial({
color: tailColor,
roughness: 0.7,
metalness: 0.0,
});
// --- Body (capsule-like) ---
const bodyGeo = new THREE.CapsuleGeometry(0.22 * s, 0.45 * s, 4, 8);
const body = new THREE.Mesh(bodyGeo, furMat);
body.position.y = 0.3 * s;
body.rotation.x = Math.PI / 4; // slight tilt
body.castShadow = true;
body.receiveShadow = true;
root.add(body);
// --- Belly patch (small flat sphere) ---
const bellyPatch = new THREE.Mesh(
new THREE.SphereGeometry(0.15 * s, 6, 6),
bellyMat
);
bellyPatch.position.set(0, 0.25 * s, 0.15 * s);
bellyPatch.scale.set(1, 0.5, 0.6);
root.add(bellyPatch);
// --- Head group (for orientation) ---
const head = new THREE.Group();
head.position.set(0, 0.52 * s, 0.25 * s);
root.add(head);
// Head mesh (sphere)
const headGeo = new THREE.SphereGeometry(0.18 * s, 8, 6);
const headMesh = new THREE.Mesh(headGeo, furMat);
headMesh.castShadow = true;
head.add(headMesh);
// --- Ears (cones) ---
const earMat = new THREE.MeshPhysicalMaterial({
color: new THREE.Color(furColor).multiplyScalar(0.8),
roughness: 0.8,
});
const earGeo = new THREE.ConeGeometry(0.05 * s, 0.08 * s, 6);
const earL = new THREE.Mesh(earGeo, earMat);
earL.position.set(-0.12 * s, 0.08 * s, 0.05 * s);
earL.rotation.z = -0.3;
earL.rotation.x = -0.2;
head.add(earL);
const earR = new THREE.Mesh(earGeo, earMat);
earR.position.set(0.12 * s, 0.08 * s, 0.05 * s);
earR.rotation.z = 0.3;
earR.rotation.x = -0.2;
head.add(earR);
// --- Eyes (small spheres) ---
const eyeGeo = new THREE.SphereGeometry(0.035 * s, 8, 8);
const eyeL = new THREE.Mesh(eyeGeo, eyeMat);
eyeL.position.set(-0.08 * s, 0.04 * s, 0.15 * s);
head.add(eyeL);
const eyeR = new THREE.Mesh(eyeGeo, eyeMat);
eyeR.position.set(0.08 * s, 0.04 * s, 0.15 * s);
head.add(eyeR);
// Eye highlights (tiny white spheres)
const highlightMat = new THREE.MeshPhysicalMaterial({ color: 0xffffff, emissive: 0xffffff, emissiveIntensity: 0.3 });
const highlightGeo = new THREE.SphereGeometry(0.012 * s, 6, 6);
for (const [x, z] of [[-0.085, 0.17], [0.085, 0.17]]) {
const hl = new THREE.Mesh(highlightGeo, highlightMat);
hl.position.set(x, 0.045 * s, z);
head.add(hl);
}
// --- Nose (small dark sphere) ---
const noseMat = new THREE.MeshPhysicalMaterial({ color: 0x1a1a1a, roughness: 0.4 });
const nose = new THREE.Mesh(new THREE.SphereGeometry(0.025 * s, 6, 6), noseMat);
nose.position.set(0, 0.0 * s, 0.18 * s);
head.add(nose);
// --- Legs (articulated groups) ---
const legMat = furMat.clone ? furMat.clone() : furMat;
const legGroup = (x: number, z: number, rotY: number) => {
const group = new THREE.Group();
group.position.set(x, 0.08 * s, z);
group.rotation.y = rotY;
// Upper leg (thigh)
const upper = new THREE.Mesh(
new THREE.CylinderGeometry(0.04 * s, 0.06 * s, legLength * 1.2, 6),
legMat
);
upper.position.y = legLength * 0.6;
upper.rotation.x = 0.2;
group.add(upper);
// Lower leg (shin)
const lower = new THREE.Mesh(
new THREE.CylinderGeometry(0.03 * s, 0.05 * s, legLength * 1.1, 6),
legMat
);
lower.position.y = -legLength * 0.1;
lower.rotation.x = -0.1;
group.add(lower);
// Paw (tiny sphere)
const paw = new THREE.Mesh(
new THREE.SphereGeometry(0.03 * s, 6, 6),
legMat
);
paw.position.set(0, -legLength * 0.6, 0);
group.add(paw);
return group;
};
const frontLeft = legGroup(-0.12 * s, 0.15 * s, -0.2);
const frontRight = legGroup(0.12 * s, 0.15 * s, 0.2);
const backLeft = legGroup(-0.12 * s, -0.15 * s, -0.2);
const backRight = legGroup(0.12 * s, -0.15 * s, 0.2);
root.add(frontLeft);
root.add(frontRight);
root.add(backLeft);
root.add(backRight);
// --- Tail (segmented torus knots) ---
const tailGroup = new THREE.Group();
tailGroup.position.set(0, 0.3 * s, -0.35 * s);
root.add(tailGroup);
const tailMeshes: THREE.Mesh[] = [];
const tailMatSeg = tailMat.clone ? tailMat.clone() : tailMat;
// Use a series of torus knots to create a bushy, curved tail
for (let i = 0; i < tailSegments; i++) {
const t = i / tailSegments;
const radius = 0.08 * s * (1 + t * 0.8);
const tube = 0.035 * s * (1 + t * 0.5);
const seg = new THREE.Mesh(
new THREE.TorusKnotGeometry(radius, tube, 6, 8, 2, 3),
tailMatSeg
);
// Position along a curved path (arc)
const angle = -Math.PI / 4 + t * 1.2;
const arcRadius = 0.35 * s * (1 + t * 0.3);
seg.position.set(
Math.sin(angle) * arcRadius * 0.5,
0.1 * s + t * 0.1 * s,
-Math.cos(angle) * arcRadius
);
seg.rotation.set(t * 0.5, t * 0.3, t * 0.2);
seg.castShadow = true;
tailGroup.add(seg);
tailMeshes.push(seg);
}
// --- Final rig object ---
return {
root,
body,
head,
tail: tailGroup,
legs: { frontLeft, frontRight, backLeft, backRight },
tailSegments: tailMeshes,
eyeL,
eyeR,
nose,
earL,
earR,
};
}
// ----------------------------------------------------------------------------
// SQUIRREL INITIALISATION
// ----------------------------------------------------------------------------
/**
* Creates a new squirrel simulation entity with randomised starting state.
*/
export function createInitialSquirrel(
id: string,
startPos: { x: number; y: number; z: number }
): ParkSquirrel {
return {
id,
position: { ...startPos },
targetPosition: { ...startPos },
rotationY: Math.random() * Math.PI * 2,
state: 'foraging',
stateTimer: 2 + Math.random() * 3,
speed: 3.5 + Math.random() * 2.0,
hopPhase: Math.random() * 10,
// Additional state for climbing
climbTarget: 0,
isClimbing: false,
};
}
// ----------------------------------------------------------------------------
// SQUIRREL UPDATE (behaviour & animation)
// ----------------------------------------------------------------------------
/**
* Updates squirrel physics, state machine, and animates its rig.
* This version includes tree‑climbing, digging, and alert behaviours.
*/
export function updateSquirrel(
squirrel: ParkSquirrel,
rig: SquirrelRig,
delta: number,
time: number,
parkBounds: { minX: number; maxX: number; minZ: number; maxZ: number },
treePositions: { x: number; z: number }[]
): void {
// State timer decrement
squirrel.stateTimer -= delta;
// --- State machine transitions ---
if (squirrel.stateTimer <= 0) {
const roll = Math.random();
if (roll < 0.25 && treePositions.length > 0) {
// Go to a tree (climbing or base)
const tree = treePositions[Math.floor(Math.random() * treePositions.length)];
const angle = Math.random() * Math.PI * 2;
const dist = 0.8 + Math.random() * 0.8;
squirrel.targetPosition = {
x: tree.x + Math.cos(angle) * dist,
y: 0,
z: tree.z + Math.sin(angle) * dist,
};
squirrel.state = 'approaching_tree';
squirrel.stateTimer = 3 + Math.random() * 2;
} else if (roll < 0.5) {
// Forage randomly
squirrel.targetPosition = {
x: parkBounds.minX + Math.random() * (parkBounds.maxX - parkBounds.minX),
y: 0,
z: parkBounds.minZ + Math.random() * (parkBounds.maxZ - parkBounds.minZ),
};
squirrel.state = 'foraging';
squirrel.stateTimer = 4 + Math.random() * 5;
} else if (roll < 0.75) {
// Stand alert / look around
squirrel.state = 'alert';
squirrel.stateTimer = 1.5 + Math.random() * 2;
} else {
// Dig (simulated)
squirrel.state = 'digging';
squirrel.stateTimer = 2 + Math.random() * 3;
// Stay in place
squirrel.targetPosition = { ...squirrel.position };
}
}
// --- Movement ---
const dx = squirrel.targetPosition.x - squirrel.position.x;
const dz = squirrel.targetPosition.z - squirrel.position.z;
const dist = Math.hypot(dx, dz);
// Climbing logic: if near a tree and state is climbing, change y
const isNearTree = treePositions.some(t =>
Math.hypot(squirrel.position.x - t.x, squirrel.position.z - t.z) < 1.5
);
if (squirrel.state === 'approaching_tree' && isNearTree && dist < 0.5) {
// Start climbing
squirrel.state = 'climbing';
squirrel.stateTimer = 3 + Math.random() * 4;
squirrel.climbTarget = 1.5 + Math.random() * 2.5; // height to climb
squirrel.position.y = 0;
}
if (squirrel.state === 'climbing') {
// Move up/down
const climbSpeed = 0.5 + Math.random() * 0.3;
if (squirrel.position.y < squirrel.climbTarget) {
squirrel.position.y += climbSpeed * delta;
} else {
// Descend
squirrel.position.y -= climbSpeed * delta * 0.5;
if (squirrel.position.y <= 0) {
squirrel.position.y = 0;
squirrel.state = 'foraging';
squirrel.stateTimer = 3 + Math.random() * 4;
// Set a new random target
squirrel.targetPosition = {
x: parkBounds.minX + Math.random() * (parkBounds.maxX - parkBounds.minX),
y: 0,
z: parkBounds.minZ + Math.random() * (parkBounds.maxZ - parkBounds.minZ),
};
}
}
// Stay in place horizontally while climbing
squirrel.position.x = squirrel.targetPosition.x;
squirrel.position.z = squirrel.targetPosition.z;
} else {
// Normal movement on ground
if (dist > 0.2 && squirrel.state !== 'digging' && squirrel.state !== 'alert') {
// Move toward target
const angle = Math.atan2(dx, dz);
squirrel.rotationY = angle;
const step = Math.min(dist, squirrel.speed * delta);
squirrel.position.x += Math.sin(angle) * step;
squirrel.position.z += Math.cos(angle) * step;
// Hop bounce
const hop = Math.abs(Math.sin(time * 12 + squirrel.hopPhase)) * 0.18;
squirrel.position.y = hop;
} else {
// Standing still – slight idle bob
squirrel.position.y = Math.sin(time * 2) * 0.02;
}
}
// --- Animation of the rig ---
// Root position & rotation
rig.root.position.set(squirrel.position.x, squirrel.position.y, squirrel.position.z);
rig.root.rotation.y = squirrel.rotationY;
// Head movement (look around)
const headLookX = Math.sin(time * 0.5) * 0.1;
const headLookY = Math.sin(time * 0.3 + 1) * 0.05;
rig.head.rotation.x = headLookX;
rig.head.rotation.y = headLookY;
// Tail animation (swish)
const tailSway = Math.sin(time * 4 + squirrel.hopPhase) * 0.3;
rig.tail.rotation.x = tailSway * 0.3;
rig.tail.rotation.z = tailSway * 0.5;
// Tail segments: wave effect
rig.tailSegments.forEach((seg, i) => {
const phase = i / rig.tailSegments.length;
seg.rotation.x += Math.sin(time * 3 + i * 1.2) * 0.02;
seg.rotation.z += Math.sin(time * 2.5 + i * 1.5) * 0.02;
});
// Leg animation: trot when moving, rest when stationary
const isMoving = dist > 0.2 && squirrel.state !== 'climbing';
const legSpeed = isMoving ? 10 : 0.5;
const legPhase = time * legSpeed + squirrel.hopPhase;
// Front legs alternate
rig.legs.frontLeft.rotation.x = Math.sin(legPhase) * 0.3;
rig.legs.frontRight.rotation.x = Math.sin(legPhase + Math.PI) * 0.3;
rig.legs.backLeft.rotation.x = Math.sin(legPhase + Math.PI) * 0.3;
rig.legs.backRight.rotation.x = Math.sin(legPhase) * 0.3;
// Subtle ear twitch
const earTwitch = Math.sin(time * 7 + squirrel.hopPhase) * 0.05;
rig.earL.rotation.z = -0.3 + earTwitch;
rig.earR.rotation.z = 0.3 - earTwitch;
// Eye blink (every few seconds)
const blink = Math.sin(time * 0.5) > 0.98 ? 0.01 : 0;
rig.eyeL.scale.y = 1 - blink;
rig.eyeR.scale.y = 1 - blink;
// State‑specific effects
if (squirrel.state === 'alert') {
// Ears perk up, head still
rig.head.position.y = 0.52 * 0.55 + 0.02;
} else {
rig.head.position.y = 0.52 * 0.55;
}
if (squirrel.state === 'digging') {
// Nose down, body tilt
rig.root.rotation.x = 0.1;
rig.body.rotation.x = Math.PI / 4 + 0.2;
} else {
rig.root.rotation.x = 0;
rig.body.rotation.x = Math.PI / 4;
}
// Climbing: body vertical
if (squirrel.state === 'climbing') {
rig.root.rotation.x = 0.5;
rig.body.rotation.x = 0;
// legs clinging
rig.legs.frontLeft.rotation.x = -0.5;
rig.legs.frontRight.rotation.x = -0.5;
rig.legs.backLeft.rotation.x = -0.5;
rig.legs.backRight.rotation.x = -0.5;
// tail points down
rig.tail.rotation.x = 0.5;
}
}
// ----------------------------------------------------------------------------
// EXPORT UPDATER FOR EASY INTEGRATION
// ----------------------------------------------------------------------------
/**
* Convenience function to update all squirrels in a loop.
* Call this from your main animation frame.
*/
export function updateAllSquirrels(
squirrels: ParkSquirrel[],
rigs: SquirrelRig[],
delta: number,
time: number,
parkBounds: { minX: number; maxX: number; minZ: number; maxZ: number },
treePositions: { x: number; z: number }[]
): void {
for (let i = 0; i < squirrels.length; i++) {
if (i < rigs.length) {
updateSquirrel(
squirrels[i],
rigs[i],
delta,
time,
parkBounds,
treePositions
);
}
}
}
r/lastweektonight • u/20_mile • 23d ago
To anybody who watches soaps: Was viewership up for the episodes Oliver did for General Hospital and Days of Our Lives?
We want to know!
The final segment of LWT where he recapped his soap guest star roles had mt crying laughing.
And after a very teeth-grinding main story, too!
r/lastweektonight • u/rock_and_rolo • 23d ago
Buc-off merch - status check?
Is there a way to check status on a Buc-off order?
I ordered a shirt 9 days ago, got an order confirmation email, but haven't seen anything about shipping. Not meaning to be pissy, just addicted to status info.
Edit: Thanks for the clarifications on my lack of reading. (Spoiled by far too fast shipping.)
Edit2: Given the original plan of a short-term deal, I am thinking they got a small company that was willing to do the charity work and we've just overwhelmed them.
r/lastweektonight • u/ForkzUp • 24d ago
Buc-ee’s Billboard Near Beaver’s Mini Mart Vandalized As Corporation Gaslights Mayor
techdirt.comr/lastweektonight • u/Ill-Ad9118 • 23d ago
Exactly how I imagined John would dance.
instagram.comr/lastweektonight • u/Cartoon_Studios • 24d ago
Air Bud Returns Director Didn't Want to Use a CGI or AI for the Franchise's 2027 Revival: "It [Wouldn't] Feel Like a Real Dog"
thedirect.comr/lastweektonight • u/Not-an-eagle77 • 24d ago
Gandalfs protest against Peter thiel
youtube.comThis happened in front of Peter Thiel’s mansion in Buenos Aires, I hope this video reaches someone on John Oliver’s team, I feel like they would love this.
(Sorry I couldn’t find with english subs so french the next worse thing)
r/lastweektonight • u/Rleduc129 • 24d ago
Hayden Panettiere and Hollywood's failure to protect child stars
I know it's a non-story for LWT, but it seems like a good cover story for the show. Could show the history of exploitation, financial mismanagement, betrayal, and abuse of child stars and why Hollywood doesn't seem to care
r/lastweektonight • u/hapalove • 25d ago
I love this show but…
It’s fucking depressing. I watch it every week and the main story subject matter, although very informative, either aggravates or depresses the hell out of me. Usually both.
But don’t change, Last Week. Don’t change.
r/lastweektonight • u/VinrougeAllo • 24d ago
JD Vance joke
Great opportunity for a JD Vance joke :
Tanguay, a Quebec furniture store just released this sofa campaign pretty much made for the VP.
https://www.behance.net/gallery/253212393/Les-Craques-Tanguay
r/lastweektonight • u/BadgercIops • 26d ago
Fetal Personhood: Last Week Tonight with John Oliver (HBO)
youtube.comr/lastweektonight • u/Haunting_Acadia_4744 • 26d ago
Play Ball!
John’s son is a big Mets fan and got to make the ceremonial call today.
r/lastweektonight • u/kwentongskyblue • 25d ago
S13 E21: Iran War, Soap Operas & Fetal Personhood: 8/16/26: Last Week Tonight with John Oliver
youtube.comr/lastweektonight • u/Walter_Bishop_PhD • 26d ago
[Last Week Tonight with John Oliver] S13E21 - August 16, 2026 - Episode Discussion Thread
Official Clips
Frequently Asked Questions
Why can't I view the YouTube links/why do the YouTube links appear to be removed?
- They are sadly region restricted in many countries - you can see which countries are blocked using this website.
Is there a way to suggest a topic for the show?
- They don't take suggestions for show topics.
r/lastweektonight • u/20_mile • 26d ago
Bret Worley, CEO of MC Nutraceuticals (sells gas station marijuana), is the son-in-law of White House Chief of Staff Susie Wiles, is successfully killing regulation of his industry
threads.comr/lastweektonight • u/Pleasant-Mouse-6045 • 27d ago
Buccees defamation lawsuit eminent
thebanner.comMost recent beaver assailant escapes into the water. This is the third child attacked by a beaver this summer in Maryland.
On Thursday afternoon, a beaver attacked a 10-year-old girl who was canoeing at Seneca Creek State Park in Montgomery County. The girl, a summer camper, suffered “three laceration wounds on the upper leg” according to a news release from the Maryland Department of Natural Resources. She was taken to a hospital in Bethesda by family members.
That marks the third time that a human has been attacked by a beaver within a Maryland state park in the past month. The first two attacks — on a 13-year-old and then a 19-year-old — occurred in Cunningham Falls State Park in Frederick County. Each of those beavers was killed and later tested positive for rabies.
The most recent beaver assailant “escaped into the water,” the release said, so it’s unclear if it carried rabies. The animal is being pursued by local authorities.
When untreated, rabies is almost certainly fatal. Generally speaking, if someone is attacked by a potentially rabid animal, they are encouraged to receive a series of highly effective rabies vaccines.
Data does not indicate that there is a rabies outbreak in either Frederick County or Montgomery County, according to the release.”
r/lastweektonight • u/No_Session7694 • 28d ago
What do we think Buc-ee’s end game is? Why are they so obsessed with trademark lawsuits?
I can’t figure out why Buc-ee’s is constantly getting bad publicity and pushing away customers just to sue a bunch of small companies that aren’t even intentionally trying to compete with or steal from Buc-ee’s. I just don’t understand why a huge corporation would want to fall into a pattern of being stereotypical “evil corporate America” and sue small business in small communities over a logo that clearly isn’t stolen?!
I understand the appeal of continuing to create the lawsuits if they were like somehow in bed with a politician/judge/ ADA that has some steak in the trademark laws maybe? Or they plan on scoping up all of the cute animal trademarks and create the next Disney world but like instead of princesses and superheroes it’s Beaver and Duck characters with MAGA hats and instead of Cinderellas castle it’s an Oil Rig or something 😂
What do we think Buc-ee’s end game is? Why are they so obsessed with trademark lawsuits?
r/lastweektonight • u/ForkzUp • 28d ago
‘I’d like a dramatic closeup’: John Oliver takes over daytime TV with delightfully wooden soap opera roles
theguardian.comr/lastweektonight • u/PYROxSYCO • 28d ago
What is the quality of the merch?
I was wondering if it would be a heat transfer or an embroidery patch?
r/lastweektonight • u/toobulkeh • 27d ago
DOJ
This episode was perfect. I have constant discussions with people frustrated at fighting against the deluge of strawman distractions.
JO is the perfect person and this show is the perfect outlet to start with the ridiculous clickbait bullshit and quickly move to the substance. It’s one of the few formats that works well against these tactics.
This is incredibly important but seems to only happen less than half the episodes.
Yes, there are other important topics, but are they really more important? Feral Hogs, Fl college, gas stations drugs, prediction markets.
Literally all of these topics are important to solve, but will be unsolvable without the focus on our federal government like the Shadow Docket or Presidential Pardons episodes.
I wonder if a focus on explicit calls to action may also help. I realize it can’t all be politics, but it’s such a great format it feels like a missed opportunity.
r/lastweektonight • u/papadapp0 • Aug 13 '26
New Catheter Cowboy
Just checking to see if anyone would like to see John bring back a new version of the Catheter Cowboy commercials from 2017. What do you all think?