Wow, the modifying assembly code part was impressive! I wouldn't even be able to find the dialog drawing routine amid thousands of lines of undocumented assembly, let alone modify it. It's amazing that a high school kid could figure it out.
If you like this kind of thing, just go in and give it a shot! The NES is a great place to start, just three registers and simple instruction set. The display unit ABI is well documented and there's a couple of NES debuggers out there.
Starting with no experience, I wrote a program to dump level images straight from a ROM:
The early stuff he shows can be done on most emulators as a way to cheat. Done it ever so often when i get bored with a game. Sometimes locking the health value will freeze a game though as developers use a cheap refill animation on leveling up or beating a boss, and you end up with the animation getting stuck as the emulator keeps resetting the value.
I have never owned one, but i think gamesharks and others work similarly.
The NES/SNES era had a lot of games that use sprite animation state/OAM memory as the canonical place to hold the current state of something. Often even important, high-level pieces of game business-logic state, were just left as sprite attributes on particular sprites.
Two examples from Super Mario World (which loves this technique):
• You can avoid dying from running out of time in SMW, by simply getting a power-up right as the level timer reaches zero. The level timer just changes the Mario sprite's animation to STATE_DYING (once, when transitioning from 1 to 0); so if you can get the sprite to play a different animation, the game forget that the player was supposed to be dead.
• The "null sprite" glitch: Yoshi 'carries around' enemies in his mouth by just 1. marking the enemy sprite as invisible and intangible, and then 2. storing a pointer to said enemy sprite. If you can get that sprite to unload from OAM memory and get something else to take its place, then when Yoshi goes to spit the enemy out, he'll instead spit out whatever random garbage is now at the OAM location referenced by the pointer.
Yes! Gamesharks / Action Replays / similar gave you an "instruction set" of sorts that was interpreted as instructions of sorts - write value to address, do if value at address is X, and so on. When I was messing with one on the Nintendo DS a few years back, you were actually able to write ARM (and THUMB, I believe) ASM and compile it to the target system (NDS) that could be loaded through the Action Replay. I'll have to check if I can dig up my old notes on this stuff when I'm home...
I'd really like to read your notes if you find them. I'm assuming the Action Replay could be used for the first bypass/homebrew loading exploits, then?
I'm not sure; I never got that involved in it. Back when I was involved, there were some communities entirely centered around taking apart individual games and figuring out how to tinker with them. Things like loading up the unused tracks in Mario Kart and changing the colours etc. to make "custom" courses.
Here's one of the main pages I used as a reference at the time: http://doc.kodewerx.org/hacking_nds.html Even without ASM, you could still write to arbitrary memory addresses, jump around with conditionals, patch, copy memory, and all sorts of things. The linked page also touches on the basics of ARM/THUMB ASM tinkering. I seem to have lost my notes, so this is all I can get you :(
It's about the same as how you'd approach modern programming, except instead of watching variables you'd watch registers and addresses in RAM/VRAM and work backward from there. Hell, you could even look specifically for instructions that manipulated those addresses.