Skip to content

Measurement

Measurement is the moment quantum becomes classical. A property in superposition collapses to a single definite value — and that collapse is the most dramatic thing your game can do.

Basic Measurement

typescript
const prop = this.getProperty("ball-1");
const [value] = this.measureProperties([prop]);
// value is 0 or 1 (for dim=2)
// The property is now in state |value⟩ — no more superposition

Key behaviors:

  • The outcome is probabilistic — follows Born's rule, not a PRNG
  • The state collapses permanently to the measured value
  • Entangled partners collapse instantly too
  • The operation is recorded when recording is active

Measure and Pool

Always release properties after measurement to stay within qudit limits:

typescript
measureEntity(id: string): number {
  const prop = this.getProperty(id);
  if (!prop) return 1; // classical fallback

  const [value] = this.measureProperties([prop]);
  this.deleteProperty(id);           // remove ID mapping
  this.releaseProperty(prop, value); // reset to |0⟩, return to pool
  return value;
}

This pattern appears in every production game. The specifics vary (what the value means, what to do after), but the sequence — measure, delete, release — is universal.

Batch Measurement

Measure multiple properties at once:

typescript
const props = [this.getProperty("a")!, this.getProperty("b")!, this.getProperty("c")!];
const [va, vb, vc] = this.measureProperties(props);

Batch measurement is slightly more efficient than measuring one at a time, and the outcomes are correlated correctly (entangled properties respect their correlations within the batch).

Reading Probabilities (No Collapse)

Query the probability distribution without disturbing the quantum state:

typescript
const prop = this.getProperty("ball-1");
const results = this.getModule().probabilities([prop]);
// results: [{ probability: 0.7, qudit_values: [1] }, { probability: 0.3, qudit_values: [0] }]

This is a read-only operation — it does not collapse the state. Use this for:

  • Rendering ghost objects at their existence probability
  • Showing probability meters in the UI
  • AI decision-making based on quantum state

TIP

probabilities() uses this.getModule() directly (not a gate wrapper) because it doesn't change state. It is not recorded in the operation log.

Reduced Density Matrix

For advanced analysis — extract phase, coherence, and correlations between properties:

typescript
const rdm = this.getModule().reduced_density_matrix([prop1, prop2]);
// rdm: array of { row_values: number[], col_values: number[], value: { real: number, imag: number } }

The off-diagonal entries carry relative phase information. From Quantum Pong:

typescript
getRelativePhase(refId: string, targetId: string): number {
  const propRef = this.getProperty(refId);
  const propTarget = this.getProperty(targetId);
  if (!propRef || !propTarget) return 0;

  const rdm = this.getModule().reduced_density_matrix([propRef, propTarget]);

  for (const entry of rdm) {
    if (
      entry.row_values[0] === 1 && entry.row_values[1] === 0 &&
      entry.col_values[0] === 0 && entry.col_values[1] === 1
    ) {
      const { real, imag } = entry.value;
      if (Math.abs(real) < 1e-10 && Math.abs(imag) < 1e-10) return 0;
      return Math.atan2(imag, real);
    }
  }
  return 0;
}

Game use cases:

  • Quantum Pong — Relative phase drives the phase dial display and biases entanglement interactions
  • Ponq — Off-diagonal magnitude (coherence) drives ball steering forces
  • Quantris — Coherence info drives piece glow/pulse visualization

Measure Predicate

Projective measurement that checks whether specific predicates are satisfied:

typescript
import type { PredicateSpec } from "quantum-forge-framework/quantum";

const predicates: PredicateSpec[] = [
  { property: prop1, value: 1, isEqual: true },
  { property: prop2, value: 0, isEqual: true },
];

const outcome = this.measurePredicate(predicates);
// outcome: 0 or 1
// 1 = predicates were satisfied (state projected onto matching subspace)
// 0 = predicates were NOT satisfied

Unlike measureProperties, this doesn't fully collapse to a basis state — it performs a projective measurement onto the subspace defined by the predicates.

Forced Measurement (Replay)

Force a measurement to produce a specific outcome. Used internally by replayLog() to reproduce exact quantum states during save/load:

typescript
const [value] = this.forcedMeasureProperties([prop], [1]); // forces outcome to 1

WARNING

Forced measurement is for replay/testing only. Using it during normal gameplay breaks the quantum contract — outcomes should be genuinely probabilistic.

Game Examples

Quantum Pong — Scoring

When a ball exits the play field, it's measured to determine if it scores:

typescript
const exists = registry.measureExistence(ballId);
if (exists === 1) {
  // Ball existed → scores a point
  state.score[scoringSide]++;
  showScoreBurst(ball.position);
} else {
  // Ball was a ghost → no score
  showGhostBurst(ball.position);
}
// Entangled partner (if any) collapses to the opposite value

Quantris — Line Clearing

When a line is complete, all quantum pieces in it are measured:

typescript
for (const piece of piecesInLine) {
  const exists = registry.measurePiece(piece.id);
  if (exists === 0) {
    // Piece was quantum and collapsed to "doesn't exist"
    // Remove from the board — creates gaps
    removePiece(piece);
  }
}

Hex Diffusion — Battle Resolution

Combat pulses measure overlapping hexes:

typescript
const results = registry.measureBattle(hexIds);
// Each hex collapses to one player's ownership
// Entangled hexes respect correlations

Bloch Invaders — Basis Measurement

The player chooses X, Y, or Z basis, then measures the invader:

typescript
// Decompose measurement into gate sequence
if (basis === "X") {
  registry.hadamard(prop);     // rotate to X basis
} else if (basis === "Y") {
  registry.inverseSGate(prop); // rotate to Y basis
  registry.hadamard(prop);
}
const [value] = registry.measureProperties([prop]);
// Damage depends on how well the basis matches the invader's state

Powered by Quantum Forge