During extended gameplay sessions, I was running into a bug where assets were failing to load due to
"Too many open files."
Due to my game design this didn't make much sense, so I set out to watch the file handles in the simulator using sysinternals Process Explorer (Process Explorer - Sysinternals | Microsoft Learn).
When combat occurs, my game pause()s the BGM and loads up the combat music. That code looks like this:
if (filePlayer ~= nil) then
filePlayer:pause() -- Pause the dungeon music, we'll RESUME it when combat is over
filePlayer = nil
end
...
filePlayer = snd.fileplayer.new("sounds/Combat_Music")
filePlayer:setVolume(0.5) -- 0 - 1.0
filePlayer:play(0) --repeat forever
After combat, I call filePlayer:stop(), set filePlayer =nil, and re-load & play()the normal dungeon music.
I can see in Process Explorer that this sequence results in the dungeon music file being held open:
Additional evidence:
- If I replace filePlayer:pause() with filePlayer:stop(), there is no leak.
- If, after seeing several leaks in Process Explorer, I re-load my game into the sim (restart debugging), the file handles remain open.
- I added debug code to examine the results of playdate.sound.playingSources() every time I change music, and playingSources() does NOT list the additional (leaked) instances of filePlayer; indicating it believes they are no longer in use, even though the file handle remains open.
I can imagine some workaround here, so it's not exactly dire, but this class of bug results in very tough to find and fix bugs where after 64 file handles are exhausted assets will just start to fail to load.
Thanks for looking!
Sam