Birdoggydog's Builds

Fixing sign letters that drew as solid boxes in Godot

Every sign had lost its lettering after the font change. A font freed too early and a decal handed a viewport texture were the two causes.

Every sign in the game had lost its letters. They drew as solid boxes, so the lift plate at the Breakout Site was a white bar with nothing written on it. I noticed it myself and drew a note in the game: “None of the fonts on the signs are rendering”. The letters are back now, on plates, stencils, scrawls and floor paint.

33 seconds: the Culture Bay 7 plate, a vat’s stenciled number, a scrawled keypad code, 6 m painted on the range floor, and the lift plate from the corridor and up close.

Why did the letters turn into boxes?

The game’s log also had the same error 12 times: “Cannot get path of node as it is not in a scene tree”. Each theme had got its own sign font the day before, and the bug had two causes that had nothing to do with each other.

The first was the font itself. A sign’s face is drawn inside a SubViewport, and the code that draws the words loaded the theme’s font and then dropped it. Nothing else in the game used the sign fonts, so Godot freed the font, and its glyph textures, before the viewport got around to drawing. A glyph with no texture is an empty quad, which is a box. The fix is a static dictionary that keeps every sign font for the whole run:

static var _fonts := {}

static func held_font(theme: String) -> Font:
	if _fonts.get(theme) == null:
		_fonts[theme] = SignKit.font(theme)
	return _fonts[theme]

Each face reuses the same fonts now, so it also stops loading them again.

Why did painted signs print errors?

Stencils, floor paint and scrawls are Decals, and a Decal was being given the face’s ViewportTexture before that viewport was in the scene tree. That was the 12 errors. A Decal can’t use a viewport texture anyway. Now it only takes the finished picture. If the face is already cached it gets it straight away, and otherwise the sign picks it up on its next tick once the picture is baked.

How do I know it’s fixed?

The headless tests can’t draw a face, so the sign test builds the same situation by hand. It gives a painted sign a viewport texture and checks the decal refuses it, then gives it a baked picture and checks the decal shows it. It also asks for each theme’s font and checks it’s still alive afterward. The test has 46 checks and passes, and 8 of them fail with either fix turned off.

For the lettering itself, the film crops the lift plate’s word area and counts how much of it is ink. Solid boxes come to about 88%. The fixed plate is 26%, and I accept anything from 3 to 45%.

A grid of eight film frames. A white plate reading CULTURE BAY 7, a vat rim with a stenciled 07, red scrawled words on green paint, a yellow bar and 6 m on a floor, and a small lift plate with a lift symbol, shown far away and then close up.

Contact sheet of the film, each frame captioned with the sign shown.