What is the best practice for loading animations into layouts?

1 favourites
  • 14 posts
From the Asset Store
Best car suspension with spring effect and very cool terrain generation.
  • Hello everyone, I'm new to C3 and I have been reading a lot of posts and tutorials on optimising memory usage and performance and I wanted to get some opinions or guidance on best practices around animations and effects to optimise my game's performance. Please do point me to the right articles if this has been addressed before as I couldn't really find anything on this. I found a thread about Spine but I didn't really understand it much.

    I am working on the core aspect of my game now which is a turn based battle system. There are up to 4 player units and up to 4 enemy units in every battle. Each unit has up to 5 abilities and the string IDs of these abilities are stored in an instance variable of the unit object.

    What I will do at startup is to load the player's variables from a server (have not designed this part yet) but most likely it will load a JSON dictionary file. While enemies, abilities and everything else will be loaded from JSON arrays (also loaded from a server). After loading these, there are invisible sprites with variables containing the properties of each of the 5 abilities belonging to all units on the battle field. To illustrate this, these are the objects:

    Player1Ability1

    Player1Ability2

    Player1Ability3

    ...

    Enemy4Ability4

    Enemy4Ability5

    So I'm thinking one of the properties of these ability objects would be a string of the filename of the icon / animation files that will be loaded from the server, and I will preload these files once the abilities to be used for the battle instance have been determined. When any unit uses their abilities, the respective sprite object for that ability will be made visible and trigger it's animations.

    Hence I would like to seek guidance on whether I'm treading in the right direction or whether there are better ways / best practices to execute this to minimize lag, loading times or other performance bottlenecks. Hope to receive some advice or opinions as there is so much I don't know at present. Thank you.

  • Why do you want to load animations from the server? This may be a difficult task, I would only consider doing this if there were lots of animations too large to add to the project, or if I needed to update the images after the game is deployed.

    In other words, I don't recommend this approach. I suggest first estimating the memory usage for one animation - place it on an empty layout, run it in debug mode and check the "Image memory" stat. Depending on the results and the number of these animations you can add them to one or several sprites.

    Once the sprite is created on the layout, all its animations will be loaded into memory and ready to use. So if the memory usage is not too bad, you can even keep all animations in one sprite.

    .

    Also, whenever possible you should use a single object with multiple instances, not multiple different objects. For example, consider making a single EnemyAbility sprite with lots of instances (or copies) instead of Enemy1Ability1, Enemy1Ability2, Enemy2Ability1 etc.. This will make the programming job much easier.

  • Thank you. This is very helpful advice. I'm still very early into development and I'm unsure how laggy it would be because I estimate to have at least 100-200 different abilities, each with their own animation. On top of that I'll likely have 200-300 unique battler sprites each with their own unique animations as well. Am I right to say that if I have all the animations for everything preloaded, it will likely cause a much longer loading time during startup and also take up more memory in the game?

    Forgive me as my fundamentals are not strong, but is there an advantage to storing all animations in a single sprite? Does this mean that when a spell is cast, I just have to invoke the specific animation frames relating to that spell? For example if I have 100 spells, and 5 frames per spell, so I'll have a sprite object with 500 frames, would that be more efficient?

    Regarding the object EnemyAbility, I'm quite confused about making a copy of the same object. Does it mean that they will be distinguished from one another using a variable like "EnemyID"? Would this also apply to Player and Enemy units? I currently have Player1, Player2, Player3 etc objects all nested into a family with family instance variables. Should I be tweaking my approach to using clones of a single object instead? Sorry for having so many questions, I would like to optimise my game as much as possible from the early stages of development.

    Why do you want to load animations from the server? This may be a difficult task, I would only consider doing this if there were lots of animations too large to add to the project, or if I needed to update the images after the game is deployed.

    In other words, I don't recommend this approach. I suggest first estimating the memory usage for one animation - place it on an empty layout, run it in debug mode and check the "Image memory" stat. Depending on the results and the number of these animations you can add them to one or several sprites.

    Once the sprite is created on the layout, all its animations will be loaded into memory and ready to use. So if the memory usage is not too bad, you can even keep all animations in one sprite.

    .

    Also, whenever possible you should use a single object with multiple instances, not multiple different objects. For example, consider making a single EnemyAbility sprite with lots of instances (or copies) instead of Enemy1Ability1, Enemy1Ability2, Enemy2Ability1 etc.. This will make the programming job much easier.

  • Like I said, the important thing is the average size of these animations. I'm working on a low-resolution pixel art game where images are small (50x50 px or less), so I have sprites with hundreds of animations. Storing multiple animations in one sprite helps to better organize the project and the code.

    I can load the entire sprite because it doesn't use much memory. But in your case you might need to put all these abilities into separate sprites and combine them into a family. Then only spawn the abilities which are required on the current level to save memory.

    Regarding the object EnemyAbility, I'm quite confused about making a copy of the same object. Does it mean that they will be distinguished from one another using a variable like "EnemyID"

    Yes, correct, use instance variables.

    I currently have Player1, Player2, Player3 etc objects all nested into a family with family instance variables. Should I be tweaking my approach to using clones of a single object instead?

    Probably not, if each player sprite has a unique set of heavy animations, and you don't need all these players on the layout at the same time, then it's better to keep them as separate objects.

    Every game is different and there is no universal advice. It's normal to re-think the way you organize your objects once you start developing the game, I do this all the time - combining/splitting sprites etc. It's good that you are using families and instance variables already, you are on the right path.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Thank you for your advice once again.

    I believe in this case I will try splitting them up into separate sprites with the respective animations and slowly scale up while testing for performance issues.

    Is my understanding correct that I should still preload all the animations into sprites but not enable them for the instance if they are not required, and not load them ad-hoc as required from the server?

  • You can preload object images in advance if the sprite is large and you want to avoid a lag when it's spawned.

    load them ad-hoc as required from the server

    This I would definitely not recommend.

  • Sorry and I have a follow up question too.

    Originally I was planning to only have four enemy objects (Enemy1, 2, 3, 4) in the layout and to load their attributes (e.g. damage, name, defense, sprite) from an array that is loaded from a json file during startup. However in order for me to achieve this, I believe I would have to use the "Load image from URL" command to allow for the correct sprite to be shown. Would this still be the right approach or is it better to:

    1. create an object for every monster I possibly have in the game

    2. have all the monster images / animations pre-loaded into each of the 4 enemy objects (will duplicated animation files cause extra memory consumptions / load times too?)

    Same scenario as earlier, I would have potentially hundreds of monsters such as (Slime, Beast, Elephant, Donkey, Tiger, Goatman, Skeleton etc), and I thought I would save loading times and memory by only loading the information that I need from the array as required at the start of the battle.

    I am really thankful for any advice you can give on this.

  • You can preload object images in advance if the sprite is large and you want to avoid a lag when it's spawned.

    > load them ad-hoc as required from the server

    This I would definitely not recommend.

    Thank you for this, I will give that a try.

  • I suggest using a single 'base' Enemy object, it may be just an invisible rectangular sprite. And create a bunch of 'skin' sprites containing animations for different monsters, for example EnemyWolf, EnemyZombie etc..

    Configure all behaviors and instance variables on the base object. And then in runtime spawn a skin sprite (say, EnemySkeleton) and pin it, or better yet connect it with hierarchy to the base object.

    This is a very common approach, you can find it in many tutorials and game templates.

  • Thank you once again. This sounds interesting. I have a few questions.

    1. Does it mean that I no longer need Enemy1, Enemy2, Enemy3, Enemy4?

    2. 'Skin' sprites are basically clones of the base object with an instance variable to differentiate them from each other? (e.g. the EnemyWolf, EnemyZombie etc.)

    3. By creating these 'skin' sprites upfront, will it mean that the loading time and memory usage will be significantly increased since they exist in the game?

    4. What does pin or hierarchy do? (I will go read on this myself too)

  • 1. Yes, it's better to use a single Enemy base object with 4 instances.

    2. The main object will be the invisible Enemy sprite, ideally it will be used in all game mechanics, AI etc. EnemyWolf, EnemyZombie are just 'skins', they will move with the base sprite and play animations.

    3. You still haven't told how big your animations are, how much memory they are using.

    If this is a web game, then I believe all graphics will be downloaded once on startup and cached. So the next time players launch the game, it will load quickly.

    Memory usage and download times are two very different things. To optimize memory usage you shouldn't create too many images on one layout.

    4. Pin attaches one object to another. Hierarchy is like an advanced version of Pin, I recommend reading about it.

  • 1. Yes, it's better to use a single Enemy base object with 4 instances.

    2. The main object will be the invisible Enemy sprite, ideally it will be used in all game mechanics, AI etc. EnemyWolf, EnemyZombie are just 'skins', they will move with the base sprite and play animations.

    3. You still haven't told how big your animations are, how much memory they are using.

    If this is a web game, then I believe all graphics will be downloaded once on startup and cached. So the next time players launch the game, it will load quickly.

    Memory usage and download times are two very different things. To optimize memory usage you shouldn't create too many images on one layout.

    4. Pin attaches one object to another. Hierarchy is like an advanced version of it, I recommend reading about it.

    Thank you so much for sharing your knowledge!

    1. Okay I will try redoing my code to check for the ID variable instead of the object, and create the clones as suggested.

    2. I understand this part, thank you so much.

    3. When you mention "on one layout" am I right to say that images that are not loaded on the layout will not take up memory? In this case if I have (zombie, skeleton, pig, monkey, monk, donkey in my monster pool) but I only invoke the 'skins' of zombie and skeleton, the other preloaded skin objects will not take up any memory. Is my understanding correct?

    My artist is still preparing the animation and I am not able to test how big the animations are yet. But will certainly test those once ready. And I may pop back with more questions if somehow I am unable to optimise the size and pixels of the animations (hopefully not the case!)

    4. Yes I have went to read about it and I think I have an understanding on how this works. Will definitely implement this!

  • 3. Exactly. Only the images from the objects which are present on the layout are occupying memory. If you create and then delete a sprite, its images will remain in memory, so next time you create it on the same layout, there will be no lag and no additional memory usage.

    4. Hierarchy is a super powerful and useful feature in C3, I highly recommend studying it.

  • Thank you so much for all your help!

    I will definitely study it. I hope I won't run into issues saving and loading player datasets from servers (thinking of firebase and/or blockchain). Will worry about that when I'm done with these initial parts.

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