The real difficulty is integrating the current game engine with the potential wasm library - there is a careful balance to be found between not giving enough information to the wasm library (that would result in having to transfer too much data at every call, making the overhead too big) and giving it too much (that would result in having to rewrite most of the game engine in this library).
I’ve made this fairly large Pull Request a while ago: https://github.com/4ian/GDevelop/pull/1393
It introduce a
gdjs.ObjectPositionsManager, which is a class responsible for holding the position of objects, their hitboxes, and giving operations like compute collisions, compute distances, etc…
Once we have this abstraction we could:
Then, we could remove this JS implementation of a
gdjs.ObjectPositionsManager and instead implement it in Rust/C++/whatever compiled to wasm. This would be possible because
gdjs.ObjectPositionsManager was designed with an API that only use simple datastructures and deal with objects using their ids (so it means that for example if you want to test the collision between objects, you just have to pass their ids, which are numbers. You don’t have to serialize the full object).
Unfortunately I stopped because the performance improved in a lot of cases, but performance was also worse in some other cases for example the Asteroids example with 1500 asteroids.
This is because in some situations, it becomes more time consuming to update the
gdjs.ObjectPositionsManager every time an object moves, rather than doing what we do now (which is to not done anything, and let the collision conditions iterate on all objects).
Of course it’s something that we can expect: there will be always a situation where the performance, even with a smart spatial partitioning, will be worse than a naive approach. So I also added an implementation of gdjs.ObjectPositionsManager that would do nothing (i.e: it would just register object position, and the collision conditions would just iterate on all objects).
But even with this, some examples were still having a decreased performance, because of the “bookeeping” work of calling a function like
this._runtimeScene.getObjectPositionsManager().markObjectAsDirty(this); every time an object is moved.
If you want to take a look and help, you can fetch the branch (expect some merge conflicts to happen and to be solved). You’ll see that
gdjs.ListObjectPositionsContainer is the “naive” class doing no special bookeeping of objects. I’d like this class to be as performant as now in the case of lots of objects being moved (like the Asteroids example with 1500 asteroids). If we can find a way to do so, we would then be able to offer an option to activate spatial partitioning (
gdjs.RTreeObjectPositionsContainer: it’s a RTree)
and then even replace this last class by a wasm powered library, which would offer predictable performance
(for example, funnily enough, when I was doing benchmarks between
gdjs.ListObjectPositionsContainer, it was important to reload the preview multiple time, to give the time to the JS engine to Just-In-Time compile the “hot” functions).