Paper, Scissors, Gravity
February 18, 2026I don't know what a Plücker transform is.
I couldn't explain the Featherstone Articulated Body Algorithm if you put a gun to my head. I have never taken a physics class beyond what was required in college (I dropped out). I don't know what a Yee lattice is, or why Wilson actions involve SU(3), or what a deficit angle has to do with general relativity.
Actually, I know that last one now. And by the end of this post, so will you.
The day
Today, a Monday, I built a differentiable physics engine from scratch. 25 Rust crates. 28,000 lines. Rigid body dynamics, collision detection, fluids, electromagnetic fields, molecular dynamics, quantum field theory on a lattice, N-body gravity, and discrete general relativity.
Then I plugged it into my CAD kernel and replaced the physics backend.
All of this between 8:38am and 9pm. On a couch. Mostly pressing enter. I also took my pregnant wife to a checkup and got some Chick-Fil-A.
I had a plan. I want to make the best sim2real software in vcad, and for that I need accurate physics with an API I can control (for an accurate sim)(i dont wanna use isaac). I want to make a world model with this for use in Municipal Robotics rovers.
17 phases, from "pendulum with gradients" to "reality ingestion." A plan-runner.sh script let Claude execute each phase autonomously. Read the plan, write the code, run the tests, commit. Seventeen phases of a physics engine. Two hours and forty-four minutes.
This post isn't about how I built it. It's about the thing that blew my mind the most. And it has to do with triangles.
You already know this
If you read my post on tessellation, you know the punchline: your GPU doesn't know what a cylinder is. It knows triangles. Every curved surface you've ever seen on a screen was actually tiny flat triangles, packed so tightly your eyes couldn't tell the difference.
Here's the part nobody told me:
The universe works the same way.
General relativity says that mass curves spacetime, and curved spacetime tells things how to move. That's Einstein's theory of gravity. That's the whole theory.
But "curved spacetime" is hard to compute. The equations are beautiful and brutal. Tensor calculus, Christoffel symbols, Ricci curvature. I can't do any of it.

In 1961, a physicist named Tullio Regge had an idea: what if you don't need smooth curves at all? What if you can approximate curved spacetime with flat triangles, just like a GPU approximates a sphere?
He was right. And the math is shockingly simple.
The cone trick
Grab a piece of paper. (Mentally. I'm not ur mom.)
It's flat. No curvature. Now cut out a wedge, like a pizza slice, and tape the cut edges together.
It pops up into a cone. The paper is still flat everywhere except at the tip. All the curvature is concentrated at that single point. And the amount of curvature is exactly equal to the angle you removed.
Removed 60°? You have 60° of curvature at the tip. That's it. That's the whole idea.
That missing angle has a name: the deficit angle.
Deficit angles
Let's make it precise. Take some triangles and arrange them around a vertex.
On a flat surface, the angles around any point add up to exactly 360°. No gap, no overlap. The deficit angle is zero.
On a positively curved surface (like a sphere) the angles add up to less than 360°. There's a gap. That gap is the deficit angle, and it means the surface curves inward, like a hilltop. This is the kind of curvature a massive object creates. The kind that makes things fall.
On a negatively curved surface (like a saddle) the angles add up to more than 360°. They overlap. The deficit angle is negative, and the surface curves outward, like a mountain pass.
Move the slider. Watch the gap appear and disappear. That gap is gravity.
Einstein's equation, in one sentence
Here's what Regge realized.
Einstein's theory of general relativity comes from one equation, the Einstein-Hilbert action:
It's a single number that summarizes everything about a spacetime. is the Ricci scalar (a measure of curvature), is the metric (the shape of spacetime), and you integrate over all of spacetime. Minimize it, and you get Einstein's field equations. All of them.
Grad-school stuff. Years of study. Unless you use triangles.

In Regge's version:
That's it.
Sum over every edge in your mesh. Multiply the edge length by its deficit angle. The result is the action. Minimize it, and you get discrete Einstein equations.
Edge length times deficit angle. Summed up. That's general relativity.
The smooth version and the Regge version converge to the same answer as you add more triangles. Just like how a tessellated sphere converges to a real sphere as you add more triangles. The tessellation insight was cosmological the whole time.
What Claude built
Phase 18 wasn't in the original plan. I asked Claude to go further. Implement Regge calculus. The full thing.
It did.
The phyz-regge crate implements the Einstein-Hilbert action on simplicial manifolds. You give it a mesh of 4-simplices (the 4D version of triangles, tetrahedra extended into spacetime), and it computes deficit angles at every edge, evaluates the action, and finds spacetimes that satisfy Einstein's equations.
But here's where it got weird :~)
Building the engine is one thing. Knowing it's correct is another. How do you validate a general relativity implementation? You can't just eyeball it. So Claude built the validation tools too.
Einstein-Maxwell coupling. Electromagnetism on curved spacetime. If your physics engine can couple Maxwell's equations to the Regge action and get the right answer, that's a strong signal your geometry is faithful. Light bending around a star isn't just a metaphor. It falls out of the math.
Symmetry search via SVD. The ultimate test: give it a spacetime, and it discovers the continuous symmetries automatically. Not hard-coded. Not looked up. Discovered from the geometry, the same way you'd discover that a sphere can be rotated. If the search finds exactly the symmetries the textbooks predict, your discretization is working.
Background spacetimes are the test cases. Each one has known symmetries, so you can check your engine against reality:
- Reissner-Nordström, a charged black hole (19 known symmetries)
- de Sitter, an expanding universe like ours (maximally symmetric)
- Kerr, a rotating black hole, complete with frame dragging (25 symmetries, some broken by spin)
I watched Claude implement Lorentz boost generators and validate them against a Kerr black hole. On a charged black hole (Reissner-Nordström), the search found 19 known symmetries with a clean gap down to the discretization noise floor at ~2.6e-4. On Kerr, 25 exact symmetries. Richardson extrapolation confirmed no hidden symmetries were lurking in the noise.
Frame dragging showed up in the spectrum. A rotating black hole drags spacetime itself around with it, and that shows up as broken symmetries. Rotations that should be equivalent but aren't, because the black hole's spin picks out a preferred direction.
How do you know it's real and not a lattice artifact? You test two backgrounds. On a charged black hole (Reissner-Nordström), the metric components , so time and space aren't interchangeable. Boosts mix time and space. They should break harder than rotations. On de Sitter (expanding universe), , so boosts and rotations should break equally. Here's what the search found:
| Background | Rotations | Boosts | Why |
|---|---|---|---|
| Reissner-Nordström | violation < | violation > rotations | breaks time-space symmetry |
| de Sitter | ~ | ~ | , isotropic, both break equally |
If boost-breaking were a lattice artifact, it would show up on both backgrounds. It doesn't. The asymmetry is physical. There's a test for it.
I don't fully understand what I have. But the tests pass, the convergence rates are correct, and the symmetry search finds exactly what the textbooks predict.

Everything else
Regge calculus was the mind-blower. But the engine has 25 crates, and some of the other stuff is worth seeing.
Rigid body dynamics, the core. Featherstone spatial algebra, O(n) forward dynamics, analytical Jacobians for differentiability. The double pendulum demo above runs the same Rust code you'd use in a robotics project.
Material Point Method, particles on a grid. Different constitutive models give you different materials. This one's water:
Electromagnetic fields, Maxwell's equations on a Yee lattice. FDTD. Watch a dipole radiate:
And because the Yee grid doesn't care what shape the boundary is, you can put a wall with two slits in front of a wave source and watch interference happen:
N-body gravity, Kepler orbits. Not flashy, but satisfying to watch:
Every demo is real compiled Rust running as WebAssembly in your browser. Same code, same physics.
Plugging it into vcad
The whole reason this exists: I'm building vcad, a parametric CAD kernel, and I need accurate physics for sim2real. I want to simulate a robot in CAD, train a policy against the simulation, and deploy it to a real Municipal Robotics rover. For that, the physics has to be differentiable (so gradients flow through the sim for optimization), high precision (f64, not f32), and structured for robotics (articulated trees, not flat body lists).
Rapier3D, our previous backend, is great for games. It's none of those things.

The swap was clean. Three source files touched Rapier directly. I rewrote them to use phyz. Rapier's flat body set became a Featherstone articulated tree. The impulse solver became spring-damper contacts. f32 everywhere became f64. The public API (PhysicsWorld, RobotEnv, JointState, Action) didn't change at all.
13 tests. All passing. WASM builds. Downstream crates didn't know anything happened.
What I actually learned today
I learned that Einstein's equations are a sum of edge lengths times deficit angles.
I learned that curvature is a gap in your triangles, the same gap you'd see if you tried to flatten a globe. That frame dragging is a broken symmetry. That the Einstein-Hilbert action is to spacetime what ear clipping is to a polygon: a way to reduce something continuous to something discrete.
I didn't learn these things the way a physicist does, through years of tensor calculus and differential geometry. I learned them the way an engineer does. By building something that passes tests.
Claude brought the physics. I brought twenty years of knowing what a good API looks like. Together we built something I couldn't have built alone, and probably couldn't have built with any team, in any amount of time, before this year.
I still don't know what a Plücker transform is.
But I know what a deficit angle is. And now so do you.
Go build something stupid
Here's what I want you to take from this: the distance between "I have an idea" and "it works" has collapsed. The bottleneck isn't knowledge anymore. It's imagination.
Build a physics engine. Build a compiler. Build the thing you've been telling yourself is too hard, too academic, too far outside your wheelhouse. The worst that happens is you learn something. The best that happens is you ship it.
Yes, you'll land in the Dunning-Kruger valley. I'm in it right now. I built a general relativity simulator and I still can't derive the Schwarzschild metric by hand. But Dunning-Kruger is only a trap if you stop there. If you keep building, keep testing, keep reading the code Claude writes and asking why, you climb out. You come out the other side knowing things you never would have learned from a textbook, because you learned them by making something real.
The tools are here. The only limit is what you're willing to attempt. Type something audacious into a prompt and press enter.
Try it
cargo install phyz
25 crates. 28,000 lines. Differentiable through everything.
- Site: phyz.dev
- Source: github.com/ecto/phyz
