Closed mattgrayisok closed 7 years ago
I also was interested in such a thing, but I was afraid MatterJS would be way too greedy on performances. I'm waiting for feedback on this matter!
In my setup I seem to be all good so far. My physics clock is running at 15ms per tick (with drift adjustments per tick to keep clients and server in sync) and it has no trouble simulating collision detection and some ray casting (people shooting each other) on 7 - 8 simultaneous players. This is running in a VM on my laptop with an i7 CPU, so definitely not the only process running.
That's as far as I've tested so far. Once the game is a little further developed I'll do some stress testing and try to find any bottlenecks. Will keep you updated.
@slice-beans
At present matter-js assumes the presence of a document object which doesn't exist within node.
Which version? Try with the latest master build if you're not already, you should be able to avoid passing any elements to the engine. Also check out the browserify branch.
Do you plan to release your game? Would be cool to see it!
@Aralun
I also was interested in such a thing, but I was afraid MatterJS would be way too greedy on performances.
The two major performance bottlenecks are the number of simultaneously colliding non-static bodies and rendering.
If you have no renderer in node then you never hit that bottleneck. If you enable sleeping you should be able to handle hundreds (thousands probably) of bodies quite easily I'd guess. I should probably do some benchmarks.
@liabru
I started by using the build provided by npm then moved over to pulling from this git repo directly, pulling the master branch and updated package.json to use matter.js rather than the 0.8.0 build so I think I'm on the latest version. That's the version that I couldn't get working initially so created a fork and made the updates mentioned above.
I haven't tried out the browserify branch yet, although I did see issue #80 and was waiting for a resolution to that. Has that been solved now?
The game is OS, you can see it here: https://github.com/slice-beans/wulfram-2d. It'll be a top down port of a game I used to play called Wulfram 2, hence the name! See the readme for things that have been implemented. Once I've got a few more features added I'll be sticking it on a server for testing so I'll send you over a link when I get to that stage.
I've just committed a fix for this. Please try out the latest master build.
You can do this on nodejs by reinstalling the matter-js
package and then referencing the edge build like so:
var Matter = require('matter-js/build/matter.js');
This will be required for now until the next release.
Note that Matter.Runner
is not yet supported in nodejs, so you'll need your own game loop.
Here's an example:
var Matter = require('matter-js/build/matter.js');
var engine = Matter.Engine.create();
var boxA = Matter.Bodies.rectangle(400, 200, 80, 80);
var boxB = Matter.Bodies.rectangle(450, 50, 80, 80);
var ground = Matter.Bodies.rectangle(400, 610, 810, 60, { isStatic: true });
Matter.World.add(engine.world, [boxA, boxB, ground]);
console.log('boxA', boxA.position);
console.log('boxB', boxB.position);
for (var i = 0; i < 100; i++) {
Matter.Events.trigger(engine, 'tick', { timestamp: engine.timing.timestamp });
Matter.Engine.update(engine, engine.timing.delta);
Matter.Events.trigger(engine, 'afterTick', { timestamp: engine.timing.timestamp });
}
console.log('boxA', boxA.position);
console.log('boxB', boxB.position);
Can you confirm this works for you?
The browserify branch has merged into master.
I'm also using the standalone
build option which outputs a UMD module so it should work everywhere and I've updated the main
field in package.json
so that it points to the latest edge build. This means installing via npm
should also work correctly now.
Thanks @slice-beans for your help. Please update thread #80 if you run into any issues!
i just did an install from NPM. after using the code block from above, node is asking me for a window. any thoughts on how i can get this to work. thank you
@glopratchet can you provide a stack trace please?
@liabru I have the same issue: using var Matter = require('matter-js/build/matter.js');
Starting child process with 'node app.js'
/Users/Ken/Blocklevel/Fussball/node_modules/matter-js/build/matter.js:3605
var _requestAnimationFrame = window.requestAnimationFrame || window.webkit
^
ReferenceError: window is not defined
at /Users/Ken/Blocklevel/Fussball/node_modules/matter-js/build/matter.js:3605:34
at /Users/Ken/Blocklevel/Fussball/node_modules/matter-js/build/matter.js:4250:3
at Object.
using var Matter = rquire('matter-js');
Starting child process with 'node app.js'
/Users/Ken/Blocklevel/Fussball/node_modules/matter-js/build/matter-0.8.0.min.js:7
{return o._nextId++}}();var p={};!function(){var a=60,e=a,h=1e3/a,j=window.req
^
ReferenceError: window is not defined
at /Users/Ken/Blocklevel/Fussball/node_modules/matter-js/build/matter-0.8.0.min.js:7:22846
at /Users/Ken/Blocklevel/Fussball/node_modules/matter-js/build/matter-0.8.0.min.js:7:26335
at Object.
Obviously the client-side code ended up on the server, which causes bad things with globals.
@liabru matter.js is great. Thanks for your work.
i get the same error as ken-blocklevel as i used your sample code. I am trying to make multiplayer game using node.js. Can you please help me on hoe i can retrieve velocities and positions of object without rendering?
I was running into this same issue. using var Matter = require('matter-js/build/matter.js'); Did not work for me either, I got the same error as @ken-blocklevel
I downloaded code to fix it, and after building manually I found that the version generated by the build already contains the fix. So @liabru, you may just need to update the build version in the repo to fix his issue. If you are not ready to cut a new release yet.
@ken-blocklevel in the meantime, just build the project yourself, and import the ./build/matter.js into your project. Worked for me. =]
Thanks for the awesome library btw. =]
This is what I'm using in the meantime. It's quite ugly but it works.
global.document = {
createElement: function(){
// Canvas
return {
getContext: function() {
return {};
}
};
}
};
global.window = {};
var Matter = require('matter-js/build/matter.js');
var World = Matter.World;
var Body = Matter.Body;
var Bodies = Matter.Bodies;
var Engine = Matter.Engine;
var options = {
render: {
element: null,
controller: {
create: function() {},
clear: function() {},
world: function() {}
}
},
input: {
mouse: {}
}
};
var engine = Engine.create(options);
The npm package has been updated, see #170
Thanks!
What's the proper way to get an Engine running on Node in the latest release, v0.10.0?
Engine.run
fails since Runner
appears to be tied to the DOM. I did get the engine loop running using the manual setInterval
that was posted earlier in this thread, but that post is a year old now.
By tied to the DOM do you mean it uses requestAnimationFrame
? If you're running in node you should either update the engine yourself like so:
Engine.update(engine, 1000 / 60);
Or if you want to use Matter.Runner
then you will need to tick it yourself in your own loop:
Runner.tick(runner, engine, time);
I guess it might be a nice idea to make Runner.run
support node though, I think I'd just need to shim requestAnimationFrame
with a node equivalent like setTimeout
. Though I'm not sure how useful this is for server-side physics as you don't normally run them in realtime like you do in the browser.
@liabru Thanks, I see.
It would be helpful to have a quick blurb about Node in the README.md, perhaps a subheader in the Usage section, just to steer people in the right direction and satisfy the ctrl-f for "node".
It might seem obvious that you'd update the engine yourself in a loop on the server, but without reassurance in the readme/wiki, I first wondered if it was even Node-friendly to begin with.
And then I wondered if the trigger/update/trigger cycle as seen in the post from 2015 was still an up-to-date solution: https://github.com/liabru/matter-js/issues/101#issuecomment-116822596.
You're right, I'll add this information to the readme shortly 👍
Not exactly 'shortly'... but I've added a mention of support for Node.js in the readme!
Hello. I'm trying to run the engine "headless".
I folowed this thread and with that code I came up with an unexpected result: without the render collisions do not work and my boxes fall forever
var Matter = require('matter-js/build/matter.js');
var engine = Matter.Engine.create();
var boxA = Matter.Bodies.rectangle(400, 200, 80, 80);
var boxB = Matter.Bodies.rectangle(450, 50, 80, 80);
var ground = Matter.Bodies.rectangle(400, 610, 810, 60, { isStatic: true });
Matter.World.add(engine.world, [boxA, boxB, ground]);
console.log('boxA', boxA.position);
console.log('boxB', boxB.position);
Matter.Engine.update(engine, 10 * 1000);
console.log('boxA', boxA.position);
//With render I get: {x: 392.95126744647774, y: 539.9193206658802}
//Running headless "Engine.update(engine, 10* 1000)" I get: {x: 400, y: 86003.16900000001}
console.log('boxB', boxB.position);
//With render I get: {x: 492.47667249176163, y: 540.009431356056}
//Running headless "Engine.update(engine, 10* 1000)" I get: {x: 450, y: 85853.16900000001}
I tested headless runnig both on browser(ff) and nodejs(v10.3.0) with the same result: my boxes fall forever.
I'm using 0.12.0-14
for browser and 0.14.1
for node (on browser I use via cljsjs project)
EDIT: I Will open a new issue
Same thing here — this bit just makes the object fall through the static floor.
const Matter = require('matter-js');
const engine = Matter.Engine.create();
var world = engine.world;
var thing = Matter.Bodies.circle(0, 5, 0.5);
var floor = Matter.Bodies.rectangle(-100, 10, 200, 1, { isStatic: true });
Matter.World.add(world, [thing, floor]);
module.exports = function() {
Matter.Engine.update(engine, 1000/60);
console.log('thing', thing.position);
console.log('floor', floor.position);
}
I'm using (and really enjoying) matter-js as a physics engine in a MMO game with an authoritative server architecture. To achieve this I need to run the physics simulation for the world on the server as well as the clients.
At present matter-js assumes the presence of a
document
object which doesn't exist within node.To fix, I have included an extra bool option for the engine called
createRenderer
then wrapped theRender.create()
call in a check for this property. There were also a couple of other places I needed to wrap, or return a function immediately, but once that was done everything worked perfectly.Not sure if my solution is the best way to achieve this behaviour, but it would be a nice addition for scenarios such as mine.