pixelhijack Posted March 5, 2018 Share Posted March 5, 2018 Does anyone know how to pass data into the game scene in Phaser 3 as you could do in Phaser 2 when started a state? game.state.start('Game', true, true, { data: 'this is some initial config' }); Phaser 3 Scene was Phaser 2 State, which you could provide parameters, the 2-3rd was as i remember caching, the 4th could be and data, which became available in the State's init() {} method as init({data}). In Phaser 3 a Scene has a second, data param, but it is not clear how it is used, the init method is not getting it, and the documentation is not ready for that as far as i know. Link to comment Share on other sites More sharing options...
samme Posted March 5, 2018 Share Posted March 5, 2018 I think it should work as you described. I did it here: https://github.com/samme/kristal-quest/blob/master/app.js#L896 https://github.com/samme/kristal-quest/blob/master/app.js#L321 pixelhijack 1 Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 6, 2018 Share Posted March 6, 2018 It should work as samme said, the data send with start function will be passed to both init and create method of the scene. pixelhijack 1 Link to comment Share on other sites More sharing options...
pixelhijack Posted March 8, 2018 Author Share Posted March 8, 2018 @samme @PixelPicoSean It is not working for me: i got an empty object as passed in data to my Scenes if i follow the documentation (https://phaser.io/phaser3/api/scene-manager), even with Phaser 3.1.2 and 3.2.0 too: const bootScene = { key: 'boot', active: true, init: (config) => { console.log('[BOOT] init', config); }, preload: () => { console.log('[BOOT] preload'); }, create: (config) => { console.log('[BOOT] create', config); }, update: () => { console.log('[BOOT] update'); } }; const gameScene = { key: 'game', active: true, renderToTexture: true, x: 64, y: 64, width: 320, height: 200, init: (config) => { console.log('[GAME] init', config); }, preload: () => { console.log('[GAME] preload'); }, create: (config) => { console.log('[GAME] create', config); }, update: () => { console.log('[GAME] update'); } }; const gameConfig = { type: Phaser.CANVAS, parent: 'phaser-example', width: 800, height: 600, scene: [ bootScene, gameScene ] }; const game = new Phaser.Game(gameConfig); game.scene.start('boot', { someData: '...arbitrary data' }); By stepping into the game.scene.start() method call in Phaser 3, as i see what is happening here is first the scenes are getting a "default" key, which only later gets overriden with the given key (here "boot" and "game"), but the default data remain the fallback empty object: start: function (key, data) { if (data === undefined) { data = {}; } // if not booted, then put scene into a holding pattern if (!this.game.isBooted) { for (var i = 0; i < this._pending.length; i++) { var entry = this._pending[i]; if (entry.key === key) { entry.autoStart = true; entry.data = data; } } return this; } var scene = this.getScene(key); Can this be a bug...? Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 8, 2018 Share Posted March 8, 2018 You set both boot and game scene as active which means they are automatically started by the game, and Phaser 3 won't start a scene if it is already started and active. So your data will never get passed to those scenes. Link to comment Share on other sites More sharing options...
pixelhijack Posted March 9, 2018 Author Share Posted March 9, 2018 9 hours ago, PixelPicoSean said: You set both boot and game scene as active which means they are automatically started by the game, and Phaser 3 won't start a scene if it is already started and active. So your data will never get passed to those scenes. Still, if i set either one active: false, or both, or delete the active property at all, i got the very same result, my data not passed in, i got the default empty object only. In Phaser 3.2.0. SceneManager.js:947 while debugging i see this, with the previous settings detailed previously, (which is from the docs) the entry.key is "default" while the key is "boot" which evaluates to false, so the entry.data will never set to what i'm trying to pass. for (var i = 0; i < this._pending.length; i++) { var entry = this._pending[i]; if (entry.key === key) { entry.autoStart = true; entry.data = data; } } @rich what is the expected behaviour here? Can this be also related to https://github.com/photonstorm/phaser/issues/3185 ? thanks for the help guys! Phaser rulez!! Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 9, 2018 Share Posted March 9, 2018 Even you set the active of first scene passed to `config.scene`, it still gets activated since it is the first one(your bootScene). What is your purpose of passing data to the boot scene? You can simply start the second one from the boot scene with whatever data and it will just work. Link to comment Share on other sites More sharing options...
pixelhijack Posted March 9, 2018 Author Share Posted March 9, 2018 36 minutes ago, PixelPicoSean said: Even you set the active of first scene passed to `config.scene`, it still gets activated since it is the first one(your bootScene). What is your purpose of passing data to the boot scene? You can simply start the second one from the boot scene with whatever data and it will just work. In Phaser 2 I always used this for dependency injection, i passed all the level configs (big JSON containing asset paths, animation frames, creature props, etc, a declarative approach) to the level which was handled by State. Now i want to have the same architecture with Scene. Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 9, 2018 Share Posted March 9, 2018 So you can simply pass all the level configs from the boot scene to the one you used for levels. And by using a boot and even a preloader scene, you can load JSON from somewhere and pass it when all the assets are loaded to LevelScene (or whatever you call it). pixelhijack 1 Link to comment Share on other sites More sharing options...
pixelhijack Posted March 9, 2018 Author Share Posted March 9, 2018 Maybe my understanding on Phaser 3 Scenes are not right, but i dont really think this should be the expected behaviour based on Phaser 2.x States. What I would expect, how it worked in Phaser 2 States, that i created a State for every phase of my game: Boot loading, Menu for selecting game modes for example, Game state for the actual game which could mean switching between levels etc, and I could pass any data to any State. Now in Phaser 3 as I see following the docs, and as you describe @PixelPicoSean seems like I cannot pass data, just to the second Scene? And also when starting one Scene from a first (the "Game" from "Boot") .create() it seems like both their update() methods are being called by turns - this was also not the case with Phaser 2.x States. Can someone approve that this is an expected behaviour (and correct my misunderstanding or point to documentation where it is described) OR if it is a bug? Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 9, 2018 Share Posted March 9, 2018 As I told before, all the scenes passed to the game config that set active will run automatically when the game start. Phaser3 allows scenes to run parallels, so it is actually expected behavior. Link to comment Share on other sites More sharing options...
pixelhijack Posted March 9, 2018 Author Share Posted March 9, 2018 12 minutes ago, PixelPicoSean said: As I told before, all the scenes passed to the game config that set active will run automatically when the game start. Phaser3 allows scenes to run parallels, so it is actually expected behavior. If i dont set it active: true, or explicitly set active: false, even both Scene, i get the very same result. Can you share a working config with my previously provided snippets where: Scenes are initialized by their keys, and not "default" Not all scenes initialized active Data is passed to any Scene, even the first? ...because this was possible in Phaser 2.x, where States were consecutive phases of a game, able to pass data. If Phaser 3 is giving the possibility to run parallelly as a plus, it is cool, but if it is not backward compatible, that is not really. Do you think i can achieve these with Phaser 3 too? Link to comment Share on other sites More sharing options...
samme Posted March 9, 2018 Share Posted March 9, 2018 I believe that when you pass multiple scenes in the game config object, all of them are added and the first one is started automatically. It's a little ambiguous. So there's no need to start the Boot scene again, and that may be causing some of the trouble. If you want it to work exactly like Phaser 2, I guess you should omit the scene config altogether and instead call scene.add, scene.add, scene.start afterwards. Link to comment Share on other sites More sharing options...
samme Posted March 9, 2018 Share Posted March 9, 2018 30 minutes ago, samme said: If you want it to work exactly like Phaser 2, I guess you should omit the scene config altogether and instead call scene.add, scene.add, scene.start afterwards. http://labs.phaser.io/edit.html?src=src\scenes\scene add manual start.js Link to comment Share on other sites More sharing options...
Stathis Posted March 10, 2018 Share Posted March 10, 2018 I am facing the same issue. I cannot make data get passed onto a scene... My use case is: Start LevelScene Stop LevelScene (I print isActive() here, it's false) Start LevelScene again with data Data never come up on LevelScene's create In my case, I am trying to make a game with a level stucture similar to Angry Birds. Each level is mostly a different configuration of the same template. I obviously don't want to create 100 different level scenes. Can you suggest a reccomended way of dynamically passing config to a scene? @samme, in your comment, I think you made a typo, what is the sequence you reccomended? Just scene.add and then scene.start? Link to comment Share on other sites More sharing options...
Stathis Posted March 10, 2018 Share Posted March 10, 2018 Ok, I digged around in the source code and I think I found what the "issue" is. Data are passed to scenes, only if the scene you are switching from is not running. I assume this is by design. Maybe that's what you meant @PixelPicoSean but I did not get it. Many of the examples I've seen, as well as the code I posted above, start a new scene from the create function. And that works fine when you have no data to pass. At that point, the currently runnig scene (eg BootScene) has not yet been fully initialised and is not considered as runnning. I was looking for another hook to put my scene switch, but I could not see anything in the code, like created, or loaded, that is triggered after create has actually finished. So, for now, I put it in update, which is not great. The first time BootScene hits update, it will switch to the new scene with data passed to it. Edit: Sorry, I might have "hijacked" () this post @pixelhijack, I realised I am talking about a different issue than yours, as you are not switching from a scene to another. pixelhijack 1 Link to comment Share on other sites More sharing options...
samme Posted March 10, 2018 Share Posted March 10, 2018 Hm, that surprised me. Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 10, 2018 Share Posted March 10, 2018 @Stathis Latest master branch has already enabled switching to same scene. I just noticed that data is missing when switching to another scene from create method, that might be a weird bug. Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 11, 2018 Share Posted March 11, 2018 10 hours ago, Stathis said: So, for now, I put it in update, which is not great I think it is totally nice to start another scene with data you wanna pass to, the update method is only called once and your data delivered to the right place, everything else works fine. Link to comment Share on other sites More sharing options...
Stathis Posted March 11, 2018 Share Posted March 11, 2018 Thanks a lot for looking at this guys! @PixelPicoSean that did seem like bug to me as well, but the souce code made me think it could be like that by design. And if so, it probably would be nice to have a post-creation hook added to the lifecycle of a scene, for cases like mine. As it is a one time thing, that gets triggered after a scene is created. And I assume it might be quite common, as people create boot scenes that do nothing but loading assets. But in its absence, I agree, update is fine. I guess I will raise an issue at the phaser repo then, and see what happens. Link to comment Share on other sites More sharing options...
pixelhijack Posted March 11, 2018 Author Share Posted March 11, 2018 @Stathis I already raised an issue for that, feel free to add anything new there, i'm looking into the SceneManager too to figure it out. https://github.com/photonstorm/phaser/issues/3363 Would be nice to have a clear view what is the flow in Phaser 3, Phaser 2 was kinda straightforward for me. To follow some architecture pattern for a game these intents would be good to know well. Stathis 1 Link to comment Share on other sites More sharing options...
samme Posted March 11, 2018 Share Posted March 11, 2018 2 hours ago, pixelhijack said: https://github.com/photonstorm/phaser/issues/3363 @pixelhijack although it's possible there's still a bug involved, you still need to follow http://labs.phaser.io/edit.html?src=src\scenes\scene add manual start.js if you want to call scene.start outside of a scene or post-boot callback. That means you need to omit the scene key from the game config altogether and instead add the scenes manually as well. Link to comment Share on other sites More sharing options...
samme Posted March 11, 2018 Share Posted March 11, 2018 @pixelhijack also you need to remove active: true, because of course that's going to make the scenes run simultaneously. Link to comment Share on other sites More sharing options...
pixelhijack Posted March 12, 2018 Author Share Posted March 12, 2018 Ok i made codepens to illustrate these and why i think there is a bug or bugs, check the console for each pen: 1. Previously: Phaser 2.6.2 Starting States with data: Expected behaviour: Start Boot State with initial data Initial data is passed to State init (used as dependency injection for level / game JSON) Start Game State with some other set of data State methods are in order: Boot:init, Boot:preload, Boot.create, Boot:update, Game:init, Game:preload, Game:create, Game:update Only active State is the last one started: Game Phaser 3.2.0 Starting Scenes with data - manually Expected behaviour: the same as in Phaser 2.x Actual behaviour: Boot is initialized with the default empty object, i cannot pass in initial data Game scene is not started if i start it manually from Boot:create Phaser 3.2.0 Starting Scenes with data - from config Expected behaviour: if you set active:false, or set delete key, it will be good Actual behaviour: Boot scene is only getting the default data object, cannot be passed init object However, you can pass data to Game scene (why just here?) does not matter if you set active:false, or remove it, or you do not set the key @samme Link to comment Share on other sites More sharing options...
samme Posted March 17, 2018 Share Posted March 17, 2018 On 3/10/2018 at 5:11 AM, Stathis said: Ok, I digged around in the source code and I think I found what the "issue" is. Data are passed to scenes, only if the scene you are switching from is not running. photonstorm/phaser/pull/3394 pixelhijack and Stathis 2 Link to comment Share on other sites More sharing options...
Recommended Posts