openfl

Open full view…

[HTML5] Game only loads on some devices

vasco
Fri, 04 Jul 2014 18:44:24 GMT

I am making a game with HaxeFlixel, and I want to export it to HTML5. I am not using a custom backend (using openfl-html5). The game wouldn't load on my desktop PC initially, but then I replaced all wav and mp3 files with ogg files, and now it loads on the PC (works on Firefox and Chrome). It also loads fine on the HTC One X+ Android phone, but the loading bar will get stuck when full (or near full) on the Kindle Fire HD, Sony Tablet S, and iPod Touch 4. What else can I try to make the game load? Thanks in advance!

hcwdikk
Sat, 05 Jul 2014 12:06:25 GMT

Some browsers use mp3s so I think that you need both mp3 files nad ogg.

vasco
Sat, 05 Jul 2014 16:09:49 GMT

So it won't load on some browsers because of the mp3s and on others because of the oggs? :/ Anyway, I don't think the browsers are the issue, because while it loads fine in Firefox on one device, it doesn't load in Firefox on another. I tried several browsers on some devices, and the result doesn't change from browser to browser; the problem seems to be related to the devices themselves.

Nascode
Mon, 07 Jul 2014 04:00:04 GMT

"Make sure you have multiple formats for a sound MP3 and OGG, as no single format is supported everywhere" from http://community.createjs.com/kb/faq/soundjs-faq OpenFL currenctly use SoundJS for sound engine on HTML5 You could also see in console log on firefox to see why your game stuck

vasco
Mon, 07 Jul 2014 16:41:29 GMT

Well, the only reason I didn't include MP3 was because the game wouldn't load otherwise. Thanks for the console log tip, I was able to find an error in Firefox's console log. I know next to nothing of javascript, but the error seems to be in openfl.utils.ByteArray.prototype, specifically at the line: this.data = new DataView(newByteView.buffer); The error is "DataView is not defined" Any ideas?

Nascode
Tue, 08 Jul 2014 03:47:15 GMT

Could you copy paste your haxe code? Especially the error part?

vasco
Tue, 08 Jul 2014 04:05:54 GMT

I don't think the error comes from my haxe code, but from OpenFL's code? It's in the openfl.utils.ByteArray class, although from the javascript I can't figure out where. Here is, from what I can tell, the ByteArray class in javascript (the error happens near the end, on the line I commented with "error happens here"): openfl.utils = {}; openfl.utils.ByteArray = function() { this.littleEndian = false; this.allocated = 0; this.position = 0; this.length = 0; this.___resizeBuffer(this.allocated); }; $hxClasses["openfl.utils.ByteArray"] = openfl.utils.ByteArray; openfl.utils.ByteArray.__name__ = ["openfl","utils","ByteArray"]; openfl.utils.ByteArray.fromBytes = function(inBytes) { var result = new openfl.utils.ByteArray(); result.byteView = new Uint8Array(inBytes.b); result.set_length(result.byteView.length); result.allocated = result.length; return result; }; openfl.utils.ByteArray.__ofBuffer = function(buffer) { var bytes = new openfl.utils.ByteArray(); bytes.set_length(bytes.allocated = buffer.byteLength); bytes.data = new DataView(buffer); bytes.byteView = new Uint8Array(buffer); return bytes; }; openfl.utils.ByteArray.prototype = { bytesAvailable: null ,length: null ,objectEncoding: null ,position: null ,allocated: null ,byteView: null ,data: null ,littleEndian: null ,clear: function() { if(this.allocated < 0) this.___resizeBuffer(this.allocated = Std["int"](Math.max(0,this.allocated * 2))); else if(this.allocated > 0) this.___resizeBuffer(this.allocated = 0); this.length = 0; 0; this.position = 0; } ,readBoolean: function() { return this.readByte() != 0; } ,readByte: function() { var data = this.data; return data.getInt8(this.position++); } ,readBytes: function(bytes,offset,length) { if(length == null) length = 0; if(offset == null) offset = 0; if(offset < 0 || length < 0) throw new openfl.errors.IOError("Read error - Out of bounds"); if(length == 0) length = this.length; var lengthToEnsure = offset + length; if(bytes.length < lengthToEnsure) { if(bytes.allocated < lengthToEnsure) bytes.___resizeBuffer(bytes.allocated = Std["int"](Math.max(lengthToEnsure,bytes.allocated * 2))); else if(bytes.allocated > lengthToEnsure) bytes.___resizeBuffer(bytes.allocated = lengthToEnsure); bytes.length = lengthToEnsure; lengthToEnsure; } bytes.byteView.set(this.byteView.subarray(this.position,this.position + length),offset); bytes.position = offset; this.position += length; if(bytes.position + length > bytes.length) bytes.set_length(bytes.position + length); } ,readDouble: function() { var $double = this.data.getFloat64(this.position,this.littleEndian); this.position += 8; return $double; } ,readFloat: function() { var $float = this.data.getFloat32(this.position,this.littleEndian); this.position += 4; return $float; } ,readFullBytes: function(bytes,pos,len) { if(this.length < len) { if(this.allocated < len) this.___resizeBuffer(this.allocated = Std["int"](Math.max(len,this.allocated * 2))); else if(this.allocated > len) this.___resizeBuffer(this.allocated = len); this.length = len; len; } var _g1 = pos; var _g = pos + len; while(_g1 < _g) { var i = _g1++; var data = this.data; data.setInt8(this.position++,bytes.b[i]); } } ,readInt: function() { var $int = this.data.getInt32(this.position,this.littleEndian); this.position += 4; return $int; } ,readShort: function() { var $short = this.data.getInt16(this.position,this.littleEndian); this.position += 2; return $short; } ,readUnsignedByte: function() { var data = this.data; return data.getUint8(this.position++); } ,readUnsignedInt: function() { var uInt = this.data.getUint32(this.position,this.littleEndian); this.position += 4; return uInt; } ,readUnsignedShort: function() { var uShort = this.data.getUint16(this.position,this.littleEndian); this.position += 2; return uShort; } ,readUTF: function() { var bytesCount = this.readUnsignedShort(); return this.readUTFBytes(bytesCount); } ,readUTFBytes: function(len) { var value = ""; var max = this.position + len; while(this.position < max) { var data = this.data; var c = data.getUint8(this.position++); if(c < 128) { if(c == 0) break; value += String.fromCharCode(c); } else if(c < 224) value += String.fromCharCode((c & 63) << 6 | data.getUint8(this.position++) & 127); else if(c < 240) { var c2 = data.getUint8(this.position++); value += String.fromCharCode((c & 31) << 12 | (c2 & 127) << 6 | data.getUint8(this.position++) & 127); } else { var c21 = data.getUint8(this.position++); var c3 = data.getUint8(this.position++); value += String.fromCharCode((c & 15) << 18 | (c21 & 127) << 12 | c3 << 6 & 127 | data.getUint8(this.position++) & 127); } } return value; } ,toString: function() { var cachePosition = this.position; this.position = 0; var value = this.readUTFBytes(this.length); this.position = cachePosition; return value; } ,writeBoolean: function(value) { this.writeByte(value?1:0); } ,writeByte: function(value) { var lengthToEnsure = this.position + 1; if(this.length < lengthToEnsure) { if(this.allocated < lengthToEnsure) this.___resizeBuffer(this.allocated = Std["int"](Math.max(lengthToEnsure,this.allocated * 2))); else if(this.allocated > lengthToEnsure) this.___resizeBuffer(this.allocated = lengthToEnsure); this.length = lengthToEnsure; lengthToEnsure; } var data = this.data; data.setInt8(this.position,value); this.position += 1; } ,writeBytes: function(bytes,offset,length) { if(length == null) length = 0; if(offset == null) offset = 0; if(offset < 0 || length < 0) throw new openfl.errors.IOError("Write error - Out of bounds"); if(length == 0) length = bytes.length; var lengthToEnsure = this.position + length; if(this.length < lengthToEnsure) { if(this.allocated < lengthToEnsure) this.___resizeBuffer(this.allocated = Std["int"](Math.max(lengthToEnsure,this.allocated * 2))); else if(this.allocated > lengthToEnsure) this.___resizeBuffer(this.allocated = lengthToEnsure); this.length = lengthToEnsure; lengthToEnsure; } this.byteView.set(bytes.byteView.subarray(offset,offset + length),this.position); this.position += length; } ,writeDouble: function(x) { var lengthToEnsure = this.position + 8; if(this.length < lengthToEnsure) { if(this.allocated < lengthToEnsure) this.___resizeBuffer(this.allocated = Std["int"](Math.max(lengthToEnsure,this.allocated * 2))); else if(this.allocated > lengthToEnsure) this.___resizeBuffer(this.allocated = lengthToEnsure); this.length = lengthToEnsure; lengthToEnsure; } this.data.setFloat64(this.position,x,this.littleEndian); this.position += 8; } ,writeFloat: function(x) { var lengthToEnsure = this.position + 4; if(this.length < lengthToEnsure) { if(this.allocated < lengthToEnsure) this.___resizeBuffer(this.allocated = Std["int"](Math.max(lengthToEnsure,this.allocated * 2))); else if(this.allocated > lengthToEnsure) this.___resizeBuffer(this.allocated = lengthToEnsure); this.length = lengthToEnsure; lengthToEnsure; } this.data.setFloat32(this.position,x,this.littleEndian); this.position += 4; } ,writeInt: function(value) { var lengthToEnsure = this.position + 4; if(this.length < lengthToEnsure) { if(this.allocated < lengthToEnsure) this.___resizeBuffer(this.allocated = Std["int"](Math.max(lengthToEnsure,this.allocated * 2))); else if(this.allocated > lengthToEnsure) this.___resizeBuffer(this.allocated = lengthToEnsure); this.length = lengthToEnsure; lengthToEnsure; } this.data.setInt32(this.position,value,this.littleEndian); this.position += 4; } ,writeShort: function(value) { var lengthToEnsure = this.position + 2; if(this.length < lengthToEnsure) { if(this.allocated < lengthToEnsure) this.___resizeBuffer(this.allocated = Std["int"](Math.max(lengthToEnsure,this.allocated * 2))); else if(this.allocated > lengthToEnsure) this.___resizeBuffer(this.allocated = lengthToEnsure); this.length = lengthToEnsure; lengthToEnsure; } this.data.setInt16(this.position,value,this.littleEndian); this.position += 2; } ,writeUnsignedInt: function(value) { var lengthToEnsure = this.position + 4; if(this.length < lengthToEnsure) { if(this.allocated < lengthToEnsure) this.___resizeBuffer(this.allocated = Std["int"](Math.max(lengthToEnsure,this.allocated * 2))); else if(this.allocated > lengthToEnsure) this.___resizeBuffer(this.allocated = lengthToEnsure); this.length = lengthToEnsure; lengthToEnsure; } this.data.setUint32(this.position,value,this.littleEndian); this.position += 4; } ,writeUnsignedShort: function(value) { var lengthToEnsure = this.position + 2; if(this.length < lengthToEnsure) { if(this.allocated < lengthToEnsure) this.___resizeBuffer(this.allocated = Std["int"](Math.max(lengthToEnsure,this.allocated * 2))); else if(this.allocated > lengthToEnsure) this.___resizeBuffer(this.allocated = lengthToEnsure); this.length = lengthToEnsure; lengthToEnsure; } this.data.setUint16(this.position,value,this.littleEndian); this.position += 2; } ,writeUTF: function(value) { this.writeUnsignedShort(this._getUTFBytesCount(value)); this.writeUTFBytes(value); } ,writeUTFBytes: function(value) { var _g1 = 0; var _g = value.length; while(_g1 < _g) { var i = _g1++; var c = value.charCodeAt(i); if(c <= 127) this.writeByte(c); else if(c <= 2047) { this.writeByte(192 | c >> 6); this.writeByte(128 | c & 63); } else if(c <= 65535) { this.writeByte(224 | c >> 12); this.writeByte(128 | c >> 6 & 63); this.writeByte(128 | c & 63); } else { this.writeByte(240 | c >> 18); this.writeByte(128 | c >> 12 & 63); this.writeByte(128 | c >> 6 & 63); this.writeByte(128 | c & 63); } } } ,__fromBytes: function(inBytes) { this.byteView = new Uint8Array(inBytes.b); this.set_length(this.byteView.length); this.allocated = this.length; } ,__get: function(pos) { return this.data.getInt8(pos); } ,_getUTFBytesCount: function(value) { var count = 0; var _g1 = 0; var _g = value.length; while(_g1 < _g) { var i = _g1++; var c = value.charCodeAt(i); if(c <= 127) count += 1; else if(c <= 2047) count += 2; else if(c <= 65535) count += 3; else count += 4; } return count; } ,___resizeBuffer: function(len) { var oldByteView = this.byteView; var newByteView = new Uint8Array(len); if(oldByteView != null) { if(oldByteView.length <= len) newByteView.set(oldByteView); else newByteView.set(oldByteView.subarray(0,len)); } this.byteView = newByteView; this.data = new DataView(newByteView.buffer); // ERROR HAPPENS HERE } ,__getBuffer: function() { return this.data.buffer; } ,__set: function(pos,v) { this.data.setUint8(pos,v); } ,get_bytesAvailable: function() { return this.length - this.position; } ,get_endian: function() { if(this.littleEndian) return "littleEndian"; else return "bigEndian"; } ,set_endian: function(endian) { this.littleEndian = endian == "littleEndian"; return endian; } ,set_length: function(value) { if(this.allocated < value) this.___resizeBuffer(this.allocated = Std["int"](Math.max(value,this.allocated * 2))); else if(this.allocated > value) this.___resizeBuffer(this.allocated = value); this.length = value; return value; } ,__class__: openfl.utils.ByteArray ,__properties__: {set_length:"set_length",set_endian:"set_endian",get_endian:"get_endia n",get_bytesAvailable:"get_bytesAvailable"} };

penry
Mon, 15 Sep 2014 20:08:54 GMT

Hi vasco, did you find a solution to this ? I've been told my html game stops just before the loading bar completes on the Kindle Fire HD, i've both .ogg and .mp3 available but no kindle to test on myself!

penry
Thu, 18 Sep 2014 16:03:32 GMT

I've found a condition which causes some mobile browser to stop before the loading bar completes. It's the inclulsion of a .svg file within the assets! (for me it was caused due to a mistake in my application.xml which meant the exclude for *.svg wasn't excluding svg files.)

Joshua Granick
Sat, 20 Sep 2014 08:25:06 GMT

Some browsers will also expect *.wav, instead of *.mp3 or *.ogg. We need to probably patch SoundJS, or do something so it won't violently fail when it doesn't find a file it wants :/

penry
Sat, 20 Sep 2014 08:48:15 GMT

I have tried including .wav too, but the file size is so huge it was unpracticle, even with them I was still having problems with not loading on some browsers. Yesterday I excluded all of my audio from my assets (having found that having a .ogg in the openfl assets folder causes a problem on some browsers, even when it's not referenced in my code or loaded !!! (not at all sure how that could be!))) - I then manually set up loading audio using the minified SoundJS, using just the webaudio plugin, and setting the only acceptable file extension to OGG, with MP3 as an alternative. It fixed loading on an older version of android firefox, but as soon as sounds load and try to play on Kindle Fire HD Silk browser, it freezes and crashes the browser! (I think i'll have to give howler a try again!, and see if it does the same!)

Joshua Granick
Sat, 20 Sep 2014 08:49:04 GMT

Definitely interested to hear what you find, though perhaps the Kindle Fire browser does not support webaudio, and that's why it failed?

penry
Sat, 20 Sep 2014 08:56:28 GMT

You're right, A quick web search about Silk, and i find mention of "only HTML 5 Audio is implemented" - So it would seem that soundJS is attempting to use the unsupported webaudio plugin, and crashing the silk browser when it does (rather than realising it doesn't has a plugin the browser can support, and playing no sound at all, like it does on the ipad 1 stock browser)

Joshua Granick
Sat, 20 Sep 2014 09:13:21 GMT

Not sure if we should be upset at SoundJS, HTML5, or just shake a fist in defiance ;)

penry
Tue, 23 Sep 2014 11:00:41 GMT

Looks like it's an Amazon Silk browser specific issue. There is a discussion and work around code here https://github.com/CreateJS/SoundJS/issues/84 , but i'm not sure from the poster what the exact problem the silk browser is showing, and how to work around it similarly in openFL !

penry
Thu, 09 Oct 2014 20:38:59 GMT

16 days later - i'm closer to narrowing this down. The Amazon Silk browser on early models of the Kindle Fire HD (2nd Gen or earlier (2012)) doesn't fire the soundJS "fileload" event whenever an audio file is loaded, - it's fixed in Silk for 3rd Gen Kindles (2013 onwards)! - i'll just keep shaking my fist as all ereaders (after all , they;re only designed for reading ebooks)

dosl
Thu, 20 Jul 2023 15:35:51 GMT

Hi everyone. If you like to play online games and want to play [friday night funkin nun](https://fnfmod.online/sarvente/), then go to the fnfmod website. On this site, you can play FNF interplay on your device. So if you want to have fun, then I advise you to take the opportunity and go to the fnfmod website for the game