Limit of babylon/javscript for RTS game ? Need advice

Hello,

I would like to create a 3D RTS-style game, and I’ve already been experimenting with BabylonJS. I have a few questions, particularly regarding whether this framework is robust enough to handle an RTS game. I assume that the best practice is to make the most use of GPUs, which seems logical, but I still wonder to what extent I might be limited by the framework or JavaScript itself.

For example, when I try to load 200 models (soldier.glb) with an active animation, I already reach a limit (it drops to 30 FPS): https://playground.babylonjs.com/#AJA5J6#291

If I switch to a model without textures, around 125KB, I can add just a few more. (I would have shown another playground with a smaller model, but there is a cross-origin problem.)

From what I understand from the performance analysis in Chromium, it’s the animations that degrade the performance.

I have also noticed that the glow effect can completely ruin performance as well. Do procedural textures (I haven’t managed to export them through the NDE yet, but I hoped to) also affect performance negatively?

Finally, since it’s an RTS, the units need to be pickable, so I have enclosed each unit in an invisible cube and disabled picking for child meshes, but it doesn’t seem to make much of a difference.

Bonus questions:

  • Regarding the environment (trees, grass…), I understood that it’s necessary to convert everything to a particle system. If you could confirm that, I’d appreciate it.
  • Are there any GPU-transferable calculation techniques ? Specifically, any tips/documentation to avoid relying on the browser for various calculations ?
  • If we decide to package the game as a standalone application with an embedded Chromium for example, could we tweak it to significantly improve performance ?

I’m a bit surprised not to see any truly polished games with BabylonJS. I feel that it has great potential, but it’s hard to overlook that demos like “rts” and “picoRTS” don’t inspire confidence.

Thank you for your help

1 Like

I’ll try to clarify some questions using my poor knowledge of Babylon and my bad sense of humour :slight_smile:

As example - https://shellshock.io/ ; this it not RTS but FPS. There are much more games actually, they just don’t announce loudly that they are made with Babylon.

As a game engine, Babylon is definitely suited for all kinds of games, RTS included. One may also notice that among open source WebGL frameworks Babylon.js supports almost everything out of the box, being ahead in this regard to other ones.

Most limitations are usually coming from usage. The framework itself just doing work with libraries as WebGL and WebGPU more comfortable. As any programming language JavaScript has good and bad sides.

There are different techniques aimed to optimize a scene. When you have 200 models you need to use clones, instances or thin instances. This is the common practice to all game engines, independent of language. More in the docs - Copies, Clones, and Instancing | Babylon.js Documentation
The simple example of soldier cloning and using animations independently - https://playground.babylonjs.com/#AJA5J6#99
Another trick is to use baked animations (VATs) - Baked Texture Animations | Babylon.js Documentation
Example with 500 robots - https://playground.babylonjs.com/#CP2RN9#140

This section will help - https://doc.babylonjs.com/toolsAndResources/thePlayground/externalPGAssets

It’s the number of independent animations running simultaneously. It is a matter of logic how to reduce the number of animations (with instancing, with stopping them when not visible etc).

To reduce the number of draw calls when using Glow layer one needs to keep the list of included meshes as small as possible - Making Meshes Glow | Babylon.js Documentation

Any thing which you add to a scene is able to affect performance; the real effect depends on usage.

There is a tiny difference for each render frame; a good optimization is the sum of such tiny differences.

It is not nececcary. It is possible, for example, to populate a dynamic terrain with SPS as here - Adding Objects to a Dynamic Terrain | Babylon.js Documentation
Or using grass and trees chunk system with shader blades - GitHub - BarthPaleologue/AssetScattering: A procedural scattering system for assets based on instancing, running in the browser.
Basically, for such things as trees and grass instancing or thin instancing is a must.

Actually Babylon is designed to pass to GPU what should be done at GPU side. But the game logic is performed by CPU, and if you use browser, you may pass some complex processing to workers and wasms. If you don’t want to use browser you may try BabylonNative - GitHub - BabylonJS/BabylonNative: Build cross-platform native applications with the power of the Babylon.js JavaScript framework

You may deliver it as .exe or PWA or what else, including only the elements which you need. As example you may have a look at Noa voxel engine (used, for example in MineCraft Classic), based on Babylon.js and reduced to the needed minimum.

As I already mentioned, there are some, and some are quite successful. To produce a truly polished game one needs some decent budget, and if you have some, be sure I may be able to help to spend it in truly Babylonian way :slight_smile:

10 Likes

Try Havok picking via raycasts instead. That gave me a huge boost in fps.

I think the reason behind that is to lower draw calls. And using a particle system or merging meshes are ways to accompish that. Anyway, this is going to be way more complex: it will span your asset workflows, the assets themslves and how you code it into Babylon. For instance, if you merge meshes, they need to have the same material (in order to stay within 1 draw call). Then you have the limit that you can only have 1 color texture (/normal/metal/emissive) per material. This ofc sucks big times because how are you going to merge these two models each with their unique 4K textures?

Come to think of it, you probably will have to deal with these challenges in all engines. So it is not just a “Babylon” or “Javascript” problem. More like a gamedev problem.

But you need to include non-glowing occluders as well. And that probably leaves the majority of meshes in :frowning: I have ended up making “Glowy effects” a game config option and informing players about its significant fps impact.

4 Likes

Wow, thank you so much for your feedback, I couldn’t hope for better responses! :heartbeat:

Games with Babylon
Regarding games using BabylonJS, it’s impossible not to mention shellshock ! I also found mvrkracer.mvrk.co; overall, it must be admitted that there isn’t much else. That being said, my strong belief is that in reality, Babylon is still young and very powerful and the video game market doesn’t yet target this type of technology much, but that’s changing.

Javascript limitation
As for limitations with JavaScript, I was mainly thinking about it being an interpreted and single-threaded language. Concerning workers, from what I’ve read, it’s not viable at all; the cost of serialization is far too high, and workers should only be used for heavy calculations that take time. In the context of a game, the calculations are small and frequent, and the gains are lost during transfers with the main thread. But I realize that before reaching this kind of issue, there are a thousand things to optimize, and in reality, these aspects are negligible.

Character animations
From what I undertsand, pre-compiled VATs seem to be THE solution for an RTS-type game!

It is a matter of logic how to reduce the number of animations (with instancing, with stopping them when not visible etc).

I assumed that by default what wasn’t in the camera’s field wasn’t calculated, but unsurprisingly, I see it’s a bit more subtle :slight_smile:

Glow effect
I thought I just have to use addIncludedOnlyMesh but it seems more complicated, I don’t have notion of occluders. Anyway I don’t need to use this feature for now.

Pickable meshs
I read that it “could” ruin performance, but for now, it’s not the case. So, thank you, I’ll switch to Havok raypicking if I encounter any issues.

Environment (also pickable)
Finally, concerning decorative objects, I’m in the dark. SPMap is for dynamicTerrain, but under the hood it is an SPS that’s being used.
Merging meshes is also mentioned, but the documentation doesn’t specify the use case. From what I understand about you said, merging meshes only brings performance gains if there’s only one material, which doesn’t seem feasible since the meshes will typically be imported from outside sources like Sketchfab. Having only one material (to get a single draw call) would mean reworking the modeling of many objects. And if we keep multiple materials on the merged mesh, I suppose we ultimately gain nothing compared to a simple TransformNode parent.

Suppose we have a (HeightMap) terrain of a fixed size with many decorative objects (let’s say 1000 identical trees and 1000 identical rocks). Each element have a position, and some are pickable and destructible. So is it preferable to use an SPS or thinInstances ?
(I am not ready to use dynamic terrain creation; there’s just too much to learn all at once)

GitHub - BarthPaleologue/AssetScattering: A procedural scattering system for assets based on instancing, running in the browser.

Thank you for this great link! It’s very technical, and I feel like I’m starting from scratch… but this is gold mine.

1 Like

I would say the best thing you could do is compare each alternative yourself in a playground. Also add normal instances to your test. Maybe imposter sprites, too.

To be fair, this is a huge new requirement.

I would first try normal instances (simpler code, KISS). If fps suck, think about ways around.

Also there is LOD and culling. Not sure if/how this works for thin instances and solid particles. So this might speak for normal instances.

1 Like

As I understand it the main performance challenges for RTS outside of employing the graphical optimizations mentioned here are from collisions and pathing of the large number of units. I would guess workers to be indispensable here, no experience but that is my impression.

2 Likes

Hello,
on this exact topic of RTS performance and challenges, I recently found this article: creating thousands of animated entities in babylon.js with its playground demo

4 Likes

Thank you @SerialF !
Very interesting