Spectacle: Simple class for monitoring your game

Here's a class that makes it easy to monitor values in your game. Borrowing some ideas from our Discord dev chat.

Latest: spectacle.lua.zip (3.7 KB)

Basic usage:

-- in main.lua (or wherever) consider creating a global instance of Spectacle.
spec = Spectacle({font = "fonts/font-rains-1x", line_height = 1.4, lines = 3, background=playdate.graphics.kColorWhite})

-- so elsewhere you can simply use:
spec:watchFPS()
spec:watchMemory()
spec:watch(game_state, "player.x")
spec:watch(self, "camera.x", "cam")
spec:watch(function()
   if self.player.is_jumping then
      return "JUMPING"
   else
      return "GROUNDED"
   end
end, "state")

-- or use the built-in graphing:
spec:graphFPS({min=1, max=50})
spec:graph(function()
  return math.random(1, 100)
end, {type="line", min=1, max=100, period=0.1, name="Random"})

-- and instead of print():
spec:print("hello", "world", val1, val2)

-- and finally, make sure you draw.
spec:draw(x, y)

-- you may also want to toggle it on/off.
playdate.getSystemMenu():addCheckmarkMenuItem("debug", spec.visible, function(value)
   spec.visible = value
end)

Note: Be sure to check watch() and graph() functions for documentation on their supported options.

Example output:

playmaker-spectacle-demo

5 Likes

Just replace my old debug system with this and love it! would only recommend to add an option to change the position where it's drawn, already changed it on my game :slight_smile:
playdate-20210710-182057

	self.x = options.x or 5
	self.y = options.y or 5
1 Like

I had draw(x, y) and removed it. Can’t remember why. I think I had this idea of making it more console like where it overlays from the top. Never did it. Hmm, I’ll add it back. :slight_smile:

Glad to hear it’s working for you!

Btw I think it was your comment in chat that got me thinking about a global debug table. Handy!

1 Like

Ah yeah makes better sense to have it in the draw function nice!

Maybe! I’m working on incorporating my graph method from another little library I shared a year or so back, but allowing you to graph any value in your game over time as part of the same UI: spec:graph(self, “sprite_count”). May make sense to set rect on init so graph has a width to draw to. Maybe?

1 Like

This could turn into an immediate mode GUI for Playdate :laughing:

Display bug (italics enabled mid way through) if you use variable names with underscore.

Quick fix

if name then
	txt = tostring(name):gsub("_", "__")..": "
end
1 Like

I’ll get that in. Yikes! :smile:

Updated with a new graphing function and spec:graphFPS(...) and a few other fixes. Thanks!

Hmm, going to start to need some documentation and I'm not sure that's a good sign.

1 Like

dropped the latest version in and my existing watches were not showing up.

line 43

self.watched[#self.watched + 1] = {type=Spectacle.kWatchTypeField, table=t, field=field, name=name}

references a non-existent constant Spectacle.kWatchTypeField

should be Spectacle.kWatchTypeTableField, as declared earlier.

fixed

self.watched[#self.watched + 1] = {type=Spectacle.kWatchTypeTableField, table=t, field=field, name=name}

graphing is super-neat!

1 Like

Thanks! Will fix today. Yikes!

Alright fixed that up and added a bit of documentation to init, watch, and graph functions. Thanks again.

1 Like