justabox21 2 Report post Posted June 8, 2012 Is there a way to "pre-cache" (If that is a real thing) a specified group of pictures so that when they are used in sequence to make a cutscene there will be less lag? Share this post Link to post Share on other sites
0 Moonpearl 32 Report post Posted June 8, 2012 (edited) Yes there is. Just insert a script before Main and load the graphics you wish using this line: RPG::Cache.picture("<your picture's name>") For each graphic you wish to load (assuming they're all pictures, otherwise you have to change the method name accordingly, i.e. RPG::Cache.character for characters) If you don't want to bother inputting all your pictures' names, you can have the game load all files from the Pictures directory instead. This piece of code should do the trick (untested): valid_ext = ['.bmp', '.png', '.jpg'] for filename in Dir.entries("Graphics/Pictures") if valid_ext.include?(File.extname(filename)) RPG::Cache.picture(filename) end end Also, if you have lots of graphics to load, you might want to add a Graphics.update inside the loop to prevent the "Script is hanging" error. Edited June 8, 2012 by Moonpearl Share this post Link to post Share on other sites
0 kellessdee 48 Report post Posted June 8, 2012 Moonpearl is right; but if I remember correctly, you were having issues with too many bitmaps loaded into memory at once and you had to clear the cache to prevent the game from crashing, right? So, to build on what Moonpearl said, you'll have to make a call to RPG::Cache.picture("picture_name") for the bitmaps you want to Cache. Then, the next time they are called with the same line of code, it will return the bitmap from memory rather than loading it into memory then returning it. module Cutscene_Loader def self.load(filenames) filenames.each do |filename| RPG::Cache.picture(filename) end end end CUTSCENE_1 = [ 'filename1', 'filename2', 'filename3' ] Cutscene_Loader.load(CUTSCENE_1) This will cache all files from the picture folder, contained in the array that is passed to #load If you wanted to extend this to ANY folder: module Cutscene_Loader def self.load(type, filenames) filenames.each do |filename| RPG::Cache.send(type, filename) end end end Cutscene_Loader(:picture, CUTSCENE_1) # works with any of the RPG::Cache methods passed in as a symbol One thing to keep in mind though, if you were having lag issues with loading them into memory, you may still want to account for possible performance issues. If loading all the bitmaps at once causes issues, you can design the Cutscene_Loader to utilize "incremental" loading: class Cutscene_Loader def initialize(type, filenames) @type = type @filenames = filenames @index = 0 end def loaded? @filenames.size - @index == 0 end def update unless loaded? RPG::Cache.send(@type, @filenames[@index]) @index += 1 end end end loader = Cutscene_Loader.new(:picture, CUTSCENE_1) until loader.loaded? loader.update end Then you can use the loader, in the scene prior to the cutscene (if this is possible), you can update the loader at specific times (every other frame, etc), to spread out the workload involved. Or, you could take advantage of the call script event: 1. Create an event (parallel process/autostart) 2. Add a bunch of single "call script"s, with a call to RPG::Cache.picture("filename") for each file. 3. At the end, flip on a switch that turns off the event. Then, when that switch is turned on, you know that the pictures are loaded into memory. Also, this takes advantage of the fact the event interpreter in RPG Maker has a frame delay between event calls, so this will automatically spread out the workload of processing the graphics. (Would probably be better as a parallel process, since autostart halts everything else.) You could also make such calls between "Message" boxes for dialogue. If you can hide all the loading in sneaky places, the loading process can remain transparent to the player. Share this post Link to post Share on other sites
0 justabox21 2 Report post Posted June 8, 2012 (edited) Wow this is alot of information (Not that I'm complaining, I really do appreciate all the help)! Ok, I'm gonna give this a try. Since I'm using "show picture commands" to make cutscenes I have a bunch of pictures. Like hundreds. I'll try using that directory method first and hope it doesn't kill my computer, lol. Ok, so I tried doing the one Moonpearl said where instead of loading each frame individually I just load them all from a directory. This is what I did, and I got a syntax error. Does this look right? valid_ext = ['.bmp', '.png', '.jpg'] for filename in Dir.entries ("Desktop/Project/ Grave Prosperity/Cutscenes/Intro/ Apartment") if valid_ext.include?(File.extname (filename)) RPG::Cache.picture(filename) end end Edited June 8, 2012 by justabox21 Share this post Link to post Share on other sites
0 Moonpearl 32 Report post Posted June 8, 2012 I got a syntax error. What line? Does this look right? If you wrote it exactly as shown here, then there are 2 problems: You shouldn't break lines unless you know exactly what you're doing. I suspect the syntax error come from either the second or third line being broken improperly Why did you enter your project's folder in the directory path? I would have told you so if it was required. Just input the path assuming you're already in the project's folder like I did in my example. Besides, Desktop being your drive's root folder is Windows bullshit, Ruby won't ever find your project using such syntax. Also, it seems like your pictures are NOT in the Graphics/Pictures folder, that's not a good thing because the RPG::Cache.picture method can't find them. Put your pictures in the Pictures folder, or at least in a subfolder from there, using: RPG::Cache.picture("<your path from Graphics/Pictures>"/#{filename}") Share this post Link to post Share on other sites
0 ForeverZer0 44 Report post Posted June 9, 2012 (edited) folder = 'Cutscenes/Intro/Apartment' files = Dir[folder + '/*.{png,jpg,bmp}'] files.each {|file| RPG::Cache.load_bitmap(folder, file) } I think this should do the trick. If you want to do multiple folders, or recursively search the entire "Cutscenes" folder, you could also do this: folder = 'Cutscenes/**/**' files = Dir[folder + '/*.{png,jpg,bmp}'] files.each {|file| RPG::Cache.load_bitmap(folder, file) } I haven't tested this, I don't really have any folders structured like that to test at the moment... Edited June 9, 2012 by ForeverZer0 Share this post Link to post Share on other sites
0 justabox21 2 Report post Posted June 9, 2012 (edited) @Moonpearl: I didn't actually break the line, that was the way the call script window had it set up after typing in the directories. I think the "prosperity" part was too long for it to stay on the same line in that tiny call script box. I just copied and pasted it the way it was. Which part goes above Main? Was it the whole thing or is that how I call it when I need it? The syntax error was just a window that said "A syntax error occurred while running script". And as far as the directory's path goes, that was my mix up. I didn't realize you were putting in a literal path to follow, I thought your directory names were just an example guide line for me to go by. I get it now though, my mistake. The pictures are in the project's graphics/pictures area, I was using the original location of the pics before they got imported into RMXP. I'm going to do it again the right way and see what happens. Sorry about the crazy mix up! @ForeverZer0: I also tried out your script. The weird thing is RMXP isn't ever reacting to the call script, like it isn't even there. I tried it the first time and the scene still lagged, then I tried it with a purposely misspelled directory just to see if it would catch it and it just went on like nothing was even there.. Edited June 9, 2012 by justabox21 Share this post Link to post Share on other sites
0 ForeverZer0 44 Report post Posted June 9, 2012 You're right. I forgot that the found files will include the folder and extension of the file. This will work, I actually even tested it. folder = 'Graphics/Characters/' files = Dir[folder + '/*.{png,jpg,bmp}'] files.each {|f| name = File.basename(f, File.extname(f)) RPG::Cache.load_bitmap(folder, name) } It shouldn't actually "do" anything, it's just caching images to prevent lag later. Exactly how are you using this anyway? In all reality, if this is just a single scene that is scene once, its probably not a good idea to use the RPG::Cache. You can cache images anyway you please, even just add them to array to reference later. It is pointless to cache all sorts of images into RAM where they will continue to take up memory when they were only needed once. If this is your scenario, it would be much wiser to simple create an array, fill it with bitmaps, use them for whatever you are doing, which I will guess is some sort of animation since speed seems to be an issue, and then iterate over the array and dispose them when you're done. Share this post Link to post Share on other sites
0 justabox21 2 Report post Posted June 9, 2012 (edited) Yeah I'm just using this for specific cutscenes that will be seen only once throughout the game. I'm not sure what an array is though. If it means anything, I am also using a clear cache script after I have used the required pictures in a cutscene in order to clear up RAM. Assuming that I'm using these things right, that is.. I hate to say it but when it comes to scripting I am one dumb bastard, so I'll need to be guided Barney style if I'm going to get this right. Well I tried your new script and it seems to be working quite nicely! The FPS didn't drop below 37, and I am using tons of pictures for these cutscenes so that's really saying something. Of course I am still curious about that array thing you put out there earlier. Edited June 9, 2012 by justabox21 Share this post Link to post Share on other sites
0 Foxkit 4 Report post Posted June 9, 2012 If you three wouldn't mind, I'd like to give a shot at answering the array question... What ForeverZer0 was suggesting is that you load all your pictures into one variable (which makes the variable an array for having multiple items stuffed into it) and use that array whenever you wanted to cache something. ForeverZer0 does have a working code using such a method. When your done, just clean the cache. When you want to use it again(if ever) just call the array again to cache everything back in. (ForeverZer0, if that's not what your doing, or I'm being too presumptuous, send me a hot scalding pm about it then xD) Share this post Link to post Share on other sites
0 ForeverZer0 44 Report post Posted June 9, 2012 Yeah, you pretty much got it right. The RPG::Cache is a very handy tool to prevent the constant re-loading of commonly used graphics in the game. It basically just loads a bitmap, and instead of disposing it and letting it get picked up by the garbage collector, it retains a reference to it, which means next time you need it, its already loaded and ready to go, no loading. Obviously the more images you cache, the more memory (RAM) the game is going to use, since it is "remembering" all these cached images. For most circumstances, this completely fine, since throughout gameplay, the same graphics are being used over and over again. There are special circumstances that I would advise against the RPG::Cache, and simply create your own container for images. Such circumstances are when you are using a large amount of graphics that are only going to be used once, such as a cutscene that will not be repeated. Basically what is going to happen is this: Lets say you load 100 images to make an animation, and each image uses 500 KB of memory. This means that if you are using RPG::Cache, you are loading 50 MB of stuff into memory that will remain there until the game closes, just for a brief scene that will never be seen again. In this case, instead of using RPG::Cache, you could do something like this: @bitmaps = [] folder = 'Graphics/Characters/' files = Dir[folder + '/*.{png,jpg,bmp}'] files.each {|f| name = File.basename(f, File.extname(f)) @bitmaps.push(Bitmap.new("#{folder}/#{name}")) } # Do whatever you need with your bitmaps, cycle through animation, etc. @bitmaps.each {|b| b.dispose } This will pre-cache your images to prevent lag, still do what you need, and release the memory when you are done. It all depends on the circumstances the bitmaps are being used. I am merely making an assumption based on the need of so many bitmaps and the fact the folder he is loading from us label "Cutscene/Intro". Share this post Link to post Share on other sites
0 justabox21 2 Report post Posted June 10, 2012 @Foxkit: Ok, that makes sense. Arrays aren't so complicated afterall. Thanks for the helpful input! @ForeverZer0: That "Cutscene/Intro" label I was using originally was from a separate folder outside of my RMXP Project. I have the needed pictures inside the normal "Graphics/Pictures" area of the project too though. But I think your post before this one pretty much fixed my lag issue. Share this post Link to post Share on other sites
0 ForeverZer0 44 Report post Posted June 10, 2012 You missed the whole point of the post then. It wasn't about where the files were located, it was about freeing up worthless RAM when you are done using the pictures, no matter where they are loaded from, and avoiding the RPG::Cache if circumstances warranted it. Its not a big deal though, more of a general programming tip about managing memory efficiently, but its just a homebrew RMXP game, not a large application that requires it. Share this post Link to post Share on other sites
0 justabox21 2 Report post Posted June 10, 2012 So using RPG::Cache.clear won't clear up the space the same way? I'm confused. Share this post Link to post Share on other sites
0 kellessdee 48 Report post Posted June 10, 2012 I think, ForeverZer0 is probably unaware of your current situation. His approach is correct, and perfect for usual RPG Maker games but in your case you are clearing the cache often to avoid rpg maker from crashing (from too many/too large bitmaps), correct? His approach was in terms of a scenario where you wouldn't want to clear the entire cache but if you are currently clearing the cache sometime before the scene and again after the scene--then it wouldn't make much of a difference. If you aren't clearing the cache before the scene, then this approach would be good (and you can save the other bitmaps that are still in the cache) ForeverZer0 is simply just using an array to build a "local cache" (if you will) of bitmaps, and explicitly freeing the memory after through "bitmap.dispose" With RPG::Cache.clear, RPG Maker clears out all references to the global cache, and asks the Garbage Collector to cleanup instead. The Garbage Collector knows how to free up dangling references to bitmaps. So essentially, it works the same, except with regards to the Cache that is targeted. ForeverZer0 clears a local cache, RPG::Cache.clear clears the global cache Share this post Link to post Share on other sites
0 justabox21 2 Report post Posted June 10, 2012 Oooh ok, that makes sense. Yeah you got it right in that first paragraph about the too many large bitmaps. So we're essentially all doing the same thing, just on different scales. Share this post Link to post Share on other sites
Is there a way to "pre-cache" (If that is a real thing) a specified group of pictures so that when they are used in sequence to make a cutscene there will be less lag?
Share this post
Link to post
Share on other sites