
Planck.js – JavaScript rewrite of Box2D physics library - vivaladav
https://github.com/shakiba/planck.js
======
shakiba
Planck.js developer here! I have posted this to reddit before, so I'm just
going to include it here too:

I have ported/rewritten Box2D physics engine to JavaScript, for cross-platform
HTML5 game development. Planck.js includes entire Box2D algorithms, a simple
HTML5 Testbed, more than 50 examples and some new game prototypes. The project
is pre-released and there may still be minor issues, which I'm working to fix.
So far I have spent more than 400 hours for developing this project and it
consists of around 20k lines of code.

[https://github.com/shakiba/planck.js](https://github.com/shakiba/planck.js)

My main motivations for working on this project are:

\- Taking advantage of Box2D's efforts, achievements and community knowledge

\- Developing readable and maintainable JavaScript code

\- Optimizing the library for web and mobile platforms

\- Providing a JavaScrip-friendly API

Your feedback is highly appreciated, and I hope you use Planck.js to make some
awesome games soon!

~~~
Edmond
The more things change the more they stay the same...I did a manual port of
[http://www.box2dflash.org/](http://www.box2dflash.org/) to JS a few years
back to make educational simulations:

[http://schoolnotez.com/](http://schoolnotez.com/) [http://appynote.com/app-
store/](http://appynote.com/app-store/) (see the pendulum example.)

good job.

~~~
shakiba
Great work! I decided to directly rewrite Planck.js from Box2D C++ code, so
that I can keep it updated (as far as I remember that flash port was few years
old).

------
d0vs
It baffles me that all those JS physics library never provide proper docs or
even an API reference and always link to the C++ Box2D manual as if it was an
acceptable alternative. Always have to guess what the JS equivalent is but
even then you're in for a surprise:
[https://github.com/shakiba/planck.js/blob/master/CHANGES.md](https://github.com/shakiba/planck.js/blob/master/CHANGES.md)

~~~
abetusk
For me, an example is worth 10 pages of documentation. The documentation is
good for reference but only after you understand the ideas behind it.

One of the biggest criteria I have for using a library is whether they have a
rich set of examples to draw from.

~~~
fdsfsafasfdas
Conversely, after the initial struggle getting the ideas behind it, examples
are worthless and documentation is king.

~~~
abetusk
Sometimes. Examples are good at giving concrete working code to use as a basis
but they only express a few ideas. Documentation will let you understand the
different pieces so you can build what you like.

Both are beneficial for different scenarios. I find I use examples much more
often but when examples fail, documentation is necessary.

------
IvanK_net
You reminded me, that I made a Javascript game with Box2D five years ago:
[http://www.loudrider.com/](http://www.loudrider.com/)

I was using Box2DWeb [https://github.com/hecht-
software/box2dweb](https://github.com/hecht-software/box2dweb) . It could be
good to mention other javascript versions of Box2D and say, what are the
differences between them and your library.

~~~
tiglionabbit
Neat game. The time trial scores seem a bit strict though. I mean, I can't
seem to get 3 stars on the first level of the tutorial even though it's
literally just holding down a single button. Am I missing something? :P

~~~
IvanK_net
You should "lean backwards" to push on the back wheel to decrease friction and
accelerate faster :) BTW. you can play it on your phones and other devices
with browsers, too :)

------
caseywebdev
I love that you kept the tried and true Box2D API as that'll make porting what
I'm working on much easier. I've been using the emscripten version [1] but the
automatic port from C++ makes the JS API quite painful at times, especially
with the manual memory management that's required to prevent leaks. Thanks for
doing this!

[1]:
[https://github.com/kripken/box2d.js](https://github.com/kripken/box2d.js)

------
degenerate
In most of the demos, you can grab the objects and drag them around. In other
demos (like 8 ball) you can 'shoot' them.

I wasn't expecting it to be so smooth and precise... this is really great
work. It makes me realize why I got a C in physics, because I could never make
this!

~~~
efnx
It's not just physics though, as I remember Erin the author of box2d
mentioning that most of the work is concerned with allocating and deallocating
tiny pieces of memory. After that the physics are rather simple Newtonian
equations.

~~~
outworlder
But then, in order to calculate those newtonian equations, you need an
integrator, right?

------
throwaway2016a
This seems like really great work.

I could have sworn this was done already but looking at all the search results
that came up the alternatives seem awful at first glance. At the very least
this project is better at marketing.

As an aside, does it bother anyone else that the 8-ball demo has two extra
pockets in the table?

~~~
paulddraper
Or that the asteroids game has (a lot of) friction?

~~~
andai
space dust

------
erikpukinskis
Off topic:

I'm interested in a physics library based on waveform collapse. It seems like
performance would be so much better. A body could arc through empty space,
without writing any new data to the GPU, just the clock changing, until an
"observation" event where you wanted to check whether it interacted with
anything, at which point you collapse some number of waveforms into particles,
do rigid body math, and then generate new wave equations for the subsequent
timeline. There would be no centralized "tick" just a tree of nested timelines
forking whenever your code decided to do an observation. When rendering you'd
just render all the waves, which means you can do arbitrary precision. You
could do 90hz rendering of the waves for head position, while only collapsing
particles every half second or so. Do that at multiple scales and you have a
physics system with arbitrary fidelity traded off for performance. You can
have different ticks at different scales (waves within waves). The properties
of a given surface would just be the sum of maybe 3-4 waves at different
levels of detail. You could collapse these independently depending on how much
compute you wanted to devote at different levels. I think this would pair well
with an SDF-based renderer, which lets you have screen-aligned surfaces that
kind of act like particles already.

It would lead to bizarre physics bugs, but I suspect they would be very
interesting and could lead to interesting gameplay. Perhaps they might even
help us learn things about how our own universe works.

------
santaclaus
Cool! Is there a big advantage to a manual rewrite vs emscripten? With
emscripten folding in updates from Box2D 'native' would be easier, it seems.

~~~
shakiba
Thanks! Repost from reddit:

The main reasons that I decided not to use Emscripten port was usability:

\- First, it is generated and unreadable code, therefore it is impossible to
understand how it actually works in JS to use it optimally, debug it or
improve it for JS. While it possible to improve Planck.js if it is not as fast
in some cases, it is not possible to do anything with Emscripten port.

\- Second, API of Emscripten port does not follow JavaScript conventions and
is inconvenient to use in JavaScript. For example it returns an empty object,
instead of no object (null or undefined) as last element of a linked list
(which is very confusing in JS). Here are some more usage comparisons:

    
    
        // emscripten
        var bd_ground = new Box2D.b2BodyDef();
        var ground = world.CreateBody(bd_ground);
        var shape0 = new Box2D.b2EdgeShape();
        shape0.Set(new Box2D.b2Vec2(-40.0, -6.0), new Box2D.b2Vec2(40.0, -6.0));
        ground.CreateFixture(shape0, 0.0);    
    
        // planck.js
        var ground = world.createBody({});
        ground.createFixture(planck.Edge(Vec2(-40.0, -6.0), Vec2(40.0, -6.0)), 0.0);
    
        // emscripten
        var bd = new Box2D.b2BodyDef();
        bd.set_type(Box2D.b2_dynamicBody);
        bd.set_position(ZERO);
        var body = world.CreateBody(bd);
    
        // planck.js
        var body = world.createBody({
          type: "dynamic",
          position: Vec2(0, 0),
        });
        // or just world.createDynamicBody();
    
        // emscripten    
        myQueryCallback = new Box2D.JSQueryCallback();
        myQueryCallback.ReportFixture = function(fixturePtr) { };
    
        // planck.js
        myQueryCallback = function(fixture) { };

------
tapirl
great, included in [http://www.tapirgames.com/blog/open-source-physics-
engines](http://www.tapirgames.com/blog/open-source-physics-engines)

~~~
shakiba
Awesome, thank you!

------
Hydraulix989
Great work! This is really impressive stuff, and it's applaudable that you saw
this project through to the very end!

I'm actually seeing some hitching in the car demo on my reasonably fast dev
machine, particularly when I'm interacting with the bridge (computing contact
forces of a bunch of bodies connected with joints is a lot of work):
[http://piqnt.com/planck.js/Car](http://piqnt.com/planck.js/Car)

Have you looked at perf yet? How does the performance of your rewrite
planck.js compare to a compiled emscripten version?

Would you ever consider using something like ASM.js or WebAssembly? Physics
libraries are definitely one of those performance-critical applications where
this kind of stuff actually matters a whole lot.

~~~
shakiba
Thank you!

I have not seen any problem with car example on my own laptop, but I will try
it on some more different devices to find the issue.

Regarding performance, because Planck.js code is hand-made and readable it is
not difficult to improve it if it is not fast enough with some cases.

asm.js looks promising, I'm going to have a closer look at it.

------
IvanK_net
I made a graphics library IvanK.js and made a Box2D demo for it (using
Box2DWeb). It ran smooth even back in 2012 :)
[http://lib.ivank.net/?p=demos&d=box2D](http://lib.ivank.net/?p=demos&d=box2D)

------
BLanen
Cool.

Did you contact the Phaser people( Or well, that one guy mostly)? This could
replace Box2d there.

~~~
shakiba
Thanks! It is easy to integrate Planck.js with other liraries and dev tools.

------
AndrewStephens
I've messed around with various incarnations of Box2D, including at least one
other Javascript port. How does this one compare performance-wise? Does doing
a full rewrite perform better than the automatically generated Javascript of
the other ports?

~~~
shakiba
The main difference is that it is a hand-made rewrite, so the code is readable
and improvable, so performance can be improved and optimized even if it is not
fast enough in some cases. Also see my other comment about comparison with
emscripten port.

------
the_arun
Awesome!! Makes it a delight to use

------
m0dE
I'm currently using Box2D intensively in one of my games: www.braains.io What
would be the easiest way for me to replace the existing Box2D implementation
with Planck.js?

------
partycoder
What I remember from Box2D is that the simulation wasn't deterministic but
rather dependent on frame rate for example. Is it the same case for this?

~~~
ewjordan
If you tie the frame rate to the physics step, then yes - that will be true
for pretty much any physics engine.

The classic advice here is [http://gafferongames.com/game-physics/fix-your-
timestep/](http://gafferongames.com/game-physics/fix-your-timestep/)

------
disease
How difficult would it be to integrate with Phaser? I believe Phaser currently
has Box2D support but only through a closed source commercial plugin.

~~~
shakiba
Probably it would be easy, I would be happy to help with that, please feel
free to open an issue on github.

------
redjamjar
Nice job!! Love the 8 ball example ... really fun :)

------
floatboth
Nice demos! I like how in the soccer example you can play as a self-driving
ball :D

