hmsong

SD3 Spell Balance patch

167 posts in this topic

9 hours ago, praetarius5018 said:

I mean technically you could change it to a fixed rate or change the luck-in-X rate from 100 to say 255.
And the +50% damage could be turned into +25%, that would be a one-byte change.
The major issue (for you) would be actually loading the luck value for the crit rate instead of the constant 0. THat would need some bytes of unused space somewhere.

Wow, implementing those two things would work greatly (probably).  255 is much more reasonable than 100 (that means crit maxes out at ~8.6%).  Fixed isn't bad either (5% sounds about right -- if I can't load the luck stat, I'll go with that).  And changing to +25% damage would work great too.  I need to test that though -- could you please tell me which byte I need to change?  I assume the address I need to change is D0CAE1~E2.

As for the unused space... I'm just gonna take a wild guess, but would I be able to use any space where there's bunch of collection of FFs? (105720~105FFF, 10B5E0~10BFFE, 112860~112A3F)  Or would I need 00s space? (11D630~11D6CF)  I don't know what is unused.  I just randomly chose D0xxxx~D1xxxx, because I have a vague feeling that that's where anything is supposed to happen.  I'm honestly not sure.  How much space would I need?

Edited by hmsong

Share this post


Link to post
Share on other sites

And that exactly is where it gets interesting.
Is it unused? Is it a black square of a graphic? Placeholder mob data?

Whether unused space is FF, 00, EA, or something else is different for each game.
Might even be different within the same game.

For a quick check I'd look at the last few bytes if they can be return codes for routines.
The most sane options for routine enders are:
6B - rtl, return for a routine usually called from a different bank (chuck of xx0000-xx7FFF or xx8000-xxFFFF), basically a public function in programming terms
60 - rts, return for a function that must live in the same bank, basically a private function
4C yy xx - jmp, goto xxyy in same bank
5C zz yy xx - jmp, goto xxyyzz for any location

Lets ignore the madness that would be function calls that rip out the return value from the stack and replace the return location..

  1. 105720 - the preceding bytes have neither of those options, could actually be legit data.
  2. 10B5E0 - might be usable, the last bytes before ff look like usual SD3 code
  3. 112860 - same as the first

Personally I'd prefer the end of 13Fxxx.
D3/xxxx is where a majority of the compressed AI code lives and FFs to that amount is not a useful operation.

So wanna do this?
Don't say I didn't warn you, I'm not a teacher.

First of, this is your bible. It tells you what hexcodes are what real operation.

Second, you need an emulator with debugging abilities, I use Snes9X v1.51.ep10r1 - Geiger's Snes9x Debugger.
Srm save files are compatible between emulators so you should at least transfer your savefile so you have some save games to work with. Preferably at least a post godbeast save so you have enough techs/spells and can quickly check every shop and whatever else you may need.

Third, grab a list with cheats, this helps finding the relevant code areas faster and if the list is good it already has the ids for items or spells you may need at some point.

Important stuff to know:

  1. if the M flag is on (big M) operations related to the value in A only use 8 bit mode, if it is off (small m) 16 bit. SEP 20 turns it on and REP 20 off. This also affects the lengths of some instructions since the extra 8 bits need to be written as well.
  2. you usually want to end your modification with the same CPU flags as you started (any SEP undone via REP and vice verca)
  3. everything you add to the stack (e.g. PHA) should be removed again before you end your modification (e.g. PLA)
  4. avoid crossing bank borders (never go past a xxFFFF)

D0/CACA is where the crit rate is loaded. Put an execution breakpoint there in the debugger and then try to hit something. Try step into a few times to see what happens next.

 

Overwrite the 4 bytes at D0/CACA in the rom with 22 zz yy xx where xxyyzz (watch snes writing and order!) is the location where you place your code.

And the location with free space you want the byte equvalent of:
LDY #$00E2 //offset for crit rate, note that the offsets for attacker and target are different because SD3...
LDA ($2A),y //loads the crit rate in this case; $2A is in the pointer to the attacker
AND #$00FF (crit rate is 8 bit but the mode is 16 bit so we need to cut off the excessive bits)
LDY #$00F3 //this was the result of Y in the section we overwrote and it may be used later
RTL //return to where we came from

so:

Spoiler

A0 E2 00 B1 2A 29 FF 00 A0 F3 00 6B

You could do this conversion autoamtically with something like xkas but I think it is better to do this a few times manually to better understand what is going on.

If you now reload the rom and try to hit something again it should give you a non-0 crit rate.

Run the same breakpoint as before and continue until the game wants to call code from C00620 this is an RNG function in SD3 and the value in A holds the range that the result should be in.
With that you should've seen where the value for A came from and can modify it to adjust the range as you want.

Last the crit damage.
Run the breakpoint again up to the RNG call and step over it.
It should be followed by a CMP $1A BCS $18, $1A holds our crit rate.
Now depending on the result the code will either branch forward $18 bytes or not.
If it doesn't jump forward that many bytes it is a critical hit.
Note how the result of the RNG call must be equal or smaller than our crit rate.
The modification to the damage (specifically attack power before defense) is handled like this:
LDA $1C 
LSR A (divide A by 2)
CLC (clear carry/overflow)
ADC $1C
STA $1C

$1C hold the current attack power (you can see that if you follow the code a long while backwards). Now we can replace the CLC with another LSR A.
This would change the bonus from 50% to 25% but add the chance for an off-by-1 error because we no longer remove the carry flag which means it may add another +1 at the ADC $1C step if that flag was set.
Since damage has a range anyway and +1 is near nothing I see no need here to create another call to currently unused space and creating a routine there.

 

Now time for homework:
change
D0/C97A 0C to 0A
D0/D83B 03 to 05
and
D/0C983
85 1A B0 03 A9 00 00 D0 01 1A to
B0 03 A9 00 00 4A EA 1A 85 1A

What have I done?
Hint: breakpoint a few bytes before each and try with and without the most OP buff.

Edited by praetarius5018

Share this post


Link to post
Share on other sites

Oh my god...

I took a look at 65816 Reference (the bible).  I couldn't even understand the 1st table.  I feel like this page assumes the viewer already knows the basics of these... codes and terms (such as the definition of "Mnemonic" or "binary value").  I am so lost.  I feel like I've been given a text book about PhD on advanced physics, when I barely passed high school physics class (15 years ago).  I'm afraid I may need something more... basic.

Well, I got the debugger snes9x (I can only find ep10r2).  I can't even open it though... (included picture)  "Side by side config"?  "Event log"?  What is the computer talking about?

I don't understand what "execution breakpoint" means.  Boy, this is a train wreck.  =::(

Maybe I'm in way over my head with trying to implement Luck to critical.  I feel like I'm too unskilled for this.  I feel... hopeless.  I'm looking at a pit, and it's bottomless.

Sigh.  Is making AGI work (well, Acc/Eva) just as complicated?  That's of higher priority than critical (since several spells are literally useless).

01.png

Share this post


Link to post
Share on other sites

I know I couldn't get 10.2 running either that's why I said 10.1, but I'm on W7 still so no idea how to help you there.

13 minutes ago, hmsong said:

Is making AGI work (well, Acc/Eva) just as complicated?

No, AGL is worse, this is just warm up.

Edited by praetarius5018

Share this post


Link to post
Share on other sites

Wow.  I googled, "Snes9X v1.51 "ep10r1" Geiger Debugger", and I only got 2 hits.  That's a first.  I always get a ton of hits on anything.  And I only got 2 hits (total of 6), and they're all in Japanese.  With no links to the download.

Uhh, can you upload ep10r1?  Apparently, GOOGLE doesn't have it.

Share this post


Link to post
Share on other sites

Thanks.  I guess I just suck at finding stuff.

Figuring out your instructions may take some time.  It's a lot to process.  I'll try my best.  Started by reading some elementary materials (google).

Btw, is there a way to reduce the amount Aura Wave is giving to the Tech bar?  It fills 9 bars, but I much prefer it do less (7 if fixed, 6 if not).  I tried to reduce D19C4C, but it's not having any effect (it still fills the bar all the way).  Is there some "quick fix" to do that for vanilla?  Or any other way to reduce the OP-ness of Aura Wave (while still having something to do with the tech bar).

Edit:  I see that Sin of Mana already has that.  I don't know what "+1 tech buff" means, but I'm still interested in how you changed the bar fill-ness from the spell.  Could you please tell me?

Edited by hmsong

Share this post


Link to post
Share on other sites

all i know is if u change D0C588  04 to 00,you can use lv1 tech always after u got 4 TP

Share this post


Link to post
Share on other sites

10DACF:E7 03          10DAD4:E7 03    attack limit

10DBD9:3C             10DBDD:3C    evade limit (bug) u know that

10DBFB:2C 01          10DC00:2C 01 defense limit 

10DC1D:2C 01          10DC22:2C 01   magic def (elements)

10DC43:2C 01          10DC48:2C 01 magic def (lihgt and dark?)not sure

d2d770-d2d8e0   characters tech learn (very simple figure out)    01=one 03=all     and tech code

that is all i know and experience  address 

 

Share this post


Link to post
Share on other sites
8 hours ago, hmsong said:

Btw, is there a way to reduce the amount Aura Wave is giving to the Tech bar?  It fills 9 bars, but I much prefer it do less (7 if fixed, 6 if not).  I tried to reduce D19C4C, but it's not having any effect (it still fills the bar all the way).  Is there some "quick fix" to do that for vanilla?  Or any other way to reduce the OP-ness of Aura Wave (while still having something to do with the tech bar).

There is a way.
The code is at D0/E586, after the homework above you should be able to figure it out.
The vanilla code just loads the current maxTP and shoves it into both currentTP values.
Don't ask me why it needs 2 TP values, at some points it checks one, at other points the other.

24 minutes ago, shiliwei said:

10DC1D:2C 01          10DC22:2C 01   magic def (elements)

10DC43:2C 01          10DC48:2C 01 magic def (lihgt and dark?)not sure

One is the (INT based) m.def for INT based spells, the other is the hidden (PIEbased) m.def for PIE based spells.

Also all of these are imcomplete. The cap value is there twice, once for the value it checks against and once for the value it then loads as the final value.
With what you've given you could only create stat spikes, like if def > 150 def = 300; but not the intended if def > 150 def = 150.

Edited by praetarius5018

Share this post


Link to post
Share on other sites
8 minutes ago, praetarius5018 said:

One is the (INT based) m.def for INT based spells, the other is the hidden (PIEbased) m.def for PIE based spells.

thank you!!

and i know why i can't use tech now.

u can't use tech if all TP got form enemy missed. that is why i can't use tech every time against boss. cuz i use spell all the time in beginning.

Share this post


Link to post
Share on other sites

Thank you, to both of you.

Sigh.  The more I read about hacking, the more I realize how difficult it is for me to really understand all this hacking knowledge.  A strong part of me wishes that there was a bug fix patch for the official Trials of Mana (I'm not expecting it, since almost nobody is working on that game).  I mean, as Soul Knight said, I ended up creating something that's mostly for Trials of Mana.  But with all the bugs present (some more devastating than others), most people will just go back to fan translation.  Hence why I'm trying to incorporate many of the bugs in my patch.  This is going to take a long time for me to learn.

Share this post


Link to post
Share on other sites

Oh my god.  I see you released a bug patch 1.3 on RHDN.  Several questions:

  1. Is that compatible with Trials of Mana?
  2. I have No Skill Counter on my balance patch, but would your bug patch overwrite that?  Which takes priority?
  3. In my balance patch, I changed several things (stats and skills) in Kevin's D classes.  Apparently, Bashkar and Deathhand got mixed up in the menu (which you corrected), but would that affect which character has which stat and/or skills?

Share this post


Link to post
Share on other sites
7 hours ago, hmsong said:

Is that compatible with Trials of Mana?

Didn't test.

7 hours ago, hmsong said:

I have No Skill Counter on my balance patch, but would your bug patch overwrite that?  Which takes priority?

Since both our edits are applied to different locations: both.

7 hours ago, hmsong said:

In my balance patch, I changed several things (stats and skills) in Kevin's D classes.  Apparently, Bashkar and Deathhand got mixed up in the menu (which you corrected), but would that affect which character has which stat and/or skills?

I ONLY switched what is displayed in that menu, so Deathhand is still Deathhand, stats and skills and all.

Share this post


Link to post
Share on other sites

Thanks.  I'm sure you had mixed feelings about releasing the bug fix patch.  I truly appreciate that you decided to do so.

For last several days, I tried to find some resource to learn about hacking.  I'm sad to say that none of them really helped much.  Very far from anything that was covered in the "bible".  The only thing that I found useful was the video about pointer table, which somewhat helped me understand... some parts of your bug fix patch, regarding what the address an another address was pointing to (not that I know what specific thing those addresses/valuees did).

Sigh.  I'm throwing in the towel.  Hacking things to create working criticals and agility that is compatible with Trials of Mana is beyond my ability.  I simply lack the prerequisite knowledge to even understand the "bible", and nothing I can find seems to help me understand that.  I have no choice but to use the fan translation if I want to play the bug fixes version.  I truly thank you for even trying to help me (esp that long explanation above).  But for now, I'll just stick with minor tweaks that's within my ability.

So... could you please tell me how to make Aura Wave fill only 6 bars? (7 if fixed)

Quote

I mean technically you could change it to a fixed rate or change the luck-in-X rate from 100 to say 255.

I assume you didn't do that for the bug fix 1.3 patch.  So, how do I make it to 255?  And would that affect Energy Ball critical rate? (I think you said you made it +10%, just like SoM, but I'm guessing that was based on 100)  Obviously, it's not for any of my public patches, since other than the obvious moral reasons, that's no good by itself anyways.  I'm just going to use it for my private usage to simply play the game.  Just gonna enjoy playing the game.

And thanks for reducing the critical rate to 25%.  And reducing the stat up/down to 20% (that ought to balance things a bit).

Edited by hmsong

Share this post


Link to post
Share on other sites
On 5/28/2020 at 9:41 AM, hmsong said:

So... could you please tell me how to make Aura Wave fill only 6 bars? (7 if fixed)

Find some free space as described above. I suggest the end of D3/xxxx.

B1 34 18 69 06 D1 36 90 02 B1 36 91 34 6B

D0/E589 B1 36 91 34 -> 22 zz yy xx, where xxyyzz (in that order!) is the address your code will go to.

On 5/28/2020 at 9:41 AM, hmsong said:

I assume you didn't do that for the bug fix 1.3 patch.  So, how do I make it to 255?

One last try.

Take the debugger, put a write breakpoint at D0CACA, try to hit an enemy, the game should stop.
Use "step into" until you reach an instruction for JSL $C00620. The LDA #$0065 before that is the range used (+1 because reasons).

Share this post


Link to post
Share on other sites

Aura Wave worked!  I don't know the logic behind it, but it worked.  Many thanks!

Quote

Take the debugger, put a write breakpoint at D0CACA, try to hit an enemy, the game should stop.
Use "step into" until you reach an instruction for JSL $C00620. The LDA #$0065 before that is the range used (+1 because reasons).

I wrote a breakpoint at D0CACA (pic 2) and then hit an enemy, but the game did not stop.  I clicked on "step into" and got pic 3, but it didn't say anything about LDA #$0065 (it says LDA #$0000).

One of the biggest problem is that I don't know know what numerous vocabularies are, in practical knowledge.  What is JSL?  What is LDA#0065?  I mean, I know "LDA #const" means, "Load Accumulator from Memory" -- that's from the bible -- but I have no idea what that actually means in hex edit (or what it's suppose to represent).  The only thing I know how to do is edit the hex numbers using HxD.

2.png

3.png

Share this post


Link to post
Share on other sites

Try again with the breakpoint set as execute.

Execute - when the address is to be executed as code
Read - when the game wants to read from that address in store it into variable A,X or Y
Write - when the game wants to write to that address, if for some reason a value is to be stored at a ROM address we're in massive trouble, at best the emulator crashes.

If in doubt check all three.

21 minutes ago, hmsong said:

One of the biggest problem is that I don't know know what numerous vocabularies are, in practical knowledge.  What is JSL?  What is LDA#0065?  I mean, I know "LDA #const" means, "Load Accumulator from Memory" -- that's from the bible -- but I have no idea what that actually means in hex edit (or what it's suppose to represent).  The only thing I know how to do is edit the hex numbers using HxD.

That's what that page should help with:

JSL Jump to Subroutine 22 Absolute Long   4

JSL is the asm representation

Jump to Subroutine - explains what it does: continue code execution at the address given. *

22 is the hex representation

absolute long means this code expects an explicit address, all 3 bytes

4 tells you how many bytes the full instruction needs, it this case 22 as the instruction + 3 bytes for the address to be used

 

*for longer explanations of what the codes mean search for the asm code and you'll find lower on the page:

JSR - Jump Subroutine

JSL - Jump Subroutine Long

If you already know a programming language, this is basically calling a function. This performs the same as JMP except the address of the current program counter is saved. In subroutines, the RTS and RTL are used to return back to the saved address.

Share this post


Link to post
Share on other sites

Hmm.  As soon as I put the breakpoint on D0CACA, the game froze (before I got the chance to hit any enemy) and gave me this result (pic 04).  And it still didn't give me " JSL $C00620" result, no matter how many times I pressed "Step Into" (pic 05).

04.png

05.png

Share this post


Link to post
Share on other sites

Good, when the game freezes that way it has reached the breakpoint, now you have to the other instruction I gave:

On 5/29/2020 at 6:47 PM, praetarius5018 said:

Use "step into" until you reach an instruction for JSL $C00620. The LDA #$0065 before that is the range used (+1 because reasons).

 

Share this post


Link to post
Share on other sites

Yes, I pressed "Step Into" (multiple times).  The problem is, I didn't see the instruction for JSL $C00620 (2nd pic of the previous post).  It gave me bunch of other stuff, such as LDX #00E3.

Also, what is "instruction" for JSL$C00620?  I don't think it's telling me what to do or anything.

Wuw, I feel like I'm talking to you real time.

Edited by hmsong

Share this post


Link to post
Share on other sites

Go on, follow the code a bit more.
Rarely is anything as simple as finding it directly within 2-3 instructions.

Clipboard01.png.277178a335ca89942e6207a3406895a2.png

25 minutes ago, hmsong said:

Also, what is "instruction" for JSL$C00620?

Exactly that JSL $C00620.

Share this post


Link to post
Share on other sites

Oh.  Okay.  Got it (just as you said).  But now what do I do?  Since crit is out of 100, I thought I'd see hex number 64 somewhere, I but I don't.  Even in at C00620.

05.png

Perhaps I'm jumping ahead, but according to what you posted above, I'm supposed to overwrite the 4-byte values at D0CACA with 22 zz yy xx, so if I were to do so at the end of bank D3 (let's say D3F140), then I'd be overwriting that with 22 40 F1 13.  And at D3F140 (it's currently full of FFs), I'd be overwrite the next few bytes with:

Spoiler

A0 E2 00 B1 2A 29 FF 00 A0 F3 00 6B

But again, I still don't see 64 anywhere.

Edited by hmsong

Share this post


Link to post
Share on other sites
7 hours ago, hmsong said:

Oh.  Okay.  Got it (just as you said).  But now what do I do?  Since crit is out of 100, I thought I'd see hex number 64 somewhere, I but I don't.  Even in at C00620.

Please read this again:

On 5/29/2020 at 6:47 PM, praetarius5018 said:

Take the debugger, put a write breakpoint at D0CACA, try to hit an enemy, the game should stop.
Use "step into" until you reach an instruction for JSL $C00620. The LDA #$0065 before that is the range used (+1 because reasons).

the way it is programmed it is programmed you need to give our intended max value but +1 to the RNG method. or rather the exact value doesn't matter. It takes the value that is currently in A, so you have to check where that came from and change that, hint: the instruction directly before it.

7 hours ago, hmsong said:

then I'd be overwriting that with 22 40 F1 13.  And at D3F140 (it's currently full of FFs), I'd be overwrite the next few bytes with:

no, you want the SNES addressing there, so 22 40 F1 D3.
SNES does NOT know our addresses in the hex editor. Just be happy you don't have to deal with headered Lo-ROM, that is a headache and a half.

Share this post


Link to post
Share on other sites

Oh, okay, so please correct me if I'm wrong:

Currently, D0CADB's value is A9 65 00.  So... I'm supposed to change it to A9 FF 00? (which will result in 254 instead of 100?)

Quote

It takes the value that is currently in A, so you have to check where that came from and change that, hint: the instruction directly before it.

The instruction before LDA #$0065 is STA $1C (which is apparently pointing to 000E1C?), but the value is 3B 18 69 08.  I have a feeling I'm looking at something completely unrelated.

Quote

no, you want the SNES addressing there, so 22 40 F1 D3.
SNES does NOT know our addresses in the hex editor. Just be happy you don't have to deal with headered Lo-ROM, that is a headache and a half.

Wait, so for Aura Wave edit, I replaced the 4-byte values at 10E589 to 22 30 F1 13 (and 13F130 to B1 34 18 69 06 D1 36 90 02 B1 36 91 34 6B).  Was I supposed to replace the values of 10E589 to 22 30 F1 D3?

Edited by hmsong

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now