Blue MoonGraphics

One frame of black

Just before the Blackbeard battle the screen flashed black for a sixtieth of a second. Catching it took every frame, two programs, and the right memory card.

Log 054 min read

You know the moment. A battle is about to start, and the screen cracks and falls away in pieces before the fight fades in. On the PC port, the night after the Blackbeard battle started working, Endymion was on his way to Valua and saw something just before that shatter. It was too quick to screenshot: the screen went black with a bit of white, and then the pieces fell as usual.

At 60 frames a second, “too quick to screenshot” means one or two frames. So the first thing I did was stop trying to see it and start counting.

Every frame, twice

The port can replay a recorded controller session exactly and save chosen frames as images. I already had a recording that sails into the Blackbeard battle from Endymion’s save, so I captured every frame from 6,555 to 6,600 in the port. Then I played the same recording in Dolphin, the GameCube emulator, and captured the same stretch there.

The port had it at frame 6,571: black over the top half, a white block over most of the bottom. The very next frame showed the first cracks. Dolphin never drew that frame. Every frame it drew there shows the cabin, with Drachma, Vyse and Aika, until the cracks appear.

Port, frame 6,571Port, frame 6,571
Dolphin, the same momentDolphin, the same moment
The frame Endymion saw. Left: the port, the frame before the shatter starts. Right: Dolphin from the same save and the same button presses. The port starts the shatter one frame earlier than Dolphin, so Dolphin’s matching frame is numbered 6,572.

The wrong scene, then the wrong card

The game has a whole module for screen transitions: wipes, a wave, a fade. I guessed the flash came from there and set breakpoints in a debugger on every function in it. None of them ran. The shatter is drawn somewhere else.

So I counted graphics calls instead, frame by frame, to find what was different about 6,571. The counts were identical on every frame, which made no sense, until I saved the frames the debugger run was drawing. They showed the save menu. While I was busy, Endymion had been playing, and he had saved in Valua. My replay copies his memory card at the start, and his new saves had pushed the old one down the list, so the recording’s button presses now chose a different file. With a copy of the card the recording was made from, the debugger run reached the cabin again.

What the game does on that frame

This time frame 6,571 had one call the others didn’t. To break the screen into pieces, the shatter needs a picture of the screen. When the game notices that a battle has started, it copies the finished frame into a texture for the shatter, and it clears the screen as it copies. Nothing draws over the screen after that, apart from a fade layer that is almost completely transparent.

The port shows the screen as it stands when each frame ends, so it showed the cleared screen. The white block is probably left by a step the port uses for copies smaller than their texture, which runs after the clear. I didn’t trace that part further. Dolphin shows the cabin.

I don’t know for sure why Dolphin skips the cleared screen. As far as I can read the game’s code, the console clears it too. So for this one frame I followed Dolphin, because it’s what this project checks every frame against. The battle start now takes its copy without the clear. The shatter draws its own black background from the next frame on, so nothing needed the clear. I tried a smaller change first: clearing only the depth and leaving the colours alone. It still flashed. Only a copy with no clear at all fixed it.

Port, frame 6,571, fixedPort, frame 6,571, fixed
DolphinDolphin
The same frame after the fix, beside Dolphin’s.

Random battles in the field start through the same code, so they probably flashed too.

Still not quite right

With the two programs side by side, one more difference showed up. Dolphin breaks the picture into triangles. The port breaks it into squares, with faint grid lines before anything falls. That one is next.

PortPort
DolphinDolphin
A moment into the shatter, a frame apart. The port’s pieces are squares; Dolphin’s are triangles.