Creating layers at runtime in C2

  • Hi,

    I'll try to make this quick. Yesterday I was thinking about how I would manage a particular issue I have with my project which involve my will to make as many things as possible automated and my strong hate for boring work.

    Basically I was in the case where my project needed a LOT of layers to work for the UI. So that meant creating a layout filled with lots of global layers dedicated to UI and then having to add these layers manually to all of my layouts that need that UI.

    I know. I don't wanna do that either. So instead I figured I might try to automate the process of creating layers. So I took a deep dive into the construct 2 code, reading most of the runtime code, most of the cr code, and most of layout.js.

    My main inspiration was Toby's Unload and Preload plugins which allow a user to load layouts and basically make a real loading screen. I knew that to do this he kinda had to take deep dives into the engine as well.

    Anyway, here's what I gathered from this, and I'm not done looking around yet, but I figured I might as well make a topic that I'd keep updated.

    The code to create a new layer in a layout is pretty simple:

    var layout = this.runtime.running_layout;
    var layer = this.runtime.layouts_by_index[1].layers[0]; // whatever method you use to get other layers.
    //You can also create a new layer by calling the constructor in cr
    layer = new cr.layer(layout, layerData) // With layerData being an array containing all of the layer's base info. You can get a look at what it looks like by logging the variable m in the Layer's constructor in layout.js
    layer.number = layout.layers.length;
    cr.seal(layer);
    layout.layers.push(layer);
    

    This works for copying any layer from any layout or creating a brand new one.

    Now this comes with issues, including some I have yet to figure out.

    The first issue is that layers are assigned an sid value which I can only imagine is used to manage layers during runtime. I can't tell which issues having two layers on two different layouts share the same sid would create, but I can guess it could mess with the existance of that layer entirely, or even overwriting it entirely which would be bad. A fix would be to just make sure to deep copy the layer and change the sid instead of copying directly.

    Having 2 layers share the same sid on the same layout seems to erase one of them. Or it could also be due to both layers sharing the same name. Anyway, it's problematic in any case.

    The second issue is that objects aren't copied over from that piece of code only. I gathered that some other piece of code is in charge of actually creating the objects a layer is holding. I'll have to keep investigating to be sure.

    The third issue seems to be a bug that should be a problem in most use cases. When I tried creating a new layer entirely, I tried setting it to non transparent, and to change the background color to cyan, just for the sake of testing the thing. The new cyan layer did appear in front of my other layer containing random sprites, but when I tried moving one of these sprites to the new layer the sprite wouldn't appear. This is weird because the debugger says that the sprite did in fact change layers, and when the layer is transparent, it works totally fine and the sprite gets thrown in front of all of the other sprites.

    Another issue that I think will never be resolved is the case of global layers. Given my initial intent, my goal was to create new empty layers named after global layers so C2 would do the job of copying all of the objects for me, but unfortunately the only reference for "global layers" I was able to find in the code was about making sure two objects from global layers didn't share the same UID, which makes me think that global layers are entirely managed in the editor and when it comes to previewing and exporting, C2 copies all of the stuff on the global layers to all the overriden ones. So global layers don't exist during runtime. Which is kinda lame, because my original idea wont work, but kinda makes sense as well.

    My initial question was "Can I make it so I can add all of my UI stuff through events, including the layers?" and the answer is "Yes, in theory, but if I don't wrap my head around these issues, I'll have to make one global layer, shove all of my UI in it, and create all the new empty layers at runtime, and manually move all of the UI to the right layer after creating it. Which hopefully works and doesn't make C2 freak out for a frame"

    Also, I guess deleting layers, reordering them, and duplicating them should be possible if done right. It even seems that creating new layouts entirely could be a thing in theory. Which would be absolutely amazing for lots of things.

    Anyway, this is what I gathered, but I didn't write any of that code, just read it and I guess I'd need to know what Ashley has to say about this. If I'm mistaken about anything in here, please tell me. If you have any insight to give me, please do. The following is addressed to you.

    Please note that this is not a feature request even though this would be amazing to have in the new C3 runtime, even though it would be super dangerous in the hands of new users. I'm not making a feature request for this because I don't see the point of making one yet.

    Please also note that while I am speaking in the Javascript SDK and while I do plan on making a plugin to allow me to control these from the event sheet if it happens to be possible, I do not plan to share that plugin to anyone any time soon. I'm not willing to give support to this, and any user wanting this is either advanced enough to replicate what I did from the piece of code I shared or shouldn't be attempting this entirely.

    Finally, please note that this is all a discussion about what can or cannot be done using C2 by potentially rewriting parts of the runtime through a plugin, and while I do realise that this may not be a good choice to step out of what is documented in the SDK (because most undocumented stuff is undocumented for a reason), I wouldn't want to talk about that because it would make no sense to warn anyone about this. I just wanna have fun with the engine without breaking half of it, so I wanna know if there are things I need to know before trying to do so. By that I mean potential issues I didn't see coming, incompatibilities with what the editor might do, stuff breaking when exporting etc.

    Thanks for reading all of this. Anyone curious about this can discuss it in this topic.

  • Ok, so what does it add that can't be done using conventional events?

  • Well. Creating layers.

    In the end the method might also be used to reorder layers, delete them or duplicate them.

    If you mean "In what context is this useful to have because it would be the only way to achieve a given goal" I'm pretty sure you can find tons of possible uses of this on your own, but let me make myself clear. The whole point of me wanting to do this is to make it easy to do stuff, not to make it possible.

    There are many ways to avoid a problem by using alternative ways, but when these ways involve wasting my time doing stuff I don't like doing then I'm out. In fact this is exactly what I described at the beginning of my post, and this is also why I don't request for this to be a feature but rather for this to be a discussion about what can be done theoretically using the engine's hidden functions.

  • Well there's a lot of context to a layer, and ease of use doesn't float to the top.

    You've got things like render order, parallax, fx, angle, collision cells, etc you have to take into account.

    If all you want is an easier way to handle some gui then I think you're working harder not smarter.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • The whole purpose of using the layer's constructor is that it already manages all of the parrallax, scale, and all of that stuff already.

    Also when copying a layer, it copies all of th layer's properties as well. Including these, but also including the instances on the layer in theory. This is why I don't quite understand why they don't get created and assumed something else did that.

  • The engine does not support dynamically creating layers. All the code assumes a fixed set of layers created on startup and does not take in to account changes, because it doesn't have to. All the internal layer code should also be considered private methods for the engine's use only and should not be used from the SDK. You will probably break all sorts of things if you do this, and we will not offer any support for using private and undocumented parts of the engine, so you should find a different solution.

  • All the internal layer code should also be considered private methods for the engine's use only and should not be used from the SDK. You will probably break all sorts of things if you do this, and we will not offer any support for using private and undocumented parts of the engine, so you should find a different solution.

    Yes I already know all of that thank you x).

    But in theory, if I manage to manually trigger the parts of the code that are only ran once because they assume that the layer number should never change, it should work.

    Again, note that I am not speaking about wether this is a good idea or not. I'm speaking about whether this is possible.

    Also, given that this is done as a 3rd party addon, you wouldn't offer support if the addon broke anything as it's 3rd party anyway. I'm not modifying anything in any of C2's files. In the worst case scenario, if I run into very bad issues, I'll just remove the plugin and everything will start working again.

  • But in theory, if I manage to manually trigger the parts of the code that are only ran once because they assume that the layer number should never change, it should work.

    This is the software equivalent of "if I saw a car in half down the middle, will I get a motorbike?"

  • Fair enough x)

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