ImageManager: Load vs Reserve vs Request

Lanzy

Veteran
Veteran
Joined
Feb 29, 2020
Messages
70
Reaction score
22
First Language
English
Primarily Uses
RMMV
I am 90% sure that that is wrong. Other scenes, built-in scenes, call reserveFaceImages in their create, and that works. There's also Scene_File which calls reserveCharacter in its create. So there must be a way that works without putting it in Scene_Boot.

For a custom window skin, yeah, Scene_Boot makes sense; but for characters, I don't believe that's the right answer.
Personally, putting the reserve method in the create function never worked for me. And yes, I too have seen built-in scenes doing it this way, but never worked for me. Why not just do it in the Scene_Boot? It will save you a lot of trouble.

I use Scene_Boot for all costum images, from menu Icons to large detailed pictures. They all load erroneously otherwise.
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
464
Reaction score
200
First Language
English
Primarily Uses
RMMV
I think I just stumbled upon what the built-in scenes do differently that I was missing. In the scene start function, they refresh whatever window uses those loaded images. I added a refresh call in my own scene start, and that seems to fix it.

Somehow, this isn't needed for face images, only for other types of images... no idea why.
 

Lanzy

Veteran
Veteran
Joined
Feb 29, 2020
Messages
70
Reaction score
22
First Language
English
Primarily Uses
RMMV
I think I just stumbled upon what the built-in scenes do differently that I was missing. In the scene start function, they refresh whatever window uses those loaded images. I added a refresh call in my own scene start, and that seems to fix it.

Somehow, this isn't needed for face images, only for other types of images... no idea why.
The image loading engine is a nightmare. I have been struggling for months with this. I also tried the refresh solution in the windows, but then, days later it would not load initially again. It always came back to me one way or another.

If it ever happens again, think of the Scene_Boot solution ;)
Good Luck!
 

bblizzard

Veteran
Veteran
Joined
Nov 6, 2017
Messages
343
Reaction score
350
First Language
Croatian
Primarily Uses
RMMV
No, no, you should put them in Scene_Boot only if they are reserveSystem() calls.

@Solar_Flare Have you made sure you called it before the superclass call? Something like this:

Code:
Scene_Mine.prototype.create = function()
{
	ImageManager.reserveCharacter("my_character_filename");
	Scene_Base.prototype.create.call(this);
};
e.g. This is a piece of code I used in my game and it works perfectly.

Code:
Scene_Battle.prototype.create = function()
{
	$gameParty.members().forEach(function(actor)
	{
		ImageManager.reserveFace(actor.faceName());
		ImageManager.reserveMicroFace(actor.faceName());
	});
	$gameTroop.members().forEach(function(actor)
	{
		ImageManager.reserveFace(actor.faceName());
	});
	Scene_Base.prototype.create.call(this);
	this.createDisplayObjects();
};
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
464
Reaction score
200
First Language
English
Primarily Uses
RMMV
No, no, you should put them in Scene_Boot only if they are reserveSystem() calls.

@Solar_Flare Have you made sure you called it before the superclass call? Something like this:

Code:
Scene_Mine.prototype.create = function()
{
    ImageManager.reserveCharacter("my_character_filename");
    Scene_Base.prototype.create.call(this);
};
Yes, I did that and it wasn't sufficient; I needed to also refresh the windows in scene start.

e.g. This is a piece of code I used in my game and it works perfectly.

Code:
Scene_Battle.prototype.create = function()
{
    $gameParty.members().forEach(function(actor)
    {
        ImageManager.reserveFace(actor.faceName());
        ImageManager.reserveMicroFace(actor.faceName());
    });
    $gameTroop.members().forEach(function(actor)
    {
        ImageManager.reserveFace(actor.faceName());
    });
    Scene_Base.prototype.create.call(this);
    this.createDisplayObjects();
};
Well, that's a built-in scene that you're just extending, so it's slightly different from my case which was a brand-new scene. I'm guessing Scene_Battle already refreshes some windows in its start method.
 

bblizzard

Veteran
Veteran
Joined
Nov 6, 2017
Messages
343
Reaction score
350
First Language
Croatian
Primarily Uses
RMMV
Did you derive your brand new scene from Scene_Base? If not, then that's your issue. Scene_Base.prototype.isReady is what the scene uses to wait until all the graphics are reserved. You should always derive from Scene_Base when you make new ones.
 

Lanzy

Veteran
Veteran
Joined
Feb 29, 2020
Messages
70
Reaction score
22
First Language
English
Primarily Uses
RMMV
No, no, you should put them in Scene_Boot only if they are reserveSystem() calls.

@Solar_Flare Have you made sure you called it before the superclass call? Something like this:

Code:
Scene_Mine.prototype.create = function()
{
    ImageManager.reserveCharacter("my_character_filename");
    Scene_Base.prototype.create.call(this);
};
e.g. This is a piece of code I used in my game and it works perfectly.

Code:
Scene_Battle.prototype.create = function()
{
    $gameParty.members().forEach(function(actor)
    {
        ImageManager.reserveFace(actor.faceName());
        ImageManager.reserveMicroFace(actor.faceName());
    });
    $gameTroop.members().forEach(function(actor)
    {
        ImageManager.reserveFace(actor.faceName());
    });
    Scene_Base.prototype.create.call(this);
    this.createDisplayObjects();
};
Interesting, the reason I use Scene_Boot for reserving images, is because I too have tried to set the reserve method in the menu scene create method, before calling the super class. And still, it didn't work. Now, after reconsidering your post, I put the reserve method in the initialize menu function, before the super class and that seems to do the trick for now.
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
464
Reaction score
200
First Language
English
Primarily Uses
RMMV
Did you derive your brand new scene from Scene_Base? If not, then that's your issue. Scene_Base.prototype.isReady is what the scene uses to wait until all the graphics are reserved. You should always derive from Scene_Base when you make new ones.
The scene is derived from Scene_Menu, so there shouldn't be an issue on that count.

Interesting, the reason I use Scene_Boot for reserving images, is because I too have tried to set the reserve method in the menu scene create method, before calling the super class. And still, it didn't work. Now, after reconsidering your post, I put the reserve method in the initialize menu function, before the super class and that seems to do the trick for now.
I have my reserve call after the super class call in scene create, and it still seems to work. It would've probably made more sense though to put it in the initialize call for the window that uses it... oh well. But what made it work seems to be the refresh calls in the scene start function.
 

bblizzard

Veteran
Veteran
Joined
Nov 6, 2017
Messages
343
Reaction score
350
First Language
Croatian
Primarily Uses
RMMV
@Solar_Flare Hm, it actually does make sense. The creation of all windows is also handled in the create method. So if you reserve the images there and then run through creating the windows, but the images aren't loaded yet, it won't work right. But if you do a refresh of those windows in the start method, they should be loaded there as start will be only called once isReady returns true (and isReady will return true once the images have been loaded).

@Lanzy You mean the menu initialize? Not sure if that will work. But if you put it in the scene initialize, you will definitely have problems as the reserved images will actually be bound to the previous scene. You should probably do the same thing with refreshing windows in the start method like I just explained to Solar_Flare above. That should be the proper way to do it.
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
464
Reaction score
200
First Language
English
Primarily Uses
RMMV
You mean the menu initialize? Not sure if that will work.
I think the menu initialize should work, because you create your windows with the new operator in the scene's create function, and that calls the menu initialize.
 

bblizzard

Veteran
Veteran
Joined
Nov 6, 2017
Messages
343
Reaction score
350
First Language
Croatian
Primarily Uses
RMMV
Yes, but the graphics still won't be loaded in time for the refresh that happens at the end of initialize. Though if you do a refresh in scene start and the graphics are actually only used by that menu, from an organizational standpoint it does make sense to add it to the menu's initialize.
 

Lanzy

Veteran
Veteran
Joined
Feb 29, 2020
Messages
70
Reaction score
22
First Language
English
Primarily Uses
RMMV
@Solar_Flare Hm, it actually does make sense. The creation of all windows is also handled in the create method. So if you reserve the images there and then run through creating the windows, but the images aren't loaded yet, it won't work right. But if you do a refresh of those windows in the start method, they should be loaded there as start will be only called once isReady returns true (and isReady will return true once the images have been loaded).

@Lanzy You mean the menu initialize? Not sure if that will work. But if you put it in the scene initialize, you will definitely have problems as the reserved images will actually be bound to the previous scene. You should probably do the same thing with refreshing windows in the start method like I just explained to Solar_Flare above. That should be the proper way to do it.
Refreshing the windows unfortunately does not help with all the window loading issues, because of the way my Menu Scene is structured. It is basically all in one scene, with refresh functions embedded in updateCursor functions for "previews" of other windows. Some windows do load correctly, when refreshing in the Scene start method, but not all. Perhaps the compromise is for me to reserve some images in the initialize method while refreshing those that do work in the start method.
 

bblizzard

Veteran
Veteran
Joined
Nov 6, 2017
Messages
343
Reaction score
350
First Language
Croatian
Primarily Uses
RMMV
I really couldn't say. I'm using a completely custom menu. (^_^')
 

Lanzy

Veteran
Veteran
Joined
Feb 29, 2020
Messages
70
Reaction score
22
First Language
English
Primarily Uses
RMMV
I really couldn't say. I'm using a completely custom menu. (^_^')
Hey bblizzard, it's me again. Missed me? :D
Ok so here is the thing, I got another ... problemo if you will.

Now that you showed me how to reserve images correctly, I'm facing the problem that there is a limit of (I believe you said 10) images that can be reserved at a time?

My costum menu however, has a lot of item, weapon and armor pics. I have easily surpassed the 10 pic limit. And yes, I also put all images into sets. But it's still not enough. Any idea how I can circumvent the 10 pic limit?

On a side note: If there is any way I can just have the game preload all images, in exchange for a few more seconds of the initial loading time, that would be great.

Edit:
rpg_core.js,
line 468:
ImageCache.limit = 10 * 1000 * 1000;

I changed the limit to 100. That won't break anything, right? *nervous laugh
Thanks in advance for your time!
 
Last edited:

bblizzard

Veteran
Veteran
Joined
Nov 6, 2017
Messages
343
Reaction score
350
First Language
Croatian
Primarily Uses
RMMV
Yup, ImageCache.limit is what you need. Just keep in mind that this is in pixels. So with 100 you have 100 million pixels available which can go up to 400 MB of data (because PNGs usually have 4 bytes per pixel, RGBA). You will likely only have some issues (ie. crashes) on older mobile devices with low RAM. I use 125 million pixels in my own game so you should be fine, too.
 

Lanzy

Veteran
Veteran
Joined
Feb 29, 2020
Messages
70
Reaction score
22
First Language
English
Primarily Uses
RMMV
Yup, ImageCache.limit is what you need. Just keep in mind that this is in pixels. So with 100 you have 100 million pixels available which can go up to 400 MB of data (because PNGs usually have 4 bytes per pixel, RGBA). You will likely only have some issues (ie. crashes) on older mobile devices with low RAM. I use 125 million pixels in my own game so you should be fine, too.
Ohh, so basically the cache is one giant 1000 x 1000 pixel sheet times 100 pictures with all the reserved images it can pick from?

Ok, very cool. Now I'm wondering why they set the cache limit so low in the first place. But probably as you said because of maximum device compatibility. Since I'm not planning on running the game on mobile devices, that should be fine then.

I'm gonna have to check your game out :D
 

YoraeRasante

Veteran
Veteran
Joined
Jun 6, 2014
Messages
1,633
Reaction score
417
First Language
Portuguese
Primarily Uses
RMMV
@Lanzy I can see you already learned more, but this thread it more visible now so better exmplain to everyone else too:
Ptting it on the Scene_Boot is only advisable for things you'll use the whole game. Like the system images.
They are always there to use, but that also means they are always there to use, taking space in your computer's ram.
This is the idea behind preloaders, they are put there right away right on Scene_Boot. It makes the game run these resources much quicker, but also takes forever (until you close the game) your ram for that. Thus why they can make the game faster, but why they also make playing it so heavy.
So yeah, mobile or weaker computers, avoid this save for really important things.

Characters, save for the main actors, are only going to be used in this or that map. So unless you plan on filling the ram with your game, better call them in an "gonna use it here" case.
 

Lanzy

Veteran
Veteran
Joined
Feb 29, 2020
Messages
70
Reaction score
22
First Language
English
Primarily Uses
RMMV
@Lanzy I can see you already learned more, but this thread it more visible now so better exmplain to everyone else too:
Ptting it on the Scene_Boot is only advisable for things you'll use the whole game. Like the system images.
They are always there to use, but that also means they are always there to use, taking space in your computer's ram.
This is the idea behind preloaders, they are put there right away right on Scene_Boot. It makes the game run these resources much quicker, but also takes forever (until you close the game) your ram for that. Thus why they can make the game faster, but why they also make playing it so heavy.
So yeah, mobile or weaker computers, avoid this save for really important things.

Characters, save for the main actors, are only going to be used in this or that map. So unless you plan on filling the ram with your game, better call them in an "gonna use it here" case.
I was happy once I began to understand js and the game system. But then I realized it's not only a question of does your code works, but also how effective it is. Optimizing your code for best performance is a whole nother thing.
 

bblizzard

Veteran
Veteran
Joined
Nov 6, 2017
Messages
343
Reaction score
350
First Language
Croatian
Primarily Uses
RMMV
And even in that case, always remember never to optimize prematurely. There's no point in spending a month on a piece of code that gives you a 1% speed boost if you have performance issues with a piece of code that's used all the time which can be fixed in a day. xD
 
Last edited:

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Got inspired and started writing a simple tower defence battle system last night :o
Good news! I have located an amazing 3D website called SketchFab that has rotatable renderings of famous statues!
Picked up a physical copy of Megadimension Neptunia VII for the PS4 today. It's pretty good. I'm having a lot of fun with it.
The only upside of this remote semester was the plenty of funny photoshop material those facecams provided. Not that I would do that. Ever.

Forum statistics

Threads
100,516
Messages
976,711
Members
132,080
Latest member
nwr
Top