News:

11 March 2016 - Forum Rules

Main Menu

Final Fantasy II Restored

Started by redmagejoe, December 10, 2019, 03:09:14 AM

Previous topic - Next topic

flamefury

#640
Quote from: abw on May 01, 2022, 06:54:10 PM
Sometime shortly after that the formula was updated to divide the sum of skill levels by 8, becauseis exactly how it works, and that was indeed way overpowered :D.

"Working like a normal unresistable spell" translates to "spell power is increased by floor(caster's Spirit / 4)" + "average number of hits = spell level + spell level * accuracy %" + "target's magic evasion is ignored", so the formula for Ultima looks more like:

spell power = 25 + floor(caster's Spirit / 4) + floor(sum(caster's skill levels) / 8) [skill levels are 0..15, not 1..16]

and then that spell power gets passed in to the standard routine for unresistable spell damage:

average damage = (spell power * (1 + random(0..spell power)) + spell power * 0.05) * (spell level * accuracy %)

So in the PSP formula, it looks like the base damage value incorporates most of the damage calculation, and the average damage is basically the base damage * 1.05, but in the NES version, the spell power is part of a larger calculation, and the average damage is basically (spell power * 1.55) * number of hits.

The damage functions scale very differently (PSP is quadratic in skill levels vs. linear in ours), but in general, the PSP version appears to be more powerful than our current version for low levels of Ultima (where the +100 dominates) regardless of the caster's overall power and when the caster has at least 50% of their maximum power (where the skill level squared dominates) regardless of Ultima's level.

I'm still not sure how you're coming to the conclusion that PSP version is more powerful at lower levels. Reminder that the +100 is not multiplied by Ultima's level. It's only relevant for very low level sums.

Even against a 25 power spell with no bells or whistles (other than always having 2*spell level hits), you would need a sizeable amount of skill+magic levels to overpower it decisively:



EDIT: Also, later releases also only use magic "evasion" though it's called defense. There's no way to lower the damage from a magic hit outside of element resist, you can only avoid magic hits to reduce damage from the spell cast overall, but each hit is more or less set on how much it will deal.

abw

Quote from: flamefury on May 02, 2022, 03:32:52 PM
I'm still not sure how you're coming to the conclusion that PSP version is more powerful at lower levels. Reminder that the +100 is not multiplied by Ultima's level. It's only relevant for very low level sums.
Try using the entire damage formulae, including critical hits and random boni. Assuming I've got enough mental energy left to do this correctly, the average damage from the PSP version based on https://finalfantasy.fandom.com/wiki/Ultima_(Final_Fantasy_II) should be:

<Average Damage> = (<Ultima Level> * (<Tier> + floor(<Tier> / 2)) ^ 2 + 100) * 1.05 + 0.5 * ((<Ultima Level> * (<Tier> + floor(<Tier> / 2)) ^ 2 + 100) % 256)

giving (rounded to the nearest integer):

Ultima Level / Tier012345678910111213141516
1155157169180211231281310378289376424529587583649792
2155158183205267307278337473551597693903890113811431429
315516019722932238340449256968581796111501322156616381937
41551612112543783315296477928191166123015241625199322602574
515516322527930640765567488710811387149918982057242127543211
6155164239304362483652829111012151608176822722488297632483848
7155166253329418559778856120513491828203725182792340437424357
81551672673534736359031011142916112049230528933223383142374993
91551692813785295839011166152417452270257432673527438747315630
1015517129527558565910271193161920072491284335133959481552256267
1115517230830064173411521348184221402711311238874390524257196776
1215517432232556981011501375193722743060338142614694567062137413
1315517533634962488612751530216125363281364946365125622568368049
1415517735037468083414011685225626703502391848825429665373308686
1515517836439973691013981712247928043722418752565860708078249195
1615518037842479298615241867257430663943445656306292763683189832

Based on those numbers, however, I'm questioning whether the linked formula is correct, as the damage growth from one tier to the next is pretty erratic and there are several places where gaining a tier actually reduces the average damage (e.g. at tier 9, Ultima 1 does about 90 damage less than at tier 8 since tier 9's maximum random damage = ((9+4)^2+100)%256 = 13 vs. tier 8's ((8+4)^2+100)%256 = 244).

Our version takes an extra variable (caster's Spirit), so to try to keep the comparison somewhat even, let's define a tier for our version as a percentage of the caster's combined skill + stat power out of a total of 16, so e.g. a caster with a total of 24 * 16 = 384 skill points and 99 Spirit has a tier of 16, a caster with 192 skill points and 50 Spirit has a tier of 8, etc. It's not entirely a fair comparison since Spirit is both easier to raise and has a larger marginal effect on average damage than do skill levels, but it's good enough for hand-waving. In that case, the average damage from our version should be:

<Average Damage> = (<Ultima Level> * (1.5 + min(0.5, <Tier> / 16))) * (25 + floor(99 * <Tier> / 16 / 4) + floor(24 * (<Tier> - 1) / 8)) * 1.55

giving (rounded to the nearest integer):

Ultima Level / Tier012345678910111213141516
158637892109124142159180192208223236251264279291
2116126156183217247285318360384415446471502527558583
3174189234275326371427477539577623670707753791837874
42332523123664344945706377197698318939421004105411161166
52913153904585436187127968999611039111611781256131813951457
6349378468549651742854955107911531246133914141507158116741748
74074415476417608659971114125913451454156216491758184519532040
846550462573286898911391273143815381662178618852009210822322331
9523567703824977111312821432161817301869200921202260237225112623
105816307819151085123614241592179819222077223223562511263527902914
1163969385910071194136015661751197821142285245525922762289930693205
1269875693710991302148317091910215823062492267828273013316233483497
13756819101511901411160718512069233724992700290230633264342636273788
14814882109312821519173119942228251726912908312532983515368939064080
15872945117113731628185421362387269728833116334835343767395341854371
169301008124914651736197822792547287730753323357137704018421644644662

The damage growth here is much less erratic, plus if we drop the tier simplification and look at the base skill levels and Spirit stat, we get damage growth with every 8 skill levels (vs. 24 for PSP) and every 4 points of Spirit; furthermore, every point of Spirit increases accuracy by 1% (up to a cap of 50% since Ultima has a base accuracy of 50%, but Spirit beyond 50 is still useful for counteracting accuracy reduction due to equipment penalties), making extra hits more likely and raising the average damage.

As for expected player stats/skill levels, our version of Ultima is the same in both the Bug Fix and Restored patches, but Restored's passive skill growth makes it pretty easy to have level 7+ in all weapon skills and level 9+ in all spell skills by the endgame, plus whatever levels you get from active usage. Give Ultima to somebody with a decent Spirit stat, and they'll likely be dealing damage around the tier 10 level with Ultima 8+, at which point the PSP version deals about 400 more damage (~20%). Of course, there are only about a dozen monsters in the entire game that have high enough max HP for that 400 damage to make a difference :P.

flamefury

#642
Quote from: abw on May 08, 2022, 12:47:19 PM
Try using the entire damage formulae, including critical hits and random boni. Assuming I've got enough mental energy left to do this correctly, the average damage from the PSP version based on https://finalfantasy.fandom.com/wiki/Ultima_(Final_Fantasy_II) should be:

<Average Damage> = (<Ultima Level> * (<Tier> + floor(<Tier> / 2)) ^ 2 + 100) * 1.05 + 0.5 * ((<Ultima Level> * (<Tier> + floor(<Tier> / 2)) ^ 2 + 100) % 256)

giving (rounded to the nearest integer):

Ultima Level / Tier012345678910111213141516
1155157169180211231281310378289376424529587583649792
2155158183205267307278337473551597693903890113811431429
315516019722932238340449256968581796111501322156616381937
41551612112543783315296477928191166123015241625199322602574
515516322527930640765567488710811387149918982057242127543211
6155164239304362483652829111012151608176822722488297632483848
7155166253329418559778856120513491828203725182792340437424357
81551672673534736359031011142916112049230528933223383142374993
91551692813785295839011166152417452270257432673527438747315630
1015517129527558565910271193161920072491284335133959481552256267
1115517230830064173411521348184221402711311238874390524257196776
1215517432232556981011501375193722743060338142614694567062137413
1315517533634962488612751530216125363281364946365125622568368049
1415517735037468083414011685225626703502391848825429665373308686
1515517836439973691013981712247928043722418752565860708078249195
1615518037842479298615241867257430663943445656306292763683189832

Based on those numbers, however, I'm questioning whether the linked formula is correct, as the damage growth from one tier to the next is pretty erratic and there are several places where gaining a tier actually reduces the average damage (e.g. at tier 9, Ultima 1 does about 90 damage less than at tier 8 since tier 9's maximum random damage = ((9+4)^2+100)%256 = 13 vs. tier 8's ((8+4)^2+100)%256 = 244).

Our version takes an extra variable (caster's Spirit), so to try to keep the comparison somewhat even, let's define a tier for our version as a percentage of the caster's combined skill + stat power out of a total of 16, so e.g. a caster with a total of 24 * 16 = 384 skill points and 99 Spirit has a tier of 16, a caster with 192 skill points and 50 Spirit has a tier of 8, etc. It's not entirely a fair comparison since Spirit is both easier to raise and has a larger marginal effect on average damage than do skill levels, but it's good enough for hand-waving. In that case, the average damage from our version should be:

<Average Damage> = (<Ultima Level> * (1.5 + min(0.5, <Tier> / 16))) * (25 + floor(99 * <Tier> / 16 / 4) + floor(24 * (<Tier> - 1) / 8)) * 1.55

giving (rounded to the nearest integer):

Ultima Level / Tier012345678910111213141516
158637892109124142159180192208223236251264279291
2116126156183217247285318360384415446471502527558583
3174189234275326371427477539577623670707753791837874
42332523123664344945706377197698318939421004105411161166
52913153904585436187127968999611039111611781256131813951457
6349378468549651742854955107911531246133914141507158116741748
74074415476417608659971114125913451454156216491758184519532040
846550462573286898911391273143815381662178618852009210822322331
9523567703824977111312821432161817301869200921202260237225112623
105816307819151085123614241592179819222077223223562511263527902914
1163969385910071194136015661751197821142285245525922762289930693205
1269875693710991302148317091910215823062492267828273013316233483497
13756819101511901411160718512069233724992700290230633264342636273788
14814882109312821519173119942228251726912908312532983515368939064080
15872945117113731628185421362387269728833116334835343767395341854371
169301008124914651736197822792547287730753323357137704018421644644662

The damage growth here is much less erratic, plus if we drop the tier simplification and look at the base skill levels and Spirit stat, we get damage growth with every 8 skill levels (vs. 24 for PSP) and every 4 points of Spirit; furthermore, every point of Spirit increases accuracy by 1% (up to a cap of 50% since Ultima has a base accuracy of 50%, but Spirit beyond 50 is still useful for counteracting accuracy reduction due to equipment penalties), making extra hits more likely and raising the average damage.

As for expected player stats/skill levels, our version of Ultima is the same in both the Bug Fix and Restored patches, but Restored's passive skill growth makes it pretty easy to have level 7+ in all weapon skills and level 9+ in all spell skills by the endgame, plus whatever levels you get from active usage. Give Ultima to somebody with a decent Spirit stat, and they'll likely be dealing damage around the tier 10 level with Ultima 8+, at which point the PSP version deals about 400 more damage (~20%). Of course, there are only about a dozen monsters in the entire game that have high enough max HP for that 400 damage to make a difference :P.

EDIT: Whoops I was asleep, my other calc here was wrong.

Just to visualize the times when tier increases lower damage (blue beside orange) and Ultima level increases lower damage (green ontop of red):


Re the linked Ultima formula being wrong, it's definitely possible I made a mistake, but I'm fairly confident my hacking was right. You can double-check my work if you like (don't mind some of the comments around the 0~99 and random bonus roll, I made them before I deciphered what it was doing):
https://pastebin.com/rie8YhB6

Or if you want to hack it yourself, the addresses are 0x0893298c (most likely the generic spellcast function) and 08932d08 (random damage and critical hit check function) in ULUS10263.

The thing causing the damage drops on some Ultima levels and some tier jumps is the mod 256 random bonus. But I'm near certain that this part I understood correctly.

andi a0,s3,0xFF     # s3 = base damage, get the lowest bits of damage, save into a0
pos_08932D74:
jal z_un_088a6470  # Rolls 0~a0(=damage % 256) for random damage bonus, outputs into v0
andi s4,s3,0xFFFF   # Copies base damage into s4
andi v0,v0,0xFF     # Not necessary, but capping v0 to 255
addu v0,s4,v0       # Adding into s4 for running sum of damage


EDIT2: Now that I look at this, I understand what's happening. This is the same function that controls damage hits, Ultima is coded as a single damage hit. However, everything else in the game would be capped at 255 power (eg, normal attacks, other spells, etc.) and the random bonus for each of their individual hits has a range of Power to 2*Power. That's this randomized bonus.

This breaks on Ultima because it's a single hit that can go beyond 255, causing its damage to fluctuate around even as its level and tier increases.

abw

Ha, that's actually a bug from the NES version (which we've fixed) that has persisted through to the PSP version :P. In the NES version, it can be triggered by physical attacks with weapons that deal bonus elemental or family damage and push the base damage per hit above 255; just as in the PSP version, the random bonus only operates on the low 8 bits rather than the full 16 bits. Fixing the PSP version's random bonus would increase its average damage and push it even further beyond our version's.

I'm leaning towards keeping our version as-is for now, but the PSP formula is definitely a great find and something to keep in mind if/when rebalancing the game.

flamefury

Yeah you'd probably have to make up another randomization function just for Ultima. I doubt they ever wanted it to randomly do (base damage ~ 2 * base damage) because that would be completely insane in terms of damage output.

Maybe something more like a randomization cap that's determined as a function of Ultima level and the level sum, starting at 0 when level sum tier is 0 and Ultima 1 and then capping out at 255 (or 510 or something like that) when the level sum tier is capped and Ultima 16.

Mirage

On the subject of Ultima, would it be possible to break up the Ultima-level-dependent part of the damage formula into individual hits and then tack on the base 100 damage at the end? I'm curious on how having multiple lower-damage hits would affect the randomization and critical damage parts of the formula.

AwesomeHairo

Hi everyone. I was able to remove Firion, or whatever you name him, from when the whole party gets wiped out. Thanks for that, abw.

Something else I want to do is move Battle Message, Message 9 (まほうは つかえません) a bit more to the left the Magic submenu in battle is opened.



Is this possible?

Also, for Misc 1, Message 15 (????), is this unused? I've never found this in any capacity. And for Misc 2, Message 30, can [14][00] (for example, [14][06]) be used to save space for Misc 2?

And by the way, I've completed every modification I wanted to regarding text. If anyone is interested in looking over my script to improve any existing translation that has been uploaded, I would be more than happy to provide. I usually aim for a "60% localised, 40% literal" approach.

Everything

Here is the code that sets the text position for the battle message in your screenshot. The ROM offset for this is 0x031EF2.

0C/9EE2: A9 00     LDA #$00
0C/9EE4: 85 76     STA $76
0C/9EE6: A9 15     LDA #$15
0C/9EE8: 85 68     STA $68
0C/9EEA: A9 08     LDA #$08           ; $08: "No Magic..."
0C/9EEC: 85 66     STA $66
0C/9EEE: A9 58     LDA #$58           ; <- try changing this to LDA #$56 to shift the text left by 2 tiles
0C/9EF0: 85 67     STA $67
0C/9EF2: 4C 2F 97  JMP $972F          ; load battle text

abw

Quote from: flamefury on May 14, 2022, 10:27:43 PM
Maybe something more like a randomization cap that's determined as a function of Ultima level and the level sum, starting at 0 when level sum tier is 0 and Ultima 1 and then capping out at 255 (or 510 or something like that) when the level sum tier is capped and Ultima 16.
Quote from: Mirage on May 14, 2022, 11:49:02 PM
On the subject of Ultima, would it be possible to break up the Ultima-level-dependent part of the damage formula into individual hits and then tack on the base 100 damage at the end? I'm curious on how having multiple lower-damage hits would affect the randomization and critical damage parts of the formula.
Little adjustments like these would help smooth out the damage curves and fix the issue with stronger stats/levels sometimes reducing damage output, but the overall properties remain the same (at low power, the + 100 dominates but Restored is stronger, at high power the (<Tier> + floor(<Tier> / 2)) ^ 2 dominates and PSP is stronger). You can run graphs all day long if you like ;).

Quote from: AwesomeHairo on June 02, 2022, 01:56:50 PM
Hi everyone. I was able to remove Firion, or whatever you name him, from when the whole party gets wiped out. Thanks for that, abw.
I'm not entirely sure what you're referring to here, but assuming that's not an oblique bug report, you're welcome :thumbsup:.

Quote from: AwesomeHairo on June 02, 2022, 01:56:50 PM
Something else I want to do is move Battle Message, Message 9 (まほうは つかえません) a bit more to the left the Magic submenu in battle is opened.
Everything already answered this, but I'll add that if you search for まほうは つかえません in the disassembly, you'll find it referenced at $0C:$9EEA, and although the commentary for that block of code is not as verbose as it could be, there is enough of it to be able to tell that $67 is the write offset in the CHR buffer for diplaying the string.

Quote from: AwesomeHairo on June 02, 2022, 01:56:50 PM
Also, for Misc 1, Message 15 (????), is this unused? I've never found this in any capacity.
I believe so. The "????" item appears to be unused, so its name should never appear in-game anywhere.

Quote from: AwesomeHairo on June 02, 2022, 01:56:50 PM
And for Misc 2, Message 30, can [14][00] (for example, [14][06]) be used to save space for Misc 2?
The easiest way to find out for sure would be to try it, but I suspect it will work - any string that goes through the main string display code at $0F:$EAE6 should be able to use any of the generic control codes without requiring any additional setup code.

Quote from: AwesomeHairo on June 02, 2022, 01:56:50 PM
And by the way, I've completed every modification I wanted to regarding text. If anyone is interested in looking over my script to improve any existing translation that has been uploaded, I would be more than happy to provide. I usually aim for a "60% localised, 40% literal" approach.
I can't promise I'll get to it any time soon, but I'd be interested in reading it!