Hey everyone, I'm seeking advice about if a super-simple hack is RHDN material or not. I'll have to elaborate a little to clarify.
So I'm new to all this and this is my first "ROM hack". Gargoyle's Quest 2 (NES) jumping physics always bugged me. Walking and hovering has 100% horizontal speed (1 pixel per frame) but while jumping/falling that is reduced to 75%. That makes it feel sluggish and kind of punishes jumping. No other game in the series does that, including GQ2's Game Boy port, making that one actually the fastest-paced game in the series while the NES original is the slowest. It causes some unnecessary frustration like in that infamous long flight over the river of fire, which is not an issue in its GQ1 or even GQ2(GB) equivalents, which made me wonder if that stage was originally designed without the slowdown in mind. It's the prime issue that makes GQ2(NES) feel less satisfying in my opinion.
So I dug into GQ2's code to remove that and make it feel more like the other games, and I found a very simple solution. At one point, there's an LDA instruction whose value kind of determines the speed percentage when in jump/fall mode. Changing LDA #$C0 (192/256 = 75%) to LDA #$FF (255/256 is virtually 100%) does the trick and I've playtested two full playthroughs with and without overclocking using the Mesen core in RetroArch. I've tried finding more elaborate solutions but found it very difficult to keep track of what's going on through all the sub-sub- and sub-sub-sub-routines, and of how the game exactly uses the carry flag for multiple operations at a time. Changing that one value seems safe and does what it's supposed to perfectly fine.
Now what I'm struggling with is if this is the kind of "hack" that's supposed to be on RHDN. I thought it'd be a shame not to share this but I'm not sure RHDN is the right place, in the sense that it seems to be a place for far more sophisticated hacks. I've read the guidelines and I believe it's in a grey area. I'd hate to submit something that the site isn't meant for.
Like, on the one hand you could say "it fixes the sluggishness, it's a more fluid experience now, a genuine gameplay improvement, and if changing a single byte does the job, then why not?"
On the other hand you could say "this is too crude for the quality standards here" or "it just changes one value to FF and it makes the game easier, it's just a cheat code!" (note: I did try to solve this via cheat/Game Genie code, but the RAM address in question is used by different subroutines, so I couldn't find a way other than manipulating the specific jumping subroutine in the ROM)
Thanks for reading, any feedback is appreciated!
I am not one that decides but I reckon I have a handle on what goes.
Volume of change is seldom the criteria. This sounds like an assembly drive game improvement (or nominal improvement) that has been play tested. One not trivially replicated to no notable effect 5 minutes after reading https://web.archive.org/web/20080309104350/http://etk.scener.org/?op=tutorial .
Could you make it a GG code? Sure. Might even want to do that just because (might even want to include it in the readme) but if it is going to see you chasing down through the ROM for a value used all over the shop then eh. Can make an IPS or something as well because that is both required and also useful for some (I know you can hardpatch codes but if we are dealing with all the "I only have an android phone" set then yeah).
There has been many other hacks with just single byte change, this (https://www.romhacking.net/hacks/3307/)for example, which is kinda similar. So yeah stop overthinking and submit it.
I'm a graphics artist. If it helps at all, I would've had no idea how to find the byte that affected horizontal speed during jumps.
The change you've made sounds like a great improvement. Don't beat yourself up over the fact that making said change was "easy" (It's all relative). What matters is the end result.
Thanks everyone, yeah I also noticed somebody already uploaded no-skid hacks for Mega Man 1/2 which I was planning to look into next, so it seems cool.
I'll submit it, but after I did more QC testing with other emulators and different region ROMs.
I would be interested in seeing your method to come up with the hack in the first place. I'd like to see a few lines of assembly, even just in the readme. You never know, maybe the method would help someone else hack another game, even if it's just changing one byte. I try to collect all the effort and knowledge that went into the hack and put it out there for someone else to learn from.
Phew, that's a long story and I haven't made notes so I forgot some of it.
I was using FCEUX. I was running the hex editor while playing to find patterns. Some memory adresses there were easy enough to spot (e.g. $0030 seems to be 0 when walking/standing, 1 when jumping/falling, 2 when hovering. $0328 and $033C are your X position, so e.g. absolute position 255 would be 255 at $0328 and 0 at $033C, while adding one to that (256) would be 0 at $0328 and 1 at $033C. This coordinate would be pretty easy to spot in the code in many situations.
While moving around, one address in particular seemed suspicious. $0314 only changes when moving left/right while jumping/falling. It is static when on the ground, static when hovering, static when jumping straight up/falling straight down. It was only changing when you were moving left/right in jump mode. It was increased by $C0(192) per frame when moving right and decreased by the same amount when moving left. This resulted in a pattern of four values $00, $40, $80, $C0 (0, 64, 128, 192) rapidly cycling on a per-frame basis.
I had a feeling I was on to something here and I had a theory: what if the carry flag from the +192 decided if you moved forward or not? Like, in 8-bit logic:
0 + 192 = 192 -- carry flag = 0
192 + 192 = 128 -- carry flag = 1
128 + 192 = 64 -- carry flag = 1
64 + 192 = 0 -- carry flag = 1
I had an idea that maybe the game decides if you move a pixel or not is decided by the carry flag from this operation. Move only when carry flag is set would mean 75% speed, which is exactly what you get in the game.
I set a cheat code to lock it to 0, and as expected, 0+192 would never set the carry flag, and I couldn't move right anymore during jump. Locking it to 192 meant subtracting 192 would never set the carry flag, so I couldn't move left anymore during jump. Locking it to 128 meant the carry flag would always be set either way, and indeed I got full 100% horizontal speed. It seemed to work.
Sadly, this messed up a few other things, like moving platforms. They also move at 75% speed, but locking the RAM value forced Firebrand to move at full speed instead of 75%, so he'd fall off the edge. It also messed with the pushback from the Blower boss. I realised that the end result stored at $0314 was a sum of several independent operations, and locking it would really mess with those.
So I started digging into the code via FCEUX's debugging disassembly. I understood a little of it thanks to my previous humble forays into x86 assembly, but was completely lost most of the time. With the help of this friggin amazing interactive 6502 tutorial: http://skilldrick.github.io/easy6502/ (http://skilldrick.github.io/easy6502/) I understood more.
In the end, I don't really remember how, I found that the game's jumping subroutine stores $C0(192) at $038C before that value is added to/subtracted from $0314. Locking this value via cheat code again didn't do any good either, but tbh I don't remember how exactly. However, changing this particular instruction in the ROM (changing the value to be added/subtracted) to value $FF so that it would set the carry flag in 255 of 256 frames did the trick. No issues with platforms or Blower. That's how I got here.
December 11, 2020, 06:51:43 PM - (Auto Merged - Double Posts are not allowed before 7 days.)
Uploaded it to RHDN, here's the link if anyone's interested: