Week 13: A laundry list of framework fixes, and a couple cool milestones for Inner-Tube Climber!

A screnshot of a button with the new "go" icon for Squirrel Away; the icon is a pixel-art outline of a jumping squirrel.
A new "go"-button icon for Squirrel Away.

tl;dr: A laundry list of framework fixes, and a couple cool milestones for Inner-Tube Climber!

What happened last week?

Again, this was a somewhat boring and technical week without any exciting visuals. Sorry!

I fixed quite a lot of miscellaneous small issues last week. My "Surfacer" and "Godot Scaffold" frameworks are in a much better state!

The laundry list

  • Fixed scaling for tree widget arrows.
  • Fixed scaling for UtilityPanel.
  • Added color and theme configuration to Scaffold.
  • Fixed scaling for styling/theme.
  • Fixed scaling and theming for ShinyButton.
  • Fixed various remaining styling/theme details.
  • Added a pause icon for the utility panel.
  • Split apart framework repos.
  • Finally got around to getting a decent quick http server setup working so I can test my HTML exports without first pushing them to GitHub.
    • Just using NPM’s `http-server` within an Ubuntu shell in Windows.
  • Fixed an issue with garbled audio in the HTML export.
    • It was caused by the presence of the pitch-shift audio bus effect (which wasn’t even doing anything).
  • Made another release of Inner-Tube Climber:
    • Updated difficulty description text to be “Hard”, “Harder”, “Hardest”.
    • Made some improvements to time tracking:
      • Reset time when dying on the first tier, in the same way that lives are reset.
      • Only start time when the user presses some input.
      • Had received feedback that this would make it more fun to try speed-running the game.
  • Cleaned up early print statements when initializing various parts of the framework.
  • Fixed assorted level state management when creating, destroying, and restarting levels.
  • Tried to have SquirrelAwayConfig extend SurfacerConfig extend ScaffoldConfig, and then just have a single AutoLoad, but that seems to break _something_ in Godot.
    • When trying, I see a type-checking error (“unable to determine type from Gs.utils.foo”) but I’m not sure if that’s just a red-herring blocking a real error from being reported.
  • Learned about how submodules get detached in their default configuration and how to fix that.
  • Refactored Profiler to use String IDs instead of enums.
  • Standardized some enum-to-string patterns.
  • Added logic to pause when losing window focus.
  • Fixed UtilityPanel empty-space click-handling and platform-graph annotation cleanup.
  • Fixed annotator enablement when restarting levels.
  • It looks like Godot’s physics engine regressed since I originally implemented Surfacer, and it will no longer allow me to access some important collision-checking APIs from threads.
  • Added support for configuring the "go" icon for the specific game.
  • Limited message count in the debug panel.
  • Added an app-running-time display in the debug panel.
  • Moved squirrel-away level state out of surfacer.
  • Integrated inspector-panel and settings-screen checkboxes.
  • Added support for configuring and overriding settings-screen items for Surfacer.
  • Added support for disabling the inspector panel within the settings screen.
  • Showed the pause button when inspector is disabled
  • Added the ability to configure whether the settings screen can be accessed without resetting the level.
  • Added the ability to toggle whether the player sprites are rendered.
  • Added a surfaces annotator (that’s independent of the inspector).
  • Fixed inconsistent music volumes.
  • Fixed a bug with non-zero TileMap positions.

Fixing Godot's default widget icons

Godot using raster images instead of vector images for their widget icons, and they don't provide multiple resolutions. This means that, out-of-the-box, if you use a checkbox in your game, and try to enlarge it to be visible on a large screen, it will be super pixelated!

The only way to fix this is to replace Godot's built-in checkbox image with a custom image of your own.

But then, if you provide a custom high-res image, you also need to deal with down-scaling the image if the screen isn't actually as big as you were expecting.

I've added support to my Godot Scaffold framework for automatically replacing and scaling checkbox images according to the current screen size (relative to your app's default expected screen size). I also currently support resizing the Tree widget's progressive-disclosure arrows.

A screenshot showing Godot's default checkbox. It looks very pixelated.
:( Godot's default low-resolution checkbox. Doesn't scale well!

A screenshot showing my custom checkbox. It looks pretty crisp and not very pixelated.
:) My custom dynamic-resolution checkbox. Scales great!

Woohoo! Inner-Tube Climber has some users!

Last week, Inner-Tube Climber's stats hit some nice numbers. The Play Store app now has over 1,000 downloads, and the YouTube trailer now has over 10,000 views! Also the Play Store app finally got its fifth rating, so it now has a publicly visible average rating (an app's average rating is hidden until you get at least five).

The App Store app has many fewer downloads, but I think that's probably mostly because it looks like my Google Ads campaign for the iOS app has something misconfigured...

Also, Inner-Tube Climber just got a handful of new reviews this morning! It no longer has a perfect 5-star rating, but that's probably a good sign. I think your app isn't really legit until you get a 1-star troll rating that says only "This is the baddest game ever".

What's next?

  • Add a couple smallish long-pending updates to the Surfacer framework.
  • Expand on my old "Squirrel Away" game to make it into something slightly more interesting to play.

🎉 Cheers!

This is a simple icon representing my sabbatical.