Planck.js – JavaScript rewrite of Box2D physics library
github.com
github.com
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
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!
http://schoolnotez.com/ http://appynote.com/app-store/ (see the pendulum example.)
good job.
In my experience good documentation takes around 3x-5x of the time of writing the code (excluding tests and tutorials), so while I hate seeing libraries without a decent documentation I totally understand it.
Edit: also it is in alpha, where writing documentation many times backfires you and you have to remove large pieces of it wasting your time.
Edit: see this "others" folder for example: https://github.com/franciscop/server/tree/master/others
Last time I was building a novel API, I opted to provide commented example code for documentation, recruited several members of the intended audience to try out the API, and just offered to answer questions directly. I wrote out actual documentation in preparation for the "official 1.0 release."
At some point it comes down to choosing how to spend your limited time. Writing documentation isn't going to be a "waste," but it's probably not high ROI because your early adopters are likely familiar with the problem domain anyway.
What I mean is that writing the final documentation with all that implies before you even know what the API is going to look like is a waste. Though I agree with the parent, stubbing some docs to get a better feeling of what the docs look like is valuable.
I'm sure once the project matures it'll get a documentation pass, but the project is quite young.
One of the biggest criteria I have for using a library is whether they have a rich set of examples to draw from.
Both are beneficial for different scenarios. I find I use examples much more often but when examples fail, documentation is necessary.
I was using 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.
PIXI.js is cool (actually they use some of my code), but I think that my library is easier and more comfortable to use.
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!
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?
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.
[1]: https://github.com/shakiba/planck.js/blob/master/dist/planck...
[2]: https://github.com/kripken/box2d.js/blob/master/build/Box2D_...
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) { };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
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.
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.
You may need to force-reload the example to see the update. Please let me know if the issue still exists for you.
Did you contact the Phaser people( Or well, that one guy mostly)? This could replace Box2d there.
The classic advice here is http://gafferongames.com/game-physics/fix-your-timestep/