Short version: I'm creating my layout completely dynamically, including loading sprite images, using XML. But is it worth the trouble? does it actually save initial download time and memory? How about animations? If you can't create them dynamically, why bother?
Hello everyone,
First of, let me say that I posted this here because I don't think it's a "how do I", I'm asking for advises and opinions, but if any admin think it should be moved, feel free to do so.
So I started working in Construct about a month ago, I really like it. My project is to make an old school point and click game. The thing is, I want to make a long game, not something you complete in 10 minutes. That means many areas to visit, meaning many layout with many images.
I already made some research about having many images and I know it can be problematic, because the game has to download everything first, and on iOS/android, Cocoon also loads all the images in memory, regardless of which layout is active, quickly reaching the phone's memory limits.
Plus, having dozen of layouts can be difficult to manage, especially if they must all match the same template. If you decide to update it later because you forgot something, like adding an extra UI layer, that means updating all the existing layouts for compatibility
So I decided to create one single layout for all the scenes, which already contains all the required layers and the pause screen, the player's sprite and then have everything else loaded dynamically with XML files. It creates empty "background" sprites on specific layers, set their size and position and load the images dynamically. Sounds overkill but I made a small proof of concept and it works!
When you move from one area to another, you just set a global variable with the name of the XML file for the new area, and restart the layout.
So far, it loads the background images, the player's initial position, the walk areas, invisible wall for collisions and layers parallax. It does not handle interactions with clickable objects yet, but that's the next step. Unique events that are proper to each layout will be loaded for a separate event sheets. I also need to add an opaque layer on top of everything, saying "loading..." that I show at the start of layout and hide once all the images are loaded, so you don't get to see a partially loaded scene.
I'm not at home right now so I can't post the capx, but if you are interested to see it, I can post it later.
To generate the XML file, I'd have a separate project with the same template (size, layers...), I'd just build the new scenes, and at runtime I'd call a function that loops through the scene elements to build the matching XML string and output it in textbox, that I can copy/paste into a file. That still needs to be done, but its' definitely not the hardest part.
So that sounds cool an all but I still have some issues:
I store the images to load in the project Files directory, so I don't have to worry about hosting them somewhere else and dealing with absolute URL in events.
But the manual says: "When published, the file is also cached for offline use alongside the rest of the project".
Does that mean that all the files in the Files folder are downloaded with the other assets when the game starts, or only the first time they are requested?
The first case sounds a lot more probable and makes more sense. That means loading images on demands becomes almost useless if said images have to download first for caching, you still end up with the same initial download time as if the images where already inserted in the sprites. But it would still help with memory problem on cellphones though, because they would not be loaded in RAM until needed.
The other problem is when it comes to animations: The dynamic image loading can only handle static images, which will do in most cases... But what if want to have animated sprites with several frames? Let's say I want to have a windmill in the background, with a looping animation. I know this could be done by rotating a sprite, but whatever, let's say I want it to be one animated sprite. As far as know, sprite animations can only be built in the animation editor. You can eventually replace an animation frame with the load URL action, but the frames themselves, even if they are blank, must be created manually first. Same for the looping option, it must be set in the animation properties.
One workaround would be to have have several blank animated sprites, with various animation length (let's say 2,4,8 frames). Then you'd design your animations accordingly. Then on load, depending on the number of frames, you'd pick the appropriate sprite and load each frame dynamically. In theory that should work, but that's really overkill and less efficient than having one sprite sheet per animation, because it means one request for frame.
The other solution is to simply create individual sprites for animated ojects, with the animations and images already set up in the project and to just not worry about download/memory, like you'd do on any small game, but still create them dynamically at runtime. But then I'm not sure, would I still have the memory issue on cellphones? I read that Cocoon does not load images layout by layout but all at the same time. Does that mean Cocoon loads all images in the project, regardless if the sprites are on any layout or not, or that it loads all the sprite that are initially on layouts but not the one that have not been created yet?
Because if it's that last case, that might be the solution: prepare all the sprites in the project (regardless if they are stills or animations), without putting them on the layout and then create them dynamically at runtime. Sure you'd have to download everything ahead, but at least the memory problem would be avoided.
The new problem here is that, unlike when loading images from URL, you can't have one function to create any sprite you want using a variable, since you must manually pick the specific sprite when you create the action.
So if you want to go that way, you're just better off forgetting the generic loading through XML and just have a specific event sheet for each area that build the scenes (just what I wanted to avoid)
So let me know what you think. What do you think is the better option? I'm missing something? Is it overkill? Am I wasting my time for nothing? am I over my head?