Server-Side Matter.js with Socket.io, P5, and Typescript
Recently, I had to develop a simulator with a physics engine for a research project. We decided to use Matter.js as the physics engine because of its Javascript support, features, and good documentation (mostly from 3rd parties). However, I couldn’t find any example on how to run it on the server-side or use it with Typescript (this was my first introduction to Typescript). Eventually, I stumble on many issues ranging from physics engines, rendering, and browser and server-side Typescript. This post shares my experiences in eventually coming up with a solution that runs Matter.js on server side.
Running Matter.js on the server-side wasn’t tricky. However, as my example allowed the physics engine to run its loop, independent of the server loop, I had to play a bit with the runner. The use of Socket.io for WebSockets wasn’t much of trouble either. I had trouble using P5 as the renderer while replacing the built-in Matter.js render. Further, I had a tough time getting Typescript to recognize Socket.io and P5 browser-side scripts, as it wasn’t possible to import ES6 modules. This was a bit difficult even though type defintions were avaibale for both Matter.js and P5.
Example
As seen above, once launched, my example generates a circle for every mouse click on the canvas. Each circle randomly picks a velocity and move towards that direction. If it hits another ball or boundary, it picks another random velocity and moves on. You can open up multiple browsers/tabs and generate more circles, and see the movement of other client’s circles. Circles generated by different browser instances use different colors (only 4 colors are used).
A few learning points in this example include the following:
- Circle positions are generated on the browser informed to the server via WebSockets
- Physics engine on the server-side manages their movement and collisions
- Physics engine runs on its loop (no game loop is used)
- Server-side position of circles are pushed to the renderer on browser at each iteration of physics loop
- Use label with Matter.js bodies to identify the body type
- Runs P5 in the Instanced mode
- Handle physics engine afterTick and collisionStart events
- Global variables and import type used in global.d.ts to overcome the inability to handle ES6 modules on browser - While imports aren’t used, we still need to tell Typescript how to find type definitions and global variables
Installing
git clone https://github.com/dilumb/matter_ws_p5_ts.gitnpm install
Usage
npm run start
This launches the webserver that you can access via: ```
http://localhost:8080/
Open the webpage on multiple browsers or tabs. Then click on the canvas to generate a new circle.
References
- Source code — https://github.com/dilumb/matter_ws_p5_ts
- Matter.js — https://brm.io/matter-js/
- P5 — https://p5js.org/get-started/
- Socket.io — https://github.com/socketio/socket.io