Simulo is a web-based TypeScript 2D physics sandbox and game engine with scripting support and soon multiplayer. It uses Box2D for physics and currently Canvas for rendering, though WebGL support is planned.
If you're interested in contributing to Simulo or just curious about how it works, you've come to the right place! This guide will explain everything, like how to run Simulo, the architecture of Simulo, and much more.
Firstly, when we say "server" in this guide, we mean the host of the Simulo room. When we are talking about the web server, we will explicitly say "web server", so keep that in mind and remember that the host often runs on the client.
Simulo is a TypeScript project which is designed to let both the web server and the client host. As multiplayer support is currently broken, hosting on the web server has not been tested in a while, but even if it doesn't currently work, it should be easy to fix.
The Simulo web server uses Node.js Express, and the client uses a custom game engine (named the Simulo engine or just Simulo) which uses Box2D for physics and Canvas for rendering. No framework is used on the UI to keep things simple, as it's just one page. Soon, a basic Simulo website will be set up, and since it'll just be 2-3 pages, it will most likely not use a framework either, though this is subject to change.
If you don't have Node.js, NPM and Git installed, install them now. You can find them at https://nodejs.org/en/ and https://git-scm.com/downloads respectively.
Clone the repository with this command:
git clone https://github.com/Carroted/Simulo.git
Or, if you have GitHub SSH set up:
git clone [email protected]:Carroted/Simulo
Next, you should install the dependencies. To do this, run this command:
npm i
Finally, you can build and run Simulo. To do this, run this command:
npm run build && npm start
If you want to start it later without rebuilding, you can just run this command:
npm start
The opposite is true for building without starting.
Building will take between 10 and 40 seconds, so try not to get frustrated if it takes a while.
In Simulo, we have 3 kinds of modules. These are client modules, server modules and shared modules.
Client modules are only run on the client, server modules are only run on the server, and shared modules are run on both the client and the server. This is useful for things like physics, which need to be run on both the client and the server. (remember again, by server we mean host, not web server)
Here's a handy table of most modules:
Name | Description |
---|---|
SimuloPhysicsServer |
Wrapper of Box2D (liquidfun-wasm) which makes it way easier to use |
SimuloNetworkServer |
WebRTC and WebSocket server |
SimuloNetworkClient |
Receives data from NetworkServer , which is sometimes the client (loopback) |
SimuloViewer |
Displays the world, plays sounds and captures input from mouse, controller and keyboard |
SimuloClientController |
Controls the client, gets input from Viewer and sends it to NetworkClient |
SimuloServerController |
Hosts the room and manages the physics, tools and more |
SimuloLocalClient |
Works identically to NetworkClient , but instead of getting data from network, it gets it directly from ServerController to avoid host sending data through network back to itself |
Here's a handy diagram to help you understand how the server-side physics works:
Here we have 3 modules running on the server:
SimuloPhysicsServer
- Wrapper of Box2D (liquidfun-wasm) which makes it way easier to useSimuloServerController
- Hosts the room and manages the physics, tools and moreSimuloNetworkServer
- Currently broken, but hosts WebRTC and WebSocket
We also have 3 modules running on the client:
SimuloNetworkClient
- Currently broken, but connects to the server via WebRTC and WebSocketSimuloClientController
- Manages UI, tools,NetworkClient
andViewer
SimuloViewer
- RendersSimuloShape
data and sets up panning and zooming (will be moved toSimuloClientController
soon)
Here we have a peer as the host, with another peer connected to it:
You'll notice it's almost the same, except for the 3 new nodes attached to SimuloServerController
:
SimuloLocalClient
- Loopback which connects directly toSimuloServerController
and is used for the hostSimuloViewer
- RendersSimuloShape
data and sets up panning and zooming (will be moved toSimuloClientController
soon)SimuloClientController
- Manages UI, tools,NetworkClient
andViewer
Same but singleplayer:
We just cut off SimuloNetworkServer
and everything connected to it.
Here's a handy diagram of the file structure:
- 📂 client - Assets and source for the client all in one
- 📂 assets
- 📂 fonts
- 📂 sounds
- 📂 textures
- 📂 icons - Custom icons and overrides of the MDI icons we serve at /icons
- 📂 src - TypeScript source for client-only scripts
- 📄 index.html
- 📄 index.css
- 📄 manifest.json
- 📄 sw.js
- 📄 tsconfig.json - Config for the TypeScript compiler
- 📂 assets
- 📂 media - Icons and logos
- 📂 server - Source for the web server
- 📂 src - TypeScript source for server-only scripts
- 📄 tsconfig.json - Config for the TypeScript compiler
- 📂 shared - Source for scripts shared between the client and server
- 📂 src - TypeScript source for shared scripts
- 📄 themes.ts - Previously
themes.json
but turned into a module to useimport
for it - 📄 tsconfig.json - Config for the TypeScript compiler
- 📄 assetFloatEqual.js - May be deleted soon or converted to TypeScript
- 📄 build.js - Builds Simulo to
📂 dist
- 📄 deploy.js - If you have write access to the Simulo repo, it will deploy to the
gh-pages
branch - 📄 Inkscape Workspace.svg - Workspace for Inkscape where logos and textures are made
- 📄 package.json
- 📄 README.md - Look, it's me!
- 📄 tsedition - Just something I'm working on for scripting API, ignore it
Since a lot of modules are shared between the client and server, it's easier to have them in the same repo.
To get started, check out the issues at https://github.com/Carroted/Simulo/issues/. If you want to contribute, fork the repo and make a pull request. If you want to make a big change, make an issue first so we can discuss it.
That's a good question.