This is just a heads-up for those who track issues that support for _nested_ Containers will be removed from a forthcoming version of Phaser (not 3.12, but probably 3.13).
The ability to create and use Containers will remain, but you will no longer be able to add a Container as a child of another.
The reasons are two-fold:
1) It will improve speed as we'll no longer need to do any iteration during matrix or bounds calculations.
2) It will reduce API complexity (both internally and externally) - there are edge-cases where, for example, a deeply nested Game Object doesn't inherit the correct blend mode. Or issues like input handling needing to crawl up a container tree to find its ultimate position, all of which are adding un-needed code into the API and causing issues (both for you and me).
It's no secret that I never actually wanted Containers to be added as a feature at all. Look at the quality games made in Construct or Game Maker, for example, neither of which offer the feature. They have caused so much branching and additional work in the API that I really question their value, but at the same time, I know some devs like using them. So I won't outright nuke them (although, believe me, I've come close many times!) - but I do question their implementation. I think there is room to explore recoding the feature entirely, but in the meantime stopping the use of nested Containers will help mitigate a number of problems.
Construct2 has 'container' feature, but it works different from container of phaser3 (or other framework) totally, it does not keep the related position and angle between parent and child object.
In the other hand, construct2 has an official behavior plugin named 'pin' which dose the container job -- keep the related position and angle between parent and child object, but it lacks of responding to scale of parent object.
I don't know the state of 'container' feature in Construct3.
I’m curious but if it didn’t keep the transform related to the container, what did it actually do? 🙂 I suspect you can’t pin a pin onto another pin either?
Official pin behavior plugin of construct2 is added to child object. Every tick it will
It does not use transform matrix like phaser3 does.
Since the executing order of behaviors is the same as the order of objects creating, nested pining might be worked only if child was created later than parent. In this condition, objects will calculate their position from root to leaf. Otherwise, the nested pining will not work well as you said.
Bad news for me... I was using Phaser.Group (Phaser 2) and Phaser.Containers a lot. In fact, currently I do not know how to code without it :-(
What is possible replacement of parent-child transform approach? If you need some child object move together with its parent, you again have to calculate its position (rotation, scale, ...)?
It was always great, that Phaser supported for example alpha in hierarchy, but even Unity does not have this. In Unity, if using Sprites and 2D features you can build hierarchies of sprites, but only position, rotation and scale (Transform) are propagated down to children. If you set alpha on parent, it does not affect alpha on child.
More, Phaser container are maintaining their lists of children and rendering all of them recursively, if containers are nested. Nice, but it breaks single flat display list, right? Unity 2D has two parameters for sprite: Sorting Layer and Order in Layer. Combination of these determines order of rendering regardless of sprites hierarchy. I do not know internal implementation, but for this you can maintain only single flat list - combination of Sorting Layer and Order in Layer is more or less setDepth in Phaser. Of course, in Unity, you can also use Z coordinate even with 2D sprites, but if using Sorting Layer and Order in Layer, then it has only 3rd level importance (1. Sorting Layer, 2. Order in Layer, 3. Z coordinate)
Let's look on this initial Unity setup:

Here are two hierarchies (like 2 containers) - first one with pillar and stone - both are on the same sorting layer (default) with the same sorting order (0), so stone is rendered over pillar. Second one is pumpkins with default sorting layer, but parent pumpkin has order in layer -5 and child has order in layer 5. If I move pumpkins over first group I get this:

Parent pumpkin is rendered below pillar and pumpkin child is rendered over pillar - single flat display list would handle this. Of course setting depth as combination of Sorting Layer and Order in Layer is very convenient - you can have for example UI layer and you always know its depth is over for example GameBoard layer.
Here is how changing alpha on pillar does not affect child stone:

There are no issues with different blend mode...
So, hierarchy changes in position/rotation/scale are separated from rendering, for which single flat list can be maintained.
What if Phaser adopted similar approach?:
Containers will remain, it's the ability to nest them that I'm going to remove.
The problem with the 'calculate world positions before rendering' approach is that it's too late by that point. There are lots of reasons you need the world positions to be perfectly accurate _all the time_. Input checks, bounds checks, intersection checks, camera culling, etc. They all need perfectly accurate transforms at every stage, not just before rendering, and what's more - they need to be perfect for every single camera in every Scene, as each one potentially needs different results :(
So the moment any transform aspect changes, in any child, or any of its parents, every single part of that ancestry tree needs recalculating, and it needs to happen every time, not just once, which means it's entirely possible to need many tree updates in just a single frame. This was the same issue that plagued v2 to be honest, except there were no multiple cameras or states so it wasn't as bad.
There were so many v2 issues over the years related to incorrect body positions and the like. Part of that problem is that Arcade Physics uses the Sprites position and scale for its body. Scale the sprite and the body scales with it. A real physics system would never do this. The body would be entirely independent and it would be up to you to reflect any changes made to the sprite into it. p2, for example, doesn't even let you scale bodies (and for good reason, scale doesn't really exist in physics simulations in the way we visually think of it) And don't get me started on the issues with containers and tilemaps :) or the way devs expect Containers to have a size that perfectly encompasses its children but should also support origin and scroll factor! They're an absolute minefield of problems and expectations.
I actually think the early versions of Lazer had the best transform approach in it. I spent a long time working on it, ensuring values were properly cached up and down the tree, removing un-needed calculations where possible. It never made it into v3 and the Container system in there currently isn't ideal. In time I think I'd much rather revert back to the transform system I originally built. Yet it still requires constant iteration to work.
But at the same time, I find it, and the approach v2 had, is actually very limiting. Having the alpha or blend modes impact the whole tree is as equally useful as it is annoying. What if you don't want to alpha out every child? What is just part of the container should have a blend mode set, not all the children? What if you want to scale a containers background but not have the children scale at all? None of these things are possible and it just feels wrong.
In the meantime though, removing _nested_ Containers will fix a number of issues and simplify the internals a lot, which will make the transition to something better a lot easier in the future.
Also forgot to add, it's not up to the developer how complex the hierarchy gets. The very fact the API supports it means all the iteration checks have to be run anyway, even if you never use it. The very existence of the feature negatively impacts all games, even those that never use a single Container. This is the biggest issue I have with them I think.
Lack of time is a good reason. No person who can be responsible for support of nested containers => get rid of them.
If nested containers are removed, how we can do "bones" like animations? Something like this?
Skeletal animations will use their own animation format / handler, they won't be containers.
Whoever will make good enough custom plugin for nested tree that doesnt change phaser internals much, will be a hero. That way it wont be "removed", just out-sourced to third-party contributor.
I'll gladly put some funds towards a solid implementation, but it would need to be discussed in depth with me beforehand, because it would literally touch every single system in the API.
@photonstorm Rich, thanks for detailed explanation above. You wrote: "_The problem with the 'calculate world positions before rendering' approach is that it's too late by that point. There are lots of reasons you need the world positions to be perfectly accurate all the time. Input checks, bounds checks, intersection checks, camera culling, etc._"
Is it because input can come in the middle of update? Any chance, that caching input during frame and then processing it all at once after (or before - next frame) gameobjects changes would help? I had something similar in my very old and crappy framework for Android/iOS/bada. I was not processing input immediatelly, but just recorded it and than processed it before scene update in next frame. Of course, there was up to 1 frame delay, but it was so negligible, that I did not even feel any delay as user.
Similar for camera culling. I always thought, that culling is applied after objects are transformed into world and during culling you are deciding, whether object is visible for that camera or not. Does it mean, that culling in Phaser 3 is somehow "distributed" during scene update?
Input, culling and so on are all scheduled, so they always happen at the same point in the game step (unless invoked directly from user code I guess) - the issue isn't when it happens, it's actually the camera system. I wrote the following as a reply in Slack, but I think it's worth including here:
In v2 you’ve a single display list, a single canvas sized camera and a single state - so each GO could carry its matrix around with it. In v3 GOs can’t do this because their transform (for both rendering and input) is calculated per camera (and potentially per Scene). GOs could, in theory I guess, store one internal matrix _per camera_, but there’s no limit on the quantity of cameras, and I think it’d be a bit of a nightmare to manage, not to mention the extra weight per object. So their matrices are transient, and because of this need recalculating any time they are queried by any system or game code. Which could potentially be a large number of times in a single frame. Or maybe just once. That’s the problem really!
I can't cache their matrix without doing it for every camera. I could cache the 'world' matrix, and then transform that for every camera, but it only avoids a single step of the process, the camera math all still needs to happen.
There's definitely a solution to be found here, it's just a bit more complex than usual.
Nested containers seems an important issue as a way of grouping some GameObject instances and having ability to control this group the same way.
It's seems very hard to implement some kind of situations, for example tables. With a help of containers I can have each row as a positioned vertically container and all its children as a game objects (any kind of, not only sprites as it possible for Groups) horizontally having vertical position of a row as a reference. And this group of containers may be included into another container which may be positioned at correct place with one command.
And this is only one example becoming completely horrible in terms of additional calculations without containers. So, disabling nested containers is not seems very good for implementing complex objects.
May be there is another solution supported to reach the desired behavior but I could not find it? But for now in terms of creation of complex objects containers seems like the best solution to use ¯\_(ツ)_/¯
PS
Did not saw @SBCGames had wrote something similar, but now I see that it is not only my pain)
@aahz
I had made a simple container plugin which could control the position and angle of children game objects. And it supports nested container.
@rexrainbow
Sounds great, will test it soon, I suppose, thanks!)
it sounds that Richard simply could not cope with elementary math.
I can not imagine how you can work without nested containers, when you do something more than tetris.
it sounds that Richard simply could not cope with elementary math.
Its not a math problem, its invalidation problem.
I can not imagine how you can work without nested containers, when you do something more than tetris.
Meet pure ECS fans, ask them about nesting entities.
This is about getting the topology and topography correct. As it stands now, it's too tied into the rendering. It should be fully abstracted from that.
Having said that, if the only issue is a bit of elementary math, you have absolutely no reason not to implement it yourself, right?
for now I use container to implement the Phaser version of DragonBones, I'm curiose what will be the replacement of the container for it.
Is it possible to leave nestable Containers in the package as optional (maybe under a different name)? So if someone wanted to use them, they would compile their own Phaser package and those who don't need them would use the new implementation.
I currently have some nested containers and I can't imagine writing all the coordinate/scaling transform code for every nested container I would want to remove. Any advice how to proceed with that?
Deal-breaker for me coming from Unity and using a hierarchy of transforms to maintain a fluid user-interface. The BitSquid blog and nVidia have articles (and the latter has code) on how to organize the data to update this very fast.
As an alternative let me assign a transform index from a palette of matrices to a game object.
Skeletal animations will use their own animation format / handler, they won't be containers.
If you allow touching on limbs you'll have to do the transforms, seems like the same problem.
Yes, coming from flash, it is very hard not to think in terms of nested children. I just started a virtual world in Phaser 3 that relies on nested containers. I knew I had to be careful with them, but they are so useful. This is going to set things back a bit.
Ouch. Just looking over my code this is going to set back 2 ebooks and an online course :( Is there anything else I should work around?
After a restless night of coding in my sleep, it is not as bad as I thought. I only need a few functions like setting child positions and visibility. I've been able to write a class that extends group to take care of that. I can live without nested containers, especially if it improves performance.
Containers will be removed and _fully recoded_ in 3.14. I'm fed up with their limitations and the issues the current implementation has. They will remain untouched (and un bug-fixed) until then.
Oh god... nested containers were so nice for complex developments... Same as William, I got used from Flash / AS3, with their nice nested movieclips, and all complex collision system, and... i admit right now, it seems like I'm back to the 2000's ....
Sometimes, I wonder... are things really get better with new 'technologies' ? Maybe Flash is old, maybe it has its problems, but still... it is years ahead of ES6/HTML5 in term of pure development..
@ElMacBgl http://pixijs.io/pixi-swf/demos/ninja-cat.html http://pixijs.io/pixi-swf/demos/ninja-cat.js I'm making new renderer that has all flash capabilities. @photonstorm knows about it, everything will be all right ;)
@ivanpopelyshev Just went to your demo: it's quite impressive actually, and if it uses quite same dev logic than what was available on AS3, it can be great. Question remains to me: how can we mix phaser and pixiJS ? Or maybe we'll have to manage that as 2 different development tools, being 99.99% compatible ?
I guess this will be the subject of another topic (don't want to pollute that one)
This issue has been mentioned on Phaser. There might be relevant details there:
https://phaser.discourse.group/t/nested-containers-moving-and-rotating-sprites/5599/3
Most helpful comment
Bad news for me... I was using Phaser.Group (Phaser 2) and Phaser.Containers a lot. In fact, currently I do not know how to code without it :-(
What is possible replacement of parent-child transform approach? If you need some child object move together with its parent, you again have to calculate its position (rotation, scale, ...)?
It was always great, that Phaser supported for example alpha in hierarchy, but even Unity does not have this. In Unity, if using Sprites and 2D features you can build hierarchies of sprites, but only position, rotation and scale (Transform) are propagated down to children. If you set alpha on parent, it does not affect alpha on child.
More, Phaser container are maintaining their lists of children and rendering all of them recursively, if containers are nested. Nice, but it breaks single flat display list, right? Unity 2D has two parameters for sprite: Sorting Layer and Order in Layer. Combination of these determines order of rendering regardless of sprites hierarchy. I do not know internal implementation, but for this you can maintain only single flat list - combination of Sorting Layer and Order in Layer is more or less setDepth in Phaser. Of course, in Unity, you can also use Z coordinate even with 2D sprites, but if using Sorting Layer and Order in Layer, then it has only 3rd level importance (1. Sorting Layer, 2. Order in Layer, 3. Z coordinate)
Let's look on this initial Unity setup:

Here are two hierarchies (like 2 containers) - first one with pillar and stone - both are on the same sorting layer (default) with the same sorting order (0), so stone is rendered over pillar. Second one is pumpkins with default sorting layer, but parent pumpkin has order in layer -5 and child has order in layer 5. If I move pumpkins over first group I get this:

Parent pumpkin is rendered below pillar and pumpkin child is rendered over pillar - single flat display list would handle this. Of course setting depth as combination of Sorting Layer and Order in Layer is very convenient - you can have for example UI layer and you always know its depth is over for example GameBoard layer.
Here is how changing alpha on pillar does not affect child stone:

There are no issues with different blend mode...
So, hierarchy changes in position/rotation/scale are separated from rendering, for which single flat list can be maintained.
What if Phaser adopted similar approach?: