Techniques for better multi-directional scrolling

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
Drakim
Posts: 97
Joined: Mon Apr 04, 2016 3:19 am

Techniques for better multi-directional scrolling

Post by Drakim »

I've been busy creating my own multi-directional scrolling code. It's hard work, but I've finally gotten it to work! I'm using single-screen mirroring (I want to use the other nametables for cool effects), and naturally there are a few challenges.

Although there are great articles like this that gives all the technical information you might need on scrolling, I'm on the hunt for all kinds "tricks" that exists that can be used to make the multi-directional scrolling better. I've found some here and there while googling around, but I'm hoping there is a whole lot more that I don't know about. The main issue to tackle is obviously scrolling artifacts, but I'm also on the hunt for things that decrease time spent in VBlank since multi-directional scrolling eats up a lot of it.

I figure I might start by listing out every trick I know:
  • 1. The most obvious thing to do is use more nametables and not have any scrolling artifacts whatsoever, but I always felt this was a bit of a waste, like using a laser cannon to kill an ant. So many cool effects can be done if you have some unused nametables. But it's an option.

    2. A well-known trick is to use the $2001 register to hide sprites and background in the leftmost 8 pixels of the screen, to partially hide scrolling artifacts on the horizontal scroll. This is enough to completely eliminate horizontal nametable artifacts, but not attribute artifacts.

    3. You can simulate hiding the 8 rightmost pixels of the screen by having a column made out of sprites. Probably not worth it due to the sprite limit. Maybe in a low-sprite situation like a world map or cutscene? This would hide horizontal attribute artifacts entirely.

    4. By using an IRQ (or some other means) you can turn off rendering for the bottom 8 pixels on the screen. Not only does this hide vertical nametable artifacts (and partially hide vertical attribute artifacts) but you can even start your VBlank updates early as long as you are careful about the "rainbow stripe" effect of messing with your palettes in that space.

    5. Instead of wastefully updating tiles on the edge of the screen every frame, you can store which row/column you updated last frame and not update again until the scroll has moved over to a new row/column.

    6. Instead of updating tiles on the exact 8px offset, you can offset your calculations to update tiles when they are scrolled halfway though. This makes scrolling artifacts less visible by dividing it equally between both sides of the screen.

    7. Instead of updating both the nametable and attribute table in one go, you can update them separately. You can then do nametable updates perfectly in the 8px "hidden" zone, while attribute updates can be done separately at a different scrolling offset to minimize visual color glitches. As a bonus you spread the VBlank work out over more frames which is a boon.

    8. A more practical rather than technical trick is to avoid mixing attributes too much in your level design. If your clouds use the same attributes as your sky background, then you'll avoid constant attribute glitches in the sky as the player is moving, as the game has no need to switch back and forth between the two attributes as the clouds swosh past.

    9. Few games are diehard about keeping the player in the dead center of the screen. By allowing a little "bias" you can avoid nasty situations where standing on a particular platform shows you constant attribute glitches on the vertical axis, because the game's engine simply scrolls a few pixels extra up or down before stopping, to align itself better.
I think that's all the ones I know. Are there any more, or maybe some ways to enhance these tricks I've mentioned to make them better?


Edit: Oh wait I totally forgot the obvious Statusbar coverup. It's essentially the same as point 4 on my list, but with a thicker statusbar you can cover up even the attribute glitches perfectly.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Techniques for better multi-directional scrolling

Post by Dwedit »

Then there's an out-of-left-field option: Use a mapper which allows Checkerboard mirroring. Then scrolling glitches become mostly confined to corners.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Techniques for better multi-directional scrolling

Post by tokumaru »

Drakim wrote:3. You can simulate hiding the 8 rightmost pixels of the screen by having a column made out of sprites. Probably not worth it due to the sprite limit. Maybe in a low-sprite situation like a world map or cutscene? This would hide horizontal attribute artifacts entirely.
Felix the Cat uses this "trick", and it's pretty sprite-heavy considering it has a large protagonist, overlaid weapons/attacks, vehicles, and so on. I guess that if you use a good sprite flickering technique, losing 1 sprite per scanline isn't so bad.

If you don't plan to do anything to hide scrolling attributes though, you can at least have the camera "snap" to attribute boundaries so that things don't look glitchy when the player is not moving.
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Techniques for better multi-directional scrolling

Post by Bregalad »

I think you pretty much summed it all. I particularly like the split of glitches between two oposite edges, so that each glitch is half as visible.

A very advanced trick, if your background and sprite palettes hapens to be identical, and that 8x16 spries are used, is to overlay the last background tile column with sprites representing the same objects. This will make colour artifacts normally invisible, but if you need 8 sprites per line (or more than 48 sprites per screen) for real gameplay, you can have them and the colour artifacts becomes visible instead of one sprite disapearing.
Last edited by Bregalad on Sun Oct 28, 2018 1:22 am, edited 2 times in total.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Techniques for better multi-directional scrolling

Post by tokumaru »

Making the sprite and background colors identical is a pretty big limitation, and together with the sprite coverage loss, the price is just too high. I'd much rather just pay the sprite price, and simply blank the right side.
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Techniques for better multi-directional scrolling

Post by Bregalad »

tokumaru wrote:Making the sprite and background colors identical is a pretty big limitation, and together with the sprite coverage loss, the price is just too high. I'd much rather just pay the sprite price, and simply blank the right side.
There's no sprite coverage loss - that's the whole point of this technique - the sprites are here only if there is room and they'd disappear first, making attribute clash visible only when there's too much sprites - rather than always. It makes sense only in cases where BG and sprites palettes were to be identical anyway, it does not make sense to make the palettes identical just for that.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Techniques for better multi-directional scrolling

Post by tokumaru »

Oh, I see. I think few people would be crazy enough to make sprite and background palettes equal though, unless they were doing something very simplistic.
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Techniques for better multi-directional scrolling

Post by Bregalad »

tokumaru wrote:Oh, I see. I think few people would be crazy enough to make sprite and background palettes equal though, unless they were doing something very simplistic.
I don't think it's that simple. Depending on what you want to do this makes things logical, for Fire Emblem for instance the sprites and BG palettes are the same. Also, it doesn't have to be ALL palettes being the same, using the trick to overlay only the tiles with palettes who are possible to overlay with sprites is also forceeable, although it's more complex to code and less efficient.
User avatar
bleubleu
Posts: 108
Joined: Wed Apr 04, 2018 7:29 pm
Location: Montreal, Canada

Re: Techniques for better multi-directional scrolling

Post by bleubleu »

That's a nice list, but which technique did you end up going with? I'm curious.

In the game I'm working on i used vertical mirroring and managed to limit all artefacts in the top/bottom 8px of the screen, where i hope they will be (mostly) hidden by overscan.

My algorithm is mostly stateless, it only keep tracks of the XY index of the current tile (a tile being 8x8), at the top left of the screen. Whenever the scroll position (which is also relative to the top-left) divided 8 doesnt match that cached XY (in X or Y), it means that its time to update "something". Sometimes only tiles are updated, something attributes, sometimes both. That also means I cant scroll faster than 8px per frame, which is perfectly fine for my game.

But you are right in saying its hard work. The number of edge you need to handle is quite surprising, especially in the Y axis where being on a odd/even nametable will offset things. And that last half-row of attributes is also annoying.

Good luck and looking forward to seeing what you do.

-Mat
User avatar
pubby
Posts: 583
Joined: Thu Mar 31, 2016 11:15 am

Re: Techniques for better multi-directional scrolling

Post by pubby »

The most obvious thing to do is use more nametables
I didn't realize this at first, but 4 nametable scrolling is actually the hardest to implement and has the clumsiest math. It's easier with 1 nametable mirrored in both directions.

Just something to keep in mind for anyone new to scrolling.
Drakim
Posts: 97
Joined: Mon Apr 04, 2016 3:19 am

Re: Techniques for better multi-directional scrolling

Post by Drakim »

bleubleu wrote:That's a nice list, but which technique did you end up going with? I'm curious.
One nametable mirrored in both directions, left column hidden with PPUMASK ($2001), bottom row hidden with IRQ interrupt, limit nametable updates to once per column/row updated exactly underneath the hidden column/row, attribute bytes updated with a different timing to split the miscoloring between both sides of the screen.

Plus some macros to unroll the loops as they do the work, as there is a lot of repetition.
Post Reply