Loading asset from bytearray in memory

Hi all,
I’d like to know if is possible to load an asset into Phaser from a bytearray source, something sent on the fly from the server, and not existing on disk. Any hint is welcome!!

Thanks,
f_lande

There’s Phaser.Loader.LoaderPlugin.binary().

Hi Samme,
thanks for your reply, first of all.
I’m not sure, though, this would be useful for what I’m thinking of. My intention is to send from the server an
encrypted file, then to decrypt it in memory, and then to load an image from it, without any clear data stored
locally in the cache. Do you think this is possible?

Thanks!!

I think it could work, although a motivated geek might find the image in dev tools somehow.

Any loaded image could be saw in console (Network page), even this image is loaded from URL.createObjectURL.

Load binary buffer to texture cache

Hi Rex,
yes, you’re surely right, but as far as I can see, in the cache I can only find the encrypted data, which is OK for me.
Any hint about how to load the decrypted binary data and the associated JSON?
This is what I tried (unsuccessfully) so far:

export function JsLoadAtlas(
atlasName: string,
atlasDataArr: any,
atlasDataLen: number,
jsonDataStr: string,
JsonDataLen: number)
{
console.log(“Enter JsLoadAtlas();”);

let atlasData = new Uint8Array(atlasDataArr); // PNG or JPG data

// Try 1:

LoadScene.load.binary(atlasName, atlasData, jsonDataStr);

// Try 2:

LoadScene.load.atlas(atlasName, null, atlasData, jsonDataStr);

console.log(“Leave JsLoadAtlas();”);
} // JsLoadAtlas() ##############################################################################

The input parameters values are correct at run-time, but neither works.

Xiè xiè!!

f_lande

Live demo

The main concepts are

  1. load image and json binary data via scene.load.binary, assume that they are separated files.
  2. Once you have image and json binary buffer, generate object url via window.URL.createObjectURL. Now you have 2 URL of image and json data.
  3. Load atlas via scene.load.atlas with url got from step2.

This demo use wait event plugin, to load atlas when image and json binary data are ready.

Hi Rex,
thanks for your reply,first of all.
I’m trying to follow your example, but I can’t fully follow it,possibly because I’m trying to avoid using your plugin, for the sake of simplicity.
This is what came up with:

export function JsLoadDataAtlas(
atlasName: string,
atlasDataArr: any,
atlasDataLen: number,
jsonDataStr: string,
jsonDataLen: number)
{
console.log(“Enter JsLoadDataAtlas();”);
let imgKey = “atlas-” + atlasName + “-jpg”;
let atlasData = new Uint8Array(atlasDataArr);
GameScene.load.binary(imgKey, atlasData, Uint8Array);

let jsnKey = “atlas-” + atlasName + “-jsn”;
jsonDataStr = jsonDataStr.substr(0, jsonDataStr.lastIndexOf(‘}’) + 1);
GameScene.load.binary(jsnKey, jsonDataStr, Uint8Array);

setTimeout(function()
{
let imgBuffer = GameScene.cache.binary.get(imgKey);
let imgBlob = new Blob([imgBuffer], {type: “image/jpg”});
let imgUrl = window.URL.createObjectURL(imgBlob);

let jsnBuffer = GameScene.cache.binary.get(jsnKey);
let jsnBlob = new Blob([jsnBuffer], {type: “application/json”});
let jsnUrl = window.URL.createObjectURL(jsnBlob);

GameScene.load.atlas(atlasName, imgUrl, jsnUrl);
GameScene.load.start();
}, 100);
console.log(“Leave JsLoadDataAtlas();”);
} // JsLoadDataAtlas() ##########################################################################

On the “let imgBuffer = …” line, I get that imgBuffer is undefined, as if the data within the cache is not available.

Any hint about what night be wrong here?

Thanks& best regards,

f_lande

I had updated another version of demo, which does not use WaitEvent plugin, please reload previous demo page again.

New loading task (scene.load.atlas) under filecomplete-... event would be added to preload stage.

Hi Rex,
thanks for your continuous support, first of all. I tried your modified snippet, and it gets executed without errors, BUT
the “LoadAtlas()” function is never called. This is my current routine:

export function JsLoadDataAtlas(
atlasName: string,
atlasDataArr: any,
atlasDataLen: number,
jsonDataStr: string,
jsonDataLen: number)
{

console.log(“Enter JsLoadDataAtlas();”);
let imgType = “jpg”;
let jsnKey = “atlas-” + atlasName + “-json”;
let imgKey = “atlas-” + atlasName + “-image”;
let LoadAtlas = function()
{
let imgBuffer = GameScene.cache.binary.get(imgKey);
let jsnBuffer = GameScene.cache.binary.get(jsnKey);
if(imgBuffer && jsnBuffer)
{
let imgBlob = new Blob([imgBuffer], {type: “image/${imgType}”});
let imgUrl = window.URL.createObjectURL(imgBlob);

let jsnBlob = new Blob([jsnBuffer], {type: “application/json”});
let jsnUrl = window.URL.createObjectURL(jsnBlob);
GameScene.load.atlas(atlasName, imgUrl, jsnUrl);
}
};

let atlasData = new Uint8Array(atlasDataArr);
GameScene.load.binary(imgKey, atlasData, Uint8Array);
GameScene.load.once(“filecomplete-binary-${imgKey}”, LoadAtlas, GameScene);

jsonDataStr = jsonDataStr.substr(0, jsonDataStr.lastIndexOf(‘}’) + 1);
GameScene.load.binary(jsnKey, jsonDataStr, Uint8Array);
GameScene.load.once(“filecomplete-binary-${jsnKey}”, LoadAtlas, GameScene);

console.log(“Leave JsLoadDataAtlas();”);

} // JsLoadDataAtlas() ##########################################################################

Hence, obviously, when I try to display the background image I’m trying to load, I get:

Texture.frame missing: Background

Thanking in advance, my best regards,

f_lande

When do you invoke JsLoadDataAtlas method? In preload, or create of scene?
In create of scene, start loader is necessary

scene.load.start()

Reference

Hi Rex,
this is a very good point,and I tried, but if Iinvoke the GameScene.load.start() after the second “GameScene.load.once()”,
I get this error message in the console:

Enter “GameScene.preload”;
Leave “GameScene.preload”;
Enter “GameScene.create”;

Leave “GameScene.create”;

Enter JsLoadDataAtlas();
TypeError: t.url.match is not a function
at t.exports (e:\home\francesco\elcenter\online\03_colorfeverdtphaserwasm\webapp\js\phaser.3.55.2.min.js:1:189348)
at initialize.load (e:\home\francesco\elcenter\online\03_colorfeverdtphaserwasm\webapp\js\phaser.3.55.2.min.js:1:20299)
at initialize. (e:\home\francesco\elcenter\online\03_colorfeverdtphaserwasm\webapp\js\phaser.3.55.2.min.js:1:943330)
at initialize.each (e:\home\francesco\elcenter\online\03_colorfeverdtphaserwasm\webapp\js\phaser.3.55.2.min.js:1:186529)
at initialize.checkLoadQueue (e:\home\francesco\elcenter\online\03_colorfeverdtphaserwasm\webapp\js\phaser.3.55.2.min.js:1:943116)
at initialize.start (e:\home\francesco\elcenter\online\03_colorfeverdtphaserwasm\webapp\js\phaser.3.55.2.min.js:1:942742)
at Object.JsLoadDataAtlas (e:\home\francesco\elcenter\online\03_colorfeverdtphaserwasm\webapp\js\00_startpage.ts:314:20)
at JsLoadDataAtlas (e:\home\francesco\elcenter\online\03_colorfeverdtphaserwasm\webapp\colorfever.js:1496:367)
at imports. (e:\home\francesco\elcenter\online\03_colorfeverdtphaserwasm\webapp\colorfever.js:6169:36)
at SdkUtils::ProcessCommand() (http://localhost:59427/ColorFever.wasm:wasm-function[437]:0x3c6b6)

and this also answers to your question about when this function is called (asynchronously), let’s say during the GameScene.update
phase.

I’m really out of mind…

Thanks & best regards,

f_lande

Sorry, this situation is out of this topic. I can’t reproduce it with there error messages.

Hi Rex,
the situation is NOT off this topic. Simply, before restarting the loading activities, I had to reset the scene’s loader through a “scene.load.reset()” and start the actual loading through a “scene.load.start()”. The working routine, for whom might be interested is:

export function JsLoadDataAtlas(
  imgType: string,
  atlasName: string,
  atlasDataArr: any,
  jsonDataStr: string
) {
  console.log("Enter JsLoadDataAtlas();");
  let imgFlag = false;
  let jsnFlag = false;
  let jsnKey = "atlas-json";
  let imgKey = "atlas-image";

  GameScene.load.reset();
  GameScene.load.on(
    "filecomplete",
    function (key: string, type: string, data: any) {
      if (key == imgKey) imgFlag = true;
      else if (key == jsnKey) jsnFlag = true;
      else if (key == atlasName) return;

      if (imgFlag && jsnFlag) GameScene.load.atlas(atlasName, imgUrl, jsnUrl);
    },
    GameScene
  );

  let atlasData = new Uint8Array(atlasDataArr);
  let imgBlob = new Blob([atlasData], { type: "image/" + imgType });
  let imgUrl = window.URL.createObjectURL(imgBlob);
  GameScene.load.binary(imgKey, imgUrl);

  jsonDataStr = jsonDataStr.substr(0, jsonDataStr.lastIndexOf("}") + 1);
  let jsnBlob = new Blob([jsonDataStr], { type: "application/json" });
  let jsnUrl = window.URL.createObjectURL(jsnBlob);
  GameScene.load.binary(jsnKey, jsnUrl);
  GameScene.load.start();
  console.log("Leave JsLoadDataAtlas();");
} // JsLoadDataAtlas()

Thanks anyway,

f_lande

The title of this thread is Loading asset from bytearray in memory, not loading files in any situation, right?

In my test, I can use scene.load.start() to start loading progress inside create stage, or out of create stage (by using setTimeout), without scene.load.reset(). So I still can’t reproduce your case yet.

Anyway, it is nice that you had solved this issue.