GameMaker [Solved] How to reduce the file size of the saved buffer?

S

Sozidar

Guest
Original png file size is 3.58 kb and file size of the saved buffer is 1088 kb, which is kinda sad. Is there a way around this, or am I doing something wrong? Any help is greatly appreciated :)

Code:
w = 128;
h = 2176;

surf = surface_create(w,h);
surface_set_target(surf);
draw_sprite(vst_castle_walls,0,0,0);
surface_reset_target();

size = w * h * 4;
buff = buffer_create(size, buffer_fixed, 1);
buffer_get_surface(buff, surf, buffer_surface_copy, 0, 0);
buffer_save_ext(buff,"test.txt",0,size);
I'm using chunk system for loading and unloading resources from included files to avoid loading screens since its open world. Have no problems with manipulating json files, but couldn't find any alternative to sprite_add. The only somewhat viable option I found is to replace all of the included images with generated surface buffer files (code above) and load them in game asynchronously and then project them onto the surfaces. This method is a lot faster than sprite_add, but the file sizes are unacceptably huge.
 
Last edited by a moderator:

CloseRange

Member
Note that the function writes each pixel of the surface to the buffer using a BGRA formatting on the Windows target
that's from the docs of buffer_get_surface
that means every single pixel gets saved from the surface directly and quite frankly that's a poopy way to save an image file (obviously its 300% worse than the original)

I don't know of any way of storing the surface as a buffer in the correct structure but you can use:
surface_save
and that will get you closer (though I'm not sure if that will act the same as a buffer)
it also isn't perfect, I did the example and my origional was 6kb and surface_save made it go to 51.
It's better but not the best it could be.

Another option is to... well... just use the origional file.
Though this is obviously useless if you need it as a surface first (like if game maker needs to edit the image in some way)

So that brings me to my last idea and that's to modify the file yourself by creating your own data structure.
If you are curious about how actual file systems store image files I recomend watching this video
Image and buffer files can be thought of as text files, so just load it like a text file, edit the data inside it, and resave it out.
 
S

Sozidar

Guest
Thanks for the reply!

I'm essentially trying to find an alternative to sprite_add because there is a noticeable fps drop when loading big images with it. Is custom file format really the only way around?
 

CloseRange

Member
oh if it's to do with sprite_add then you just need to optimize how you're using it.
For every sprite you need to add make sure you only ever use it once.
Remember to always use sprite_delete when you no longer need the sprite

Make absolutely sure you arn't calling sprite_add every single step (aka every frame)

a good test is to go directly under the sprite_add and add:
Code:
sprite_add( ... );
show_debug_message("Sprite Added!");
assuming you are using just the one image, then you should only see this message pop up one time. If you see it come up a bunch then there is a problem

Think about other games you play, most will have a loading screen. During that loading screen this is what's going on. It is loading all the image files (and other stuff) that will be used in the next scene (or room or level or whatever you want to call it)
This usually only occurs in the loading screen at the begging of the level for the same reason you described, it takes long time.
Chances are though that you will NOT need a loading screen because (assuming you do it right and you only load the resources one time when you need them) then the loading process will be really quick.
The reason big games need them is because they load a lot of high quality images, models, connect to server, load meta data, and maybe do some map generation.

Once apon a blue moon I worked on a Pokemon game (just the first generation) and I used only sprite add because I didn't want to hand load each Pokemon image into it's own sprite and so it was easier to just drag it into the included files and do sprite add.
each pokemon had 4 images attached to it. A front animation, a back, a front shiny version and a back shiny version. The file sizes ranged from anywhere from 3kb to 21kb in size and there were 151 pokemon (604 files)

I loaded this in the loading screen before the game started, took about 15 seconds for the game to start (that would be where I put the loading screen) but once it did start it ran perfectly fine just the occasional hiccup but that was caused by unrelated code
 
S

Sozidar

Guest
Thank you for the tips, although I'm well aware of them. I should have explained the situation much clearer from the very beginning, my bad. I'm using chunk system for loading and unloading resources from included files, so loading screens is exactly the thing that I'm trying to avoid, since its open world. Have no problems with manipulating json files, but couldn't find any alternative to sprite_add. The only somewhat viable option I found is to replace all of the included images with generated surface buffer files (first post) and load them in game asynchronously and then project them onto the surfaces. This method is a lot faster than sprite_add, but the file sizes are unacceptably huge. The whole open world thing goes kaput if I wouldn't find any solution to this :(
 
Last edited by a moderator:
S

Sozidar

Guest
You can compress your buffers
Oh, alright, thank you :oops:. That helped with their size, but now buffer_decompress is damaging fps instead of sprite_add (although slightly less). Vicious cycle. I'll mark the topic as solved anyway. Thank you again.
 
Top