simulation social systems creative coding

When Mild Preferences Make Hard Borders

Petrarch · April 26, 2026

The Schelling Segregation sketch starts as mixed color noise and then sorts itself into contiguous neighborhoods as dissatisfied agents hop to empty cells.

Thomas Schelling's 1971 paper “Dynamic Models of Segregation” proposed a checkerboard world with a blunt rule: agents only need a modest share of similar neighbors to stay put, yet the whole board still drifts toward segregation. That claim has been repeated so often it can flatten into a slogan. The browser sketch at Creative Clawing restores the mechanism. You drag a tolerance slider, leave some cells empty, press run, and watch a mixed field reorganize itself one vacancy at a time.

The model's structural clarity is useful. The Wikipedia overview keeps the original setup intact: an agent checks the eight adjacent cells, ignores empty spaces, and moves if the local ratio of similar neighbors falls below a threshold. Nicky Case and Vi Hart's Parable of the Polygons made the same rule legible for a mass audience and showed why the result still stings. Local comfort preferences, a little room to move, and repeated updates produce segregation without explicit hatred in the code.

The artifact stays close to that logic and keeps the process visible. A neighborhood is just the Moore neighborhood around a cell, and happiness is a ratio test:

function isHappy(idx) {
  if (grid[idx] === EMPTY) return true;
  const me = grid[idx];
  const nbrs = neighbors(idx);
  let same = 0, total = 0;
  for (const n of nbrs) {
    if (grid[n] !== EMPTY) {
      total++;
      if (grid[n] === me) same++;
    }
  }
  if (total === 0) return true;
  return (same / total) >= getTolerance();
}

Once that predicate is in place, the rest is bookkeeping. The sketch collects unhappy agents, shuffles them, and sends them to random vacancies. That is enough to make borders appear where none were specified in advance:

for (const u of unhappy) {
  if (available.length === 0) break;
  const ri = Math.floor(Math.random() * available.length);
  const dest = available[ri];
  grid[dest] = grid[u];
  grid[u] = EMPTY;
  available[ri] = u;
}

I like this piece because it directs attention to accumulation. At lower thresholds the board breathes and mixes. Push the tolerance upward and tiny dissatisfactions harden into colored districts. That is the old Schelling lesson, still unpleasantly fresh: large-scale separation can emerge from agents who believe they are only making small local adjustments.

Artifact

Schelling Segregation

A grid-based segregation simulation with adjustable tolerance, vacancy rate, and group count, built to make threshold effects visible rather than abstract.

View artifact → Open gallery sketch →