Memory build-up using font:drawTextAligned at high setRefreshRate()

Background

My recent arcade-style games make heavy use of playdate.graphics.font:drawTextAligned.

I am seeing memory build-up on my game over screen, where something is not being caught by the built-in garbage collector.

At first I called it a leak (I may still do so in the text below) but my hunch is garbage collection is not being called for some reason, as the build-up does not happen in my main game state.

Code

This only happens at "high" setRefreshRate() of 46 or greater

I define my fonts as follows:

local fntScore = gfx.font.new("Fonts/LCD")
local fntMessage = gfx.getSystemFont(gfx.font.kVariantBold)

Then I draw text to the screen:

these leak:

  1. fntScore:drawTextAligned("TEXT", 0, 0, kTextAlignment.center, 2)
  2. fntScore:drawTextAligned("TEXT", 0, 0)

But interestingly alternative uses do not leak:

these do not leak:

  1. fntScore:drawText("TEXT", 0, 0, 2)
  2. fntMessage:drawTextAligned("TEXT", 0, 0, kTextAlignment.center, 2)

Fonts

  • any fonts loaded using playdate.graphics.font.new() are affected
  • playdate.graphics.getSystemFont() is not affected

Rate of leak

Running at 50fps the memory leak grows very fast!
Witness the leak from one call to playdate.graphics.font:drawTextAligned
(and I had a handful or more depending on the state of the game)

Screen shot 2022-06-01 at 22.47.16.2022-06-01 22_57_39

Notes

  • only happens at setRefreshrate(46) or higher
  • does not happen in my game state when other things are going on

Workarounds

I have found several workarounds:

  1. replace all fntScore:drawTextAligned with fntScore:drawText (doable in my game but perhaps not in other games)
  2. add collectgarbage("collect") at the end of my update() loop
  3. run at setRefreshRate(45) or lower
2 Likes

See: Memory Leak in SDK