Inspiration

Most physics software starts by showing you the physics: here is a simulation, here is \( F = ma \), now move the sliders. I noticed that I could recite most of these formulas and still couldn't predict what a thrown ball would actually do.

The moments I did understand something were always the same: I tried to make something happen, it didn't work, and I had to figure out why. So I asked: what if a physics lesson started with a problem instead of a formula? You'd try to build something, commit to a prediction, watch what actually happens, and only then see the equation, as the explanation for something you've already seen.

LumenLab is built for high school and early university students who have met physics formulas but don't yet feel them, and for teachers who want students experimenting instead of memorising.

What it does

LumenLab is a physics lab in the browser with three experiments. Every one runs the same learning loop:

Construct → Predict → Run → Observe → Explain → Understand → Transfer

01 · Make the ball hit the target (Motion). You aim a launcher at a target on a tower. Before each shot you place a marker where you think the ball will land. After a hit, your own winning shot replays with position dots every 0.2 s and velocity arrows. The dots are evenly spaced sideways, while the vertical arrow shrinks, flips and grows. Only then does the formula appear:

$$ x(t) = x_0 + v_x t, \qquad y(t) = y_0 + v_y t - \tfrac{1}{2} g t^2 $$

filled in with your numbers and checked against what the simulation measured. The transfer task moves the lab to the Moon (\( g = 1.62 \ \text{m/s}^2 \)), and every Earth solution overshoots.

02 · Build a bridge that holds the truck (Structures). With 48 m of steel, you add beams between joints to hold up a 40 kN truck. You predict whether it holds and which beam breaks first. The load ramps up, stressed beams glow, and when one passes its limit it snaps and the bridge can collapse into the river. The result names the exact beam and the load fraction where it failed. The reveal colours every beam cyan (pulled) or coral (pushed) and checks equilibrium at the truck's joint:

$$ \sum F_x = 0, \qquad \sum F_y = 0 $$

03 · Make the output turn clockwise at 120 rpm (Mechanisms). You chain gears around a housing from a motor to an output shaft, and predict the direction and speed. The reveal shows that every mesh reverses direction and that only the first and last gears set the speed:

$$ \omega_{\text{out}} = (-1)^n \, \omega_{\text{in}} \, \frac{r_{\text{in}}}{r_{\text{out}}} $$

Failures are never marked "wrong". They're labelled Observation, with measured facts: "It landed 6.30 m short of the target line", or "B08 was pushed past its limit at 71% of the full load." Every attempt stays in a history bar and can be replayed exactly.

How we built it

  • TypeScript + Canvas 2D, no UI framework, built with Vite and tested with Vitest. No backend, no accounts, and no AI inside the product: everything runs locally and deterministically.
  • Three physics engines, written from scratch instead of using a physics library, so every result can be explained:
    • Projectile: fixed time step \( \Delta t = 1/120 \) s with velocity Verlet integration, which is exact for constant gravity. Continuous collision detection samples 8 points per step and refines the first contact by bisection, so a fast ball can't skip through the tower.
    • Bridge: a pin-jointed truss solved with the direct stiffness method. Each beam adds the block \( \frac{EA}{L}\begin{bmatrix} c^2 & cs \\ cs & s^2 \end{bmatrix} \) to a global matrix, and solving \( K\mathbf{u} = \mathbf{F} \) gives joint displacements and then beam forces. A singular matrix means a joint can move freely: the structure is a mechanism. Because the model is linear, the first beam to fail breaks at load fraction \( f = \text{limit} / |F| \). It is removed and the structure is re-solved, until the bridge holds or collapses.
    • Gears: gears mesh when \( d = r_1 + r_2 \). Motion propagates from the motor by breadth-first search using \( \omega_2 = -\omega_1 r_1 / r_2 \), and an odd loop of meshes produces a contradiction that locks the train.
  • Lessons are data. Each experiment plugs into one shared interface (simulate, evaluate, check the prediction, reveal measurements). The learning loop itself is a pure state machine, so adding the bridge and the gears needed no changes to it.
  • Replay is re-simulation. A run is stored as its settings only. Because the engines are deterministic, simulating again reproduces every frame.
  • 42 automated tests, including exact agreement with the analytic trajectory, equilibrium at loaded joints, jam detection, and a check that every lesson is actually solvable.

Challenges we ran into

  • Choosing the numbers so the bridge is a real puzzle. With some beam limits every bridge held; with others nothing could. I tested candidate designs through the solver until a shallow truss fails, a deeper or better-braced one within the steel budget holds, and an unsupported road folds.
  • A collapse that didn't fall. A broken truss can end up as three hinges in a straight line. The maths correctly calls that a mechanism, but a rigid animation barely moved. The animation now lets beams tear when they are forced to stretch, while the verdict still comes from the static analysis.
  • Gear grids and parity. On a whole-number peg grid with two gear sizes, some targets were impossible to reach. I used a breadth-first search over gear placements to prove which targets were solvable, then added a 15-tooth gear and half-step pegs so both the main and the transfer challenges have solutions.
  • Recording the demo on one CPU core, which only captured about 12 fps. The fix was to slow the app's clock down 2× during recording and speed the video back up afterwards.

Accomplishments that we're proud of

  • The formula really is the last thing you see, and it is checked against your own run rather than a textbook example.
  • Three different physics domains share one engine-independent learning loop.
  • Everything is deterministic and tested: the same setup always gives the same result, and replay is exact.
  • It explains failures precisely (which beam, what load, which joint, which gear loop) instead of just saying "try again".
  • Keyboard controls, screen-reader announcements, reduced-motion support and a responsive layout.

What we learned

  • How numerical integration works, and why velocity Verlet is exact for constant acceleration while simpler methods drift.
  • How structural engineers solve trusses with the stiffness method, and what a singular matrix means physically (a mechanism).
  • That triangles are rigid for a reason, and why compressed beams usually fail before stretched ones: buckling.
  • How to model a gear train as a constraint graph, and how a contradiction in that graph is a jam.
  • That determinism is a design decision. It is what made replay, fair evaluation and meaningful tests possible.
  • On the learning side: asking students to predict before they run changes the experience far more than making the simulation prettier.

What's next for LumenLab: Learn Physics by Making It Happen

  • More experiments on the same loop: energy (get the roller coaster over the hill), momentum, orbits and optics.
  • A saved notebook across sessions, and teacher-shareable challenge links.
  • A camera that follows long shots, sound design, and more transfer tasks per experiment.

AI usage disclosure

LumenLab was built with significant AI assistance, which the hackathon rules allow and ask us to disclose.

  • Claude (Anthropic) did the heavy implementation work: most of the code for the three physics engines, the evaluators, the state machine, the UI and the tests, plus the README. The demo voiceover was generated with Piper TTS.
  • My part: the concept and the construct-predict-run-observe learning philosophy; a detailed design brief covering the product, the learning design, the visual direction and the engineering constraints; choosing the experiments and the decisions throughout; and reviewing, running and testing the app, directing fixes and deciding what shipped.
  • I have worked through how each engine operates (integration, the stiffness solver, gear propagation) and can explain the decisions made in it.

Built With

Share this project:

Updates

Submission history