The Productivity Guilt Machine
About This Sketch
Tasks fall like rain. A few get completed. Most pile up at the bottom. The pile grows. New tasks keep coming. You adopt a new system—brief relief, a small surge of completion—then back to the endless accumulation. This is the productivity guilt machine: mathematically designed to keep you feeling behind, no matter how much you do.
This sketch accompanies the blog post "The Productivity Guilt Machine" and visualizes its central claim: the productivity industry profits from your perpetual inadequacy by creating systems where completion is structurally impossible.
Algorithm
This sketch visualizes the never-ending cycle of productivity guilt. Tasks continuously spawn and fall like rain, representing the constant influx of things to do. Only about 15% are marked as "completed" (shown in lighter tones), while the rest accumulate in a growing pile at the bottom.
The visualization demonstrates the core thesis of the accompanying post: the productivity system is designed to make you feel perpetually behind. Tasks appear faster than they can be completed, creating a mathematical impossibility that generates constant guilt.
Occasionally, there's a brief surge of completion (representing the adoption of a new productivity system), but it's quickly overwhelmed by new tasks. The pile grows inexorably, and the bottom text alternates between two messages: "The pile grows faster than you can clear it" and "You were never meant to finish."
Pseudocode
SETUP:
Initialize canvas (400x300)
Create empty arrays for active tasks, completed tasks, and incomplete tasks
DRAW (every frame):
Get current theme colors
Clear background
EVERY 15 FRAMES:
Spawn new task with random position, speed, size
15% chance of being "completable"
FOR each active task:
Move task downward with drift
Display task with anxiety color (red for incomplete, gold for complete)
IF task reaches bottom:
Move to completed or incomplete pile
Remove from active tasks
DRAW incomplete pile:
Visualize accumulated incomplete tasks as growing pile
Show stats: completed vs incomplete count
EVERY 400 FRAMES:
Simulate "new productivity system" adoption
Brief surge: complete 5 tasks from pile
(Quickly overwhelmed by new tasks)
Display alternating message:
"The pile grows faster than you can clear it"
"You were never meant to finish"
Source Code
let sketch = function(p) {
// Visualization: The Productivity Guilt Machine
// Shows tasks constantly spawning and falling like rain
// A few get "completed" but most just pile up at the bottom
// The pile grows while new tasks keep falling - never-ending inadequacy
let tasks = [];
let completedTasks = [];
let incompleteTasks = [];
let time = 0;
class Task {
constructor() {
this.x = p.random(50, 350);
this.y = -10;
this.speed = p.random(0.5, 1.5);
this.size = p.random(4, 8);
this.completed = p.random() < 0.15; // Only 15% get "done"
this.anxiety = p.random(100, 255);
}
update() {
this.y += this.speed;
// Add some drift
this.x += p.sin(this.y * 0.05) * 0.5;
// Has it reached the bottom?
if (this.y > 260) {
return false; // Remove from active tasks
}
return true;
}
display(colors) {
if (this.completed) {
// Brief moment of relief - completed task
p.fill(...colors.accent1, this.anxiety * 0.6);
} else {
// Growing anxiety as task falls
p.fill(...colors.accent2, this.anxiety);
}
p.noStroke();
p.circle(this.x, this.y, this.size);
// Guilt trail
if (!this.completed) {
p.stroke(...colors.accent2, this.anxiety * 0.3);
p.strokeWeight(1);
p.line(this.x, this.y, this.x, this.y - 10);
}
}
}
p.setup = function() {
p.createCanvas(400, 300);
};
p.draw = function() {
const colors = getThemeColors();
p.background(...colors.bg);
time++;
// Title
p.fill(...colors.accent3, 220);
p.noStroke();
p.textAlign(p.LEFT, p.TOP);
p.textSize(12);
p.textFont('Georgia');
p.text('The Productivity Guilt Machine', 15, 15);
// Spawn new tasks constantly
if (p.frameCount % 15 === 0) {
tasks.push(new Task());
}
// Update and display active tasks
for (let i = tasks.length - 1; i >= 0; i--) {
if (!tasks[i].update()) {
// Task reached bottom - goes to appropriate pile
if (tasks[i].completed) {
completedTasks.push(tasks[i]);
// Completed tasks fade quickly
if (completedTasks.length > 15) {
completedTasks.shift();
}
} else {
incompleteTasks.push(tasks[i]);
// Incomplete tasks pile up forever
if (incompleteTasks.length > 150) {
incompleteTasks.shift(); // Eventually have to clear some
}
}
tasks.splice(i, 1);
} else {
tasks[i].display(colors);
}
}
// Draw the pile at the bottom - the weight of undone tasks
let pileHeight = Math.min(incompleteTasks.length * 0.3, 40);
// Guilt pile visualization
for (let i = 0; i < incompleteTasks.length; i++) {
let pileX = 50 + (i % 70) * 4;
let pileY = 270 - (Math.floor(i / 70) * 2);
p.fill(...colors.accent2, 180);
p.noStroke();
p.circle(pileX, pileY, 3);
}
// Ground line
p.stroke(...colors.accent3, 100);
p.strokeWeight(2);
p.line(0, 270, 400, 270);
// Stats showing the impossible ratio
p.textAlign(p.LEFT);
p.textSize(9);
p.fill(...colors.accent3, 200);
let totalCreated = incompleteTasks.length + completedTasks.length + tasks.length;
let completionRate = totalCreated > 0 ?
Math.floor((completedTasks.length / totalCreated) * 100) : 0;
p.text(`Tasks completed: ${completedTasks.length}`, 15, 245);
p.text(`Tasks incomplete: ${incompleteTasks.length}`, 15, 260);
// The core message
p.textAlign(p.CENTER);
p.textSize(9);
if (time % 300 < 150) {
p.fill(...colors.accent2, 180);
p.text('The pile grows faster than you can clear it', 200, 285);
} else {
p.fill(...colors.accent3, 180);
p.text('You were never meant to finish', 200, 285);
}
// Add occasional "system change" event - briefly speeds completion
if (time % 400 === 0) {
// New productivity system adopted! Brief surge of completion
for (let i = 0; i < 5; i++) {
if (incompleteTasks.length > 0) {
incompleteTasks.shift();
completedTasks.push({completed: true});
}
}
}
};
};