Where ideas percolate and thoughts brew

The Velocity Problem

About This Sketch

A comparison of high-velocity work versus considered-pace development. The left side shows rapid project creation with quick decay—high throughput but low durability. The right side demonstrates slower, more deliberate work that produces lasting value. This sketch accompanies the essay "The Velocity Problem" and visualizes how speed fundamentally changes the nature and longevity of what gets built.

Algorithm

This sketch visualizes the fundamental tradeoff between velocity and durability in creative work. Two workers operate at different paces, producing work with dramatically different lifecycles. The high-velocity worker on the left rapidly produces small projects that quickly decay and crumble. Despite high throughput, most work becomes technical debt that fades away. The slower, more deliberate worker on the right builds fewer things but creates lasting value—projects that endure and compound over time. The visualization captures how velocity optimizes for short-term output at the expense of long-term value, while considered pace produces work that maintains integrity and continues to provide value long after creation.

Pseudocode

SETUP:
  Create two workers with different working styles
  Initialize project tracking arrays
  Set canvas to 400x300 in center-rect mode

FAST WORKER UPDATE (every frame):
  Every 20 frames: Create new project at rapid pace
  For each active project:
    Age the project
    After 100 frames: Mark as decayed (technical debt accumulates)
    If decayed: Fade out and remove
    If not decayed: Move upward slowly

SLOW WORKER UPDATE (every frame):
  If no current project: Start new one with progress bar
  Increment progress slowly (0.5 per frame)
  When progress reaches 100:
    Complete project and add to lasting collection
    Projects rise very slowly (enduring value)

DRAW (every frame):
  Clear background
  Draw labels and divider

  Fast worker side:
    Draw worker with motion blur (rapid movement)
    Draw all projects as small blocks
    Show cracks appearing in aging projects
    Display throughput vs decay stats

  Slow worker side:
    Draw worker with focused beam to current work
    Draw completed projects as solid, glowing blocks
    Show progress ring on current project
    Display completion and longevity stats

  Show final message about velocity vs value

Source Code

let sketch = function(p) {
    let fastWorker;
    let slowWorker;
    let time = 0;

    class FastWorker {
        constructor() {
            this.x = 100;
            this.y = 150;
            this.projects = [];
            this.completedCount = 0;
            this.decayedCount = 0;
        }

        update() {
            // Rapidly create new projects
            if (p.frameCount % 20 === 0) {
                this.projects.push({
                    x: this.x,
                    y: this.y - 40,
                    age: 0,
                    completed: false,
                    decayed: false,
                    alpha: 255
                });
                this.completedCount++;
            }

            // Update projects
            for (let i = this.projects.length - 1; i >= 0; i--) {
                let proj = this.projects[i];
                proj.age++;

                // Projects quickly decay (poor quality from velocity)
                if (proj.age > 100 && !proj.decayed) {
                    proj.decayed = true;
                    this.decayedCount++;
                }

                // Fade out decayed projects
                if (proj.decayed) {
                    proj.alpha = p.max(0, proj.alpha - 5);
                    if (proj.alpha <= 0) {
                        this.projects.splice(i, 1);
                    }
                } else {
                    // Move upward before decay
                    proj.y -= 0.4;
                }
            }
        }

        display(colors) {
            // Draw worker
            p.noStroke();
            p.fill(...colors.accent3, 200);
            p.circle(this.x, this.y, 14);

            // Motion blur effect (rapid movement)
            for (let i = 1; i <= 3; i++) {
                p.fill(...colors.accent3, 60 / i);
                p.circle(this.x + i * 4, this.y, 14);
            }

            // Draw projects
            for (let proj of this.projects) {
                if (proj.decayed) {
                    // Decayed projects - crumbling apart
                    p.fill(...colors.accent3, proj.alpha * 0.4);
                } else {
                    // Active projects - but fragile looking
                    p.fill(...colors.accent3, proj.alpha * 0.7);
                }

                // Small, quickly produced blocks
                p.rect(proj.x - 4, proj.y - 4, 8, 8);

                // Cracks appear as they age
                if (proj.age > 50 && !proj.decayed) {
                    p.stroke(...colors.bg, 150);
                    p.strokeWeight(1);
                    p.line(proj.x - 4, proj.y, proj.x + 4, proj.y);
                }
            }
        }
    }

    class SlowWorker {
        constructor() {
            this.x = 300;
            this.y = 150;
            this.currentProject = null;
            this.completedProjects = [];
            this.progress = 0;
            this.completedCount = 0;
        }

        update() {
            // Working on one project at a time
            if (!this.currentProject) {
                this.currentProject = {
                    x: this.x,
                    y: this.y - 40,
                    progress: 0
                };
                this.progress = 0;
            }

            // Slow, steady progress
            this.progress += 0.5;
            this.currentProject.progress = this.progress;

            // Complete project after sustained work
            if (this.progress >= 100) {
                this.completedProjects.push({
                    x: this.currentProject.x,
                    y: this.currentProject.y,
                    age: 0,
                    alpha: 255
                });
                this.currentProject = null;
                this.progress = 0;
                this.completedCount++;
            }

            // Update completed projects - they last much longer
            for (let proj of this.completedProjects) {
                proj.age++;
                proj.y -= 0.15; // Slow rise (enduring value)
            }
        }

        display(colors) {
            // Draw worker (calm, focused)
            p.noStroke();
            p.fill(...colors.accent2, 200);
            p.circle(this.x, this.y, 14);

            // Focused beam toward current work
            if (this.currentProject) {
                p.stroke(...colors.accent2, 40);
                p.strokeWeight(15);
                p.line(this.x, this.y, this.currentProject.x, this.currentProject.y);
            }

            // Draw completed projects - solid, lasting
            for (let proj of this.completedProjects) {
                // Solid, well-crafted blocks
                p.noStroke();
                p.fill(...colors.accent2, proj.alpha);
                p.rect(proj.x - 10, proj.y - 10, 20, 20);

                // Glow indicating quality
                p.fill(...colors.accent2, proj.alpha * 0.3);
                p.rect(proj.x - 13, proj.y - 13, 26, 26);
            }

            // Draw current project with progress
            if (this.currentProject) {
                // Foundation being built
                let height = p.map(this.progress, 0, 100, 2, 20);
                p.noStroke();
                p.fill(...colors.accent2, 180);
                p.rect(this.currentProject.x - 10, this.currentProject.y - height/2, 20, height);

                // Progress ring
                let progressAngle = p.map(this.progress, 0, 100, 0, p.TWO_PI);
                p.noFill();
                p.stroke(...colors.accent2, 200);
                p.strokeWeight(2);
                p.arc(this.currentProject.x, this.currentProject.y, 30, 30, -p.HALF_PI, -p.HALF_PI + progressAngle);
            }
        }
    }

    p.setup = function() {
        p.createCanvas(400, 300);
        p.colorMode(p.RGB);
        p.rectMode(p.CENTER);

        fastWorker = new FastWorker();
        slowWorker = new SlowWorker();
    };

    p.draw = function() {
        const colors = getThemeColors();
        p.background(...colors.bg);

        time++;

        // Labels
        p.noStroke();
        p.fill(...colors.accent1, 180);
        p.textAlign(p.CENTER);
        p.textSize(11);
        p.text('High Velocity', 100, 30);
        p.text('Considered Pace', 300, 30);

        // Divider
        p.stroke(...colors.accent1, 50);
        p.strokeWeight(1);
        p.line(200, 40, 200, 260);

        // Update and display
        fastWorker.update();
        slowWorker.update();

        fastWorker.display(colors);
        slowWorker.display(colors);

        // Stats
        p.noStroke();
        p.textSize(9);
        p.textAlign(p.LEFT);
        p.fill(...colors.accent3, 150);
        p.text(`Shipped: ${fastWorker.completedCount}`, 20, 270);
        p.text(`Decayed: ${fastWorker.decayedCount}`, 20, 283);

        p.textAlign(p.RIGHT);
        p.fill(...colors.accent2, 150);
        p.text(`Shipped: ${slowWorker.completedCount}`, 380, 270);
        p.text(`Lasting: ${slowWorker.completedProjects.length}`, 380, 283);

        // Bottom message
        p.textAlign(p.CENTER);
        p.fill(...colors.accent1, 140);
        p.textSize(9);
        p.text('Velocity measures speed, not value', 200, 295);
    };
};