The rendering engine is using Three.js which is a WebGL library. The physics/collision detection code is using Rapier through a WebAssembly module available on npm [1], which means that it can be used on the web even though it's originally written in Rust.
The levels were built inside the Unity Editor, then exported to FBX, then went through a pipeline based on Blender python scripting that optimized their geometry, assigned materials and exported them to GLTF (the final format that we load in the browser).
Nothing complicated, we simply have initialization code that parses the GLTF scene on startup by iterating over the children of a specific group, and creating Rapier colliders for each of them (Triangle Mesh Colliders to be specific, in order to allow things such as curved ramps). Since their geometry is very simple, we can use directly the rendering geometry for the collider geo.
thanks for answering! Interesting you used unity for level layout. Interested to hear the advantage here. Considering you already use Blender down the pipe, how come you haven't used Blender for it or any other dcc app lile maya, max, whatever?
The main draw of the Unity Editor for us is how it auto-reloads assets, like 3D models, as soon as the asset file is updated. So the workflow is having your DCC app open in which you model things and export assets from, and Unity Editor to design your level where every model is always up-to-date.
This is not possible with Blender because it contains all models inside a single .blend file, so assets must be manually re-imported each you change them. There is a Link feature in Blender but in my experience it's not as good as what Unity does out of the box.
The physics engine we are using is Rapier 3D which does a lot of the heavy lifting, even though we had to tweak a lot the physics properties of the ball and surfaces in order to get something that felt right. For hotspots specifically, we implemented the magnet-like effect with custom code (by applying a force that pushes the ball toward the center and slowing it down at the same time) as there is no attractor primitive in Rapier.
The dual input is indeed a consequence of our isometric-view design choice, which I agree may not be the easiest way to control the ball. But the 45 degree angle just looks cooler in our opinion.
Yeah, sometimes the ball does some crazy things due to the way collision detection works. We tried to optimize and avoid most of the issues but it can happen.
There is code in place to respawn the ball if we detect that it's stuck inside a block or wall, which can occur due to frame drops during the physics simulation. I'll try to reproduce this issue. Thanks for reporting it!
I was being malicious and dropped down onto the hovering pink cube outside the play area on the final level. Once you roll off that pink cube your respawn point is on the cube, leaving you stuck and unable to get back to the main course.
NBD but sharing in case you want this kind of playtesting feedback!
Yes this is an old project that we did back in 2015, but thank you for the broken link report, I just fixed it. Also, thanks for your feedback (which I agree with!) but we currently have no plans to update it.
Oh I loved the Journeyman Project as a kid and I didn't think of it at all when creating Equinox, but thanks to your comment I'm now starting to think it had some unconscious influence!
Thanks a lot for your kind words! Metroid Prime wasn't a direct inspiration but it may certainly have had some influence on us, as we loved playing that game when we were younger.
Thanks! About the character height, it's set at 1.6m and all the environment is supposed to be at the right scale, but perhaps we made the doors a bit too short. We tried to convey a bit of claustrophobic feeling, especially in the lower level, as you would expect in this kind of spaceship.
Thanks a lot. I wish there was more too, but we unfortunately had to keep the project's scope under control! Lots of puzzle ideas and content were cut.
The levels were built inside the Unity Editor, then exported to FBX, then went through a pipeline based on Blender python scripting that optimized their geometry, assigned materials and exported them to GLTF (the final format that we load in the browser).
[1] https://rapier.rs/docs/user_guides/javascript/getting_starte...