Best way to cache/preload images and other assets for later use?

General discussion about LÖVE, Lua, game development, puns, and unicorns.
therektafire
Prole
Posts: 12
Joined: Mon May 22, 2017 3:45 am

Best way to cache/preload images and other assets for later use?

Post by therektafire »

Hello everyone :) Everyone knows that loading your assets ahead of time at the beginning of the game is usually preferable to loading them only when they are needed (unless your game is really large and memory hungry or there's some other particular reason why you can't do that) but what I am wondering is what is the best way to do that in Love? Right now i am only taking care of image loading since I'm not particularly experienced at game dev in general and don't know how to make and parse level/save data/etc formats yet...

So for loading and working with images/sprites/etc I made a little module called "ghelp" (stands for "graphics help" of course :]) and one of the functions is a preload function that creates a table of images by first getting the names of all the files in a specific folder that contains the images (in my case "img/", puts them in a table called "files", then a new table called "images" is created and for each entry in the "files" table newImage is called to import the image for use in the game, with the name of the file used as the key and the extension removed to make it easier to write (so I can use, for example, images.foo instead of images["foo.png"]). Here is the code for that:

Code: Select all

preloadimgs = function()
        local dir = "img/"
        local files = love.filesystem.getDirectoryItems(dir)
        local images = {}
        local k = ""
        for i = 1, #files, 1 do 
            k = files[i]
            images[k:gsub("%p%a%a%a", "")] = love.graphics.newImage(dir..files[i])
        end
        return images
    end
    
Then at the top of the main.lua I import the ghelp module via require and call this function to create a local script-scope table with all the images in it.

My question is is this the correct way to do this kind of thing or are there better ways? Also would this way work for other kinds of assets or just images?
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Best way to cache/preload images and other assets for later use?

Post by ivan »

Generally, it depends on the size and number of assets you are working with.
Mobile platforms in particular don't have a lot of RAM.
For small games you can preload everything at the start and not worry about it.
If your assets are small but numerous, then it's fine to just load them "on demand".
For larger games, you may need to load/unload between levels.
I use simple ref counting to avoid reloading assets that persist between levels.
User avatar
zorg
Party member
Posts: 3436
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Best way to cache/preload images and other assets for later use?

Post by zorg »

Also, loading assets takes time, of course, but having data move from your storage mediums to the memory also blocks the thread you're doing that in; if you're loading many or big assets, there may be hiccups along the way; in those cases (after profiling whether this does affect you badly enough) would i go for a threaded asset loader approach; basically load the data into memory in another thread, and when it's done, signal back to the main thread; in the meantime, the main thread can just check the signal variable each cycle, and continue processing graphics, updating the world, animations, etc. while the data loads, giving you a more seamless game experience.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Best way to cache/preload images and other assets for later use?

Post by ivan »

zorg wrote: Mon Nov 20, 2017 1:06 pm Also, loading assets takes time, of course, but having data move from your storage mediums to the memory also blocks the thread you're doing that in
Or, if you're lazy like me you can just show a splash screen.
Works fine as long as there is nothing moving on the screen and the thread is not blocked for more than a few seconds.
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Best way to cache/preload images and other assets for later use?

Post by grump »

ivan wrote: Mon Nov 20, 2017 3:39 pmWorks fine as long as there is nothing moving on the screen and the thread is not blocked for more than a few seconds.
Coroutines are another possibility to prevent blocking. I tried coroutines when I realized rendering took a while and I needed to display progress in my font rendering tool. It was very easy and painless to implement, even as an afterthought, with just a few lines of code.
User avatar
zorg
Party member
Posts: 3436
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Best way to cache/preload images and other assets for later use?

Post by zorg »

grump wrote: Mon Nov 20, 2017 8:55 pm Coroutines are another possibility to prevent blocking. I tried coroutines when I realized rendering took a while and I needed to display progress in my font rendering tool. It was very easy and painless to implement, even as an afterthought, with just a few lines of code.
Coroutines are fine if the granularity of operations you have control over (i.e. lua commands and such) are small enough; io will still block a thread whether or not you use coroutines, if you want to read in a significantly large part of data (or if your HDD/etc is sufficiently slow/ has relatively gigantic seek times) - coroutines are serial in nature, they just allow "jumping around" the code more.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Best way to cache/preload images and other assets for later use?

Post by grump »

zorg wrote: Wed Nov 22, 2017 7:31 am Coroutines are fine if the granularity of operations you have control over (i.e. lua commands and such) are small enough; io will still block a thread whether or not you use coroutines, if you want to read in a significantly large part of data (or if your HDD/etc is sufficiently slow/ has relatively gigantic seek times) - coroutines are serial in nature, they just allow "jumping around" the code more.
You're not wrong, but for OP's use case, loading a bunch of image files at the start of the program, coroutines are totally fine. Unless you want to preload a single 500 MB video file and/or want the program to remain fully interactive during loading. A worker thread might be the better idea in that case.

I wrote a lot of stuff for a lot of large and small systems, and I've never had to load an atomic chunk of data so big that blocking became a problem that needed to be solved with threads. Not even when loading from optical media. It was always UX considerations (i.e. the smoothly spinning loading icon is a MUST HAVE) that led to threads for loading, never technical reasons (i.e. the OS deemed the program unresponsive). For local data, that is. Sockets are another story.
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Best way to cache/preload images and other assets for later use?

Post by ivan »

I can confirm from experience that Zorg is correct.
Something like love.graphics.newImage is always going to block the thread (for large images).
Best case scenario, the frame rate will be choppy, especially if the assets you are loading vary in size.
There are ways to make it work using coroutines, if you read image by chunks and later pass it to ImageData,
but then you might as well use threads.
therektafire
Prole
Posts: 12
Joined: Mon May 22, 2017 3:45 am

Re: Best way to cache/preload images and other assets for later use?

Post by therektafire »

Well loading times or low framerate while loading stuff probably won't be an issue for me right now since I am just making small non release games right now to get some experience since I only have slightly above 0 as it currently stands :D But I will take the advice about coroutines into consideration. Honestly I will probably have more trouble making things like menus/splash screens/load screens/other game state dependent things
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Best way to cache/preload images and other assets for later use?

Post by grump »

ivan wrote: Wed Nov 22, 2017 11:18 pm Best case scenario, the frame rate will be choppy, especially if the assets you are loading vary in size.
OP is specifically asking about loading a bunch of images at the start of the program, not about loading in the background. Frame rate is irrelevant.
therektafire wrote: Wed Nov 22, 2017 11:31 pm Well loading times or low framerate while loading stuff probably won't be an issue for me right now
You just need to care about the OS assuming your program froze because it loads assets for a while. Coroutines are an easy way to make sure that doesn't happen. Threading is the cleaner and more flexible solution, but also much more complicated to implement, as opposed to 5 lines of code for a coroutine.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 52 guests