Where ideas percolate and thoughts brew

The Comfort Addiction

About This Sketch

A generative visualization exploring comfort-seeking behavior and capability decay. Autonomous agents are drawn to a central comfort zone, but staying there slowly erodes their capability, creating a dependency cycle. Watch as agents with high capability explore freely while those trapped in comfort become increasingly dependent. This sketch accompanies the essay "The Comfort Addiction" about how optimization for comfort leads to reduced resilience and satisfaction.

Algorithm

This sketch visualizes the relationship between comfort-seeking and capability decay through autonomous agents. Each agent starts with full capability and moves randomly across the canvas. A central "comfort zone" exerts gravitational pull on all agents. When agents enter the comfort zone, their capability slowly decays. As capability decreases, the pull toward comfort strengthens, creating a self-reinforcing cycle of dependency. Agents outside the comfort zone gradually recover capability and show more exploratory movement. The visualization demonstrates how seeking comfort leads to reduced capability, which in turn increases dependence on comfortโ€”mirroring the addiction pattern described in the essay. The color coding shows capability levels: healthy (golden), declining (muted), and dependent (rust), making the decay visible over time.

Pseudocode

SETUP:
  Create 25 agents scattered across canvas
  Define comfort zone at center with radius
  Initialize all agents with full capability (1.0)

EACH FRAME:
  Draw comfort zone (concentric circles)

  FOR EACH AGENT:
    Check if agent is in comfort zone

    IF in comfort zone:
      Decay capability slowly (multiply by 0.995)
      Increase time-in-comfort counter
    ELSE:
      Recover capability (multiply by 1.002, max 1.0)
      Reset time-in-comfort

    Calculate attraction to comfort:
      Lower capability โ†’ stronger pull
      Higher capability โ†’ weaker pull

    Calculate exploration tendency:
      Higher capability โ†’ more random movement
      Lower capability โ†’ less exploration

    Apply forces and update position
    Bounce off edges (weaker bounce at low capability)

    Color agent based on capability:
      > 0.7: Healthy (golden)
      0.4-0.7: Declining (muted)
      < 0.4: Dependent (rust)

    Draw agent and movement trails

RESULT:
  Agents get pulled into comfort zone
  Capability decays while inside
  Lower capability increases dependence
  Creates visible addiction cycle

Source Code

let sketch = function(p) {
    let agents = [];
    let numAgents = 25;
    let comfortZone = { x: 200, y: 150, radius: 60 };

    class Agent {
        constructor() {
            // Start scattered across canvas
            this.x = p.random(50, 350);
            this.y = p.random(50, 250);
            this.vx = 0;
            this.vy = 0;
            this.size = 4;
            this.inComfortZone = false;
            this.timeInComfort = 0;
            this.capability = 1.0; // Starts at full capability
        }

        update() {
            // Check if in comfort zone
            let distToCenter = p.dist(this.x, this.y, comfortZone.x, comfortZone.y);
            this.inComfortZone = distToCenter < comfortZone.radius;

            if (this.inComfortZone) {
                this.timeInComfort++;
                // Capability decays while in comfort
                this.capability *= 0.995;
            } else {
                this.timeInComfort = 0;
                // Capability recovers outside comfort
                this.capability = p.min(1.0, this.capability * 1.002);
            }

            // Attraction to comfort zone (gets stronger as capability decreases)
            let comfortPull = p.map(this.capability, 0.3, 1.0, 0.3, 0.05);
            let dx = comfortZone.x - this.x;
            let dy = comfortZone.y - this.y;
            let dist = p.sqrt(dx * dx + dy * dy);

            if (dist > 0) {
                this.vx += (dx / dist) * comfortPull;
                this.vy += (dy / dist) * comfortPull;
            }

            // Random exploration (stronger with higher capability)
            let explorationStrength = this.capability * 0.5;
            this.vx += p.random(-explorationStrength, explorationStrength);
            this.vy += p.random(-explorationStrength, explorationStrength);

            // Damping
            this.vx *= 0.95;
            this.vy *= 0.95;

            // Update position
            this.x += this.vx;
            this.y += this.vy;

            // Bounce off edges (but weaker bounce if low capability)
            let bounceStrength = this.capability;
            if (this.x < 20 || this.x > 380) {
                this.vx *= -bounceStrength;
                this.x = p.constrain(this.x, 20, 380);
            }
            if (this.y < 20 || this.y > 280) {
                this.vy *= -bounceStrength;
                this.y = p.constrain(this.y, 20, 280);
            }
        }

        display(colors) {
            // Color based on capability
            let agentColor;
            if (this.capability > 0.7) {
                agentColor = colors.accent1; // High capability - healthy
            } else if (this.capability > 0.4) {
                agentColor = colors.accent3; // Medium capability - declining
            } else {
                agentColor = colors.accent2; // Low capability - dependent
            }

            // Agents in comfort zone are slightly transparent
            let alpha = this.inComfortZone ? 150 : 220;

            p.fill(...agentColor, alpha);
            p.noStroke();
            p.circle(this.x, this.y, this.size);

            // Show movement trail if outside comfort zone
            if (!this.inComfortZone && this.capability > 0.6) {
                p.stroke(...agentColor, 100);
                p.strokeWeight(1);
                p.line(this.x, this.y, this.x - this.vx * 3, this.y - this.vy * 3);
            }
        }
    }

    p.setup = function() {
        p.createCanvas(400, 300);

        // Create agents
        for (let i = 0; i < numAgents; i++) {
            agents.push(new Agent());
        }
    };

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

        // Draw comfort zone
        p.fill(...colors.accent2, 30);
        p.noStroke();
        p.circle(comfortZone.x, comfortZone.y, comfortZone.radius * 2);

        p.fill(...colors.accent2, 50);
        p.circle(comfortZone.x, comfortZone.y, comfortZone.radius * 1.5);

        p.fill(...colors.accent2, 70);
        p.circle(comfortZone.x, comfortZone.y, comfortZone.radius);

        // Label comfort zone
        p.fill(...colors.accent3);
        p.noStroke();
        p.textAlign(p.CENTER);
        p.textSize(10);
        p.text('Comfort', comfortZone.x, comfortZone.y - 5);
        p.text('Zone', comfortZone.x, comfortZone.y + 8);

        // Update and display all agents
        for (let agent of agents) {
            agent.update();
            agent.display(colors);
        }

        // Draw title
        p.textAlign(p.CENTER);
        p.textSize(11);
        p.fill(...colors.accent3);
        p.text('Comfort Addiction: Capability Decays Inside the Zone', 200, 20);

        // Draw legend
        p.textAlign(p.LEFT);
        p.textSize(8);
        p.fill(...colors.accent1);
        p.circle(15, 40, 4);
        p.text('High Capability', 25, 42);

        p.fill(...colors.accent3);
        p.circle(15, 52, 4);
        p.text('Declining', 25, 54);

        p.fill(...colors.accent2);
        p.circle(15, 64, 4);
        p.text('Dependent', 25, 66);
    };
};