The Legibility Game
About This Sketch
A competitive simulation showing two work styles: quality (complex, organic, hard to perceive) versus legibility (clean, geometric, easy to evaluate). Rewards fall and agents compete to capture them, but the legible agent has a larger "capture radius" because its work is more visible. Watch how legibility systematically wins despite quality doing equally valuable work. This sketch explores how institutions optimize for appearances over substance.
Algorithm
This sketch visualizes the disconnect between actual value (quality work) and perceived value (legible work) in professional environments. Two agents produce different types of work while competing for falling rewards.
The Quality Agent (left, circular) produces complex, organic work represented by scattered particles. This work is valuable but harder to perceive—the agent has a smaller "capture radius" for rewards.
The Legibility Agent (right, square) produces clean, geometric work represented by polished rectangles. This work is more visible—the agent has a larger capture radius, capturing more rewards despite not necessarily doing better work.
Rewards fall from the top periodically. The visualization demonstrates how legibility (ease of evaluation) often matters more than quality (actual value) in determining success. The Legibility Agent consistently captures more rewards because its work is more visible, not because it's better.
This accompanies the blog post "The Legibility Game" which explores how institutions systematically reward appearances over substance.
Pseudocode
SETUP:
Initialize canvas (400x300)
Create Quality Agent (left side, circular, organic work style)
Create Legibility Agent (right side, square, geometric work style)
Initialize reward tracking systems
DRAW (every frame):
Get current theme colors
Clear background
// Spawn rewards periodically
IF frame is multiple of 60:
Create new reward at random X position, top of screen
// Update all rewards
FOR each reward:
IF not captured:
Move reward downward
Check if Legibility Agent can capture (large radius)
ELSE check if Quality Agent can capture (small radius)
IF captured:
Increment respective score
Display reward if still visible
Remove if off-screen
// Agents produce work artifacts
FOR each agent (every 30 frames):
IF Quality Agent:
Generate multiple small, scattered organic particles
IF Legibility Agent:
Generate single large, centered geometric shape
// Display agents and their work
Draw agents with appropriate styling
Update and fade work particles over time
Display current scores
Show labels and explanatory text
Source Code
let sketch = function(p) {
// Visualization: Legibility vs. Quality
// Two agents competing for rewards
// Left: "Quality Agent" - does complex, deep work (messy, organic shapes)
// Right: "Legibility Agent" - produces clean, impressive-looking output (geometric, polished)
// Top: "Reward" tokens that fall down
// The Legibility Agent captures most rewards despite Quality Agent doing better work
// Shows the disconnect between actual value and perceived value
let qualityAgent, legibilityAgent;
let rewards = [];
let qualityScore = 0;
let legibilityScore = 0;
let frame = 0;
class Agent {
constructor(x, type) {
this.x = x;
this.y = 220;
this.type = type; // 'quality' or 'legibility'
this.workParticles = [];
this.capturedRewards = 0;
}
doWork() {
// Generate work artifacts
if (frame % 30 === 0) {
if (this.type === 'quality') {
// Complex, organic work - harder to see value
for (let i = 0; i < 3; i++) {
this.workParticles.push({
x: this.x + p.random(-15, 15),
y: this.y + p.random(-15, 15),
size: p.random(3, 8),
alpha: 255,
age: 0
});
}
} else {
// Clean, geometric work - easy to see
this.workParticles.push({
x: this.x,
y: this.y - 20,
size: 12,
alpha: 255,
age: 0,
shape: 'square'
});
}
}
}
display(colors) {
// Display agent
p.noStroke();
if (this.type === 'quality') {
// Quality agent - organic, complex representation
p.fill(...colors.accent1, 180);
p.circle(this.x, this.y, 20);
// Show work particles (messy, organic)
for (let i = this.workParticles.length - 1; i >= 0; i--) {
let particle = this.workParticles[i];
particle.alpha -= 3;
particle.age++;
if (particle.alpha <= 0 || particle.age > 100) {
this.workParticles.splice(i, 1);
} else {
p.fill(...colors.accent1, particle.alpha);
p.circle(particle.x, particle.y, particle.size);
}
}
} else {
// Legibility agent - clean, geometric representation
p.fill(...colors.accent2, 180);
p.rectMode(p.CENTER);
p.rect(this.x, this.y, 20, 20, 2);
// Show work artifacts (clean, geometric)
for (let i = this.workParticles.length - 1; i >= 0; i--) {
let particle = this.workParticles[i];
particle.alpha -= 3;
particle.age++;
if (particle.alpha <= 0 || particle.age > 100) {
this.workParticles.splice(i, 1);
} else {
p.fill(...colors.accent2, particle.alpha);
p.rectMode(p.CENTER);
p.rect(particle.x, particle.y, particle.size, particle.size, 2);
}
}
}
}
canCaptureReward(reward) {
let distance = p.dist(this.x, this.y, reward.x, reward.y);
if (this.type === 'legibility') {
// Legibility agent has wider capture radius (more visible)
return distance < 60;
} else {
// Quality agent has smaller capture radius (less visible)
return distance < 30;
}
}
captureReward() {
this.capturedRewards++;
}
}
class Reward {
constructor() {
this.x = p.random(60, 340);
this.y = 20;
this.speed = 1.5;
this.captured = false;
this.size = 8;
}
update() {
if (!this.captured) {
this.y += this.speed;
}
}
display(colors) {
if (!this.captured && this.y < 250) {
p.noStroke();
p.fill(...colors.accent3, 200);
p.circle(this.x, this.y, this.size);
}
}
isOffScreen() {
return this.y > 260;
}
}
p.setup = function() {
p.createCanvas(400, 300);
// Create two agents
qualityAgent = new Agent(120, 'quality');
legibilityAgent = new Agent(280, 'legibility');
};
p.draw = function() {
const colors = getThemeColors();
p.background(...colors.bg);
frame++;
// Title
p.fill(...colors.accent3, 200);
p.noStroke();
p.textAlign(p.CENTER);
p.textSize(11);
p.text('The Legibility Game', 200, 20);
// Spawn rewards periodically
if (frame % 60 === 0) {
rewards.push(new Reward());
}
// Update and display rewards
for (let i = rewards.length - 1; i >= 0; i--) {
let reward = rewards[i];
reward.update();
// Check if either agent can capture this reward
if (!reward.captured) {
// Legibility agent checks first (gets priority - bias of the system)
if (legibilityAgent.canCaptureReward(reward)) {
reward.captured = true;
legibilityAgent.captureReward();
legibilityScore++;
} else if (qualityAgent.canCaptureReward(reward)) {
reward.captured = true;
qualityAgent.captureReward();
qualityScore++;
}
}
reward.display(colors);
// Remove off-screen rewards
if (reward.isOffScreen()) {
rewards.splice(i, 1);
}
}
// Agents do work
qualityAgent.doWork();
legibilityAgent.doWork();
// Display agents
qualityAgent.display(colors);
legibilityAgent.display(colors);
// Labels
p.fill(...colors.accent3, 180);
p.textSize(9);
p.textAlign(p.CENTER);
p.text('Quality', qualityAgent.x, 255);
p.text('(deep work)', qualityAgent.x, 265);
p.text('Legibility', legibilityAgent.x, 255);
p.text('(visible work)', legibilityAgent.x, 265);
// Scores
p.textSize(10);
p.fill(...colors.accent1, 200);
p.text(`Rewards: ${qualityScore}`, qualityAgent.x, 280);
p.fill(...colors.accent2, 200);
p.text(`Rewards: ${legibilityScore}`, legibilityAgent.x, 280);
// Top label
p.fill(...colors.accent3, 150);
p.textSize(8);
p.textAlign(p.CENTER);
p.text('Rewards fall → Legible work captures more despite Quality doing better work', 200, 42);
// Insight at bottom (rotating)
p.textSize(7);
p.fill(...colors.accent3, 180);
if (frame % 300 < 150) {
p.text('The person who looks competent beats the person who is competent.', 200, 295);
} else {
p.text('Visibility matters more than value. The legibility game is the real game.', 200, 295);
}
};
};