Advanced Debugging with the Playdate Simulator
Not only that, but the Playdate Simulator comes with a few super-powers not present in the hardware that really help you debug while you build your games. Let’s take a look.
While a handful of keys are used to simulate button inputs in the simulator, that leaves a lot of unused inputs on your keyboard. Fortunately, you can capture these key presses in your code and tie them to special actions while debugging.
There are two callbacks you can implement to accomplish this:
playdate.keyPressed(key)is called whenever you press a key on the keyboard.
playdate.keyReleased(key)is called whenever you release a key on the keyboard.
function playdate.keyPressed(key) print("Pressed " .. key .. " key") end function playdate.keyReleased(key) print("Released " .. key .. " key") end
How you use these methods is a bit open-ended. You could use them to:
- Quickly reset the level you’re playing
- Tweak settings in your app to see how they feel
- Log details of the game’s state to the console.
The Simulator also gives you another super power: the ability to draw in a color on top of the Simulator’s black-and-white display. You can use this to draw bounding boxes, highlight areas of interest, or show private variables to the screen.
To do that, you’ll need these two methods:
playdate.setDebugDrawColorto set the color you’d like to display the debug overlay in. Each color component (red, green, blue, and alpha) is a value from 0 to 1, inclusive, indicating how much of that color to use.
playdate.debugDrawis where you can do your custom drawing. This is called immediately after
playdate.updateon each frame.
Normally, when drawing an image to the screen, you’ve got 3 “colors” to deal
with: black, white, and transparent. This limited color palette doesn’t change
debugDraw. How do we achieve color drawing?
- First of all, we only get one more color. Later calls to
setDebugDrawColorsupersede previous ones. This is a debug view, not a full screen display.
- Second, black pixels are treated as transparent. They won’t be rendered with the debug color.
If you’re just drawing with the
playdate.graphics API, you might not notice
that second part. Even if you set the draw color to
kColorBlack in your
playdate.update callback, it gets reset to
kColorWhite in the graphics
debugDraw is called.
However, your images and text might not render. Let’s solve that.
Drawing Text & Images
Drawing images doesn’t use the graphics context’s current color. Instead, it uses whatever color is present in the image. This sound perfectly reasonable: if we’ve gone through the trouble to produce a black & white image, then ask the system to draw it, we’d expect it to be drawn just as we made it.
What you might not expect: those same rules apply to text. Text is rendered
with a font, which is just - you guessed it - a series of images. Most fonts
define their glyphs as black-on-transparent images, which works great for
rendering to a white screen. But it makes one big problem:
black-on-transparent images are totally transparent in
Fortunately, there’s a way to solve this without making custom white-on-transparent debug fonts. And that’s to change the fill mode.
changes how all images are drawn to the current graphics context. Choosing
kDrawModeFillWhite here says to treat any non-transparent pixels as white.
Now, any text or images you render in
debugDraw will show up in your
Bring It All Together
Let’s see it in action. Here, we’ll
- Draw some normal in-game text in
- Draw some geometry & text in
- Change the debug color used when you press
function playdate.update() -- Show normal text drawing working gfx.drawText("update", 10, 60) end function playdate.debugDraw() gfx.pushContext() -- All drawing, including text, should be drawn in the debug color gfx.setImageDrawMode(gfx.kDrawModeFillWhite) -- Show geometric drawing working gfx.drawLine(10, 20, 10, 30) gfx.drawPixel(20, 20) gfx.fillRect(30, 20, 30, 30) -- Show text drawing working gfx.drawText("debug", 10, 90) gfx.popContext() end function playdate.keyPressed(key) -- Toggle the color palette when "B" tapped if key == "r" then playdate.setDebugDrawColor(1.0, 0.0, 0.0, 1.0) elseif key == "g" then playdate.setDebugDrawColor(0.0, 1.0, 0.0, 1.0) elseif key == "b" then playdate.setDebugDrawColor(0.0, 0.0, 1.0, 1.0) end end
Final Simulator Caveats
These debug methods are super powerful, but their power is limited. Specifically:
- You can only register key presses for printed characters. You won’t get called when someone taps “Shift”.
- You can only register key presses for characters the Simulator doesn’t already use.
- You only get one debug color to draw with. No debug rainbows here.
Given that though, these are still fantastic, fun tools to use to help build your Playdate game.