Jump to content

Phaser Bug(?) when reloading page with F5


Tom Atom
 Share

Recommended Posts

Hi, I have strange bug.

 

During early development I am using Firefox (currently 40.0.3) as it allows me to test game without server - it is only browser (from FF, IE, Chrome), that loads .json and .xml files. With this, I can load texture atlases.

 

Today I encountered strange issue - I have big atlas (2048x2048) and and it has also size over 2MB. When I run game it displays test sprite from atlas, but when I press F5 to reload that page, the test sprite is not displayed

 I found that this does not happen when:

 - I decrease size (in Kb - not dimension) of image (used tinyPNG to do this). Then pressing F5 reloads page and displays test sprite,

 - it works without changing Kb size of image in Phaser 2.2.2, but does not work from Phaser 2.3.0 on. In Phaser 2.3.0 texture in texture cache is replaced with texture with 0x0 dimensions,

 - when I delete browser caches and then press F5, everything is also OK (only for very next reload),

 - tried to put it on remote server and everything worked fine,

 

 In attached file there are two files: index222.html and index230.html (the number is Phaser version). Also assets are included. To test it unpack on disk and run index222.html in Firefox - when pressing F5 it reloads page and test sprite is visible. Then do the same with index230.html - after pressing F5 test sprite disappears.

 

 I also found, that this problem appears only when loading atlas - if you load the texture as image (uncomment line in indexxxx.html) then texture is correctly reloaded on every F5 press (of course mess - part of atlas - is displayed as an image)

 

BugExample.zip

 

 

 I am not sure whether it is Phaser bug - it worked until version 2.2.2 and stopped from 2.3.0. On the other hand it may be some Firefox issue when running the game's .html file locally.

 

 Does anyone have idea, what it could be?

Link to comment
Share on other sites

There is no bug and nobody is to blame.

 

It's clearly the cache. Now do yourself a favor and invest some little time to get a small server running. The whole world is doing it- so you can do it. You don't need to use a full blown lamp, wamp or mamp stack. I hated this in the past too. Guess what? There a faster solutions: Try using the python webserver (`python -m SimpleHTTPServer 8000`) or install node.js and use the fast ws package to boot up a webserver in every folder you want with `ws` within milliseconds. You will a get a webserver which will serve all the files from the current folder.

 

You can do this on every OS in no time nowadays. And trust me, you will sing hallelujah afterwards and thank me for the rest of your life if you don't forget do turn of the cache in your browser- as it's still caching your pages otherwise.

 

Good luck and have fun developing.

George

Link to comment
Share on other sites

This happens to me too using a webserver (grunt connect with a watcher that reloads on changes). It doesn't happen on chrome so it's probably some issue with firefox. It thought it had to do with nightky but I reverted to ff stable and it keeps happening

Link to comment
Share on other sites

I can now confirm, that it also happens with remote server, but again - only with Phaser version 2.3.0 and higher. With 2.2.2 it is OK.

 

Here are two links to simple test:

1) with Phaser 2.3.0 or higher: http://sbc.littlecolor.com/bug230/

 First time it displays image (see first load image below).

 After pressing F5 and reload it displays nothing (see image reload below)

 

2) with Phaser 2.2.2: http://sbc.littlecolor.com/bug222/

 You can press F5 lot of times and sprite is displayed all the time on screen

 

 

 I prevented FF from using caches with these settings:

browser.cache.disk.enable = false

browser.cache.memory.enable = false

network.http.use-cache = false

 

 In case 1) you can repeate whole cycle (first load - reloads) if you manually clear caches (ctrl+shift+delete) ... but there should be nothing as I prevented using them?!

 

 

 

 Additional information - already in original post, but to emphasize it: problem is only with atlas - not with image. If I am loading the same image as image then I can do reloads even on 2.3.0 or higher without problem. This. is full source of example and commenting and uncommenting lines in create swithces from image to atlas and vice versa:

    <script>    var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create });    function preload() {      this.load.image("Game", "assets/atlas/Game.png");      //this.load.atlas("Game", "assets/atlas/Game.png", "assets/atlas/Game.json");    }    function create() {      var test = game.add.sprite(200, 200, 'Game', 0);    }        </script>

image first load:

post-12887-0-47395600-1442909497.jpg

 

image reload:

post-12887-0-75855200-1442909497.jpg

 

Link to comment
Share on other sites

@rich, MichaelD

 

 to simulate the issue these settings in about:config has to be set to false:

browser.cache.disk.enable = false

browser.cache.memory.enable = false

network.http.use-cache = false

 

 It says you do not want to use cache, but it looks like some garbage is still left in it - see more below.

 

Cache disabled under Advanced Settings: 'Disable Cache when toolbox is open'.

 

 

Ticking this box solves the issue. Looks like this is "stronger" or working: "do not use caches", without garbage in caches (or maybe not looking into them at all).

 

Why should I? I thought these settings where used to try and solve the issue, correct?

 

 

No, these settings are set to simulate the issue (not to solve it).

 

As it looks to me, by setting those settings to false you say: I do not want to use caches and I want to reload image every time. It seems that FF is reloading image, but it looks like something still resides in cache (maybe some garbage?). Phaser 2.2.2 can handle it, but 2.3.0 does not (if issue occurres and you manually clear caches with ctrl+shift+delete it again works for first F5 reload ... again it looks like something was left in chache despite settings). Setting that tick box in developer settings seems to be another way how to ask for reloading and not using caches which works - both Phaser 2.2.2 and 2.3.0 can handle it.

 And finally it happens only for atlas and not for image ... which is strange.

 

 I can record video if needed...?

Link to comment
Share on other sites

On Win Firefox Ver40.0.3, testing the Phaser230 link, using the browser settings as suggested:

 

browser.cache.disk.enable = false

browser.cache.memory.enable = false

network.http.use-cache = false

 

I get a black screen as does Tom.  I did note that it appears that the sprite creation in create() gets hit way before the Game.png has finished downloading (according to the network trace), which is suspicious.

Link to comment
Share on other sites

This is such an edge-case, even within the realms that is Firefox normal behaviour (if there is such a thing) that I can't see how this could be easily addressed. If Firebug is open, there's no issue. If you don't have a bunch of browser internal settings disabled, there's no issue.

 

This is the code that handles image loading:

    loadImageTag: function (file) {        var _this = this;        file.data = new Image();        file.data.name = file.key;        if (this.crossOrigin)        {            file.data.crossOrigin = this.crossOrigin;        }        file.data.onload = function () {            if (file.data.onload)            {                file.data.onload = null;                file.data.onerror = null;                _this.fileComplete(file);            }        };        file.data.onerror = function () {            if (file.data.onload)            {                file.data.onload = null;                file.data.onerror = null;                _this.fileError(file);            }        };        file.data.src = this.transformUrl(file.url, file);        // Image is immediately-available/cached        if (file.data.complete && file.data.width && file.data.height)        {            file.data.onload = null;            file.data.onerror = null;            this.fileComplete(file);        }    },

Feel free to edit it yourself in your local version of Phaser until it works. Maybe getting rid of the 'file.data.complete' check may do it. Perhaps Firefox incorrectly has that value set when something is in the cache, even if it's not actually there. Sounds like a FF bug to me either way.

Link to comment
Share on other sites

Rich, I took some time to investigate and it seems, it is not as edge as it looked, while it is probably FF issue (even without any wild settings as previously). I found, that in xhr.onload the file.data.width and file.data.height are temporarily set to 0 if image is taken from cache. I know it sounds strange, but I will try to prove it:

 

 In the source I put console logs on various places. This is output of loading atlas if you run it first time (adding sprite is 4 seconds delayed - I will explain later):

file:///D:/aaa/qqq/js/phaser230.js"Phaser v2.3.0 | Pixi.js v2.2.8 | WebGL | WebAudio | http://phaser.io"         phaser230.js:26170:13file:///D:/aaa/qqq/assets/atlas/Game.pngimage loaded                     phaser230.js:56190:42                  1)calling xhr load 2048x2048             phaser230.js:56542:27            2)before call to xhr.send 2048x2048         phaser230.js:56339:9          3)after call to xhr.send 2048x2048         phaser230.js:56341:9           4)file complete 2048x2048             phaser230.js:56632:9                5)in xhr.onload 2048x2048             phaser230.js:56291:23               6)in jsonLoadComplete 2048x2048             phaser230.js:56645:9          7)adding atlas 2048x2048                 phaser230.js:56660:17            8)texture data = 2048x2048             phaser230.js:53296:1               9)in asyncComplete 2048x2048             phaser230.js:55979:9            10)add sprite                                                             11)

1) image is loaded - callback file.data.onload in loadImageTag() is called,

2) as it is atlas there is xhr call to load json file - in this time dimension of image is 2048x2048

3,4) output before and after call to xhr.send() - still everything ok,

5) end of method for loading image - ok,

6) xhr.onload callback called - image dimension still 2048x2048 ... ok,

7), 8), 9), 10) rest of the loading of atlas is OK,

11) waiting 4 seconds and adding sprite - here is no reason to wait (again, will get to this later)

 

 So far everything OK.

 

 Now, if you press F5 to reload the output is like this:

file:///D:/aaa/qqq/js/phaser230.js"Phaser v2.3.0 | Pixi.js v2.2.8 | WebGL | WebAudio | http://phaser.io" phaser230.js:26170:13file:///D:/aaa/qqq/assets/atlas/Game.pngimage from cache 2048x2048             phaser230.js:56209:38         1)calling xhr load 2048x2048             phaser230.js:56542:27         2)before call to xhr.send 2048x2048         phaser230.js:56339:9       3)after call to xhr.send 2048x2048         phaser230.js:56341:9        4)file complete 2048x2048             phaser230.js:56632:9             5)in xhr.onload 0x0                 phaser230.js:56291:23              6) !!!in jsonLoadComplete 0x0             phaser230.js:56645:9             7)adding atlas 0x0                 phaser230.js:56660:17               8)texture data = 0x0                 phaser230.js:53296:1              9)in asyncComplete 0x0                 phaser230.js:55979:9           10)add sprite                                                          11)

1) image is taken from cache - dimension is ok 2048x2048,

2), 3), 4), 5) image is still (file.data.width and file.data.height) correct,

6) in xhr.onload it suddenly changes to 0, 0

7), 8), 9) 10) and it stays zero until setting atlas, and creating texture - so textures are 0x0 and there is nothing on screen

11) sprite is added with 4 seconds delay - nothing is on screen as atlas texture is wrong

 

Now, if you add any small delay from xhr.onload on the output will be different. Lets, add it to jsonLoadComplete, just before atlas is added (here is reason why I am adding sprite with 4 sec delay - I have to wait in this case till the atlas is created).:

         :        else        {            this.game.time.events.add(1000, function() {                console.log("adding atlas " + file.data.width + "x" + file.data.height);                this.game.cache.addTextureAtlas(file.key, file.url, file.data, data, file.format);                }, this);        }        :

And output is this:

file:///D:/aaa/qqq/js/phaser230.js"Phaser v2.3.0 | Pixi.js v2.2.8 | WebGL | WebAudio | http://phaser.io" phaser230.js:26170:13file:///D:/aaa/qqq/assets/atlas/Game.pngimage from cache 2048x2048             phaser230.js:56209:38           1)calling xhr load 2048x2048             phaser230.js:56542:27           2)before call to xhr.send 2048x2048         phaser230.js:56339:9         3)after call to xhr.send 2048x2048         phaser230.js:56341:9          4)file complete 2048x2048             phaser230.js:56632:9               5)in xhr.onload 0x0                 phaser230.js:56291:23                6) !!!in jsonLoadComplete 0x0             phaser230.js:56645:9               7)in asyncComplete 0x0                 phaser230.js:55979:9              8)adding atlas 2048x2048                 phaser230.js:56660:17           9) !!!texture data = 2048x2048             phaser230.js:53296:1             10)add sprite

1) image taken from cache - dimensions OK,

2), 3) 4), 5) still everything OK,

6) in xhr.onload callback - dimensions are set to 0x0,

7), 8) still zero until we get to 1 second delay we added,

9) and WOW!... dimensions returned back to 2048x2048 after small delay,

10) atlas textures are correct, everything OK

11) sprite is added - 4 second delay is just higher delay than delay in atlas loading

 

And... yes everything works!

 

 You can also check it with break points - if you place breakpoint anywhere from xhr.onload on and then press resume, everything works as your break created small delay. If it is without breakpoint you get wrong texture dimension (0x0)

 

Various points:

* yesterday in my original post I wrote, that small images are OK, but big are problem ... the problem is most easy to simulate without any wild settings if you download test code and run it with FF locally without server. My conclusion is that that delay is proportional to size of the image (like there is time  needed to decode it?). If you run on network, there is delay in loading .json and it gives time to image to be processed (decoded?). If you run it locally, json is loaded quickly and you run into issue, that can be solved with that small delay. It means: if you have big images and fast network, you are more likely to run into the issue.

* these FF settings from morning were to not use cache, but it looked, like there is still something in it. I found on internet, that it should prevent caching decoded image, but not caching image data from network. It means, that setting it increased probability of the problem (if the delay is really from decoding the image... but it makes sense),

* the setting in developer console, you was using prevents any caching, so everything had to be downloaded and network transfer delay gave time to image to decode - everything worked

 

 Maybe the reason for temporary reseting width and height to zero is different...? But it only happens when xhr request follows. If you instead of atlas load image, then there is no problem and dimensions are correct all the time (which is little bit against my "decoding" theory, so the explanation may be different)

 

Here is test project (Phaser 2.3.0) with those console comments in it:

xhrLoadingBug.zip

 

 

 

 

Link to comment
Share on other sites

Found, that file.data.complete is reset to false for short time period as well as width and height are set to zero (see my previous post). It is only done if xhr.load request follows (as well as for width and height).

 

Commenting this piece of code in loadImageTag solves the issue:

/*// Image is immediately-available/cachedif (file.data.complete && file.data.width && file.data.height){file.data.onload = null;file.data.onerror = null;this.fileComplete(file);}*/

 If image is in cache, it is taken from there anyway, only fileComplete is called from onload callback ... looks like FF needs it in this way. And again: problem happens only if image loading is followed with loading of other file throught xhrLoad (.json for atlas). If loading only image then previous piece of code can be left uncommented.

Link to comment
Share on other sites

  • 3 months later...

Thanks Tom!

 

I encountered the same issue when using FF, but OK when using Chrome or IE.

Now FF is OK with the solution above.

 

+1, thanks Tom!

My program had this same issue on Firefox 43.0.2.

Note, my browser had the following settings by default:

browser.cache.disk.enable = false

browser.cache.memory.enable = false

The bug also repros for me with a lot of the examples on phaser.io when I disable the browser cache through firebug.

For example: http://phaser.io/examples/v2/loader/load-texture-atlas

 

While searching for a solution, I found this thread: http://www.html5gamedevs.com/topic/15111-atlasxml-texture-loading-issue-in-mozilla/ which seems to indicate that someone else encountered this problem. I agree with Tom that this isn't such an edge case.

Commenting out the code in loadImageTag solves the problem. Is there a downside to doing that? Or, should this fix be included in the next release of Phaser?

Link to comment
Share on other sites

  • 3 weeks later...

I have had exactly the same issue with FF43.0.1 and 43.0.4 on Windows 10.

Colleagues on similar systems do not have this problem. Could it be a hardware issue?

Using Tom Atoms fix did the trick for me though commenting out the following in Phaser.Loader loadImageTag

/*// Image is immediately-available/cachedif (file.data.complete && file.data.width && file.data.height){file.data.onload = null;file.data.onerror = null;this.fileComplete(file);}*/
Link to comment
Share on other sites

3 minutes ago, r8n5n said:

Colleagues on similar systems do not have this problem. Could it be a hardware issue?

Seems a bit of a leap... I'd be guessing something like race condition or that some hardware/driver combination aggravates the issue before calling this a "hardware issue"

Link to comment
Share on other sites

  • 5 months later...

Firefox newly sends error messages into console:

consoleError.png

 So, if you have black texture instead of your sprites and get this in console, then your game works, but there is FireFox issue. Note, black texture means completely black texture - if you get black texture with green border and crossing, then problem is probably in your game (loading assets or using incorrect frame or frameName).

 Workaround - commenting these lines in loadImageTag() still works:

        if (file.data.complete && file.data.width && file.data.height)
        {
            file.data.onload = null;
            file.data.onerror = null;
            this.fileComplete(file);
        }

 

Link to comment
Share on other sites

  • 1 month later...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...