14

This is something I often notice whenever I see a first-generation Pokémon game being played on a Game Boy emulator. It might be present on real hardware as well, but I don’t have that to test.

When the player moves around so that the map has to scroll, and there are also NPC sprites present on the map, the other sprites tend to lag a few pixels behind the scrolling motion; it takes a couple more frames for the sprites to move into their correct position. Here’s a demonstration in Pokémon Yellow, recorded in mGBA:

The player character walks horizontally, then vertically on the ground floor of his house in Pallet Town. An NPC sprite is noticeably lagging behind.

And here’s Pokémon Crystal for comparison (targetting the Game Boy Color), where there is no such effect:

The player character walks horizontally, then vertically on the ground floor of his house in New Bark Town. There are two NPC sprites, but no lagging.

I have a number of hypotheses why this might happen:

  • This is an inaccuracy in the emulator. Given that I remember seeing this in probably every emulator in which I tried, I regard this explanation as rather improbable.
  • This is a limitation of Game Boy’s hardware sprite support, which emulators dutifully replicate, and it was fixed in Game Boy Color.
  • This is a bug in the scrolling subroutine, fixed in Generation II games, and in principle it should be possible to backport the fix; the issue just wasn’t considered significant at the time.
  • This is a deliberately inserted artefact meant to compensate for LCD ghosting or a similar effect, which was rendered unnecessary in Generation II thanks to Game Boy Color’s improved display.

Which one of these is the closest to truth?

2 Answers 2

17

Lacking meaningful research avenues, I started surveying YouTube videos, and I think I managed to mine some insights even from that scant evidence. Here is what I found out:

  • The issue is apparently just barely visible, if at all, on the original Game Boy; it probably cannot be noticed on a real handheld unless one is specifically looking for it, as LCD motion smearing masks the issue to the point of imperceptibility. Take this video: it’s hardly perfect for this investigation, as the handheld isn’t exactly still in the frame. Nevertheless, around 3:05 you may take a close look at the guard standing next to the house, or around 6:10 at the NPC sprite on the right. When I watch those moments frame by frame, I do notice some familiar-looking, if only slight, wobbling of the sprite against the map. But I am not even entirely sure if I am actually seeing it, or just imagining it because I know it should be there.

    Either way though, the NPC sprites don’t seem to be any more sharp when in motion either (compared to the map), so this seems to count against the ‘deliberate kludge’ explanation. Then though, the aforementioned shaking, and the fact that the video was recorded at 30 frames per second might have, well, distorted the picture somewhat.

  • The scroll drag is just as pronounced on a Super Game Boy (a Game Boy cartridge adapter for the SNES) and on the Game Boy Player (an analogous adapter for the GameCube) as it is on emulators. Both are official Nintendo products containing original Game Boy hardware, and as such may be considered alternative, equally legitimate implementations of the Game Boy ‘platform’.

    This weakly counts against the emulators being at fault; or at least it means that whatever pitfalls the emulators fell into, Nintendo themselves couldn’t help but do the same.

    The first Pokémon games were released two years after the Super Game Boy became available, and do contain some SGB-specific features (like a customised border, and SGB colour support); clearly, the game must have been tested on this hardware. It is therefore somewhat surprising that this issue slipped through.

  • Not so many people are aware that the original second-generation games (Pokémon Gold and Silver) are actually playable on the monochrome Game Boy, even though they weren’t particularly optimised for it. Having recalled this, I decided to emulate Pokémon Gold in Game Boy mode to see how it behaves. When I did, the lagging effect was absent, unlike with first-generation games, but very much like running in Game Boy Color mode:

    Pokémon Gold, played on an emulated Game Boy in grayscale. The player character walks horizontally, then vertically on the ground floor of his house in New Bark Town. There is an NPC sprite, but no lagging.

    This seems to rule out the ‘hardware limitation’ explanation (one that I much doubted anyway), and to count in favour of the ‘problem with the game’ hypothesis.

Eventually, I decided to study a disassembly of the game. I found that the game maintains a shadow copy of the hardware sprite registers; during a vertical blanking interrupt, it first updates that shadow copy, and then triggers a DMA memory transfer to the real registers. Except… it’s the other way around: it first transfers the old values, and then updates them, which will only be picked up during the next blanking interrupt.

This means that this patch:

--- i/home/vblank.asm
+++ w/home/vblank.asm
@@ -31,11 +31,11 @@ VBlank::
        call VBlankCopy
        call VBlankCopyDouble
        call UpdateMovingBgTiles
-       call hDMARoutine
        ld a, BANK(PrepareOAMData)
        ldh [hLoadedROMBank], a
        ld [MBC1RomBank], a
        call PrepareOAMData
+       call hDMARoutine
 
        ; VBlank-sensitive operations end.
        call TrackPlayTime ; keep track of time played

corresponding to this binary difference:

 00001de0  c9 cf c3 33 22 f5 c5 d5  e5 f0 4f f5 af e0 4f f0  |...3".....O...O.|
 00001df0  b8 ea 21 d1 f0 ae e0 43  f0 af e0 42 fa 9f d0 a7  |..!....C...B....|
 00001e00  20 04 f0 b0 e0 4a cd 30  1b cd b5 1b cd da 1a cd  | ....J.0........|
-00001e10  21 1c cd d1 1b cd 75 1c  cd 80 ff 3e 01 e0 b8 ea  |!.....u....>....|
-00001e20  00 20 cd 9b 49 cd f5 1e  cd 6d 3e cd c8 01 f0 d6  |. ..I....m>.....|
+00001e10  21 1c cd d1 1b cd 75 1c  3e 01 e0 b8 ea 00 20 cd  |!.....u.>..... .|
+00001e20  9b 49 cd 80 ff cd f5 1e  cd 6d 3e cd c8 01 f0 d6  |.I.......m>.....|
 00001e30  a7 28 03 af e0 d6 f0 d5  a7 28 03 3d e0 d5 cd c2  |.(.......(.=....|
 00001e40  27 3e 08 cd 7e 3e cd 1e  53 3e 02 cd 7e 3e cd 9d  |'>..~>..S>..~>..|
 00001e50  50 cd b7 2f fa 21 d1 e0  b8 ea 00 20 f1 e0 4f e1  |P../.!..... ..O.|

suffices to fix the problem:

Pokémon Yellow, with sprites not lagging

At least in an emulator; I am not sure what effects it has on real hardware. Hypothetically, it might for example cause problems if hDMARoutine does not finish executing before the blanking period ends if PrepareOAMData is called before; moving hDMARoutine earlier and introducing the update lag might have been a kludge inserted to compensate for this. Without real hardware to test, I cannot really be sure.

But so far everything points towards this being an unintentional defect in the game itself, one that has either slipped through unnoticed entirely, or was neglected before Generation II. My guess is that it was probably fixed more for the sake of the Super Game Boy than the handhelds themselves.

10

Well, there's a fifth one: A sequence issue not really considered relevant when first published.

The underlaying issue is that sprites are not moved during scrolling the background, prior to (re)drawing the screen. While this is rather obvious with large sharp screens, it will be perceived less of an issue on original Game Boy hardware due the small screen and it's less than great display quality with moving images.


Sprites are positioned in screen coordinates, not relative to a background. Thus, sprites that should move with the background, like the people sat at the table, need to be repositioned in a second, separate step. Here the developers may have skipped it at all, only updated internal coordinates, so the next 'normal' drawing cycle will reposition them anyway.

The player sprite in contrast does not move at all. He stays always at screen center. That non-moving (in terms of screen coordinates) makes it seem to 'move' flawless (in terms of perceived movement).

In total this looks quite like a sequence issue.

When the player moves, then the program sequence looks like:

  1. Reposition (scroll) background against direction of movement
  2. Draw picture
  3. Reposition 'non-moving' sprites

When the movement ends another redraw is done. That's a 'solution' often found in games to clean up any artefacts that may be left over from complex animations like effects and movement. With high frame rates (like on TV), the effects are next to invisible.

As an LCD based game, screen redraw is only needed with changing content, so way less often, making the effect visible on a good display - which the Game Boy didn't feature :))

By flipping step 2 and 3 the 'lag' will vanish and that seems to be what happened with later versions.

Bottom line: One might call it in hindsight a sequence error, but at the time it was within expectations (state of the art), as it doesn't get as annoying with the Game Boy hardware.

2
  • 4
    With the slow update of the LCD, I wouldn't be surprised if the lagging actually improved the appearance slightly by enhancing the visual separation between the foreground and background objects.
    – supercat
    Commented Feb 28, 2021 at 5:01
  • @supercat yes. I skipped that argument, as I wanted to avoid useless side threads that usually end in heated opinions. So, yes, as you mention,many effects don't translate well between different media - much like CGA colours look crappy on a dedicated screen but (comparable) great on a TV. Here it's about the low contrast (resolution) and sluggish of the original game boy vs crisp clear and quite sharp displays of modern emulation.
    – Raffzahn
    Commented Feb 28, 2021 at 16:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .