Objects on layouts vs. event creation

0 favourites
From the Asset Store
Very simple code without excess options (15 events for server and 11 events for client)
  • Are there any performance differences between putting a bunch of objects on a layout vs. using events to create them at runtime? Just curious.

  • My guess is the hit for having them on the layout is in the initial memory consumption and load. Creating them at run time gives you much more control of where and when they come into the layout which I would think may make avoiding some slowdowns a bit easier. Can't test it right now though as I am on a train...

  • This is my thinking as well, although the download size/memory usage hasn't really changed much after I moved everything to event-based creation. I figure download size doesn't change because you're still loading the same sprites that have to be downloaded anyway, but I thought memory usage might change. My project is still sitting at 24.7MB expected memory usage.

  • It matters when you have a huge map made of tiles. Creating them just offscreen as it scrolls means you control how many objects are created. Whereas, creating that huge map in the layout is a huge performance hit.

  • procrastinator

    Can you give an example of how you would create them offscreen efficiently? I know you can invert 'is on-screen', but that alone is no better than just creating all the objects on the layout. How do you determine when the screen is 'close' enough to the object to have it created?

  • I have a basic tilemap loader going using xml files exported from PyxelEdit. I'll try and work up a scrolling example tomorrow (remind me though ;p).

    For a simple example that I can explain now, I'll use Gradius. You'd store the whole level in an array. Draw all the tiles that are "onscreen" in the array. When scrolling through the level, every X seconds you'd use an offset in the array to draw the new column offscreen, and increase the array position by 1. When the tiles.X are less than -TileWidth (offscreen to the left), then you'd destroy those. So a level that would potentially have 1000s of tiles, you're only processing / moving a couple of hundred or less. This is why C2 isn't efficient with tiles placed in the layout as it processes / moves all of them.

    Hope I explained that ok. I'm pretty tired mentally right now ;)

  • procrastinator

    I'm not quite used to working with arrays, so I'm interested in how you populate an array to store the layout objects/information.

  • An array can be 1D, 2D or 3D, and can only store a single number or text per entry. Read the manual on arrays first, it explains it pretty well.

  • I know what arrays are, I'm just not used to using them to store objects.

    For example, my space shooter game has asteroids floating around. If I understand correctly, these can be 'destroyed' once they get outside of a certain range but their movement can be tracked in the array so that if the camera ever gets close, they can be created and given the associated speed/direction.

    Maybe that's a bit complicated, but that's what I was thinking of. Sure, one can leave them unrendered since they are off the screen, but if they are moving, they are still consuming memory. Updating in an array takes up a smaller amount of memory, and so for performance reasons I can see this being done.

    procrastinator's example seems to apply to tiled/grid based games, whereas a game like my shooter isn't bound to a grid.

  • You're right, I did mean tile based games. I just assumed that, because you brought up placing objects in the layout. I'm not sure you'd see much of a performance gain by doing just what C2 does - tracking every object. It would probably be slower to access an array 1000+ times in one go rather than just letting C2 do its job.

    That's not to say that splitting the whole level into segments and only dealing with the objects in that segment (array) wouldn't have a positive effect.

    The main reason it works for tile based games is because you're only accessing a small portion of the array at a time. That's why splitting it into segments could work, but that depends on the game really.

  • procrastinator

    Makes sense. I think for non-grid games, it's still more efficient to create all the objects through events, and just let C2 handle it.

    But say we want something to not spawn until the player gets to a certain area. Would the best way to handle this just be make an invisible sprite across the area and trigger the objects once the player overlaps?

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • I think where C2 is inefficient is objects that have animations (they'll still animate offscreen - even if under the hood it's just keeping track of the frame number and increasing that - 1000 objects is still more than the few that's onscreen) and objects with a behaviour like the bullet behaviour will still move around offscreen and so on. I don't think an invisible zone trigger would matter in those circumstances, since you have "inverted if object onscreen" event to control those. Of course, having an invisible zone trigger would mean you could have some turret fire at the player even if it's 500 pixels (or whatever) offscreen.

    Is it just an asteroids game? Or a bit more complex?

  • procrastinator

    You can play the latest version of the game (arcade mode) here: http://exeneva.com/html5/IcarusWA

    The next step is to turn it into an iOS space shooter with a campaign, and the campaign levels won't have wrapping but will involve a large layout and many objects to be rendered.

  • Ahhh nice!

    If you had a LARGE layout, for example, 10000x10000 and let's pretend you had 100 zones, laid out in a grid like fashion. So each zone would take up 1000x1000. Each zone would have its own invisible trigger (an invisible 16x16 rect scaled up to 1000x1000 to save on memory).

    You would dynamically create each zone rect at start of layout. Add an array to the rect in a container. So when each rect is created, the array is created with it. Loop through all the rects and store each zone's ship positions / types in the array and then destroy the objects / ships (except in the zone the player is currently in).

    When the player leaves each zone and enters another (basically testing if the ship overlaps that zone's rect), the one the player leaves would save the positions and ship types in an array that's attached to that zone at the time of leaving, and then destroy those objects. If a ship is onscreen but is attached to the previous zone, then don't destroy it, instead attach it to the new zone. This way you'll only be dealing with the ships in the current zone, plus any others that straggled into the new zone. Then you won't have ships suddenly disappear when entering the new zone. It seems simple enough in my head, but I imagine it could be quite complex when you get down to it.

    Does that make sense? It does to me, but I'm not sure if I've explained it correctly. Sleep deprivation and all that ;p

  • Regarding the OP question, the peak memory use is probably identical. However each option affects when Construct 2 loads the object images.

    If objects are placed in the layout, Construct 2 will pre-load all the object's images (for all animations with Sprites) at the start of the layout.

    If the object is not placed on the layout and you create it at runtime, Construct 2 probably has released the object's images to save memory. This means it has to load them the moment you create the object. This can cause pauses/stuttering at runtime.

    Apart from that it should be identical. Basically, any objects you use on a layout should be placed on the layout, even if you destroy them on startup (C2 will still pre-load them).

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