In Morterra, if you rotate the camera while walking, you will experience a massive ping spike until the camera stops rotating. This started happening out of the blue (not after any updates), and only happens to some users (didn’t happen to me for quite some time but just recently started happening).
I have narrowed it down in the code to 2 different functions being called within the runRenderLoop().
One is a socket.emit(), where the new player direction is sent to the server (when it changes).
The other is a scene.pick() function that is used to show the user a description of the object they’re hovering over.
Each of these functions cause the game to stop sending & receiving any packets while the player is rotating the camera. What’s really bizarre is that this lag doesn’t happen when the Chrome developer console is open.
Does anyone have any ideas on what could be causing this?
scene.pick()
is a blocking operator, and will take as long as it “needs” in order to provide the right information. There are many ways to optimize this - set the right predicate (or set a minimal set of meshes to be “pickable”), use a short(er) ray, and some even integrated a different ray-tracing approach than what we are using. Until this function finishes its important job, the render loop will be blocked.
socket.emit
should not be bloacking (as far as I know), unless you run some heavy calculations before emiting. But you could offload those calls to a service worker, and have it run independently, outside of the render loop. The entire network connection can be offloaded to a worker, and have messages sent to the main thread, that will process them during the render loop. You can also offload the heavy pick function to a different worker, but that would require having a copy of your entire scene at the worker (and constantly updating it, if needed), so I wouldn’t entirely recommend that. It is, however, possible - I did something similar a few years ago - Collisions using Workers for BabylonJS (Part 1)
3 Likes
Thanks for the feedback!
I had the same thoughts, but scene.pick is returning in 2-3 millis, and showing no FPS drops whatsoever. The render loop takes very little time to execute. If picking is blocking the packets from being received or sent, it would have to be taking a long time to process, and then the packets would send upon completion, but they aren’t. If you continually drag your mouse around it will just completely block out any packets being sent/received, meanwhile the render loop is still being called as quickly as usual.
" socket.emit
should not be bloacking (as far as I know), unless you run some heavy calculations before emiting" - I’m only commenting out the socket.emit call, leaving all of my other calculations intact, and the lag stops.
I’m not sure how I’ll come up with a real solution for this problem because I can’t seem to find a true reason behind it. The same code that is “causing” the problem has been the same and working without any flaws for over a year. It didn’t come after any updates, it only happens for some users, and magically the problem won’t occur if the Chrome developer console is open.
My only theory is that there’s some issue with the most recent Chrome update, so maybe only users with the latest version experience the issue. I was hoping someone on here has had a similar experience.
Anyways, my hacky fix is to just only call the pick and emit functions every 5th render.