Sprite vs tilemap performance

Hi all,

I'm working on a game that uses a grid of background tiles. These tiles update occasionally, but don't move outside of the grid. My initial implementation made each tile a sprite, but now that I'm testing on device, I'm seeing some pretty rough performance. I can just about make 30 fps, but about half the frame time seems to be spent in graphics.sprite.update(). And if I scroll my camera, I rapidly drop to 14 fps or so, with the majority of the additional time spent in image.drawTiled() being invoked by sprite.update()

I've gone through and made two major optimizations, calling sprite:setUpdatesEnabled(false) on as many sprites as I can and manually calling sprite:remove() on anything off-screen. However, it seems like sprite.update() is still doing a lot of work to determine if any sprites have moved and redrawing them if they have.

I have about 70 sprites onscreen, which I wouldn't have thought would be too much for the Playdate to handle, but maybe it is? Are there any general tips on improving performance when working with sprites? And specifically, do people think it would be more optimal to convert my sprites to a tilemap instead?

I experimented with moving all of my sprites into a single large tilemap-backed sprite rather than updating them as individual sprites. However, whenever I scroll my camera (by setting the current drawOffset) I still drop down to about 15 fps. This makes scrolling feel really laggy, as you can imagine.

Based on the profiler, basically all of that time is being spent in drawTiled() as triggered by sprites.drawCallback().

Does anyone have a suggestion for how to scroll a camera smoothly without incurring massive framerate hitches, or is drawing simply too costly to re-draw the whole screen while maintaining a steady framerate?

For reference, the game I'm working on uses a grid of tiles as shown below. The whole level is one screen high and about two screens wide.

Aha! I found something of a smoking gun — drawTiled() was actually being invoked by my own code! Very early on I had created a custom background drawing callback (via sprite.setBackgroundDrawingCallback()) that was attempting to draw a tiling pattern behind my sprites. Turns out that was accounting for about half of the frame time while moving the camera!

Seems like, if I remove that, I can hang out just under 30 fps while scrolling the camera. I can live with that! I'll try moving the background into a static sprite and just use that instead.