• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM Sprites That Don't Take Up A Page Each

H

Heropants

Guest
So I'm making a game where you basically create your own sprites for many of the objects in game (it's a tycoon game where the player is building different objects to sell. Every object they create to sell gets it's own custom sprite). I do this by transferring the sprite the player makes to a surface then use the function: sprite_create_from_surface function. This allows the player to create their own custom sprites that can be used in-game.

The problem is that each of these new sprites creates their own sprite page (or texture page or whatever it's called). So if the player creates more than a handful of sprites, the game has to do a bunch of texture swaps and it really starts to slow the game down.

Does anyone have any idea of how I could save custom sprites to a single page rather than having it create a new page every time.


Here's some of the ideas I've tried that failed:

- Instead of actually creating and saving a new sprite, I just have the object draw a bunch of different sprites together to make up the sprite. The probably with this is that the sprites the player creates can be made up of 1024 different sprites. So it turned out that even with the texture swaps, it's still takes a lot less power to create a single custom sprite than have the object draw 1024 different sprites together.

- I also tried making it so every time a new sprite was created, it took all the custom sprites and redrew them on one surface and then created a single sprite from that. This worked because it saved all the custom sprites into 1 sprite that was 1 texture page. However, I then had to use the draw_sprite_part function to split up the sprite back into the individual sprites for each object. The problem is that the draw_sprite_part function takes up more power (if there's more than like 10 objects) then it does to swap between texture pages.

Any help guys would be massively helpful. Thanks in advance!
 

Jabbers

Member
Hello! I had this issue too when I was building the mod system for my game. As I understand it, not only do you get a new texture page for every imported sprite, but also every sub-image! In my case I had to create my own texture page system. This is how it works:



So in step 1 you import the sprites with sprite add.

In step 2 you create a data structure. I format mine so it associates the sprite with the name of the mod, but also remembers the sprite dimensions, and adds in 0 as placeholder for our new texture page id (the sprite we are creating to act as a texture page) and texture pos x and texture pos y (the position on our future texture page).

Step 3 you create a new surface.

Step 4 you have to draw each of the imported sprites to fit on the texture page. You'll need to create a script to fit them all into the space in a way that isn't wasteful. If you want animated sprites, you'll need to import it as a strip to fit it onto the page.

Step 5 you return the position the sprite has drawn on relative to the surface, and update your data structure so the game knows what texture page to draw from and at what position to draw from.

Step 6 you save the texture page as an image then re-import as a sprite.

Step 7 you delete all of the sprites you have previously drawn to your new texture page, thus compacting all of those texture pages into a single image. If you have more sprites, you repeat this process. If you had 20 sprites and you drew 10 of them to your first texture page, make sure that for the next 10 sprites you update the data structure so the game knows to draw from the 2nd custom texture page, and so on.

Remember to delete the surface after you are finished with it. Forgot to mention that in the image!

In this example, once you are in the game, if you create the flower pot item the draw code would be something like this:

draw_sprite_part(sprite, subimg, left, top, width, height, x, y);
draw_sprite_part(custom texture page sprite index, 0, tex pos x, tex pos y, width, height, x, y);

If you want animation, then have the game note how many subimages are part of the sprite (e.g specify this in a mod file and load it into a data structure) and then have it increase the tex pos x by it's sprite width, say in an alarm, and reset it back to the original tex pos x when it reaches the subimage number. Gif image below:



There may be better ways to do this but this works for me.
 
Last edited:
H

Heropants

Guest
So that system is fairly similar to how I was taking about with my second thing I tried. However, when I suggested that, everyone told me that the power it took to draw every sprite with draw_sprite_part was probably more than it took to just swap texture pages. What do you think? Have you noticed the power it takes to run draw_sprite_part creating more of a problem than swapping pages?

Thanks for the reply btw, I think what you've got here is great! And thanks for the write up, that was incredibly easy to follow.
 

Jabbers

Member
However, when I suggested that, everyone told me that the power it took to draw every sprite with draw_sprite_part was probably more than it took to just swap texture pages. What do you think?
My opinion is that this is wrong in any situation where you want the player to be able to include a large amount of custom content, like a modding system for your game. If you only plan on letting the user import a few images, then it might be easier to just use sprite_add.

A single animated sprite could take up tens of texture pages if you simply use sprite_add, which is a bit insane. I think you also waste memory as well, because you get extra blank space padded out on the image. A door sprite that is 200x90 would most likely end up on a texture page of 256x128 or something similar. If you were to create a mod system simply using sprite_add, you could easily end up with hundreds of wasteful texture pages, and that would be a serious problem. I believe having lots of sprites in memory on a single texture page is much faster than hundreds of texture pages all trying to be used every step.

I don't know much about the efficiency of draw_sprite_part or the inner workings of the function. I know it is slower than draw_sprite, but unless you are trying to draw hundreds of objects in the visible area of the screen, it hardly matters in my opinion. My game has a mod system using the system I described above. I tested it on a iMac from 2007, with low memory and integrated graphics, and it worked well.

Thanks for the reply btw, I think what you've got here is great! And thanks for the write up, that was incredibly easy to follow.
Thanks! The ideas I've expressed were inspired by discussions I've read or participated in with people like @Mike and @YellowAfterlife, and I know there are lots of people who have come up with similar systems to combat this problem. This isn't to say these people endorse my particular way of doing it, but they might be able to tell you more about ways to solve this problem. I'm not sure of a better way of doing it but I'd like to hear it!
 
H

Heropants

Guest
A single animated sprite could take up tens of texture pages if you simply use sprite_add, which is a bit insane.
Hmmmm, I think this is where our games differ but I'm thinking you're still right. In my game, the player does create their own sprite but they aren't animated. Therefore, a custom sprite will always take up only 1 texture page. So my texture pages won't be in the hundreds like an animated sprite would be. However, I know even after 10 or 20 texture pages, gamemaker really starts slowing down. So my prediction is that if I want to allow the player to do more, I'm still going to run into the same problem you would have.

I don't know much about the efficiency of draw_sprite_part or the inner workings of the function. I know it is slower than draw_sprite, but unless you are trying to draw hundreds of objects in the visible area of the screen, it hardly matters in my opinion. My game has a mod system using the system I described above. I tested it on a iMac from 2007, with low memory and integrated graphics, and it worked well.
This is great to know! I haven't actually fully implemented the draw_sprite_part system into my game because I was told it'd take up too much power. But if you've actually done it and had it work, then I think I should definitely try it your way. I'll give it a shot and post my results/process here.

Thanks for all your help Jabbers! I really appreciate it!
 
R

renex

Guest
I haven't actually fully implemented the draw_sprite_part system into my game because I was told it'd take up too much power.
I use this for every game. It's not nearly as cpu-expensive as you'd think.
 
Top