HomeJournalThis post

Wave Function Collapse With Visual Rhythm

Turn a constraint-valid tile field into a designed pattern with inspectable adjacency, deterministic propagation, solve-rate evidence, and rhythm controls.

JP
JP Casabianca
UI/UX designer and full-stack engineer · Bogotá

Wave function collapse can generate locally compatible tile fields from a small adjacency model, but valid output is not automatically good composition. Low-entropy choices, propagation order, retries, and tile weights all leave visible fingerprints.

This guide builds a deterministic solver, makes contradictions inspectable, and adds rhythm zones without disguising the underlying constraints.

The supporting vocabulary is tile adjacency, constraint propagation, procedural generation, minimum-choice observation. Each term serves the same search intent: generate constraint-valid tile fields while adding visual rhythm, recovery, and deterministic debugging.

My position is that contradiction is design feedback. A solver that frequently collapses to nothing is telling you something about the grammar, boundary, or weight system—not merely asking for another random seed.

wave function collapse: a possibility grid narrowing from uncertainty to pattern An original editorial diagram maps Tile grammar, Possibility sets, Propagation, Resolved rhythm into one decision system. A B C D
  1. Tile grammar
  2. Possibility sets
  3. Propagation
  4. Resolved rhythm
Figure 1: a possibility grid narrowing from uncertainty to pattern. The drawing turns the article's four-part argument into an inspectable visual model.

Wave function collapse starts with grammar

Tiles, rotations, frequencies, and directional adjacency rules define every possibility the solver can later express. The original WaveFunctionCollapse repository documents the reference algorithm, examples, and entropy-based observation. In this wave function collapse method, the important move is to make the hidden variable visible before optimizing the attractive output.

Use four concrete actions:

  • Normalize tile identities
  • Generate rotations carefully
  • Encode directional neighbors
  • Validate reciprocal edges

The useful measurement is allowed-neighbor counts by tile and side. Record the input, configuration, observation window, and rejected control together. That bundle makes the result debuggable: another reviewer can tell whether a change improved the system or merely moved cost into a quieter part of the experience.

The failure to provoke is a missing reciprocal rule creates hidden dead ends. A test that never produces that failure is too polite; it cannot show that the guardrail works. Design the smallest counterexample first, then scale the experiment only after the bad case is unmistakable.

My decision rule is the grammar must pass symmetry and reachability checks. This is a proposed operating boundary, not a claim about an undisclosed client system. It gives wave function collapse a defensible stopping point while leaving room for a different workload, visual goal, or device constraint to choose another answer.

Keep possibility sets visible

A cell is not a tile until observed; its current possibility set is the state that propagation changes. The SVG specification defines accessible vector tile output and reusable motif geometry. In this wave function collapse method, the important move is to make the hidden variable visible before optimizing the attractive output.

Use four concrete actions:

  • Use bitsets or stable sets
  • Render possibility counts
  • Log every removal
  • Preserve deterministic ordering

The useful measurement is state reductions per propagation event. Record the input, configuration, observation window, and rejected control together. That bundle makes the result debuggable: another reviewer can tell whether a change improved the system or merely moved cost into a quieter part of the experience.

The failure to provoke is silent mutation makes contradictions impossible to trace. A test that never produces that failure is too polite; it cannot show that the guardrail works. Design the smallest counterexample first, then scale the experiment only after the bad case is unmistakable.

My decision rule is every removal must name the constraint that caused it. This is a proposed operating boundary, not a claim about an undisclosed client system. It gives wave function collapse a defensible stopping point while leaving room for a different workload, visual goal, or device constraint to choose another answer.

Choose entropy with intention

The lowest-entropy heuristic resolves constrained cells first, while weights shape which valid motif appears. The CSS Grid specification defines a semantic layout option for rendering inspectable tile matrices. In this wave function collapse method, the important move is to make the hidden variable visible before optimizing the attractive output.

Use four concrete actions:

  • Compute entropy consistently
  • Break ties with seeded randomness
  • Compare uniform and learned weights
  • Map selection order

The useful measurement is contradictions and motif distribution. Record the input, configuration, observation window, and rejected control together. That bundle makes the result debuggable: another reviewer can tell whether a change improved the system or merely moved cost into a quieter part of the experience.

The failure to provoke is weights overwhelm constraints or create monotony. A test that never produces that failure is too polite; it cannot show that the guardrail works. Design the smallest counterexample first, then scale the experiment only after the bad case is unmistakable.

My decision rule is choose weights from both solver health and visual rhythm. This is a proposed operating boundary, not a claim about an undisclosed client system. It gives wave function collapse a defensible stopping point while leaving room for a different workload, visual goal, or device constraint to choose another answer.

OptionObserved signalVerdict
Loose grammarvalid but incoherentreject
Brittle grammarfrequent contradictionsreject
Tested grammarvalid with varied rhythmship
Figure 2: Hypothetical worked example. Values are illustrative rather than claimed production results; the comparison shows how evidence changes the choice.

Treat boundaries as grammar

Wrapping, fixed borders, openings, and masks change legal neighborhoods and often create the hardest contradictions. In this wave function collapse method, the important move is to make the hidden variable visible before optimizing the attractive output.

Use four concrete actions:

  • Test each boundary mode
  • Add edge-specific tiles
  • Visualize masked cells
  • Start with small fixtures

The useful measurement is contradiction location by boundary type. Record the input, configuration, observation window, and rejected control together. That bundle makes the result debuggable: another reviewer can tell whether a change improved the system or merely moved cost into a quieter part of the experience.

The failure to provoke is the interior works while every corner fails. A test that never produces that failure is too polite; it cannot show that the guardrail works. Design the smallest counterexample first, then scale the experiment only after the bad case is unmistakable.

My decision rule is no large generation before tiny boundary fixtures resolve. This is a proposed operating boundary, not a claim about an undisclosed client system. It gives wave function collapse a defensible stopping point while leaving room for a different workload, visual goal, or device constraint to choose another answer.

Test propagation to a fixed point

A small adjacency chain proves that removing one option eliminates incompatible options until no more changes remain. In this wave function collapse method, the important move is to make the hidden variable visible before optimizing the attractive output.

Use four concrete actions:

  • Create three cells
  • Remove one candidate
  • Queue affected neighbors
  • Assert final sets

The useful measurement is exact remaining possibilities. Record the input, configuration, observation window, and rejected control together. That bundle makes the result debuggable: another reviewer can tell whether a change improved the system or merely moved cost into a quieter part of the experience.

The failure to provoke is the queue stops early and leaves impossible states. A test that never produces that failure is too polite; it cannot show that the guardrail works. Design the smallest counterexample first, then scale the experiment only after the bad case is unmistakable.

My decision rule is propagation must continue until the queue is empty. This is a proposed operating boundary, not a claim about an undisclosed client system. It gives wave function collapse a defensible stopping point while leaving room for a different workload, visual goal, or device constraint to choose another answer.

Runnable artifact. Save this bounded check as wave-function-collapse-patterns.test.mjs and run node --test wave-function-collapse-patterns.test.mjs. Expected output: PASS: propagation removes incompatible tile.

import assert from "node:assert/strict";
import test from "node:test";
const allowed={A:new Set(["A"]),B:new Set(["B"])};
const prune=(left,right)=>new Set([...right].filter(r=>[...left].some(l=>allowed[l].has(r))));
test("propagate",()=>{assert.deepEqual([...prune(new Set(["A"]),new Set(["A","B"]))],["A"]);console.log("PASS: propagation removes incompatible tile");});

Recover without hiding failure

Blind restarts can eventually produce an image while concealing a grammar that is fragile or impossible in common regions. In this wave function collapse method, the important move is to make the hidden variable visible before optimizing the attractive output.

Use four concrete actions:

  • Count contradictions
  • Save failing seeds
  • Try bounded backtracking
  • Report restart cost

The useful measurement is success rate and recovery work. Record the input, configuration, observation window, and rejected control together. That bundle makes the result debuggable: another reviewer can tell whether a change improved the system or merely moved cost into a quieter part of the experience.

The failure to provoke is the release depends on hundreds of invisible retries. A test that never produces that failure is too polite; it cannot show that the guardrail works. Design the smallest counterexample first, then scale the experiment only after the bad case is unmistakable.

My decision rule is the grammar must meet an explicit solve-rate floor. This is a proposed operating boundary, not a claim about an undisclosed client system. It gives wave function collapse a defensible stopping point while leaving room for a different workload, visual goal, or device constraint to choose another answer.

  1. EncodeEncode

    Declare tiles, rotations, and neighbors.

  2. ObserveObserve

    Choose a low-entropy unresolved cell.

  3. PropagatePropagate

    Remove impossible neighboring states.

  4. RecoverRecover

    Backtrack or restart with evidence.

Figure 3: The sequence keeps the method readable without JavaScript and makes the release decision the final step.

Add rhythm above local validity

Zones, landmarks, density gradients, and reserved negative space can guide composition without breaking adjacency. In this wave function collapse method, the important move is to make the hidden variable visible before optimizing the attractive output.

Use four concrete actions:

  • Define optional zone weights
  • Pin sparse landmarks
  • Protect quiet regions
  • Compare a neutral control

The useful measurement is global motif rhythm beside local validity. Record the input, configuration, observation window, and rejected control together. That bundle makes the result debuggable: another reviewer can tell whether a change improved the system or merely moved cost into a quieter part of the experience.

The failure to provoke is every cell is legal but the field has no hierarchy. A test that never produces that failure is too polite; it cannot show that the guardrail works. Design the smallest counterexample first, then scale the experiment only after the bad case is unmistakable.

My decision rule is composition controls may bias choices but never bypass constraints. This is a proposed operating boundary, not a claim about an undisclosed client system. It gives wave function collapse a defensible stopping point while leaving room for a different workload, visual goal, or device constraint to choose another answer.

Publish a solver trace

Seed, grammar hash, tile set, selection order, contradictions, recovery, and final grid make the result reproducible. In this wave function collapse method, the important move is to make the hidden variable visible before optimizing the attractive output.

Use four concrete actions:

  • Serialize the grammar
  • Save chosen seed
  • Save event log
  • Export semantic tile labels

The useful measurement is byte-identical grid reconstruction. Record the input, configuration, observation window, and rejected control together. That bundle makes the result debuggable: another reviewer can tell whether a change improved the system or merely moved cost into a quieter part of the experience.

The failure to provoke is a pretty export cannot explain or repeat the run. A test that never produces that failure is too polite; it cannot show that the guardrail works. Design the smallest counterexample first, then scale the experiment only after the bad case is unmistakable.

My decision rule is the final field must regenerate from the trace alone. This is a proposed operating boundary, not a claim about an undisclosed client system. It gives wave function collapse a defensible stopping point while leaving room for a different workload, visual goal, or device constraint to choose another answer.

The useful version is bounded

Make the grammar and propagation trace inspectable before art-directing the output. Contradictions reveal brittle rules, and solve rate is a quality signal.

Add hierarchy through lawful biases: zones, landmarks, weights, and quiet space. The most interesting field remains locally valid and globally composed.

Continue with Truchet tile composition, constraint-based layout, seeded randomness, design system escape hatches. Those field notes deepen adjacent implementation choices without turning this page into several articles at once.