## 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: 11
Joined: Mon May 22, 2017 3:45 am

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

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?

ivan
Party member
Posts: 1320
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

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

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".
I use simple ref counting to avoid reloading assets that persist between levels.

zorg
Party member
Posts: 2376
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?

Me and my stuff True 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.

ivan
Party member
Posts: 1320
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

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

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: 388
Joined: Sat Jul 22, 2017 7:43 pm

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

ivan wrote:
Mon Nov 20, 2017 3:39 pm
Works 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.

zorg
Party member
Posts: 2376
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?

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 True 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: 388
Joined: Sat Jul 22, 2017 7:43 pm

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

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.

ivan
Party member
Posts: 1320
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

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

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: 11
Joined: Mon May 22, 2017 3:45 am

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

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 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: 388
Joined: Sat Jul 22, 2017 7:43 pm

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

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.