RAM limitations

Started by lafouine88, Fri 28/03/2025 19:58:36

Previous topic - Next topic

lafouine88

Hi guys

I'm currently facing a problem with my game that displays this message of error
error" border="0

I discussed it a bit with @Crimson Wizard and this seems to be due to a RAM overflow, the current limit of the engine is 3GB.

My game is not really adapted to the AGS engine,it's not really a point and click but more of a RPG. This entails a very greedy use of graphics :
-My maps are 2800*5000px ,oO
-the enemies get created cutting a big spritesheet into dynamic sprites that create 5 views of 8 directions and 8-16 sprites per loop(on average that's 480 sprites per enemy)
-The player's pieces of armor get created similarly creating views for each one, this time:7 views of 8 directions and 816 sprites per loop (670 sprites per piece of armor).

At first I planned to create all the views at startup and then just use them but this definitely asks too much memory. So I tried to divide the needed memory by just loading what's necessary and then deleting the sprites.

For example :
-At game start, the game loads the first map and the 5 first pieces of armor. It also loads the NPC on that map(by creating the necessary views through dynamic sprites).
-When the player changes room, the pieces of armor are kept because the player still wears them, but all the dynamic sprites for NPC get erased to create the new ones : the ennemies from this zone.
-If I get back to the first one, those same dynamic sprites are erased again and replaces by the NPC's.
-and so on...it's a bit longer to load maps because the game creates and recreates over again each time but this saves RAM.

The problem is, even with this method the game still crashes, it actually seems that the 3GB limit is reached very quickly.
According to my calculations, each enemy should use around 125mB, and armor is 175mB. Which means that if I carry 6 pieces of armor (helmet,shoulder,weapon1 and 2, torso and trousers), I already reach 1/3 of my allowed space. Each map loads around 8 different enemies so that's 1/3 more. My map takes around 120mB so that doesn't leave much room, but still it should work.

Do you know how much RAM loaded arrays take(because I use a lot of those for spells, capacities,ennemy stats etc.), and do you think this should also be reduced to a strict minimum? Same for sprites, I use 256*256 because it's more convenient but I guess I could crop the sprites to the minimum necessary, should I ? Or do you have other suggestions to keep my RAM alive ?

Thanks a lot  :-D

Crimson Wizard

#1
First of all, I do believe that this should have been posted in "Advanced Tech Forums", because it's not a basic question, and the topic should have a more specific title, because "ram limitations" is just way too abstract.



But, speaking on the topic...

The peculiarity of 2D sprite-based games is that you need separate sprites for all directions and movement frames, and because of that their numbers may grow exponentially.

Compare this with 3D games where you use textures and models: a single texture may be displayed from all sides because it's calculated in real-time. Animations are done by changing model pose, but texture is skinned on any pose automatically. Shaders allow to change the looks further dynamically using pure math (without an extra set of images). This may seem paradoxical, but 3D games often require much less resources to load to display same thing (at a cost of more processing done by gfx card).
That is why, in the contemporary game making, it may be more suitable to make such games, as you described above, in the 3D engines or 2D engines which use skinned models, rather than sprite-based engines.

I know nothing of what your game has in it, so it's difficult to give precise advises.
But if you want to stick to 2D engine and use sprites, then you need to know that such game may be only kept under reasonable memory limit if it's either done in low-resolution, or it has limited amount of variants of "skins", OR it has a efficient resource management, where you keep only limited number of things in memory at a time. Or, better, all the above at once.

For example, if I remember correctly, the first episodes of Diablo series (1,2) were sprite based, but did not have a separate "body" sprite for literally every unique item, instead they had separate sprites per a "class" of an item, like: a small shield, a big shield, a sword, a mace etc. So a player could change from e.g. "weak sword" to a "stronger sword", but the character on map would still display same sword sprite.

In regards to resource management, I don't know how you do that now. I vaguely remember our past conversations, but I don't remember how they went and which solution did you choose in the end.
I assume that you are using "paper doll" technique, where you gather your character from multiple pieces, either by applying to their frames or by having separate character or overlay for a piece, following the main body.
Assuming that's right, why do you need to load all possible armor pieces into memory, when you only need them to display on your character? Do you keep them or most of them in memory in case player changes the outfit? How do you do that? I suppose that I'd try to limit the number of stuff loaded, and only keep things that player has in inventory, or even only things that he/she was wearing very recently; and load anything else only when necessary.

There are other considerations here, such as size of armor sprites. How these are done, why do they take so much mem? What is your game resolution, and your item resolutions? You've mentioned "256*256" sprites, not sure what that is exactly. Are you saying that each piece of armor is drawn as a full-body size transparent sprite with armor piece somewhere in the middle, instead of a smaller sprite to only fit the armor piece itself? Can you post some examples?

Another thing, you say that you are preparing everything as dynamic sprites. Which means that you likely have less use for the default engine's sprite cache. Which size do you have set for the sprite cache in the game config?

lafouine88

QuoteI know nothing of what your game has in it, so it's difficult to give precise advises.
Let's say on this part of the game, it's basically Diablo 2 like with huge rip off from Warcraft interface^^ it's just for personnal use :p
Here is a quick video I recorded, obviously still WIP so there's a lot of parasites everywhere but that gives you basically the style. It's very fast and I'm godmode for test purposes as well so sorry if you feel sick^^
https://streamable.com/82desi

QuoteFor example, if I remember correctly, the first episodes of Diablo series (1,2) were sprite based, but did not have a separate "body" sprite for literally every unique item, instead they had separate sprites per a "class" of an item, like: a small shield, a big shield, a sword, a mace etc.
It's pretty much the same, I don't use a single skin for every piece of item, but still, it requires a lot.

QuoteI assume that you are using "paper doll" technique, where you gather your character from multiple pieces, either by applying to their frames or by having separate character or overlay for a piece, following the main body.
That's it, Chead,cShoudler,cTorso,cLegs,Crarm and cLarm a following exactly the character and adding their separate skin when called. I can link the code I use if need be.

QuoteAssuming that's right, why do you need to load all possible armor pieces into memory, when you only need them to display on your character? Do you keep them or most of them in memory in case player changes the outfit? How do you do that? I suppose that I'd try to limit the number of stuff loaded, and only keep things that player has in inventory, or even only things that he/she was wearing very recently; and load anything else only when necessary.
Initially I wanted to have everything created at first game load so that afterwards the player can change at will with no loading time whatsoever. After speaking with you I rejected that possibility to just have a limited amount of armor sprites ready to use. I haven't yet decided how I'm going to select which should be stored and which should be erased but I don't think it's gonna be that hard. Problem is, even now with just 8 pieces of armor (all different types of weapons take a lot of space : shield,sword,left hand sword, mace, left hand mace,dagger....) I'm blocked when trying to load the NPC's sprites.

QuoteAre you saying that each piece of armor is drawn as a full-body size transparent sprite with armor piece somewhere in the middle, instead of a smaller sprite to only fit the armor piece itself?
Exactly. The size of each sprite is 256*256px, always a square because it was much easier for me to have every item with the same size (a polearm would be larger than a dagger),that way I don't have to worry about positions. But again, that was when I thought this would be no problem for the engine.
000-0001" border="0

And finally I didn't touch game config (except for compression) so I guess it's the default values :
config" border="0

I can link any piece of code you might want to see
Thanks :)



lafouine88

Hi again guys

So tonight I tried to see how many pieces of armor the engine can load to the maximum, it is 17.
Which is logical because according to what @Crimson Wizard  told me, the amount of RAM spent to create a sprite is width*height*4 per sprite
So : (256*256*4)*7views*8directions*12 frames ~175Mb per item
175*17= 2 994 Mb,
175*18 =3 170Mb which is too much.

So in the end this all seems quite logical, and the obvious solution that came to me is just to divide all my spritesheets by 2. With 128*128 px I can get 4 times as many items, which will be much more cumfortable.

I don't think there is any magical solution here, so unless there is a magical solution to expend the RAM limit or anything else I can touch in the settings I guess I'll go with this. I tried it and it still looks quite alright :)

Thanks anyway and many special thanks to @Crimson Wizard for all his explanations and patience ;)

Crimson Wizard

#4
Quote from: lafouine88 on Sat 29/03/2025 20:03:43I don't think there is any magical solution here, so unless there is a magical solution to expend the RAM limit

There's an opportunity to use the 64-bit engine version, which supports much higher ram cap (as much a computers can have today). But that will still mean that your game will require that much, which may not be a good thing.

I'd suggest to reduce sprite sizes as much as you can to still accommodate the pieces of equipment. That will of course make setting things up less convenient: you will have to script a system of offsets which each part should have relative to the main body. But this also may have a significant positive effect on memory requirements.

lafouine88

QuoteI'd suggest to reduce sprite sizes as much as you can to still accommodate the pieces of equipment. That will of course make setting things up less convenient: you will have to script a system of offsets which each part should have relative to the main body. But this also may have a significant positive effect on memory requirements.

Yes. I actually tried a bit more today with half sized sprites and the loss in quality show a bit too much, especially on small pieces of armor. Which is a shame.
So I think I'll actually go with the trimmed sprites. It's going to be very annoying to code with every piece of item having different sizes^^(actually if someone has suggestions to do that in an elegant way I would love it because I'm pretty sure I'll do something very complicated :P) but it will definitely be worth it.

I'll let you know if this solution is better.
Thanks

Snarky

Are you scaling your characters? If so, using different-sized sprites is going to introduce positioning errors because of rounding.

Do you really need to have 17 different pieces of armor all loaded at once? Can't you load it as needed?

(But my advice would pretty much be to not try to make this game in AGS.)

lafouine88

QuoteAre you scaling your characters?
Yes, that is the worst of it. I'm downscaling to 50% to match the interface. So I load a big file and then reduce it to 50% so that with 'render sprites at screen resolution' it looks quite sharp... :-X

QuoteDo you really need to have 17 different pieces of armor all loaded at once? Can't you load it as needed?
No, it's just that if 17 is the strict maximum, and I need to load at least 6 at a time for the character+ennemies there is not much margin remaining and I must be very cautious not to use too many visuals, which is a bit annoying. But yeah the idea is not to load everything but just what is strictly needed.

Quote(But my advice would pretty much be to not try to make this game in AGS.)
And I also wish I could turn back time and do this again on a more adapted engine. I figured AGS would be more than enough for an isometric 2d game but really it would have saved a ton of time and work to do this on a different software:/
Let's say that after one year of creating functions and GUIs everywhere I really want this to work out^^ and I'm not so far "^^

Crimson Wizard

Quote from: lafouine88 on Mon 31/03/2025 07:26:25
QuoteAre you scaling your characters?
Yes, that is the worst of it. I'm downscaling to 50% to match the interface. So I load a big file and then reduce it to 50% so that with 'render sprites at screen resolution' it looks quite sharp... :-X

Well... you are doing opposite to what people are usually doing when they load a small image and scale it in the engine in order to make scaling fast and save memory. You are loading bigger image, thus increasing memory requirement of each of them by 50% compared to their size on screen.

I would propose to not downscale sprites, and instead have them 1:1 of a size. They may look not so sharp, but at least your game will be running well.


Quote from: lafouine88 on Sun 30/03/2025 23:31:36So I think I'll actually go with the trimmed sprites. It's going to be very annoying to code with every piece of item having different sizes^^(actually if someone has suggestions to do that in an elegant way I would love it because I'm pretty sure I'll do something very complicated :P) but it will definitely be worth it.

I may suggest to create a table of relative offsets per piece per direction (maybe even per frame if that's required).
Have this table as an array in your script, or perhaps a text file, which may be parsed in script and loaded into array.
Then you may be using this array when updating character in rep-exec, by moving other characters around it by these relative offsets.

SMF spam blocked by CleanTalk