Skip to content

Latest commit

 

History

History
109 lines (79 loc) · 4.17 KB

File metadata and controls

109 lines (79 loc) · 4.17 KB

Quantum Wave Interference

Verification

After making changes, always run from the totality root:

npm run check

This runs type checking and linting and must pass.

For runtime verification, the default is the headless smoke test:

npm run sim-test -- --sim=quantum-wave-interference

Exception: when you are running under claude --chrome (a live browser session), visual verification in that live Chrome session substitutes for the headless sim-test smoke test. In that mode, load the sim in the live browser, confirm it starts without console errors, and exercise the changed feature directly instead of running sim-test.

Using sim-test to Inspect Runtime State

sim-test accepts a --script flag that evaluates JavaScript in the browser after the sim starts. Use this to interrogate model state, verify property values, and understand the sim at runtime.

Basic Examples

# How many screens?
npm run sim-test -- --sim=quantum-wave-interference --script="phet.joist.sim.screens.length"

# Sim version
npm run sim-test -- --sim=quantum-wave-interference --script="phet.joist.sim.version"

# List screen names
npm run sim-test -- --sim=quantum-wave-interference --script="phet.joist.sim.screens.map(s => s.tandem.phetioID).join(', ')"

Inspecting Model State

# Dump key model properties from screen 0
npm run sim-test -- --sim=quantum-wave-interference --script="
  const model = phet.joist.sim.screens[0].model;
  const scene = model.sceneProperty.value;
  JSON.stringify({
    selectedScene: scene.sourceType,
    isPlaying: model.isPlayingProperty.value,
    wavelength: scene.wavelengthProperty.value,
    intensity: scene.intensityProperty.value,
    slitSetting: scene.slitSettingProperty.value,
    isEmitting: scene.isEmittingProperty.value
  }, null, 2)
"

Verifying a Change

After modifying model code, use --script to confirm the change took effect:

# Example: verify a new property exists and has the expected default
npm run sim-test -- --sim=quantum-wave-interference --script="
  const model = phet.joist.sim.screens[0].model;
  JSON.stringify({ myNewProperty: model.myNewProperty.value })
"

Exploring Unfamiliar State

When you're not sure what properties exist, explore incrementally:

# List own property names on the model
npm run sim-test -- --sim=quantum-wave-interference --script="
  Object.getOwnPropertyNames(phet.joist.sim.screens[0].model).filter(k => k.endsWith('Property')).join('\n')
"

# Then drill into a specific one
npm run sim-test -- --sim=quantum-wave-interference --script="
  phet.joist.sim.screens[0].model.someProperty.value
"

Multi-Pass Workflow

When working on Quantum Wave Interference, use sim-test iteratively:

  1. Explore -- Use --script to understand the current model state before making changes.
  2. Change -- Edit the code.
  3. Check -- Run npm run check for type/lint errors.
  4. Smoke test -- Run npm run sim-test -- --sim=quantum-wave-interference to confirm the sim starts.
  5. Verify -- Run sim-test with --script to confirm the change has the expected runtime effect.
  6. Repeat as needed.

Reference

See doc/implementation-notes.md for architecture details, component nickname/street-name mappings (e.g., "camera" = snapshotButton, "eye" = viewSnapshotsButton), and other helpful context.

Sim Structure

  • Screens: Experiment, High Intensity, Single Particles (in that order). Use --screens=N (1-indexed) to load a specific screen, e.g. ?screens=2 for High Intensity.
  • Common code: js/common/ -- colors, constants, query parameters, and any code shared across two or more screens
  • Experiment screen: js/experiment/ -- model and view
  • High Intensity screen: js/high-intensity/ -- model and view
  • Single Particles screen: js/single-particles/ -- model and view
  • Entry point: js/quantum-wave-interference-main.ts -- registers all three screens
  • Strings: quantum-wave-interference-strings_en.yaml

When refactoring to share code between screens, move the shared code into js/common/ rather than importing across sibling screen directories. Never modify the Experiment screen's observable behavior when doing so.