Week 11: GDC Showcase, and a new Godot-scaffolding framework

An animated GIF of a recording showing my old Surfacer app now integrated with some infrastructure from Inner-Tube Climber.
"Ooooh, aaahhh..." My old Squirrel Away/Surfacer app now has my Inner-Tube Climber menu screen!
I know, it's truly amazing.
...Don't worry about the 10-second load time. I'll fix that later.

tl;dr: Watched GDC Showcase talks, created a reusable Godot-scaffolding framework, fixed Godot's viewport scaling.

What happened last week?

GDC Showcase

"GDC Showcase" was a special free-to-attend, all-online, one-of-a-kind event that was meant to substitute for the skipped in-person conferences during quarantine. It offered a single track of talks—one talk at any given time—and a live chat window with the speaker and all the attendees.

It was ok.

In general, I often find that I'm not too interested in a lot of the stuff going on in a conference, and this was definitely no exception.

About a third of the talks were just prerecorded ads plugging new tech and services from whichever big company was sponsoring that day.

And another big chunk of the talks were just reruns of recorded talks from previous years, but with the original speaker in the live chat.

And a lot of the talks focused on flashy new stuff from the latest and greatest AAA games, which just isn't really relevant or interesting to me for the most part.

Maybe one talk a day was really interesting for me.

I especially found some of the talks from indie folks to be valuable and engaging to me.

But, mostly, I think everything was actually probably more valuable than I immediately appreciate, just because it gave me more familiarity with the broader context of all the various stuff going on with game dev.

I suspect that the normal annual conference would probably be much more valuable to attend, since it would give me the opportunity to actually talk to people, and it would probably offer multiple choices of talks at any given hour.

A stand-alone framework with app scaffolding

Between talks, I had a little time last week to pull-out reusable infrastructure from Inner-Tube Climber, put it into a stand-alone framework, and integrate this framework into my old Squirrel Away/Surfacer app.

NOTE: "Squirrel Away" is what I call the little demo game where you click on the screen, and the cat moves to that position. "Surfacer" is what I call the underlying framework for intelligent pathfinding, which Squirrel Away is using.

A screenshot of my Godot project showing the new separation and configuration of the Surfacer and Scaffold frameworks.
The Surfacer and Scaffold frameworks are now decoupled and configured separately from the client app.

Viewport scaling in Godot

I did make an interesting change relating to how the overall application viewport scales.

Making your app look good on lots of different screen shapes and sizes is extremely difficult to get right. This is a universal problem—not just specific to Godot.

But the problem is harder with games than with things like web development, because, in addition to resizing GUIs, the developer also needs to worry about how to handle camera transformations (basically, how much to zoom-in).

Godot tries to offer some high-level project-configuration options to deal with this problem, but nobody really understands how to use them, and even if you do, they still aren't a magic bullet.

I really liked this quote from another Godot user:

Scaling is a nightmare, scary stuff

Here are some related posts from other folks trying to figure out how to handle scaling in their games:

The option I used in Inner-Tube Climber (stretch-mode "viewport", stretch-aspect "expand") makes it easy to give limits on the horizontal and vertical dimensions of the level, but it makes fonts look really fuzzy and bad in all the GUIs.

I've decided that the only option that really handles all of my cases correctly, is to use Godot's "disabled" stretch-mode option and handle GUI and camera scaling manually.

Handling camera zoom

I want to allow some limited flexibility in how far the camera is zoomed. That is, I want you to be able to see more of the level on a larger screen, but not too much more of the level. Similarly, on a wider screen, I want you to be able to able to see more from side to side, but not too much more.

  • I configure a minimum and maximum aspect ratio for the game region.
  • I also configure a default screen size and aspect ratio that the levels are designed around.
  • Then, at runtime, if the current viewport aspect ratio is greater than the max or less than the min, I'll show black bars along the sides or top and bottom of the game area.
  • And I set the camera zoom so that the same amount of level is showing, either vertically or horizontally, as would be visible with the configured default screen size. If the screen aspect ratio is different than the default, then a little more of the level is visible in the other direction.
  • I also show a lot of annotations in a separate layer overtop the level, and I need to manually transform their positions to match whatever the game-area's current zoom and position is. I need to do the same calculations for click positions.

Handling GUI scale

I also need to adapt my GUIs to fit different screen sizes.

  • I calculate a `gui_scale` value according to how the current screen resolution compares to the expected default screen resolution, as described above.
  • Then I resize all of the fonts—which have been registered with my new scaffold configuration process—according to this `gui_scale`.
  • Then I recursively iterate through all GUI nodes, and update the scale and position of any node that is image-based (the text-based nodes should be handled by the font resize).

What's next?

  • I still need to spend a bit more time on the new stand-alone Scaffold and Surfacer frameworks.
  • Then I need to fix a couple issues with the Surfacer framework. Should be easy and quick to do...
    • Make it load faster, by pre-computing the platform graph and saving it in a separate file.
    • Make it run faster, by bypassing Godot's collision system at runtime, and just force player movement to match what is expected from the platform graph.
  • Then I can start creating a new small game with the Surfacer framework! I have the starts of some ideas, but you'll have to wait and see.

🎉 Cheers!

This is a simple icon representing my sabbatical.