(SOLVED, THANKS)Problem with loading external sprites with sprite_add()

Cheeztaco

Member
Hey guys,

For my recent project, a RPG, I need to import sprites externally, because adding them by hand would just be... overwhelming.

I currently have a problem with the sprite_add function.
Im trying to load a few sprites (a lot more in the future with more items).
Currently about 640 strip sprites (8 directions, 8 different sprites, 10 animations)
The basic single sprite dimensions are 128x128px, so the strips are relatively with a max of about 25frames.

All sprites together are 15.3Mb on disk, but if I import them with sprite_add, I land at 1.9Gb RAM, which is huge...
After learning that sprite_add does create a texture map (so 640 maps total), I had a simple fix in mind.

I created the texture maps on my own (via external python code) and it packs every direction in a single map. So now I have 80 sprite maps (8 different sprites, 10 animations) and thus I should only have 80 texture maps. But as it turns out, even with cutting 87,5% of texture maps, I still reach 1.9Gb RAM and I simply can't understand the problem.

btw: Without sprite_add I land at about 20Mb RAM

Does anyone have an Idea what might happen, or how I can fix this issue?

Working with sprite_flush and sprite_prefetch wont suffice, because we are currently talking about just 8 different sprites (equippable items) and in a standard RPG there are way more then 8 combination on the screen at any time, like in a city with just a few NPC.

Thanks in advance and happy coding!

TL;DR

External sprites are 15.3Mb on Disk
640 sprites with sprite_add result in 1.9Gb RAM and 640 texture maps
80 packed sprite maps with sprite_add also result in 1.9Gb RAM but 80 texture maps
Without sprite_add I run on just 20Mb RAM
Send help! :D
 

TsukaYuriko

☄️
Forum Staff
Moderator
You can't compare file size on disk to file size in memory. On disk, graphics will likely be stored compressed, but you can't do that in memory. They need to be uncompressed to be available on demand, otherwise you'd stab your game's performance in the heart.

Let's do the math.

If I'm interpreting that correctly, you have 640 strips with 25 frames each, with each frame being 128x128. Each frame therefore consists of 16384 pixels, each strip consists of 409600 pixels and all strips contain roughly 262 million pixels. At 32 bits per pixel, that'll be 8388608000 bits, or 1048576000 bytes, or exactly 1 GB. Add overhead to that and your results line up.

You'll bring any engine down to its knees with this massive truckload of graphics. Don't load everything at the start, load it when it's needed and unload it when it's no longer needed. You said this won't suffice, but this is the only way aside from modifying your graphics to use less space.
 

Cheeztaco

Member
Ok I get it now. So that means, that if I have a city with about 20different loaded npcs, who wear about 5 different pieces of armor and 8 different weapons, I would need about 13 different strips * 8 for each direction.
The result would be 104 strip sprites for just the walk animation.
To make a city feel alive they would need different animations like cooking, drinking beer, etc. which adds up to about 10 different animations at the same time. Our total would be about 1040strip sprites with the known size.

I get the math now, (about 2Gb+) but that means, that I shouldn't preload every animation and just load it if someone needs it.
Wouldnt that create a fps drop, if I load these textures on demand?
 

FoxyOfJungle

Kazan Games
What prevents you from adding all these sprites to the GMS IDE? Without having to do this manually? You save VRAM/RAM. In addition to that you can drag and drop files into the IDE.
 

Cheeztaco

Member
What prevents you from adding all these sprites to the GMS IDE? Without having to do this manually? You save VRAM/RAM. In addition to that you can drag and drop files into the IDE.
I currently planned about 50 Weapons, 30 Armors and about 25 Animations and 8 directions just for the human character. That would be about 16000 strip sprites to add to the game, which would be insane. Even if I create a map on my own with all direction on it and write a custom draw sprite function, it still would be about 2000 sprites.

Fixing just one animation would result in changing 640 sprites in the IDE with strips. This sounds insane to me.
 

TsukaYuriko

☄️
Forum Staff
Moderator
Ok I get it now. So that means, that if I have a city with about 20different loaded npcs, who wear about 5 different pieces of armor and 8 different weapons, I would need about 13 different strips * 8 for each direction.
The result would be 104 strip sprites for just the walk animation.
To make a city feel alive they would need different animations like cooking, drinking beer, etc. which adds up to about 10 different animations at the same time. Our total would be about 1040strip sprites with the known size.

I get the math now, (about 2Gb+) but that means, that I shouldn't preload every animation and just load it if someone needs it.
Wouldnt that create a fps drop, if I load these textures on demand?
Not necessarily. It would cause a performance drop, but that only causes a noticeable FPS drop if it makes a frame take longer to execute than the frame rate allows it to.

I currently planned about 50 Weapons, 30 Armors and about 25 Animations and 8 directions just for the human character. That would be about 16000 strip sprites to add to the game, which would be insane. Even if I create a map on my own with all direction on it and write a custom draw sprite function, it still would be about 2000 sprites.

Fixing just one animation would result in changing 640 sprites in the IDE with strips. This sounds insane to me.
Are all of the frames you have in your graphics absolutely vital? Developers usually save space (and work) by cutting out any duplicated frames, or frames that can be dynamically generated at run time, e.g. by mirroring or rotating another frame, overlaying other frames, etc.
 

Cheeztaco

Member
Not necessarily. It would cause a performance drop, but that only causes a noticeable FPS drop if it makes a frame take longer to execute than the frame rate allows it to.
Ok so I dont have to worry about loading them on demand if it the current hardware is not older than 2012 :D

Are all of the frames you have in your graphics absolutely vital? Developers usually save space by cutting out any duplicated frames, or frames that can be dynamically generated at run time, e.g. by mirroring or rotating another frame, overlaying other frames, etc.
Not all of them. I have a palette shader, so that I can reuse weapons and armors with a different color palette, which would decrease my armor and weapon count. Also not every animation has to be loaded in at any time.
I going to try loading everything on demand for know and create a ds_map with a last used timestamp, tofree the memory of unused sprites. I just saw, that sprite_flush(id) doesnt free the RAM, soI have to delete the loaded sprite instead.
 

Cheeztaco

Member
Not all of them. I have a palette shader, so that I can reuse weapons and armors with a different color palette, which would decrease my armor and weapon count. Also not every animation has to be loaded in at any time.
I going to try loading everything on demand for know and create a ds_map with a last used timestamp, tofree the memory of unused sprites. I just saw, that sprite_flush(id) doesnt free the RAM, soI have to delete the loaded sprite instead.
@TsukaYuriko I just wanted to let you know, it works like a charm. I have no performance issues and I just load an animation in a certain direction, but only for visible items. The game is now running at about 100Mb at any given time, and it even deletes unused sprites after a few seconds because of the timestamp map.

Thanks for the quick help, you saved my butt :D
 

FoxyOfJungle

Kazan Games
@TsukaYuriko I just wanted to let you know, it works like a charm. I have no performance issues and I just load an animation in a certain direction, but only for visible items. The game is now running at about 100Mb at any given time, and it even deletes unused sprites after a few seconds because of the timestamp map.

Thanks for the quick help, you saved my butt :D
Is there a demo of this game (.exe)? I was curious to see if it runs well on my notebook (an old one), but if you can't, no problem :)
 
Last edited:

Cheeztaco

Member
@TsukaYuriko after implementing everything an importing all sprites I did notice a certain amount of lag. I checked everything and the Problem still occours but I fixed the problem with just the simplest of tricks.

After finding out, that you can drag&drop images in the IDE (thanks @FoxyOfJungle) I stumpled upon the file naming trick. Just naming the file "bla_stripXY.png" the IDE just creates a strip animation with XY images, which is huge.
I thought I had to manually create every sprite, but dragging them im like that and have a animated sprite created is just wonderful.

The importing took a while, because the IDE cannot handle all sprites imports at once, but man... the performance increase...
I know run at 30mb RAM and every sprite is neatly packed by the IDE and I dont have to worry about these issues anymore.

So thanks to @TsukaYuriko for explaining what really happened
and thanks to @FoxyOfJungle for the simplest of solutions for a really overcomplicated subject :D (Btw I dont have a demo ready at the time, but I testet it on my old 2011 notebook and it runs at a decent 350FPS)

TL;DR

To everyone with this issue. Listen to @FoxyOfJungle and just import your sprites directly in the IDE witha File naming like "name_stripXY.png" and it will all be created for you.
 
Top