Random, bizzare black screen mid game

Hi,
I’m a massive fan of Phaser and really enjoy programming with it.

However I have come across an rather severe issue. Randomly during my game, people’s screen’s go completely black. It’s just Phaser that does this. My VueJS overlay is unaffected and their connection to the server is also unaffected, intact they can still play the game, the controls which are listened to via Phaser work fine. It is just the graphics that stop.

Furthermore, this issue appears to occur far more frequently on some computers over others.

My work around for now is adding functionality to the F10 key that reloads the phaser instance. However this is obviously not a permanent fix.

I know that I am not providing much technical info on this problem but that’s because I have really no idea what’s causing it!

I would really appreciate some help.

Stan

Do any errors appear in the browser’s console? It sounds like the WebGL context is being lost, which is done by the browser if your game takes up too many resources. From what I’ve tested, Phaser can’t recover from a lost context, but I haven’t dealt with cases of this in practice, so I’m not sure if it’s even possible to regain the context after you’ve lost it once.

Assuming that this is the problem, there isn’t really a way to predict it. I guess you could check that the game doesn’t do anything too expensive?

Thank you,

Yeah it would make sense. The game is relatively intensive. Is there anything I could perhaps do to improve this?

Is there anyway to stop browsers from killing the game when it is taking up a lot of resources?

As I said in my previous post, it’s up to the browser. The unprivileged, sandboxed environment you work in is one of the downsides of developing games on the web platform. The only thing you can do is make the game less resource-intensive, perhaps by introducing different options for different platforms or by using canvas instead of WebGL (since context loss cannot happen with the canvas renderer).

In any case, the first thing you should do is figure out whether context loss really is the culprit here. The contextLost property of the renderer (this.game.renderer) can help if you have no access to console logs.

1 Like

I added a listener to the contextLostHandler, but it didn’t get called when the back screen error occurs. And the contextLost Boolean isn’t set to true either. I tried switching the renderer to canvas but this just makes the whole game slow, laggy and a bit buggy.

And yeah, there are no console errors or warnings at all when these black screens occur.

What are some of the settings I could perhaps change to increase performance?

If there are no warnings or signs that the context’s been lost, I have no idea what this is. At this point, I can’t say whether my advice about resource intensity is still valid, but if it’s a solution you still want to attempt, performance is generally adversely affected by the canvas size, the number of Game Objects you have, blend modes, custom pipelines, and masks.

Hmmm, the canvas is fullscreen but there are never any more than 40 objects on screen at once. Also the processing is pretty minimal on the phaser instance, I don’t use any physics. The objects are just interpolated from the server positions. I am unfamiliar with blend modes and custom pipelines, but I don’t think my game uses them. I do uses a few particle systems, but not excessively.

Ok so I have discovered the issue. It is caused when the camera is zoomed to match the display size so that everyone sees the same amount of the map no matter the computer. With this information is there anything else you think could help?

Camera zoom is supposed to be a finite number greater than 0. Negative numbers, Infinity, and NaN produce weird effects (including a black screen), while 0 will set the scroll values to NaN, which you can only recover from if you directly set them back to a finite number. How do you calculate the zoom, what do the final values end up at, and does anything happen to the scroll (scrollX / scrollY)?

Zoom is only ever set when the page is resized or loaded up for the first time. It’s set to about 0.7 most the time, never 0 or NaN though because then the screen would go instantly black which it never does. I use the camera.centerOn function to make the camera follow interpolated values set by the server.

What I’d do is see what the camera is doing when the screen goes black - logging to displaying as much of its internal state as possible could help.

SOLUTION: if anyone else is having a similar problem. It turns out that on some screen sizes Phaser 3 doesn’t like moving the camera to incredibly specific co ordinates, e.g. (353.534723745143). My game interpolated the camera movement which is why it was coming out with such specific numbers. I just added a round function for both x & y before the camera moves to the position, rounding to 2 decimal places.

var x = Math.round(smooth_x * 100) / 100

3 Likes

How could I reproduce this? Is it via setCenter(), setZoom(), or something else?

Did you try setting roundPixels?

Ahh, yeah roundPixels might have fixed it, I was using camera.centerOn. But the zoom was also being set to something like 1.484738292946 from another part of the code.