Invincible Guardian

If it has bytes, we can change it. Talk about anything relating to hacking and emulation here.

Moderators: General Moderator, Game Moderator

Invincible Guardian

Postby Rainflush » Thu Feb 16, 2012 5:09 am

Does anyone know why enemy 273 (Invincible version of Guardian) hits for around 20 damage even when I set his level to 71 and his Battle Power to 218? There doesn't seem to be anything in his AI script which would indicate why this happens, and he still hits like a Leafer even when the Special Event box is unchecked. Likewise, I can't see anything in his encounter profile which would explain it.
User avatar
Rainflush
Regular User
Regular User
 
Posts: 118
Joined: Wed Apr 28, 2010 2:54 pm

Re: Invincible Guardian

Postby Assassin » Thu Feb 16, 2012 9:07 am

the physical damage function doesn't check for overflow, so invincible Guardian's damage can "wrap" past 65535 to a smaller number. characters at or near level 99 with Gauntlet and a weapon like Illumina are also susceptible to this bug.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1195
Joined: Tue Sep 14, 2004 5:10 am

Re: Invincible Guardian

Postby Rainflush » Thu Feb 16, 2012 5:26 pm

I see, is there a patch to rectify this problem?
User avatar
Rainflush
Regular User
Regular User
 
Posts: 118
Joined: Wed Apr 28, 2010 2:54 pm

Re: Invincible Guardian

Postby Assassin » Fri Feb 17, 2012 3:14 am

not yet. Lenophis and i got pretty far on one in late January, but it's not done yet.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1195
Joined: Tue Sep 14, 2004 5:10 am

Re: Invincible Guardian

Postby Rainflush » Fri Feb 17, 2012 7:34 am

Oh excellent, perhaps make a post about it whenever you should get around to completing it.
User avatar
Rainflush
Regular User
Regular User
 
Posts: 118
Joined: Wed Apr 28, 2010 2:54 pm

Re: Invincible Guardian

Postby Lenophis » Fri Feb 17, 2012 12:16 pm

I thought I had a working patch for a while, but my end is still buggy with the gauntlet boost. Working on it! :p
Image
Lenophis
Veteran
Veteran
 
Posts: 588
Joined: Sat Mar 26, 2005 5:52 am
Location: Duluth, MN

Re: Invincible Guardian

Postby Drakkhen » Tue Feb 21, 2012 5:22 am

ff3pdof.ips Obsoleted

Didn't thoroughly test it, but this patch should fix physical damage overflow by capping initial damage at 32,767.

Uses 33 bytes of free space at C2/6780(Should be safe) and assumes a headered headerless rom.

Let me know if it works.
Last edited by Drakkhen on Mon Jul 08, 2013 10:58 am, edited 4 times in total.
Drakkhen
Active User
Active User
 
Posts: 71
Joined: Thu Sep 09, 2004 9:06 am
Location: Dry Land, Earth

Re: Invincible Guardian

Postby Assassin » Tue Feb 21, 2012 11:00 am

Uses 35 bytes of free space at C2/6780(Should be safe) and assumes a headerless rom.


Fixed. :P

a couple other issues with it (i haven't fully digested the code, so correct me if i'm wrong):

1) capping damage at 65535 before any of the modifications in the function that can further reduce damage (i.e. Genji Glove and Offering) means that when we're done with this function, we won't necessarily have made full use of our potential 0-65535 raw damage range. this can result in problems of too-low damage against high-Defense targets.

suppose we: cap a huge damage value of 100000 to 65535, reduce it to ~24575 since the attacker has both Genji Glove and Offering. the target has a high Defense of 192, so we reduce that damage by another 3/4, giving us ~6143 final damage (before randomization, anyway).

if we had waited until the END of this physical damage function to cap the 100000, we'd get ~37500 damage. then after Defense modifications, it'd become 9375. that's far away from the 6143.

now, you're capping at 32767, which means everything i've said above with the 65535 cap can only wind up worse in accuracy.

this is why my-and-Lenophis' patch in progress keeps the running damage at 24-bits for as much of the physical damage function as possible, waiting until the end of the math to cap. yes, the code is big and ugly. :/ but arguably worth it. :)

2) let's look at your C2/6790 (ignore the different addresses, i Tracer dumped it):

Code: Select all
00/8010: 29 00 FF     AND #$FF00
00/8013: D0 09        BNE $801E
00/8015: A5 E8        LDA $E8
00/8017: 6D B0 11     ADC $11B0
00/801A: 8D B0 11     STA $11B0
00/801D: 60           RTS


presumably, you don't want the final damage to exceed 16 bits. so if it already has before the addition of $11B0, you branch and cap it rather than adding in $11B0. ah, but what if the running value is just shy of exceeding 16 bits, and adding $11B0 makes it overflow? your code doesn't account for that.

here's an example.
---- skip to next dotted lines if you don't like sorta abstract stuff. -----
when multiplying multi-byte values, i like to pretend they're multi-digit decimal values to simplify things so i can check it on paper. in this case, we start with a 16-bit (2 byte) Attack and an 8-bit (1 byte) Level, and our running product is 24-bits (3 bytes). so let's use example input numbers of 2 digits and 1 digit in size, producing a 3-digit product.

let 2-digit Attack = 28
let 1-digit Level = 6

3-digit $e8 - $ea = 28 * 6 = 168
bottom digit(8) * 6 = 48
$11b0 = 4

3-digit $e8 - $ea = 16 * 6 = 96
96 + $11B0 = 96 + 4 = 100 (uh oh!)

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

ok, an example involving actual bytes that screws C2/6790 are Attack of 1784 and Level of 97. now, one obviously can't get Attack that high without hacking Level past 99 somehow. i'm not trying to strawman you into submission here... just saying that it'd be worth another overflow check in the end of the function to make it more robust. :P
User avatar
Assassin
Moderator
Moderator
 
Posts: 1195
Joined: Tue Sep 14, 2004 5:10 am

Re: Invincible Guardian

Postby Assassin » Tue Feb 21, 2012 12:47 pm

another thing: sorta related to #1, i suspect there could be a relative damage issue.

if the running damage is under 65535 but over 32767, you don't cap it. if it's over 65535, you cap it to 32767 (before adding in the 1-byte $11B0). so we could end up with a case where initial 70000 damage becomes < initial 50000 damage, after the capping takes place. not an issue unless the target has high Defense. but figured i'd note that you could have one damage "leapfrogging" another damage that should be larger than it.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1195
Joined: Tue Sep 14, 2004 5:10 am

Re: Invincible Guardian

Postby Drakkhen » Tue Feb 21, 2012 2:10 pm

Oops, my roms used to be headered...

This is what I get for coding at 4 in the morning.

ff3pdof2.ips Obsoleted

There, caps at 65535.

For a headerless rom, apparently.
Last edited by Drakkhen on Mon Jul 08, 2013 11:00 am, edited 2 times in total.
Drakkhen
Active User
Active User
 
Posts: 71
Joined: Thu Sep 09, 2004 9:06 am
Location: Dry Land, Earth

Re: Invincible Guardian

Postby Assassin » Tue Feb 21, 2012 6:12 pm

lookin' sharp. i like how you changed that LSR to a ROR, and how you reused part of your function with JSRs. the patch still has the issue described in #1 (though less pronounced than the first version) against high-Defense targets. my/Lenophis' patch will avoid such trouble with the ~24575-65535 value range, but it's also slated to consume an extra 70 bytes of free space. :/
User avatar
Assassin
Moderator
Moderator
 
Posts: 1195
Joined: Tue Sep 14, 2004 5:10 am

Re: Invincible Guardian

Postby Drakkhen » Tue Feb 21, 2012 9:36 pm

ff3pdof3.ips Obsoleted

A slightly bigger patch file size, but only 18 bytes of free space used. And with 2 bytes to spare in the original function.
Headerless, as before.

I should give this patch a proper release.
Last edited by Drakkhen on Mon Jul 08, 2013 11:00 am, edited 1 time in total.
Drakkhen
Active User
Active User
 
Posts: 71
Joined: Thu Sep 09, 2004 9:06 am
Location: Dry Land, Earth

Re: Invincible Guardian

Postby Assassin » Wed Feb 22, 2012 1:57 am

from the previous release:

Code: Select all
C0/0005: 20 81 47     JSR $4781
C0/0008: EB           XBA
C0/0009: 8D B0 11     STA $11B0
C0/000C: 9C B1 11     STZ $11B1
C0/000F: 60           RTS


from the current release:

Code: Select all
C0/0004: 20 81 47     JSR $4781
C0/0007: C2 20        REP #$20
C0/0009: 8D B0 11     STA $11B0

how is this equivalent? i thought you wanted the top byte of the product returned by C2/4781 to be in $11B0.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1195
Joined: Tue Sep 14, 2004 5:10 am

Re: Invincible Guardian

Postby Drakkhen » Wed Feb 22, 2012 9:33 am

ff3pdof4.ips Obsoleted

I sure hope I got it right this time, I'm running out of space optimizations.
Last edited by Drakkhen on Mon Jul 08, 2013 11:01 am, edited 1 time in total.
Drakkhen
Active User
Active User
 
Posts: 71
Joined: Thu Sep 09, 2004 9:06 am
Location: Dry Land, Earth

Re: Invincible Guardian

Postby Assassin » Wed Feb 22, 2012 9:57 am

so you're doing "AND #$FF" while in 8-bit mode? i don't think that does anything, aside from affect the flags. in the future, can you upload assembly code (assuming you have it, and aren't typing in opcodes by hand) along with the .IPS? it's a pain in the ass to have to dump a block of the modified ROM, then disassemble that block, for each and every revision.

EDIT: i think a simple "LDA #$00" can replace the "AND #$FF".
User avatar
Assassin
Moderator
Moderator
 
Posts: 1195
Joined: Tue Sep 14, 2004 5:10 am

Re: Invincible Guardian

Postby Drakkhen » Wed Feb 22, 2012 4:08 pm

ff3pdof.zip Obsoleted

Pretty sure I meant for that to be "AND #$00", but chopped off the wrong half.

ZIP file this time, including the IPS file and a disassembly of the affected areas.
Last edited by Drakkhen on Mon Jul 08, 2013 11:02 am, edited 1 time in total.
Drakkhen
Active User
Active User
 
Posts: 71
Joined: Thu Sep 09, 2004 9:06 am
Location: Dry Land, Earth

Re: Invincible Guardian

Postby Assassin » Wed Feb 22, 2012 4:42 pm

Code: Select all
C2/2BED: 20 67 47      JSR $4767

that should be:

Code: Select all
C2/2BED: 20 B7 47      JSR $47B7

i guess you had 67 on the brain from the function call right after it, to the ever-shrinking free space area. :P
User avatar
Assassin
Moderator
Moderator
 
Posts: 1195
Joined: Tue Sep 14, 2004 5:10 am

Re: Invincible Guardian

Postby Drakkhen » Wed Feb 22, 2012 5:25 pm

Fixed. Updated the zip file.
Drakkhen
Active User
Active User
 
Posts: 71
Joined: Thu Sep 09, 2004 9:06 am
Location: Dry Land, Earth

Re: Invincible Guardian

Postby Assassin » Thu Feb 23, 2012 10:29 am

regarding the pending release: with your other patches, you don't normally make FF6j versions, or include disassemblies. i think both would be worth it here, and can assist where needed. commented code would be better yet. btw, the recently-fixed JSR still has "20 67 47" listed in the disassembly's opcode bytes, but that's mostly a nitpick since the JSR appears right and was corrected in the patch.
User avatar
Assassin
Moderator
Moderator
 
Posts: 1195
Joined: Tue Sep 14, 2004 5:10 am

Re: Invincible Guardian

Postby Assassin » Thu Feb 23, 2012 10:57 am

Assassin wrote:a couple other issues with it (i haven't fully digested the code, so correct me if i'm wrong):

1) capping damage at 65535 before any of the modifications in the function that can further reduce damage (i.e. Genji Glove and Offering) means that when we're done with this function, we won't necessarily have made full use of our potential 0-65535 raw damage range. this can result in problems of too-low damage against high-Defense targets.

[...]

of course, there will be accuracy issues ANY time you cap, including when waiting until the end of the function to cap, as i've been advocating instead.

suppose there's no capping at all. say there's a character who was going to do 100000 raw damage. slap an Offering on them, and they'd be doing 50000 raw damage. with Drakkhen's capping in place, these damages become 65535 without the Offering, and 32767 with it. so both numbers are reduced, but the 2:1 ratio between them remains the same.

with my proposed capping in place, the character would be doing 65535 damage without the Offering, or 50000 with it. so the Offering damage is being altered less by capping than in the previous example, but i've utterly distorted the 2:1 ratio. not an issue in most cases, as these raw damages are still well above 9999, but against high-Defense targets, the skewed ratio will be apparent.

now, i still think that capping later rather than sooner in the function causes less distortion to the damage numbers on average. but i have to admit that either approach has its shortcomings. aside from making $11B0 into a 24-bit variable that persists between the various damage-related functions, there's really no way to avoid this entirely.

wish i was handier with Excel graphs; then i'd cobble together three for comparison...
User avatar
Assassin
Moderator
Moderator
 
Posts: 1195
Joined: Tue Sep 14, 2004 5:10 am

Next

Return to ROM Hacking and Emulation

Who is online

Users browsing this forum: No registered users and 1 guest

cron