Journey to Cygnus

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Journey to Cygnus
by on (#167395)
Before I work on the Metal Gear-inspired stealth game and after making some basic programs for the NES, I want to get some simpler games made.

My primary semi-long term goal is Journey to Cygnus. Currently in its pre-production, infant stage, I'm developing an on-the-rails tubular space-shooter about a space pilot whose wife is captured by aliens and imprisoned in the center of the infamous supermassive black hole called Cygnus X-1. The gameplay has you, the Pilot, on a treacherous journey, flying a combat spaceship from your home planet Earth towards the distant black hole Cygnus, hence the title Journey to Cygnus. Outer space is teaming with obstacles ranging from asteroids to ice clouds to space aliens and more.

-------------------------------------------------------------------------------------------------

Image
Screenshot from Gyruss

Image
Paint.Net mock-up

Image
NES Screen Tool mock-up

-------------------------------------------------------------------------------------------------


You overcome these obstacles by moving clockwise and counterclockwise on a circular rail, going "foward" through space, and using your standard Cannon Blaster and your powerful but scarce Super Blaster (ammo indicated by yellow squares below the score). Progress is measured by Warps. Much like how there are eight worlds in Super Mario Bros., there are a series of territories in outer space that the Pilot must warp through. The Pilot warps from Earth to Mars to Ceres to Jupiter to Saturn to Uranus to Pluto to the ice-filled Oort Cloud and so on into the farthest reaches of space until you reach your destination: Cygnus.

What has been roughed out for the game is up on Itch.io right now. It's currently developed in Game Maker: Studio in order to have a functioning canvas to try out new ideas with and work out game design problems before retrofitting/porting it to 6502 ASM6. To help me work through how to go about programming the 6502, I've bought Programming the 6502 by Rodnay Zaks. It is doing an excellent job of teaching what each instruction does and how it works. Once I understand that, the problem of formatting it to a NES (and preferably also MMC5 or a new, better mapper) arises. After having played through Rockman 4 Minus Infinity, I am inspired by what it is capable of doing visually and how much content it can hold in memory. The NES Dev Wiki is incredibly helpful, though the act of actually putting pen to paper is still an enigma. With determination and know-how, I know it can be done.

Upon its completion, I'd like to sell it to retro game publishers like Piko Interactive assuming their business model is reasonable.

The game takes inspiration from Gyruss, Tempest, Galaga, Rush's Cygnus X-1: Book 1 and Book 2, and the Star Wars movies.

-------------------------------------------------------------------------------------------------

Image
So freakin' cool.

-------------------------------------------------------------------------------------------------
Re: Journey to Cygnus
by on (#167396)
If you're going to sell your Gyruss clone on cartridge, you probably won't want to target it for MMC5. In increasing order of complexity (that is, co$t), the practical mappers for a cart release are
  1. NROM (0)
  2. CNROM (3), GNROM (66), Color Dreams (11), UNROM (2/180), AOROM (7), BNROM (34)
  3. MMC1 (1)
  4. MMC3 (4/118) or FME-7 (69)

Gyruss is CNROM.

I wish you luck with your game design. If you can't fit all sprite graphics into a single sprite page, you may end up having to use CHR RAM to replace individual sprite cels in real time, which is doable (Battletoads; Haunted: Halloween '85) but may be tricky. Let me know when you have a sprite sheet ready so I can try to recommend a strategy.
Re: Journey to Cygnus
by on (#167398)
Yeah, the MMC5 is a bad choice for homebrew, since no one can manufacture cartridges with that mapper (without cannibalizing one of the few MMC5 games that were made). Unless you don't care about that. Anyway, it seems to me that a lot of beginners feel like the only way to get the most out of the NES if by using the MMC5, while most people, even the more experienced programmers, have barely scratched the surface of what the system can do without those enhancements.

Also, don't get too hung up on the 6502 thing. I estimate that knowing assembly is only about 10 to 15% of what it takes to make a game. Knowing how to interface with the system to handle graphics, sound and input is another 25 or 30% maybe, but the bulk of it is coding a solid game engine using various game programming concepts related to animations, physics, collisions, A.I., object management, and so on. 6502 assembly is just a language, and more important than knowing that is knowing WHAT to say in that language, even if you don't do it fluently. Prototyping the game in Game Maker should help a bit with this I guess, but a lot of things that a tool like that will handle for you will have to be designed and built from the ground up for the NES.
Re: Journey to Cygnus
by on (#167401)
I used to play lots of Gyruss back in the 80s.

Good game.
Re: Journey to Cygnus
by on (#167461)
dougeff wrote:
I used to play lots of Gyruss back in the 80s.

Good game.


For some reason, people tend to dislike or feel indecisive about the game. It's my favorite space shooter game next to *Galaga*, it just desperately needs improvement. The arcade version was updated and ported to X-Box Live Arcade a few years ago and it got 2/5 and 3/5. It appeared to be the exact same game as the original but with flashier graphics and live music. The NES version (the generally more enjoyable version) adds improvements to the original that certainly help, but it feels like it wants more like 2-player co-op, different enemy patterns, more music, and so on. The game is also incredibly, incredibly hard, so beating the game is out of the question. The plan is that Journey to Cygnus fixes these problems and makes a better experience.


tokumaru wrote:
Yeah, the MMC5 is a bad choice for homebrew, since no one can manufacture cartridges with that mapper (without cannibalizing one of the few MMC5 games that were made). Unless you don't care about that. Anyway, it seems to me that a lot of beginners feel like the only way to get the most out of the NES if by using the MMC5, while most people, even the more experienced programmers, have barely scratched the surface of what the system can do without those enhancements.

Also, don't get too hung up on the 6502 thing. I estimate that knowing assembly is only about 10 to 15% of what it takes to make a game. Knowing how to interface with the system to handle graphics, sound and input is another 25 or 30% maybe, but the bulk of it is coding a solid game engine using various game programming concepts related to animations, physics, collisions, A.I., object management, and so on. 6502 assembly is just a language, and more important than knowing that is knowing WHAT to say in that language, even if you don't do it fluently. Prototyping the game in Game Maker should help a bit with this I guess, but a lot of things that a tool like that will handle for you will have to be designed and built from the ground up for the NES.


I thought that custom chips could be created that can be used instead of using a donor mapper. Not new mappers, but I mean a new mapper modeled after the MMC5. One thing about the MMC5 that I like besides its memory is the audio expansion. The ability to add more texture to the music in order to create that "space-y" vibe would help instead of just the vanilla 2A03. There are other options, too. The Squeedo is something I'd rather use instead for its FM synth and PCM when it comes out. However, I don't know when that is, so currently, I'm focusing on game design and placeholder graphics like the ones in the original post.

I'm doing the same thing with Game Maker with the stealth game. I understand that, essentially, I'll be making the same game twice by doing this: a PC version and a NES version. As to how far I take the dev for the PC version, I don't know. It'll likely be nothing more than a display of the basics of the design to find out what works and what doesn't. As for 6502, I understand that optimization is something that is done late in development, so the fluency can be changed then.

tepples wrote:
If you're going to sell your Gyruss clone on cartridge, you probably won't want to target it for MMC5. In increasing order of complexity (that is, co$t), the practical mappers for a cart release are
NROM (0)
CNROM (3), GNROM (66), Color Dreams (11), UNROM (2/180), AOROM (7), BNROM (34)
MMC1 (1)
MMC3 (4/118) or FME-7 (69)

Gyruss is CNROM.

I wish you luck with your game design. If you can't fit all sprite graphics into a single sprite page, you may end up having to use CHR RAM to replace individual sprite cels in real time, which is doable (Battletoads; Haunted: Halloween '85) but may be tricky. Let me know when you have a sprite sheet ready so I can try to recommend a strategy.


One particular graphic effect from Rockman 4 Minus Infinity that the MMC5 allows that blew my mind is some kind of wave-like distortion when Wily teleports. This effect is used at other parts in the game like in Pharaoh Man's stage with the heat waves. That's another thing that I wanted to include it. It is, of course, not necessary.
Re: Journey to Cygnus
by on (#167462)
AlexE wrote:
One thing about the MMC5 that I like besides its memory is the audio expansion.

How's your Japanese?

North American, European, and Australian consoles cannot play MMC5 audio without modification. A game including audio expansion would need to include a jumper pack that fits in the bottom of every console, more co$$t.

Quote:
One particular graphic effect from Rockman 4 Minus Infinity that the MMC5 allows that blew my mind is some kind of wave-like distortion when Wily teleports. This effect is used at other parts in the game like in Pharaoh Man's stage with the heat waves. That's another thing that I wanted to include it. It is, of course, not necessary.

That teleport effect is very simple. It amounts to changing the scroll once a scanline. It doesn't need even MMC3, let alone MMC5.
Re: Journey to Cygnus
by on (#167463)
AlexE wrote:
I thought that custom chips could be created that can be used instead of using a donor mapper. Not new mappers, but I mean a new mapper modeled after the MMC5.

Yes, it's possible to fully clone the MMC5 or create a new mapper based on it, but has anyone done it yet? No. Partial implementations exist for flash cartridges, but that won't help you with manufacturing cartridges of your homebrew game. If you're not a hardware guy yourself, or are working closely with one that plans on developing such mappers, targeting nonexistent hardware is never a good idea.

Quote:
One thing about the MMC5 that I like besides its memory is the audio expansion.

Which an unmodified NES cannot play. Someone apparently created a hack for this, but I'm not sure the audio is mixed properly, and it's far from aesthetically pleasing.

Quote:
As for 6502, I understand that optimization is something that is done late in development, so the fluency can be changed then.

My point is that game programming takes a long time to learn. I've been doing this on and off for over 20 years and every project teaches me something new. Sometimes it's something big, that completely changes my way of thinking about a specific aspect. So don't worry about becoming a master of assembly, or of anything really, for your first project. This is not realistic. Just focus on making something, even if it's not the masterpiece you envisioned. The things you learn along the way will probably make you want to go back and redo a few things in a better way, but you can put that off if you think there won't be any immediate advantages.

Quote:
One particular graphic effect from Rockman 4 Minus Infinity that the MMC5 allows that blew my mind is some kind of wave-like distortion when Wily teleports.

That looks like common horizontal mid-frame scroll changes (the same effect used to distort the road in many racing games, only more random), which even NROM (mapperless) games can pull off if you can spare the CPU time to time the effect. If you can't spare the time, virtually any mapper with scanline IRQs can help, no need for the MMC5 in particular.

There are a lot of effects you can pull off with simpler mappers or no mappers at all, you just have to be creative. You can use an emulator's debugging features to study how these effects are created. Many times the mapper is minimally involved. Battletoads for example is a game that uses a very minimal mapper (it does nothing more than allow access to more PRG-ROM, which doesn't help with special effects at all), and still does a lot of impressive effects. Bucky O'Hare is another game with really interesting effects, and while it does use an MMC3, many of the effects don't rely on it at all.
Re: Journey to Cygnus
by on (#167469)
I was under the impression that it was a special piece of hardware that allowed for those kinds of effects like an add-on. Well then. Ya learn something new every day.

At any rate, the first program I'm making is a simple display of graphics. There is a single tutorial that I've managed to find that fully explains how to do this, explaining not only what to write but giving commentary as to why it's written (even then it leaves more to be desired). I don't want to have to cling to tutorials and cookie-cutter copy-paste the code forever; I want to be able to understand what each important step in the code does so that I can write it myself in a different situation. Not that I have to be able to read the code of Super Mario Bros. like a book, but enough that I can do a basic task without having to consult a tutorial.

For example, when reading this tutorial on ASM6, the tutor wrote that code starts at $C000. Why $C000? Why not any other address? These important things were never explained and I don't recall this matter ever being explicitly explained on the Wiki either. It wasn't until later inferring that certain addresses are reserved for certain things like $4016 reserved for reading the first controller and $4017 reserved for reading the second. This overarching problem has been something I've been slowly but surely resolving by writing whatever I learn in a separate document kind of like notes, finding the missing links for each ambiguity. But doing this leaves me open to being completely flat-out wrong, which many of the people here have pointed out. (I ended up starting up a new document because the old one was so cluttered up with inaccuracies.) Thankfully, a good few of the problems I've been having were long-since talked about. However, if the tutorial simply explained why the code starts at $C000—a seemingly random point without knowing the context—all ambiguity would've been cleared up then and there, circumventing any confusion.

I don't mean to sound whiny and my complaints aren't really directed towards you or any specific person. I'm grateful that these sorts of tutorials exist because without them I'd be completely freakin' lost. It just gets frustrating at times. Regardless, I think moderate comprehensiveness when trying to teach beginners would really help clear out the "easy-for-the-experienced-but-hard-for-newbs" questions. Unless that comprehensiveness over-complicates the tutorial. In that case, I don't know. :? Think of it like being spoonfed info in a non-patronizing, educational way.

I also don't want to unnecessarily bog down the forum with questions that I should be able to figure out the answer myself. If there's one tutorial that I'd love to see, it's an assembly tutorial that explains the first thing you write for the code after the iNES header and RESET & NMI vectors and all that. Kind of like a writing prompt about a guy named Jack where the iNES header explains who Jack is, then the tutorial says "Jack had a pretty average life until one fateful day when...___(INSERT ADVENTURE HERE)____". Because that is really having me stumped.

Basically, I have a lot of questions and each question that's answered spawns five more questions.
Re: Journey to Cygnus
by on (#167470)
AlexE wrote:
If there's one tutorial that I'd love to see, it's an assembly tutorial that explains the first thing you write for the code after the iNES header and RESET & NMI vectors and all that.

Basically, you enter the first program mode. Each "mode" (there are many names for this) consists of an "initialization" step (where everything is setup: graphics are loaded, variables initialized, etc.) and an "update" step (which runs once every frame and updates everything that changes over time or because of user input). There's also a "draw" step, which depending on the way the program is designed can be shared among all modes, and is responsible for modifying the video according to instructions buffered during the "update" step.

Every game is a collection of such modes. The title screen mode usually draws some background graphics during the initialization step and then executes the update step every frame, allowing the player to select options in a menu or start a game. When you know which mode to run next, as a consequence of a selection the user made, a timer expiring, or whatever, just JMP to that other mode's initialization code and it'll pick it up from there. Of course you have to code some supporting routines to make all this look pretty, like a palette fading system that you can use to fade out before jumping to the other game mode (something you'll only do when you detect the screen is fully black), and the new mode can fade in from black to complete the transition.

Each program mode, and especially the main gameplay mode, will make use of many sub-systems to handle all the little things that have to be done. You'll need a sprite animation system, a map scrolling system, a physics system, an object management system (objects usually have an "initialize-update-draw" structure as well), and many others... the more modular these are, the easier it will be to reuse them across the entire program.
Re: Journey to Cygnus
by on (#167478)
AlexE wrote:
For example, when reading this tutorial on ASM6, the tutor wrote that code starts at $C000. Why $C000? Why not any other address?


The PRG address starting from $C000, is the fixed PRG bank. $8000 is the switchable PRG.
Keeping the available ROM split in half seems logical.
Re: Journey to Cygnus
by on (#167479)
Alp wrote:
The PRG address starting from $C000, is the fixed PRG bank. $8000 is the switchable PRG.

Actually, that's something that changes from mapper to mapper. On the MMC3 for example, only $E000-$FFFF is fixed. And on NROM, EVERYTHING from $8000 to $FFFF is fixed. Considering this was probably in a tutorial for beginners, the reason for starting the code at $C000 is that from $C000 to $FFFF there are 16KB, the smallest ROM size allowed by the iNES standard, and more than enough for anyone's first NES experiments. The reason for it being aligned to the upper end of the addressing space is because the CPU vectors must be at $FFFA.
Re: Journey to Cygnus
by on (#167482)
tokumaru wrote:
the reason for starting the code at $C000[...]
And that's also why they didn't explain it. Because it's arbitrary but with some vitally important and easily-forgotten constraints, and explaining those constraints would be a bit of a distraction from getting your first program working.

If I were trying to explain it, the obvious place is to explain it is the first time you start using bankswitching, and not just NROM. At that point, the programmer is going to have to start getting used to indirection, and the constraints on the fixed bank of code will dovetail nicely.
Re: Journey to Cygnus
by on (#167484)
I think it's important to explain that the CPU can see 64KB of memory, and that this space is broken up to accommodate all the different things it has to interface with, and that the upper half of that space is mapped to the cartridge. And then that you don't necessarily need to use the whole 32KB, but if you go with 16KB of PRG-ROM you should align it to the upper end because of the vectors. I'd definitely omit the fact that the 16KB are mirrored at $8000-$BFFF, so it's actually possible to map a small ROM to that range as well, because saying the vectors can also be at $BFFA would be confusing.