Golden Sun Hacking Community

Golden Sun Resources => Misc. GS Hacking => Topic started by: Caledor on 11, April, 2017, 07:53:59 AM

Title: [Solved] Making leveling not RNG dependant
Post by: Caledor on 11, April, 2017, 07:53:59 AM
As some of you probably already know, in order to remove the Beta from Golden Sun Reloaded's name i need to make the level up not dependent on RNG, since that could be abused, especially with Luck.

Leveling in GS works as follows: you have a "goal stat number" for each 20 levels (0, 19, 39, ..., 99). To determine how much you gain in that stat by leveling up, the game takes the next goal number (example: for a level 14 character it'd be the level 19 stat), subtracts the last goal number from it and divides by 20. then it adds either 0 or 1 from RNG.

What i'm doing is: instead of subtracting last goal number and divide by 20, subtract current base stat and divide by the number of levels remaining to reach the goal level. Since i've also removed the RNG part, you are bound to reach the goal stat set.

Less than 1 hour ago i finished implementing and testing this method for HP and PP in TLA and it worked flawlessly.

But then i realized something: Stat boosting items affect (obviously) the base stat of the character, which means that the stat boost will be absorbed by the new leveling formula as soon as the characters gains a level, effectively making those items useless if until before the very end of the game (when you know you won't level up anymore).

So... does anybody have an idea to make those 2 concepts (leveling not RNG dependent and stat boosting items) coexist?
Title: Re: Making leveling not RNG dependant
Post by: Salanewt on 11, April, 2017, 12:31:16 PM
I'm still waking up, but is there a reason why you didn't just remove the RNG part of the calculation?

I can also see an issue with your idea counting equipment bonuses upon level up, meaning that holding a sword could prevent you from actually gaining a meaningful attack boost, while wearing something like the Turtle Boots would give you much greater agility boosts.

Edit: Although that does give me an interesting idea for a hack. One where, if different kinds of equipment promote different kinds of growths while others do not change stats at all, you can implement training gear while also punishing players for using gear that provides too great of a handicap.

Edit 2: I think the games also store the number of stat boosting items used on player characters. I think? It may be worth looking into if you really want to use your new formula.
Title: Re: Making leveling not RNG dependant
Post by: Caledor on 11, April, 2017, 01:56:06 PM
QuoteI'm still waking up, but is there a reason why you didn't just remove the RNG part of the calculation?
The rng part is supposed to be some sort of compensation cause division always round up to the lowest. if your stat increase over 20 levels is supposed to be X, you'll always lose X mod 20 (the remainder). This also implies that luck wouldn't grow at all, since it's growth is always less than 20 for a 20 level jump.

QuoteI can also see an issue with your idea counting equipment bonuses upon level up, meaning that holding a sword could prevent you from actually gaining a meaningful attack boost, while wearing something like the Turtle Boots would give you much greater agility boosts.
I don't think equipment affects base stats. IMO their values are just added to actual stats before class bonus. If not the same would be true for djinn. I think stat boosting items do though, cause if they didn't the bonus would be lost on any stat refresh, be it an equipment change or a djinn changing state

QuoteEdit: Although that does give me an interesting idea for a hack. One where, if different kinds of equipment promote different kinds of growths while others do not change stats at all, you can implement training gear while also punishing players for using gear that provides too great of a handicap.
I know this mechanic from Final Fantasy IX. Upon leveling up you gain a fraction of the bonus provided by the equipment as a permanent stat boost.

QuoteEdit 2: I think the games also store the number of stat boosting items used on player characters. I think? It may be worth looking into if you really want to use your new formula.
I really hope that is the case, cause if they just alter base stat i don't know how i can manage
Title: Re: Making leveling not RNG dependant
Post by: Salanewt on 11, April, 2017, 03:30:11 PM
Aah, makes sense.

Equipment: OH, right! For some reason the fact that there are separate base and current stats wasn't registering in my brain. My apologies! :p

Mechanic idea: Well, sort of. I was thinking in the reverse, where negative stat bonuses would increase natural growths but that positive ones would decrease or at least have a neutral effect on them.

Item tracking: I think so, but I can't remember and I may be mistaken on that. Hopefully someone else can weigh in on that.


Idea: You currently subtract the base stat from the goal stat, as well as current level and goal level, and depending on the difference calculate growths? What if you instead try to make the game calculate what your current base stat should be without items, and then use that to calculate them instead of the real base stat? You could use modify the original formula to figure this out.

(Goal_Stat - Start_Stat) / 20 = Growth

Could be expanded into something like...

Actually, I'll get back to you on that later unless you come up with a good formula.


Edit 2: Actually, that formula feels slightly off. I'll do a quick test but I need to get back to my studies soon so no promises just yet.
Title: Re: Making leveling not RNG dependent
Post by: leaf on 11, April, 2017, 03:45:39 PM
if (CurrLevel < 20): LevelsBetweenGoals = 19
else: LevelsBetweenGoals = 20

Stat gain = [(NewGoal - PrevGoal)*(CurrLevel - PrevGoalLevel)/LevelsBetweenGoals] - [(NewGoal - PrevGoal)*(CurrLevel - PrevGoalLevel - 1)/LevelsBetweenGoals]

It's kinda ugly, but this should bypass the problems of integer division. It basically calculates the projected total stat gain of the current level and the previous level, then subtracts them for the individual stat gain. As such, the total stat gain will *always* equal exactly the goal stat at goal levels.

Note: It should divide by 19 instead for the 0-19 range, otherwise you'll get slightly lower stats than expected.
Title: Re: Making leveling not RNG dependant
Post by: Salanewt on 11, April, 2017, 04:25:39 PM
I came up with this for calculating a character's Expected_Stat (using Garet's HP growths and a current level of 14):

((Start_Stat x 100) + ((Goal_Stat - Prev_Goal) x 100 / 200) x (Current_Level +1)) / 10


((33 x 10) + ((191 - 33) x 100 / 200) x (14 + 1)) / 10
((330) + (158 x 100 / 200) x (15)) / 10
((330) + (15800 / 200) x (15)) / 10
((330) + (79) x (15)) / 10
= Garet should have 151 HP at level 14.

This is almost exact as far as I can tell. I get the exact number as displayed in the editor by plugging in a level of 19, but it seems to be slightly off for higher ranges so you may have to multiply the [Current_Level] variable by some number and tweak the formula a bit to be able to correct itself if you decide to use this. Oh, and it somewhat works for low values like Luck but needs a little more work put in to make it better.


I think leaf's formula does everything I wanted to do plus this though, without having the time to test it out right now. Nice work!



Title: Re: [Solved] Making leveling not RNG dependant
Post by: Caledor on 11, April, 2017, 04:48:13 PM
I just tested leaf's formula on excel and it works flawlessly! (proof pic attached)

I still haven't "converted" that to assembly so i don't know if it will fit, but even if it doesn't it'd be a very minor issue.

Thanks a lot for your efforts guys, you just saved me from a lot of headaches (i hate this stuff lol).
Title: Re: [Solved] Making leveling not RNG dependant
Post by: Salanewt on 11, April, 2017, 05:27:01 PM
Happy to help. You should post a patch for this when you're done, I'm sure people will love it!
Title: Re: [Solved] Making leveling not RNG dependant
Post by: Daddy Poi's Oily Gorillas on 11, April, 2017, 08:02:23 PM
So is this going to be a Luck Increase table with ~100 8-bit bytes? Or are we doing the equation itself in assembly?

(I skimmed this topic if I'm asking a dumb question. May look more closely later?)
Title: Re: [Solved] Making leveling not RNG dependant
Post by: Caledor on 11, April, 2017, 08:16:42 PM
I'm changing the equation in assembly with the one suggested by leaf.
Title: Re: [Solved] Making leveling not RNG dependant
Post by: Caledor on 12, April, 2017, 12:57:21 PM
Already implemented in TLA both ita and eng.

@Squirtle: about the separate patch: sadly it doesn't fit so part of the formula is in another section of the ROM that i can't use in a patch over a clean rom. I'll post here the assembly functions when i'm done with TBS though.
Title: Re: [Solved] Making leveling not RNG dependant
Post by: Daddy Poi's Oily Gorillas on 12, April, 2017, 03:29:25 PM
Sounds like fun. Can't wait to see the assembly. I might see if there's any optimizing that can be done to make it fit as well... Not sure yet, though.
Title: Re: [Solved] Making leveling not RNG dependant
Post by: Caledor on 12, April, 2017, 07:35:39 PM
Attached.

As you can see from the first pic, blocks for each stat are more or less identical.

It goes like this: at the end of the unchanged part, r7 contains NewGoal - PrevGoal.

Then i load char level into r0, put lv-1 into another registry, check if level is <20 cause in that case i have to divide by 19 and not by 20. Then I put (NG-PG)*lv into r0 and (NG-PG)*(lv-1) into r2 and jump to the part that didn't fit here.

a few backups, first division since i already have everything in the right place, restore registries altered by the division, backup result, second division, restore first result, subtraction and... done!

For reference the formula is:

if (CurrLevel < 20): LevelsBetweenGoals = 19
else: LevelsBetweenGoals = 20

Stat gain = [(NewGoal - PrevGoal)*(CurrLevel)/LevelsBetweenGoals] - [(NewGoal - PrevGoal)*(CurrLevel - 1)/LevelsBetweenGoals]

I removed the "- PrevGoalLevel" from leaf's formula cause it wasn't needed.
Title: Re: [Solved] Making leveling not RNG dependant
Post by: Daddy Poi's Oily Gorillas on 12, April, 2017, 09:42:02 PM
Interesting...

Is x/z - y/z the same as (x-y)/z? If so, then we only need one division per stat? = Or did I miss something, and rounding is needed in both cases? Etc.

If you move stuff down a bit, maybe could use r4 to r7 for important variables to avoid recalculating them. (e.g. The 19 and 20 thing.) But I'm not sure of the most efficient way to do this yet.
Title: Re: [Solved] Making leveling not RNG dependant
Post by: leaf on 12, April, 2017, 09:51:05 PM
It's not, because it uses integer division.

As ints, 20/7 + 1/7 = 2 + 0 = 2
As floats, 20/7 + 1/7 = 21/7 = 3
Title: Re: [Solved] Making leveling not RNG dependant
Post by: Daddy Poi's Oily Gorillas on 12, April, 2017, 10:21:57 PM
So that means rounding is needed in both cases, then... (Well, clipping off the decimal, I mean.)
I had a feeling - Was just making 100% sure. Would have been sweet if we could have reduced that down somehow, though...  Division can take up a bit of space with those function calls and setting of args.... and stuff, afterall... But I don't have any ideas....


I am also not sure if there would be a consideration to use level scaling of 0, 20, 40, 60, 80, and 100  rather than 0, 19, 39, 59, 79, 99 ... to help remove the 0x13 number. (Or anything of the like.) - Can't say if there's a huge difference? (It probably makes more sense, anyway. Since from an informational point of view, wouldn't we be more interested in a stat at say level 20 than a stat at level 19? GS's love for the 9s.)