• Welcome to Final Fantasy Hacktics. Please login or sign up.
 
March 28, 2024, 08:41:40 am

News:

Please use .png instead of .bmp when uploading unfinished sprites to the forum!


Bravestory Shenanigans

Started by 3lric, August 18, 2018, 05:46:45 pm

3lric

August 18, 2018, 05:46:45 pm Last Edit: August 18, 2018, 07:00:15 pm by Elric
While working on TLW, I have come across some trouble with bravestory events, and rather than keeping the info on this on IRC/Discord, or to myself and the others involved, as is the norm these days, I thought I would chronicle the findings here, incase anyone ever gets the urge to try to make a tool to get around the seemingly weird hardcoding that is related to events and their bravestory counterparts.

So basically this was the issue:

STEP 1: I finished rearranging all the events for TLW. Removed all the setup events, redid the entire attack.out (both GUI and spreadsheet event conditions), and the worldmap. Tested the entire game from start to finish and verified that all events played where and when they should according to WotL, plus our changes. This was a success.

STEP 2: Redoing the attack.out slot calls for the Bravestory events. This was pretty easy stuff, since it was just matching up the event slots with my own workbook that I made for tracking the events. However, this is where the trouble started.

Now, we know that the Bravestory events are supposed to skip variables when replayed, so that they don't change story/shop/etc variables and muck up the playthru. However, upon testing scenes in the Bravestory in TLW, this was NOT happening. You can view story progress via pSX (aka PSXFin) by monitoring r3000 and watching offset 0x800578D4 in the memory window. I was able to watch the Balbanes death event revert the story progress, which at the time, was at 0F, back to 02. So something was definitely wrong.

At this point, I went WTF at Xifanie, Raven and Pride. After Xif spent a while trying to decipher wtf is going on, she ended up running out of time and we decided to go with a solution presented by Pride, which was to simply use this setup to control variable calls/saves/etc. for the end of Bravestory events:

ORVar(x0000,x006E)
OR(x0001,x????)
EQ()
JumpForwardIfNot(x00)
//Variables changes
ForwardTarget(x00)

With ???? being the value before the change

And this was working PERFECTLY, until of course I hit the inevitable wall. This wall being the interrogation scene in the broken down shed, at the end of the Dorter Slums battle in Chapter 1. I tried a bunch of stuff, but no matter what, the story would not progress past 6E = 5. Pride then said I should try to zero out the variables 0000 and 0001, and try again. Lo and behold, this solved the issue... for now... I was able to progress past this event and then progress the story. I then viewed the event via the bravestory and verified that it indeed, did not reset the story progress in any way. So success. This made the new standard setup for these events, as follows:

ZERO(x0000)
ZERO(x0001)
ORVar(x0000,x006E)
OR(x0001,x????)
EQ()
JumpForwardIfNot(x00)
//Variables changes
ForwardTarget(x00)

I have not yet tested the rest of the game. However, I wanted to document this as this sort of thing happens ALOT while working on both TLW and Jot5, which most people don't ever realize or even consider in the grand scope of things how something so small can fuck us so hard during testing.

I've also made this post in an effort to provide as much info as possible incase someone, at some point, wants to find whatever table or hardcoding controls these event slots.

So, why did this happen? Well, I don't have an answer for that, but I can provide a couple of would be reasons, for anyone looking for a more permanent solution in the future.

- We removed the setup events (we already know that this will mess with saves that lead directly to battle formation without a roster/equipment formation screen in between the save and the battle, ie: academy into the gariland battle, which we now have a standard formation seperating to combat this. Without the setup event, upon loading a save that didn't have a formation (variable 55) between it, the battle formation screen will be completely derped, and any attack.out set portraits will not hold)

- We redid the attack.out/event slot order. Obviously this needed to be done since we made space for more events by removing setups, however if there is indeed hardcoding for the event slots themselves, to control the bravestory viewed versions of the events, and their variable calls, then this would have been mucked up by our rearranging.

I'm inclined to believe that the issue is the latter rather than the former, but at this point, I cannot say for sure what the hell was going on, and I am glad to have the fix we currently have, at least.

I know this post was extremely convoluted and for 99.9% of people, completely unnecessary, but hey, that's the name of the game when it comes to doing things others haven't before. Hopefully someone can find some sort of use of this information and the pain suffered to acquire it.

I will update this thread with more info as it comes about (if it does) likewise, i invite Xifanie, Raven or Pride to offer more insight on this if they so choose (or any other ASMer/Modder who might also have some ideas on this).

Some BS happened with BS events, the BS is being handled so the BS works properly. Progress slowly, TLW happening soon still


  • Modding version: PSX

Glain

I did some looking into this, and wanted to see what routine was handling the variable control commands.  Seems to be this one, which I've now documented on the Wiki.

The difference that I was able to see between seeing a storyline event normally and viewing it in the brave story is that the brave story version will set the 0x1FC variable to 1 before starting, which will block most variables from being updated, as can be seen in the documented routine.

I'm curious if the 0x1FC variable isn't being set when you see the problem.  It's the 0x10 flag on the byte at RAM address 0x8005794B.
When run normally, I see the value for that byte go from 0 to 0x20.
When run in the brave story, it goes 0 -> 0x10 -> 0x30.


I eventually tracked down what sets the 0x1FC variable from the brave story.  It's a call to the routine that sets a script variable value in WORLD.BIN (0xef25c in RAM). 
Essentially the call is 0xef25c(0x1fc, 1).

Stack trace of call:

LOCATION    ROUTINE     NOTES
0x831a0      0x830a8      ?
0x6c434      0x6c3dc       Menu?
0x67380      0x672f8      WLDCORE main()?
0x45218      0x451cc      Loads WLDCORE?
[...]



I'm still not sure why the 0x1FC variable wouldn't be getting set, but this could perhaps be a starting point to figuring it out, if that's what it is...
  • Modding version: Other/Unknown

3lric

Thank you for the information. Unfortunately that's not the only issue either. For some reason most bravestory events that link to another event (attack.out go to next scenario, instead of go to worldmap) are not playing only the single event, but are rather linking up. 

Like viewing the first prayer scene from the game via bravestory, ends up playing the first battle from the game followed by the academy scene. This is after using the commands in my first post to skip the varibles in the events if a certain story progress has past.
  • Modding version: PSX

Xifanie

I tried changing variables 0x01FC and 0x01FD after the event started (in memory), and the vanilla event changed the story progression. Sooo, that definitely looks like the right thing to investigate.

Edit: 0x8008319C sets variable 0x01FC to 1. When 0x800BC2F0 = 0x00000010... aaaaaaaaaand that's where it gets hard to debug.
  • Modding version: PSX
Love what you're seeing? https://supportus.ffhacktics.com/ 💜 it's really appreciated

Anything is possible as long as it is within the hardware's limits. (ie. disc space, RAM, Video RAM, processor, etc.)
<R999> My target market is not FFT mod players
<Raijinili> remember that? it was awful

Glain

I went ahead and documented the routine that sets the 0x1fc variable here.  I actually think the check for the 0x10 flag on 0x800BC2F0 may just be checking for the Triangle button press, which is how you launch an event from the brave story.

If so, you'd think 0x1fc would always be getting set.  At this point I'd be interested to run through the code in a debugger, but I suppose I would need the PPF for that.
  • Modding version: Other/Unknown

3lric

August 21, 2018, 12:39:05 pm #5 Last Edit: August 21, 2018, 07:27:09 pm by Elric
Ill be at the doctor for a while, probably 4-6 hours. But i can get you that once im home and any other info you might need.

EDIT: PM Sent
  • Modding version: PSX

Glain

Awesome, new PPF is good.  I have a few findings.

Variable 0x1FC is being set back to 0 before the event starts in the brave story (after BATTLE.BIN is loaded).  The culprit routine is 0x142d58.  The check it makes to determine whether to do this is a call to routine 0x142b5c.  If that routine gives a non-zero return value, it happens.

Routine 0x142b5c is checking the event ID and doing a lookup into a table at 0x8004e5d0.  That's the table that gets loaded with data from ATTACK.OUT corresponding to the After Event Operation and Next Scenario ID for each ATTACK.OUT scenario.  If the loaded value is anything other than zero (no After Event Operation and no Next Scenario ID) then the return value will be non-zero, and routine 0x142d58 will merrily unset the 0x1FC variable.  I'm guessing in vanilla, the brave story always points to a setup event, which would make the routine return zero and everything would be fine.

I tried a few things using the Ovelia prayer event as a test.  Forcing the inner routine to return zero... actually causes the battle to break out in the monastery itself!  If I zero out only the call to set variable 0x1FC to zero, then it seems to work as it should. 

I'm not sure of the implications of this, or if this could cause some other problem somewhere down the line, but one thing you could try is to zero out that instruction.  It's at 0x80142e84 in RAM, or 0xDBE84 in BATTLE.BIN.  91 ED 04 0C would be changed to 00 00 00 00.
  • Modding version: Other/Unknown

3lric

Fantastic. Thanks Glain! I will try this out once i get home from work. Ill do another playthru of the game this weekend as well (if it works) to make sure there are no other negative side effects.
  • Modding version: PSX

3lric

Just tested on a Chapter 4 save, after applying that change, and it does indeed work as intended. Thanks again, I will be doing another full playthru this weekend with your 'press buttons to win' hack and Xif's cross skip hack, to make sure it didn't break anything at all, but for now, all seems well.

Quick question, would this also solve the variable issue as well? Or should I keep the event commands i mentioned above for skipping these, intact?
  • Modding version: PSX

Glain

Nice!  This should solve the variable issue too, so in theory the extra event commands shouldn't be needed.
  • Modding version: Other/Unknown

Timbo

I've decided, I'm going still want to do the WotL version. I love the idea of having a definitive base version of the game for others to work from and this is a great way for me to contribute.

Are you still intending to to release all of the files necessary for people to use TLW as a base patch?
  • Modding version: PSX
  • Discord username: Timbo

3lric

I think you meant to post this in the TLW thread. But yes i am lol
  • Modding version: PSX

Timbo

I did indeed, and man you're fast. I didn't even have time to delete my post... 😅
  • Modding version: PSX
  • Discord username: Timbo

3lric

Glain, there is another issue unfortunately.

I went ahead and reverted the events I had put the commands in, and have now begun gameplay testing. Everything seemed to be working fine and the story progress did not revert when viewing scenes in the Bravestory

I started a new game, got to the worldmap, and after the Balbanes death scene, I went to the Bravestory, watched the Cadets scene, then after it finished, I proceeded to Mandalia to see the Algus scene, when I got there, there was no units on the map aside from Ramza and Co. Delita was also not present (TLW doesn't have guest in formation, only has them forced via ENTD).

I reloaded the savestate from before I went to Mandalia and this time did NOT watch the Cadets scene and when I stepped on Mandalia, everything was as it should be.

The event itself played fine, but from what I can tell, it seems like the ENTD is not loading

EDIT:
I just did some testing and it looks like what is happening is that after viewing a Bravestory scene, the game doesn't STOP trying to load Bravestory ENTDs (I verified this by setting the empty Bravestory ENTD to that of the normal scene). Scenes like the mandalia battle (or any other scene/battle that doesn't have a Bravestory ENTD setup via Attack.out GUI) don't have a Bravestory ENTD set, would load ENTD 000, which would make nothing appear aside from your units chosen via battle formation. This would be extremely problematic for events that have two separate ENTDs based on normal or bravestory viewing.

Any suggestions on how to get the game to load standard ENTDs again, instead of Bravestory ENTD after viewing a Bravestory Scene?
  • Modding version: PSX

Glain

Ha, well I guess now there's a scenario where variable 0x1FC isn't being set to 0 when it actually needs to be.  It probably just needs to be set back to 0 before you leave the brave story...  maybe when you come back to the brave story menu from the event, or when you X out of the Records menu or something like that.  I'll have to delve into the ASM/debugger to figure out where that code is, but that's the general strategy, anyway.
  • Modding version: Other/Unknown

Glain

Testing it, the variable wasn't being unset, like I thought.  I found the code that closes the menu... it's in the same routine that launches the event from the brave story (0x830a8).  I wrote a patch to have it set variable 0x1fc to 0.  I tested it in a save state and saw that the variable wasn't changing without the patch and does change with it, so hopefully this will fix the other issue.

The patch also includes the previous change.  Most of it is actually just moving code down a line or two to make way for the new call.


  <Patch name="Mess around with brave story">
    <Location file="BATTLE_BIN" offset="142E84" mode="ASM" offsetMode="RAM">
        nop
    </Location>
    <Location file="WORLD_WLDCORE_BIN" offset="83220" mode="ASM" offsetMode="RAM">
        jal     0x800903e4
        addiu   a0, a0, -0x1108
        bne     v0, zero, 0x80083428
        li      a0, 0x1fc
        jal     0x800ef25c
        li      a1, 0
        jal     0x80090d30
        li      a0, 2
        lui     t0, 0x800c
        lw      a2, -0x4b10(t0)
        nop
        addiu   v0, a2, -2
        sll     a0, v0, 1
        addu    a0, a0, v0
        sll     a0, a0, 3
        subu    a0, a0, v0
        sll     a0, a0, 2
        addiu   at, t0, -0x466c
    </Location>
  </Patch>
  • Modding version: Other/Unknown

3lric

Awesome! I did not expect to wakeup to a fix so quickly! I will test this out on a playthru tonight. Thanks again Glain!
  • Modding version: PSX

3lric

August 26, 2018, 12:35:23 am #17 Last Edit: August 26, 2018, 09:33:05 am by Elric
Just started my playthru, I'm at Igros and can so far confirm that watching Bravestory scenes does not reset variables and that the correct ENTDs load again after viewing a scene.

Will report back if i encounter any issues during the rest of this playthru

EDIT: Chapter 1 completed, no issues.
EDIT: Chapter 2 completed, no issues.
EDIT: Chapter 3 completed, no issues.
EDIT: Chapter 4 completed, no issues.
  • Modding version: PSX

Glain

Awesome, looks like that was it, then!
  • Modding version: Other/Unknown