Why are we unable to add a family to a family in construct?

0 favourites
  • 7 posts
From the Asset Store
Casino? money? who knows? but the target is the same!
  • I am sure this has been asked before... but...

    Simple question: Why can't a family be in a family? Why can't one family know all objects in it are also in another family? As it stands, you can't put an object into a family that has the same variable as another which obviously means construct knows what families an object is in or not in.

    I think everyone understands the reason why, so I'll not get into detail here, but if you don't I'll try to explain.

    The basic idea is that, while you can recreate the effect of family in family, you often have to duplicate functionality across multiple families(bad programing period.) or have conditional branches based on object type variable stored in the family (extremely bad programing technique, full stop page break period.) This isn't to say conditional branches are bad - but they are in this case, because you can easily find that everytime you have an event for FamA you need a series of sub events to pick for type (meaning you are repeating yourself, and creating a terrible codebase). Now you have a project where everytime you add a new type, you have to hunt down all the different sub picking events to add to it and woe to those who forget where. Then removing a type involves the same thing.

    The above isn't a opinion as much as it is an accepted industry truth for the last 30 years. Those who disagree simply haven't felt the pains of managing such a product at an appropriate scale long term.

    The work arounds for family in families involve techniques that make a project harder to scale, increase difficulty of maintaining codebase, etc...

  • This came up on the suggestions platform, and Ashley wrote a response there. Might be something that could eventually be added, but it's a complex area for Scirra to modify:

    github.com/Scirra/Construct-feature-requests/issues/1

  • It's a good example of something that might sound simple, but actually involves a great deal of complex work to support. As it stands families are independent collections of other object types - a nice and simple system. If you can add families to families, then it transforms that in to a tree structure of families. Changing the structure of the tree (e.g. by adding/removing/moving families in families) will have complex repercussions in your project regarding which instance variables, behaviors and effects are inherited through the tree, and cause various parts of the project to become invalid, which the editor has to handle (e.g. by deleting events referencing things that are no longer applicable).

    It can be done, but it's time consuming and painstaking work to do upgrades like that, and as ever we get far, far more feature requests than we can possibly do, so we have to be pretty ruthless about prioritising.

  • That makes sense. Thanks for the details ASHLEY. indeed, it is clear now.

    If you had any thoughts on the below, I would great appreciate it.

    If nested families takes too much work and isn't a priority, there is one thing that may be easy to implement that would alleviate part of the issue (namely communicating between families). Currently, the easiest way to to communicate between families is to use a common variable (z order, opacity, color, etc...). But that won't work if need those for what they were made for. The following suggestion is useful not just in context of the current issue, so deciding to have nested families in the future wouldn't make this suggestion obsolete.

    If we could extend/define our own common variables for a plugin, then would could use those between families to communicate and aid in picking. For example, if I could create an instance variable that would then be available to every single instance, regardless of family, then I could use that to share data between them. Basically a type of custom common variable.

    The other option (which also has its own beifits even if nesting is later added) is to allow families to share instance variables or behaviors between them. Currently construct knows when a behavior called "platformer" already exists on an object type and won't allow us to add it again without it being a different name. Would it be easy to simply allow both families to refer to the same behavior/var? Then defining shared functionality would be as easy as naming the behavior or variable the same name accross families and not preventing it. Since construct prevents the same name, I am assuming that a particular conflict could be leveraged as a useful feature. You would still have to potentially repeat code in this setup, but using a shared variable would be more akin to defining an interface.

    I made the argument that nesting is the most important feature on the github post, but I think that only applies to managing larger projects or advanced use cases where complexities of abstraction are the most pressing issue. But I understand the benefits of this would not be apparent to many beginners.

    I would add, that for me at least, if changing families to allow for nesting made all family use less performant at game run time, I wouldn't like that either. lol

    As it stands the foreach workaround and uid picking isn't terribly inconvenient, but it does become a performance drain, and if the performance drop from that is unbearable I can at least try other methods.

  • Heh, this had come up before on the older suggestions platform:

    construct.net/en/forum/construct-3/general-discussion-7/suggestion-custom-data-feature-176502

    I agree, does feel like there needs to be a way to deal with variables between families.

    It seems the best way currently, is to forget instance variables, and use JSON or dictionaries as a form of instance variables.

    That's typically what I've ended up doing, it has its pros and cons, but personally I think there are far more pros to use a dictionary than instance vars!

    • You can "dynamically add new instance variables during runtime" (dictionary keys)
    • Can throw the dictionary into a family if you need to create logic relating to 2 dictionary instances and still get any keys needed or do loops (can do dictionary.get on both a dictionary or a family of dictionaries).
    • Can get the names of keys in a loop, unlike instance vars where it's impossible to get names.
    • Can get the keys as expressions, which cannot do with instance vars.

    Cons being picking the dictionary and storing uids and such, and if you want to use containers to avoid picking, then can't add dictionaries to a family container. Boo.

  • It seems the best way currently, is to forget instance variables, and use JSON or dictionaries as a form of instance variables.

    That's typically what I've ended up doing, it has its pros and cons, but personally I think there are far more pros to use a dictionary than instance vars!

    Yeah, I like dictionaries too for those reasons. I never have had or thought to put them in a family. Can you elaborate on the benefits of that? currently I'm using overboy's data+ so I can have them on instances in order to avoid foreach picking loops. But, obviously that means I lose the benefit of two families being able to reference the same dictionary.

    The workarounds are all decent and simple to use, but they all end up requiring for each loops. Hierarchies, compound objects, uid family shifting (where you simply pick another family by UID), are all viable until you have performance bottlenecks.

    I fear that high count objects simply have to have as little abstraction as possible, even if it means recreating the same behaviors multiple times. Fun facts, I even noticed family events take a little longer to run than the same thing on an object with equal counts, etc... The performance was maybe only a 10% difference, so not a concern for me given other high costs, but still fun to notice.

    I think that in the end I am probably going to go with ease of programing and simply design the game around a smaller object count. I'll be able to simply get the core of the game complete and then see how many objects it tolerates and then go from there.

    In unity or unreal, having several 1000 objects can start to bog things down, but you can get crazy insane performance for millions of objects if you go with ECS (an alternate paradigm for games that is neither oop or component based, but allows modern AAA games to have things like schooling fish or flocking birds by the thousands). The downside is that it takes more work to set up, has to be custom tailored, and is difficult to make modular or extend - so it ends up being a real pain every time, regardless of how similar two sets of objects are. I think the case stands here in similar fashion. If you have 100 dynamic/complex objects, performance differences between an abstracted framework running a foreach and a custom optimized solution will be meaningless. If you want 1000s, you start to see the benefits, but optimizations start to really be case specific.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Heh, this had come up before on the older suggestions platform:

    https://www.construct.net/en/forum/construct-3/general-discussion-7/suggestion-custom-data-feature-176502

    I also think this would be very useful in production environments, though, it looks like this is to address the global space, if I understand correctly. In order to be able to communicate from family to family, per instance, you need to be able to have data that is common across a particular plugin. So an obj in both FamA and FamB could set a common var through FamA and then later FamB could use that info in whatever way it needs to.

    I totaly agree that its a great practice to keep code isolated and performing its own thing, but games often require coupled code (platformer and Solid is a grand built in example) and a common data shared between all instances and accessible by any family would solve that issue. Z order, opacity, and color can be used to facilitate communication, but those have other uses obviously.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)