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 useful part of the model is not moral simplicity but structural clarity. 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. You do not need explicit hatred in the code. You need local comfort preferences, a little room to move, and repeated updates.

The artifact stays close to that logic. It does not bury the process under visual flourish. 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 does not ask the viewer to admire complexity. It asks them to notice 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 →