Instance variable initial values for instances created at runtime?

  • Can someone explain to me the rules determining how C3 assigns initial values to instance variables when creating an object at runtime with System -> Create Object?

    My observations:

    • If I've added only one instance to a layout (as C3 requires at least one), not surprisingly the new instance added at runtime takes on the initial values specified for that original object instance.
    • If I have two instances added to the layout in editor Layout View, each given different initial values for their instance variables, the third instance created at runtime takes on the initial values of one of the original two, but I don't know how C3 chooses. It seems like maybe it's the one with the lowest UID.
    • If in the editor Layout View I have one instance added to layout B with UID 10, and two instances added to layout A with UIDs 15 and 20, and at runtime I create a new instance on layout A, it seems like the initial values of instance variables are taken from the initial values of UID 15. (The lowest UID from the layout the new instance is created on, but not the lowest UID across all layouts.)
    • In the example above where instance with UID 15 is used as the template for initial values of instance variables on newly created instances, it doesn't seem to matter if instance UID 15 is destroyed prior to creating the new instance. Nor does changing the values of UID 15's instance variables at runtime prior to creating the new instance affect it -- the instance variable initial values for the new instance will come from whatever was input in the editor before running the layout.

    In the end what I'm looking for is 100% predictability on what the initial values of instance variables will be for instances created at runtime. I do wish each object had global default values that are independent of any instances added to the layout so I don't have to worry about which one is the lowest UID on the layout (if that is indeed how it works). But at least being clear on what's happening will help me plan accordingly.

  • If not set on an instance I'm pretty sure it takes default values from the object properties as defined for the one in the project tree.

    Not 100% sure tho. Can't check right now.

  • Well, it's true that when in the editor you add an instance of an object to the layout, and there are no instances of it yet on the layout, its instance variables will be assigned the default values specified in the project tree.

    But I've found once you add an instance to the layout in the editor, that first instance is treated as special -- further instances you add to the layout in the editor will take their instance variable values from this one, not from the project defaults for the object. Even those instances added to different layouts in the project will grab their values from the first instance.

    By contrast, it (seems) to work a little differently for objects created at runtime. I'm finding object instances created at runtime will take their initial values of instance variables from the first instance of that object on that same layout; if there are no instances on that layout, it will take its instance variable initial values from the first instance on another layout, though not necessarily from the first instance created--it seems to go through the layouts in a certain order (by when they were created?) and looking for the first instance on each. Some examples to illustrate what I see:

    - Project has layouts A, B, and C created in that order, and one Sprite object

    - Scenario 1: In editor, I first add 2 sprite instances to layout C, then 2 to B, then 2 more to A and change their instance variables to unique values

    - At runtime, I create a new instance of the sprite on layout A

    -- Result: new instance on layout A takes its instance variable initial values from those set for the first instance added to layout A in the editor

    - Scenario 2: In editor, I first add 2 sprite instances to layout C, then 2 to B, and none to A and change their instance variables to unique values

    - At runtime, I create a new instance of the sprite on layout A

    -- Result: new instance on layout A takes its instance variable initial values from those set for the first instance added to layout B -- even though I added instances to layout C first, there is some order through which C3 goes through the layers that happens to look at B first.

    - Scenario 3: In editor, I don't add any instances to any layouts

    - At runtime, I create a new instance of the sprite on layout A

    -- Result: C3 hangs because there must always be at least one instance of an object on at least one layout before using the System -> Create Object action. (Actually C2 runtime gives a helpful error message, C3 runtime just hangs on a black screen.) Notably, the runtime does not create the object and use the instance variable defaults set in the project tree.

    I was wrong (I think) about the UID order having anything to do with all this. There are probably more nuances as well so I'd love to hear the exact logic in use, so I know exactly what to expect when dynamically creating new object instances.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • It's always been fuzzy to me, so I had a look at the runtime source in C2. C3 is probably very similar, since if they changed it it would be a breaking change.

    It seems that the it picks the default instance by going through the layouts in order they are in the project, and then the layers in order and the instance with the lowest uid becomes the default.

    I didn't look too much further but another thing to test is the order of the layers. Are they defined by their order in the editor or the order they were added? I'm guessing just their order. I have no idea if global layers mess things up. I think the layout order is the most useful thing to know.

    Anyways, from that it seems that a nice strategy to control default instances is to create a new layout and add one instance of each object. Then drag that layout to the top of the layout list. Be sure to set the initial layout in the project properties.

    Thanks for the interesting question, it revealed something useful I didn't know before.

  • Yes, I did a little test and it seems you're right, the order of the layouts in the project bar is the first thing the runtime uses ... it does not start by looking at the currently active layout as I previously wrote. When I set an instance in Layer A and an instance in Layer B to have different instance variable intial values, and then ran the debugger on Layout B with an event action to spawn a new instance on Layer B, it pulled the initial value from the instance on Layer A even though B was the active layout. This was with Layer A as the first layer in the hierarchy under the Layouts folder in the Project Bar. Dragging Layer B up to be first under Layouts changed the spawned instance to inherit initial instance variable values from the instance on Layer B.

    Therefore it would seem best practice is to make my first layer the non-playable "holding cell" for one of every object in the project, and set the default values of instance variables on those instances for how I want them to be throughout the project. I previously had my holding cell layout as the last layout.

    One small caveat to what you wrote, I found (at least in the C3 runtime) it is possible for spawned instances to use instance variable initial values from an existing instance that isn't the lowest UID on the applicable layout. I can make this happen in the editor by dragging instance 1, (with C3 assigning, say, UID 14), than dragging one more instance of the same object (assigning UID 15), then deleting instance with UID 14, then dragging a new instance back to the layout. The last instance will get assigned 14 since it was just freed up, but the editor remembers 15 as being the "first" instance on the layout since at one time it was the only instance. Spawned instances (in my testing) then take the initial values from the UID 15 instance and not the 14.

  • Man, this is all very well but...besides not being very noob friendly.... this is also seriously messing with my chi.

    I have been happily assuming that the default values are taken from the one in the project tree and my project depends critically on values set there and assumes those values when spawning new instances...

    Ashley

    ehhh... yea re above posts .... is there some rhyme reason to all this , what assumptions can we assume WRT initial instance values ?

  • Newly created objects copy properties from an arbitrary instance. It's not something you should rely on; whatever ordering the runtime uses, it could change by accident as you edit the project. So if you want to make sure a newly created object gets specific properties after creation, set those properties with actions after creating it.

  • Newly created objects copy properties from an arbitrary instance. It's not something you should rely on; whatever ordering the runtime uses, it could change by accident as you edit the project. So if you want to make sure a newly created object gets specific properties after creation, set those properties with actions after creating it.

    Hi Ashley Ive been meaning to follow this up

    please see screenshot below.

    I have a family called 3d object. It has many instance variables.

    some of the instance variables for certain objects , like enemy example below, I set in the editor on the object properties in the project tree. eg see like speed , health, score.

    I have been messing around with my game for nearly 2 years , the game can create 20 to 100 of different enemies at once and I have never experienced any issues with newly created versions of these objects not behaving as expected. All properties set in the editor are always inherited correctly at run-time when created as far as I can see.

    I guess my question is , after your statement above, is it safe to proceed as I have been doing so, or is everything likely to come crashing down at some point in the future?

  • If i could just bump this once Ashley

    as you see on the left above

    for each of the enemy sprite objects

    which are members of the "3D_Object" family

    I am setting instance variable initial default values for

    score, health, speed, scale etc

    directly on the object in the project tree. The instance variables are inherited from the 3D_Object family

    I have never had any issue ever with enemy behaviour even creating tons of them during runtime. The values entered on the project tree object have always been set correctly at creation during runtime.

    so OK to continue to work like this?

  • If it works, it works. It means if you change any of the existing properties in the layout, newly created objects will also get changed values. Sometimes that's what you want, other times not. The only unpredictability is if you have multiple instances in the layout with different properties; in that case Construct will pick one of them as the one to copy from (and deleting instances or changing properties may or may not change the values a newly created instance gets). However it's common that all the objects in the layout have identical properties, so it doesn't make a difference.

    Maybe calling it "safe" or "unsafe" is the wrong term, it's just a game design point really. In general this approach seems good enough to not unexpectedly cause values to change as you work. Even if they do change, you just need to add some actions to set the values you want for newly created objects and it works around it. So it seems like a pretty minor point.

  • OK I think get it, its actually really important info to understand, thanks for your response.

    (and happy new year BTW!)

    Then it seems im getting away with it as I dont have multiple instances of enemy objects in the layout. Just the one of each for they layout load which are destroyed on layout start (which I believe we dont even have to do that any more with C3). Enemies are then created in game when needed and they seem to be picking up the project object default values ok. I'll leave for now then as it does indeed work. but definitely good to note. cheers.

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