An example of C3 Spritesheeting Problems

Post » Wed Jun 07, 2017 3:53 am

@Ashley
In another thread you asked for evidence that the auto spritesheeting could be a problem. I ran a test and wanted your thoughts. I cant give concrete numbers because I can't set up my whole game in C3 but hopefully this will show you there needs to be a better method to spritesheeting.

I recreated how my game is set up but in C3. Here are my test spritesheets:
Image
Image

The green sprites are the player, the red and blue are enemies, and the smaller ones are fx related to each of those. The green sprites that say "Death" and "Death 2" are animations that should never be loaded together as only one of those is ever needed when the player dies. The green sprite that says "swim" should only ever be loaded on levels that have water. There are also Enemy 1 red sprites which only ever exist on one level. But here it is loaded every time the player is loaded. Also on Sprite Sheet #4 there is a grey star which represents player FX. If I use this player effect, it will load a larger than needed sprite sheet which contains an Enemy sprite, and Enemy FX. Lastly, the red and blue enemy sprites never appear together in game, but they share spritesheets. Every one of these sheets are completely wasteful.

Keep in mind this is just a small test of a few enemies and FX objects. My player character has 16 standard animations, 5 deaths, 6 cinematic animations, 3 unique level animations...and counting. Most of those shouldn't be loaded unless necessary to optimize as much as possible.
Image

The most simple enemy in my game has 7 animations averaging 6 frames of animation each.
Image

There are tons of FX most of which are animated too
Image

All of those player sprites and related FX would be spread out into multiple enemies and their related FX even if those enemies and FX should never exist together.

I hope you can see why some type of sprite sheet grouping is necessary for larger games.
B
81
S
53
G
42
Posts: 370
Reputation: 26,455

Post » Wed Jun 07, 2017 9:26 am

Construct has no provision for only loading specific animations, it only loads entire objects. This probably won't be changed since loading textures as animations change causes jank (the game will pause momentarily while it loads the textures), so it preloads everything that might be used at the start of the layout.

In addition to that, the engine already places sprites with 20+ (IIRC) frames on their own spritesheet, avoiding long animations ever being loaded unless they're really used. So this case only crops up when you have a few animation frames, lessening the impact.

All these sheets together use just under 5mb of memory, which is not much given modern systems have gigabytes of memory. So I don't think it's too wasteful, especially since if all those objects are used together (which they will be for some different kinds of game), it is actually more efficient. Anyways, you get a kind of natural granularity as images spill over multiple spritesheets, so it still doesn't have to load everything at once.
Scirra Founder
B
403
S
238
G
89
Posts: 24,660
Reputation: 196,167

Post » Wed Jun 07, 2017 2:17 pm

Ashley wrote: Construct has no provision for only loading specific animations, it only loads entire objects.

I'm sorry I didn't make it clear in this post. In a previous topic, I explained that these are all separate objects. Death, Death2 and Swim are not included in the main player sprite object. At the start of levels that have water in them, I load the Swim sprite that contains SwimIdle, SwimForward, SwimStop, etc so there is no jank. This is good memory management for large games.

Ashley wrote: All these sheets together use just under 5mb of memory, which is not much given modern systems have gigabytes of memory.

This is just a test case. Of course I won't complain about 5mb of memory. But brought out to larger scales, this becomes a problem. If I have huge bosses and C3 shoves in a small FX texture unrelated to the boss, then a huge texture will be loaded whenever I use that FX sprite. This is bad memory management especially for lower spec PCs. You have a whole blog post dedicated to not wasting memory.

Ashley wrote: (From another thread)A manual tagging system is boring to do and error-prone (you could easily actually make it worse by getting tags wrong), and the editor has a lot of information it could use to apply grouping automatically, such as inspecting which layouts objects are used together on.

Being boring is a strange excuse to exclude a feature. There are lots of things in game dev that require boring work but are necessary. There are also simple solutions to avoid errors. Unity lets you create tags, and then just assign that tag to sprites so there are no spelling errors. Thinking about this more, just use a similar system to creating families to create sprite sheet groups.
B
81
S
53
G
42
Posts: 370
Reputation: 26,455

Post » Thu Jun 08, 2017 10:21 am

UberLou wrote:I'm sorry I didn't make it clear in this post. In a previous topic, I explained that these are all separate objects. Death, Death2 and Swim are not included in the main player sprite object. At the start of levels that have water in them, I load the Swim sprite that contains SwimIdle, SwimForward, SwimStop, etc so there is no jank. This is good memory management for large games.

What measurements did you make that demonstrated this was necessary? If you didn't make any, how do you know this isn't just a waste of time?
Scirra Founder
B
403
S
238
G
89
Posts: 24,660
Reputation: 196,167

Post » Thu Jun 08, 2017 6:29 pm

Ashley wrote: If you didn't make any [measurements], how do you know this isn't just a waste of time?

"Remember not to waste your memory" is literally the title of your blog post. And I've just shown that C3 sheets waste memory in a small test case. In larger games, the amount of VRAM used will just balloon.
Most engines allow you to have control over sprite sheet packing. There must be some reason they allow this, right? If you need links for proof: Unity ,Gamemaker, Stencyl, GoDot, Fusion 3 (which has an automated method using playthroughs)

From Stencyl's page, "Our goal is to minimize our game's memory footprint. You do that by only loading what you're going to use in your scene."

Ashley wrote:What measurements did you make that demonstrated this was necessary?

None. I've shown that C3's spritesheets are wasteful. I have an 8oz cup that I need to fill with 8oz of milk and C3 will automatically put soda in there. If you are filling up VRAM, you want to be able to control what gets put in. I'm fine staying with C2 since I have that control.

EDIT: I'm just realizing that you're asking about what measurements I took in C2, not C3. I did do a lot of testing awhile ago (been working on this project for years) and saw the need to break out non essential animations because of memory concerns. I don't have exact numbers at the moment.
B
81
S
53
G
42
Posts: 370
Reputation: 26,455

Post » Thu Jun 08, 2017 10:09 pm

You can see on the example sheets that the loading of PFX wastes so much VRAM. PFX can fit in a 128x256 texture most likely, but loading it in causes a 256x256 AND a 1024x1024 texture to be loaded. 33x more than the amount of VRAM required. In most use cases this won't matter because you'll be using the other loaded sprites at the same time so they'll be needed anyway, but in certain situations, in games with a lot of art, it could be very wasteful. If every particle effect you load consumes 34x the amount of VRAM required, in a worst case scenario, that's bad. A little bit of control in this area could let devs optimize. Maybe add a field to animations that lets you specify a packing group.
B
48
S
10
G
9
Posts: 1,224
Reputation: 8,449

Post » Fri Jun 09, 2017 5:24 pm

Just did an export for a job.
This was one of the objects setup to use frames as instances:
Image

I added the background to show the size.
Image ImageImage
B
172
S
50
G
184
Posts: 8,445
Reputation: 116,109

Post » Mon Jun 12, 2017 2:39 pm

UberLou wrote:And I've just shown that C3 sheets waste memory in a small test case. In larger games, the amount of VRAM used will just balloon.

That does not necessarily follow. So far I've not seen any reports of someone porting their game from C2 to C3 and the memory use increasing significantly. Almost all spritesheeting approaches will inevitably involve a few extra sprites being bundled in to a sheet, but it's not necessarily a major problem. Actual cases of real-world games using more memory is what would persuade me this needs addressing. Further, it gives me something to actually benchmark, so I can measure there's a real improvement rather than just shooting in the dark.
Scirra Founder
B
403
S
238
G
89
Posts: 24,660
Reputation: 196,167


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest