What are your opinions for best NES games as you have learned programming techniques and learned how some games work? My list has to be:
Battletoads, just raw data used for so much animation and such. We're talking 256+ bytes/frame with also NO WRAM at all to work with said unrolled loops.
Recca, huge ammount of sprites and shows great design and good programming as a overly complex sprite engine would normally slow down to a crawl with not as many objects.
And what are yours that you have looked at that just did things that just pushed some limits of the system and design of it to achieve gameplay mechanics that wouldn't normally happen?
Gimmick!, one of Sunsoft's masterpieces, features extreme levels of detail you would not expect from a Famicom game. Lots of traps and enemies only appear once in the game, there are a lot of superfluous animations and extra graphical sprites that do nothing for the game play, and surprisingly good enemy AI. The physics seem universal across all game objects, and the engine is super-tight and versatile. The audio is great too.
I was pretty impressed by
Rad Racer, which manages to change the scroll on specifically targeted scanlines many times per frame, without a mapper that would provide any kind of timer. The timing is kept consistent by very carefully constructed code (good thing it isn't using DPCM).
Battletoads has some of that; it does parallax scrolling by a couple of different means; sometimes its with code carefully timed to hit a scanline, sometimes it's with CHR-RAM animation of repetitive tilings. It's also using one of the simplest possible mappers with no additional timing capability.
Bucky O'Hare uses various techniques throughout the game to simulate multiple background planes, or to seamlessly move huge objects made out of background tiles. Some of the tricks rely on MMC3's scanline counter, but others are just combinations of clever name table layout, CHR animations and carefully placed sprites, and could be performed even in NROM without problems.
Rad racer uses sprite 0 hit to start everything out.
I think NASIR wrote that game.
StarTropics (1 and 2) may not be particularly impressive from a gameplay perspective, but if you ever see the code, it's beautifully written.
tokumaru wrote:
Bucky O'Hare uses various techniques throughout the game to simulate multiple background planes
Battletoads too.
Galaxian once impressed me with clever hardware usage. Sprites for background and background for sprites.
Maybe an obvious answer, but Super Mario Bros. continues to impress me as I work through its engine. It creates its own sort of priority system to draw background scenery, foreground scenery, terrain, area objects, and enemy objects (all terms from doppelganger's disassembly). THEN sprites go on top of that. It's really clever and helps compress level data into compact byte blocks. There's impressive variety for an NROM game.
Contra has a neat 'cascading' OAM cycling routine (based on observation, not code). There's tons of flicker but then again, there are tons of objects on screen at once too.
Wild Gunman uses a really neat palette cycling routine to check for light gun hits.
Is the Star Tropics source available somewhere?
noattack wrote:
Is the Star Tropics source available somewhere?
Nah, that was just me stepping through it with a debugger.
However, I discovered the game (at least the second one) uses a routine similar to
Duff's device in order to copy strings to $2007. Considering you have precious little vblank time to upload things to the PPU, this is very efficient.
In addition, it uses a fairly efficient routine to update the palette in the middle of the screen (for the status bar).
Maybe it's not all right to write about unreleased game, but
Dream World Pogie amazed me when I realized that this game "remember" every star taken and every enemy killed. Some levels have more than 100 stars alone.
After some poking in debugger, It become quite clear how, but it's still pretty neat.
What? SMB3 can also do the same? Yes, but it uses WRAM, DWP does not.
Moreover, it remembers everything(stars, powerups, checkpoints, enemies, and even exit door and moving platforms) as flags. Total bytes used is a mere $20, resulting in 256 flags available.
About
Battletoads When I played it firrst, I was surprised by number of levels. I mean, it's mapper 7, meaning it have no CHR ROM. I mean, PRG space have to be shared with GFX. Also, more importantly, Battletoads pushed another limit(not related to NES, I think).Frustration limit
From other games, Maybe
Fantastic Adventures Of Dizzy also is worth mentioning. It's not like it have great GFX, or anything. It's just overall. I mean, this game is quite huge. A game where you explore the world and all that dizzy games things. Also the game remembers item location, X and Y (64 items or so).Same for stars collected(250), same trick as in Dream World Pogie, it seems.And all that with no WRAM.
Drag wrote:
However, I discovered the game (at least the second one) uses a routine similar to
Duff's device in order to copy strings to $2007.
Do you mean something like
this?
Quote:
In addition, it uses a fairly efficient routine to update the palette in the middle of the screen (for the status bar).
Can it do it without visual glitches? That would be really interesting!
Another one I was really impressed by is the use of CHR-RAM in Solstice. To get the 3D isometric view, it actually masks off pixels of the character sprite in CHR-RAM when you walk behind a block.
tokumaru wrote:
Quote:
In addition, it uses a fairly efficient routine to update the palette in the middle of the screen (for the status bar).
Can it do it without visual glitches? That would be really interesting!
If I got the
right game then it's nothing special.
Game seems to turn rendering off at scanline no.183, change pallete(via $2006 and $2007 writes). After that it waits until right moment (everything it timed) to turn rendering back on(at Scanline 188). Just the same as Fantastic Dizzy does for it's status bar.
Note: I just took a quick look at the code, I may be mistaken. But I'm pretty sure about what I stated above.
Even "Back to the Future" changes the palette for the status bar, and that is not a good game at all.
Dwedit wrote:
Even "Back to the Future" changes the palette for the status bar, and that is not a good game at all.
Isn't this a very easy operation? Couldn't hypothetically even SMB be modified to have one palette for the status bar, then on sprite 0 hit update the palette in addition to the scrolling?
I'm guessing it's hard to squeeze the palette update into horizontal blanking without causing rainbow artifacts.
The rainbow artifacts can be inside the overscan area. Visible on the AVGN's review of Back to the Future.
Is the vram management in Battletoads similar to the vram management in DKC, where there can be up to 14 objects (excluding bananas), and objects are limited to 32 8x8 blocks (except for bosses).
VRAM management in Battletoads is very simple. VRAM is decoded once for all possible sprites at the beginning of the level. Except for the main character's graphics, 32 tiles are reserved for that (16 tiles for each player). And the animated tiles too, they are also changed during run time.
One 4 KiB CHR RAM page is enough for two copies of the tiles for all 64 sprites, even in 8x16 mode. In one NTSC vblank, you can update eight tiles plus one nametable row, nametable column, or whole palette. So if you aren't changing all sprites to new frames of animation at once, you don't even need complicated VRAM management; you can just continuously load in new animation frames.
Dwedit and tepples are giving me seemingly contradictory information.
Battletoads builds its CHR upload code in RAM so it can upload a little faster (doesn't have to increment a pointer, etc.). They also ran out of vblank time for two levels (the snake level, and the revolution), so they leave rendering off for a bit of the top of the screen (and push down the status bar) to accommodate.
psycopathicteen wrote:
Dwedit and tepples are giving me seemingly contradictory information.
Dwedit explained the design chosen for Battletoads. I explained another design that other games might use, which I gather is similar to what a lot of fourth-gen and GBA games used.
tokumaru wrote:
Do you mean something like
this?
Maybe (I'm not familiar with the assembler commands in that code). Duff's device is basically a combination of using an unrolled loop and a regular loop, used to copy memory from one location to another. In Startropics II, there's an unrolled loop of 8 LDA/STA's, so the game uploads stuff to the PPU 8 bytes at a time using this unrolled loop (fast). Afterwards, the remainder (for when the string length isn't divisible by 8 ) is uploaded using a regular loop (slower).
tokumaru wrote:
Can it do it without visual glitches? That would be really interesting!
It basically uses A, X, and Y to quickly cram bytes into the palette right at hblank, and then it uses a cycle timed loop to get to the next hblank, to do it again. It still has to turn off rendering, but not for long.
Or just use an indirect jump into the duff's device loop.
That works too.
Duff's Device is just the trick of how to do it in C in a concise way.
Unrolled loops are just unrolled loops. If you're writing in assembly there's no such thing as Duff's Device.
Drag wrote:
I'm not familiar with the assembler commands in that code
That code is meant to run on
Michal Kowalski's 6502 simulator. I always use it to test new ideas.
Quote:
Duff's device is basically a combination of using an unrolled loop and a regular loop, used to copy memory from one location to another. In Startropics II, there's an unrolled loop of 8 LDA/STA's, so the game uploads stuff to the PPU 8 bytes at a time using this unrolled loop (fast). Afterwards, the remainder (for when the string length isn't divisible by 8 ) is uploaded using a regular loop (slower).
I see... Yeah, not exactly what my code does, which is completely unrolling the copy loop and using a jump table to land on the appropriate part of it to copy the desired amount of bytes.
Quote:
It basically uses A, X, and Y to quickly cram bytes into the palette right at hblank, and then it uses a cycle timed loop to get to the next hblank, to do it again. It still has to turn off rendering, but not for long.
I guess that the ~28 cycles of HBlank are indeed enough to update all 4 entries of a palette when rendering is disabled, and in the end the VRAM address will point to color 0 of the next palette, so there are no visible glitches (well, except maybe for the overscan area). It would take 8 scanlines to update all the colors though, but I guess that's acceptable in some cases.
That reminded me.
Long time ago I started a MMC5 game project(which will not be finished soon, it progresses slowly) which use IRQ interrupt to change BG color.
I don't know if this "trick" is known(probably is) and if any games use this(again, probably yes). But this enables me to change one color of pallete with no glitches. In MMC5 project, I use it as sort of gradient.
I know, effect is poor, but it's because of NES's color number.
I tested this extensively and works perfectly with any emulator. I have no means to check it with real hardware, though.
Anyway, I think this could be done tih sprite0, but you can have only one hit per frame.
I just thought it might be worth mentioning, as a contrast to turning rendering off.
Such gradients with just a few color steps could work much better with dithering, it is seen in many NES games (horizontal color lines of varying height).
That palette trick might work fine in most emulators, but will glitch horribly on real hardware if you use any sprites at all.
The sprite CHR patterns to be displayed on the next scanline get fetched during the first half of the hblank period, and there's just not enough cycles in the second half to turn rendering off, write $2006, write $2007, then restore scrolling with $2006 and possible $2005 and finally turn rendering back on again. So you'll end up with corrupted CHR graphics for your sprites...
Shiru wrote:
Such gradients with just a few color steps could work much better with dithering, it is seen in many NES games (horizontal color lines of varying height).
Can you give some titles? My code isn't prefect-I can change 1 color every 8 vertical pixels(need to restore scrolling with $2006).Maybe I can learn something from these games.
@Bananmos
If I'm not mistaken, Shiru just said that this effect is seen in many NES games, so i think it is possible even on real hardware(provided that all this games use it for another things than cutscenes with no sprites).
Also, I can remember bug with corrupted sprited, on emulator. I got around it somehow.
Quote:
The sprite CHR patterns to be displayed on the next scanline get fetched during the first half of the hblank period, and there's just not enough cycles in the second half to turn rendering off, write $2006, write $2007, then restore scrolling with $2006 and possible $2005 and finally turn rendering back on again. So you'll end up with corrupted CHR graphics for your sprites...
Is there really no way around this?
I didn't mean that the palette update used in games, I mean that the 'dithering' used to make better gradient using just a few colors in many NES games.
Something like this.
Shiru wrote:
I didn't mean that the palette update used in games, I mean that the 'dithering' used to make better gradient using just a few colors in many NES games.
Something like this.
If you want one that looks even crazier, try
the ending from Goonies 1. (Which looks really nice on a real NES, by the way
)
I'm sorry, I didn't understand, Shiru.
Anyway, Dithering can't be used for background color, color0(the"invisible" color, at $3F00), can it?
@Drag
That looks really good!
I guess if you need a wide variety of background colors, try doing it without using color #0, but Attribute Clash would be a problem.
So backgrounds near the bottom use one set of palettes, and the sky color shares colors with that, then backgrounds near the middle of the screen use another set of colors, and the sky colors are shared with that, then different colors at the top of the screen.
I guess so. But this would require different level designs.
And sorry about that off top. Back to games that push limits.
I actually played BattleToads(never bothered to do so before) and I'm amazed by the level where you fly on plane(Level7).
The mapper is AOROM.It has no IRQ. So how did they make
this effect?
I mean those violet flames at the top of the screen.
The only way that comes to my mind is to wait for the end of status bar code, then time the code carefully so it'll wait for Hblank, change Horizontal scrolling on every scanline. But that's....insanely hard to do. For me, at least.
I'm sure it is done with timed code. Since you only would need to put precalculated offsets, and you have most of frame time (at bottom part of the screen) to calculate them for the next frame, it shouldn't be too difficult.
I think that screen just times all code from NMI. Notice how after the purple stuff is scrolled line-by-line, the rest of the screen scrolls very simply.
In the Turbo Tunnel, they use a sprite 0 hit that happens after the top part is done scrolling. Then they use a simplified screen renderer if it's playing PCM samples (game paused, etc.)
Quote:
In the Turbo Tunnel, they use a sprite 0 hit that happens after the top part is done scrolling.
I doubt it. Battletoads uses the sprite zero hit in the status bar, for the separation between the status bar and the playfield. The sound driver is called after the VBlank (which is constant timed) ends and the screen is enabled (late, after the extended VBlank). The sound driver is variable-timed, so they need the sprite zero hit in the status bar to split to the playfield accuracely.
I guess all other effects mentioned is simply timed code after this split. This reduces CPU usage for the game, of course. Apparently they managed it to be fast enough, even when most of the screen is taken by raster effects, which means the game engine is very fast and efficient. When playing a sound effect via $4011, they ignore this part apparently, which causes weird scrolling glitches when you punch enemies.
In Battletoads & DoubleDragon, they did it the other way around, the timed code continues to run, but the PCM sound effects are distorted when there is a raster effect on the screen.
Sprite 0 in the Turbo Tunnel is at scanline 141. It's a black 1-pixel high horizontal line placed at X position 6. You can visibly see it if you look carefully at how the background disappears at that point.
In other levels, sprite 0 is indeed inside the status bar. But not the Turbo Tunnel.
Wow, so they programmed something different for different levels !!
I must admit that's a little crazy, but after all why not ?
Also the status bar is lower (and the extended VBlank bigger) for the Snake Pit and the Cylindrical Level in the NTSC version. There is still no extended VBlank in the PAL version though.