Hi folks, I’ve been working on something really exciting — a 3d physics engine in Elm, and have something to show!
The reason why I started this in the first place, was because of a crazy idea for the Elm Game Jam to build a physically simulated dice roller! I looked at all the existing options available in JavaScript and found Cannon.js easier to comprehend. Due to lack of knowledge in maths and physics, I wondered how far I could go by just reading and understanding the JavaScript code — turns out it was possible, and I even learned some theory on the way.
Conversion was somewhat painful, because of little mistakes that I did here and there that were not caught by the type system, e.g. vec1 |> Vec3.sub vec2
is not equivalent to vec1.sub(vec2)
.
I went by manually stepping through the compiled code in Chrome Dev Tools and comparing intermediate values to the same scene running in Cannon.js, I did this to discover some anomalies in the coefficients and then traced them up to find the bugs in code.
Writing tests did help me in most cases, because I could write them for both the original JavaScript library and my Elm package, and then compare the results. In some cases, when collision wasn’t working properly, I used the debugger to get into the wrong state, and manually copied all the values into the tests.
I learned that the current linear-algebra package in Elm doesn’t support things that I needed, so I had to implement things like Mat3 and Quaternion. Perhaps supporting typed arrays in Elm would make it possible to roll out Elm implementation of linear-algebra without native code.
In order to port mutable object oriented code to Elm, I had to clearly separate reads and writes, because in some places the values were mutated on read (perhaps for performance reasons). In the end, it really streamlined the algorithms, and made them easier to understand.
Because the current Elm code is much slower than the JavaScript implementation, I plan to look into performance and work on improvements in a measurable way, most likely utilizing elm-benchmark.
There are also a lot of features that I didn’t implement, because I was mostly focused on just enough API to make the dice game.