Matt Hughson Profile picture
Game Programmer @CoalitionGears | #GameDev on @Gearsofwar | #IndieDev on the Side (#Retrobrew, #WitchNWiz, #FromBelow) | #PICO8 #NESDEV #ファミコン #NES #gbdev

Nov 28, 2022, 37 tweets

Got the day off work, and kids are in school! Time to go ham on this project, and turn *this* (side scroller) into *this* (top down rpg-like world map). #nesdev

Bringin' in the lil' guy!

Believe it or not, this is actually *progress*! Graphics data for the top down character is being properly swapped in (replacing the side scroller graphics).

Just the animation data hasn't bee updated!👍

Told you! 😅

Let's get 'em in a more appropriate test level!

He's ready to go on an adventure!!

Question:

Should movement be *grid-based* like in Zelda 2 or unrestricted like the previous video?

Gameplay in the top down potions will be similar to a JRPG (travelling, exploration, no combat).

Think I'm just going to keep unrestricted for now (since that's easier). 🧠

Now I'm back from lunch and I have a little over an hour before I need to pick up the kids from school.

Do I attempt 4 way scrolling?

or

Get transitions to and from side-scroller levels working?

And actually, I don't even support maps that are taller than 1 screen, so I'll have to do that first as well :D

I threw is a map 2 screens tall and it doesn't completely break everything! Horizontal scrolling still works, but I haven't implemented any vert. scrolling yet, so I'll need to do that still. But the fact that all the collision lookups and background rendering works is pretty OK!

THE MAP

Camera now follows the player downward, and properly clamps to the height of the map. Level data isn't being streamed in as the player moves down yet, hence the same "pink" level appearing twice in a row (rather than the "brown" level seen in the screenshot of previous post).

Follows the player upwards now too. Was only a few lines of code... not sure why I didn't just do that in the first place? HAHA

Still not streaming in tile data though... that's next I think! Running out of time in the day though...

New map for reference. Added the background arrows to make it clearer what room I am looking at.

I'm just about out of time but vertical scrolling is "somewhat" working!🤯 I haven't added attributes yet (hence the wrong colors) and the tiles are offset slightly from where they should be). It also doesn't account for Y scroll in the horizontal streaming code yet.

You can see tiles being streamed in at the bottom right. I'm using vertical mirroring, so I have to stream in the tiles to the visible area for vertical movement. You've probably seen similar glitches in many other NES games... or maybe not because it is hidden on many CRT TVs!

Alright, kids are off to bed, and it's time to return to this 4-way scrolling. I've updated the map again to make it even more clear what is happening.

First task is to figure out why the tiles are "mostly right" by seem to be offset by 16 pixels.

Got it! NES resolution is 256x240 pixels. The BG region of VRAM has enough space for 256x256. That extra "256x16" of VRAM stores the color data for the BG. My code was writing to that "color" area of memory as if it were the next section of screen, hence the offset of 16 pixels.

On to the next issue! 💔

The vertical scrolling logic is hardcoded to always load into the left most nametable (background area). As you can see here, where I walk over to the right room before walking down, the bottom right room is NOT loaded!

I can already tell that this is going to be troublesome, as the background *row* could cross nametable boundaries, which is a totally different part of memory, and will need to be written to as a separate operation.

As I suspected, solving the case for a perfectly aligned camera-to-nametable was pretty easy (first half of video). But if I try to move downwards when straddling the 2 nametables, things go bad.

Much worse if I try to move at diagonals! 😭

I think I have a workable solution. I simply detect when I am about to go over a nametable boundary, and halt the update for the frame (scrolling updates are already time-sliced). Then when it picks up again next frame, the existing logic already detects the correct nametable.

Here I try to demo it frame by frame.

Keep an eye on the red boxes; those are the tiles being updated. You will notice that regardless of where the player stands, the red boxes halt at the edge of the nametable (marked with my mouse in the video).

Bed time. Hope to get horizontal scrolling working properly tomorrow.

This morning I had a bit of free time before work, and I was able to get upward scrolling in. It was pretty straight forward.

Was able to put in a bit more time over lunch. 8-way scrolling is getting closer. Still a few bad tiles here and there, but all of it seems solvable. I need to decide if it's worth fixing these, or just making the switch to grid-based movement, which will likely avoid the issues.

And after all those, I ended up throwing that version out and writing it again from scratch! 😅

This time in only took an hour or so, and it seems much more stable and seems to handle every test case I can throw at it.

Threw together a much larger test map (512 x 960) to stress test things a bit. Found a few bugs, but they were easy fixes.

It now supports proper coloring of tiles as you scroll!! 🥹

It also lags like crazy when you move diagonally... 😭

My plan to improve perf is to build a "render queue", where each operation will get queued up and executed 1 frame at a time.

Render queue concept is "working" but it's very easy to overflow the queue. Working on reducing the amount of updates by removing duplicate events.

8-way scrolling, with tile and color updates works and runs at 60fps!

I'm *very* hesitant to say so because this is the 8th time I've written this post only to notice a bug in the video at the last second.

The glitches at the top/bottom of the screen are expected. #nesdev

I'm going to play with it a bit more to make sure I didn't miss any bug, and then next step will be to get a more presentable tileset in there.

This is a little more complex than it maybe sounds, as it will introduce the first *alternate* tileset to the memory banks.

*this is fine...* 🫠

Plot twist: It *was* fine.

*Morgan Freeman voice*

It was NOT fine.

Getting so close to fully functional, but real life calls, and I got to leave it as is for now...

I think that's a wrap! Full 8 way scrolling on levels of unbounded size + transitions to and from side-scrolling levels!

This was a little under a week of (free time) work to get to this point, but I'm pretty happy I didn't give up on the 8-way scrolling.

#nesdev

@UnrollHelper unroll

Share this Scrolly Tale with your friends.

A Scrolly Tale is a new way to read Twitter threads with a more visually immersive experience.
Discover more beautiful Scrolly Tales like this.

Keep scrolling