Skip to content

Quantum Pong

The canonical starter example: a Pong game where balls enter quantum superposition when they pass through a quantum zone.

Overview

When a ball enters the quantum zone (center of the field), it splits into two entangled balls. Both exist as quantum ghosts (semi-transparent) until one exits the field and is measured. Measurement collapses both balls: one scores, the other vanishes.

Players can bias which ball survives by applying phase rotations via a paddle-mounted phase dial.

Quantum Mechanics Used

MechanismGateGame Effect
Entangle-splitcycle + i_swap(0.5)Ball splits into correlated pair
Quantum-spliti_swap(0.5) on existingAlready-quantum ball splits again
Phase rotationclock(fraction)Paddle dial biases survival probability
Existence probabilityprobabilities()Ghost opacity reflects quantum state
Relative phasereduced_density_matrix()Phase dial display
Measurementmeasure_properties()Scoring, collapses to exists/ghost
PoolingreleaseProperty()Reset measured balls for reuse

Registry

QuantumRegistry extends QuantumPropertyManager with five operations:

typescript
class QuantumRegistry extends QuantumPropertyManager {
  constructor(logger?: LoggerInterface) {
    super({ dimension: 2, logger });
  }

  entangleSplit(originalId: string, newId: string): void {
    const prop1 = this.acquireProperty();
    const prop2 = this.acquireProperty();
    const m = this.getModule();
    m.cycle(prop1);                    // |1⟩ (exists)
    m.i_swap(prop1, prop2, 0.5);      // entangle
    this.setProperty(originalId, prop1);
    this.setProperty(newId, prop2);
  }

  quantumSplit(originalId: string, newId: string): boolean {
    const prop1 = this.getProperty(originalId);
    if (!prop1) return false;
    const prop2 = this.acquireProperty();
    try {
      this.getModule().i_swap(prop1, prop2, 0.5);
    } catch {
      this.releaseProperty(prop2, 0);
      return false;
    }
    this.setProperty(newId, prop2);
    return true;
  }

  applyPhase(id: string, fraction: number): void {
    const prop = this.getProperty(id);
    if (!prop) return;
    this.getModule().clock(prop, fraction);
  }

  getExistenceProbability(id: string): number {
    const prop = this.getProperty(id);
    if (!prop) return 1.0;
    const results = this.getModule().probabilities([prop]);
    for (const r of results) {
      if (r.qudit_values[0] === 1) return r.probability;
    }
    return 0;
  }

  measureExistence(id: string): number {
    const prop = this.getProperty(id);
    if (!prop) return 1;
    const [value] = this.getModule().measure_properties([prop]);
    this.deleteProperty(id);
    this.releaseProperty(prop, value);
    return value;
  }
}

Key Design Patterns

Entangle-Split as Core Mechanic

The quantum zone is a spatial trigger. When a classical ball crosses the threshold:

  1. Two properties are acquired (from pool if possible)
  2. One is cycled to |1⟩, the other stays at |0⟩
  3. i_swap(0.5) entangles them into (|10⟩ + i|01⟩)/√2
  4. Both balls render at ~50% opacity

Phase as Player Skill

The phase dial on each paddle gives players a way to influence quantum outcomes. Applying clock(fraction) rotates the relative phase between entangled balls. When the next iSwap occurs, the phase bias redistributes probability, so a skilled player can increase their scoring chance.

Measurement as Drama

The moment of measurement is the highest-drama event in the game. The player doesn't know which ball will score until it exits the field and gets measured. Ghost bursts (for |0⟩) and score bursts (for |1⟩) provide visual feedback.

Pooling for Sustainability

Every measured ball returns its property to the pool. This means the game can run indefinitely without hitting the qudit limit. There are always recycled properties available for the next entangle-split.

Source

framework/examples/quantum-pong/. Shipped with the framework, available as a template via npx quantum-forge init my-game --template quantum-pong.

Powered by Quantum Forge