• Welcome to Final Fantasy Hacktics. Please login or sign up.
 
April 18, 2024, 01:59:16 am

News:

Use of ePSXe before 2.0 is highly discouraged. Mednafen, RetroArch, and Duckstation are recommended for playing/testing, pSX is recommended for debugging.


ASM Questions

Started by BigManStan, March 07, 2016, 08:37:06 pm

BigManStan

Hi all,

New to FFT hacking and hacking in general.  This is my first foray into assembly language coding and I had a few questions on how stuff is done.


1)  I want to create a new routine in free space that is called from existing code.  In order to do that I need to use 2 instructions I assume, a jump and delay slot.  Assuming this is correct, what is done with the instructions that are overwritten by the jump/delay? 

I was studying Xifanie's Weapon Strike fix v1 as an example, and it looked like the 2 existing instructions that were stomped (saving $31 to stack) were tacked on to the end of the Weapon Strike routine before jumping back to the original code.  I was wondering if this is a general solution that can be used.


2)  Temporary registers:  If I call a routine from my code that is in the middle of an existing routine in the original code, and the original code is using the temporary registers (4-7 I think) do I need my routine to handle saving the temporary registers?  I was reading some assembly stuff and it says that saving temporaries is the caller's responsibility, not the callee's but in this situation I would need to overwrite even more existing code lines to do this.  I was wondering how this works?  Does my code need to save them (seems bad) or do I need to overwrite more lines from the existing code to do this?

And please let me know if I am way off base with these questions, or if I am lacking some fundamental knowledge.  I am very new to assembly and hacking so there may be some holes in my knowledge that I am not aware of.

Thanks!

Choto


1) You just have to make sure that everything that you bump out of place gets returned the way it should have been after your routine finishes. The simplest way is just to execute the commands that got stomped on at the beginning of your routine. However, depending on the situation you may want to move them around if needed.

2) One little trick is that you can look further down the routine and see if any registers get straight-overwritten by an ori or load command. Basically if the game doesn't use what's in that register and overwrites it, it's safe to use up until that point. Otherwise, you can save registers on the stack, or even a designated location in free space that you reserve. It will take additional commands to do so, but it's not bad at all. You can run these commands in your custom routine as soon as you jump. There's a quite a bit of free space so number of commands isn't a huge deal.

Hope it helps!

Xifanie

Oh please don't use my old hacks as examples... I didn't even have any "coding practice" back then. In fact, that hack doesn't even work as advertised; it only affects formula 2D. Please forget everything you saw in that hack and just focus on these aspects:
- Use registers that are are overwritten afterwards to your heart's contents
- If you need more registers, usually the stack range is only used for temporarily storing registers, so if you see addiu r29, r29, 0xFFEC and addiu r29, r29, 0x0014 with sw/lw r??, 0x0008/0x000C/0x00010(r29), that means 0x0000 and 0x0004 are free to use. Just increase the range if you need more and save the registers yourself then load them back before jumping back
- Try to ONLY use r1 for memory addresses
- Don't do that shit I used to do with mflo/mtlo/mfhi/mthi to temporarily store registers. It's ugly and using the stack is way cleaner... not to mention that it can't be used if you plan to use mult/div.
  • 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

BigManStan

Thanks for the helpful replies. 

I wanted to be diligent about maintaining the program state and using the stack correctly, especially since I was planning on calling some of the existing FFT routines from within my code.

Xifanie, I was only looking at the jump and return portions of your hack, so hopefully my coding standards haven't been damaged too badly :P

Choto

No problemo, you seem well spoken and we always help people who help themselves. Looking forward to seeing what you cook up!

Ask us if you get stuck on something, ASM is really easy once you know how to do it.

BigManStan

Cool, thanks :)

I thought I would post a preview of what I'm working on.  I'm currently exploring the concept of dynamically generated skillsets.

Specifically, what I wanted was some type of class/skillset that can inherit the abilities of monsters that are in battle with me.  I originally drew this up to be a skillset that's equipped to a 'specialty monster' (eg Archaic Demon, Byblos, etc) but if it makes some sense I could extend it so it's a full fledged job.  I have no interest in overriding a current generic class for this.

Anyway, as a proof of concept I wanted to develop a skillset that just groups all the abilities of monsters that players select for battle in the formation screen.  The skills would only be present while in battle, and not in the overworld.

What I have so far is the code that will populate the skillset with monster abilities at the start of battle.  It's very rough around the edges at this point.

Good Stuff:
- Abilities work properly
- Selectable in act menu and in status screen in battle
- AI will use abilities, although the available abilities are from the player's team rather than their team.  Unsure if slot 2 is required for the AI to have access to all abilities.

Needs Work:
- Missing animations if the sprite set is missing the correct stuff, I think
- Abilities use MP
- Speed is displayed in the status screen for some abilities, ideally they should all display 0 or 'Now' if they do not have a CT
- Erase the skillset at the end of battle
- I want to not include abilities that require monster skill

Nice to Have:
- Have the code search allied units instead of player units.  This would allow enemy formations to use their own monster skills.
- Have all abilities be instant-learned if I expand this to a job.

Most of these issues are just stuff I haven't gotten to yet, I have just reached the point where I have a first release that does something!  Feel free to offer any input or critique.

Patch:

<Patch name="Battle Monsters Skillset v0.1">
    <Description>
   This patch dynamically generates a skillset in skillset [SETID]
   (default 94, an unused skillset) at the start of battle.
   
   The generated skillset consists of up to 16 unique monster
   skills, sourced from monsters brought by the player to battle.
   </Description>
   
   <Variable name="SETID" default="94" file="BATTLE_BIN" offset="F929C" />
   
    <Location file="BATTLE_BIN" offset="1185F0">
      80810508
    </Location>

    <Location file="BATTLE_BIN" offset="F9600">
      FCFFBD27
      0400BFAF
      1600083C
      9C020835
      00000491
      00000000
      8C81050C
      00000000
      0400BF8F
      0400BD27
      0800E003
      00000000
      E4FFBD27
      0400BFAF
      0800B0AF
      0C00B1AF
      1000B2AF
      1400B3AF
      1800B4AF
      1C00B5AF
      00009520
      B000A92E
      2C002011
      00000000
      0C82050C
      0000A422
      1980103C
      CC241036
      21880000
      01000892
      FF000934
      1E002811
      00000892
      82000934
      1B002815
      12001292
      00000000
      B000492E
      17002015
      21980000
      00004422
      5A69010C
      00006522
      00005420
      0D008012
      A701892E
      0B002011
      0000A422
      EF81050C
      00008522
      07004014
      0000A422
      00002522
      CD81050C
      00008622
      21882202
      0F00292E
      09002011
      01007326
      1600692E
      EBFF2015
      00000000
      C0011026
      FFFF0832
      CD2B092D
      DBFF2015
      00000000
      1C00B58F
      1800B48F
      1400B38F
      1000B28F
      0C00B18F
      0800B08F
      0400BF8F
      1C00BD27
      0800E003
      00000000
      21100000
      0002C92C
      1D002011
      1000A92C
      1B002011
      B000892C
      19002011
      06800B3C
      944A6B35
      19000834
      19008800
      12400000
      21586801
      2150AB00
      030046A1
      00006A91
      00520A00
      01006891
      25504801
      00800834
      0640A800
      0001C92C
      03002015
      00000000
      25504801
      02000010
      27400001
      24504801
      01006AA1
      02520A00
      00006AA1
      01000234
      0800E003
      00000000
      F0FFBD27
      0400BFAF
      0800B0AF
      0C00B1AF
      1000B2AF
      0002892C
      0F002011
      0002A92C
      0D002011
      00009020
      0000B120
      21900000
      00000422
      5A69010C
      00004522
      02005114
      01000234
      04000010
      01005226
      1600492E
      F7FF2015
      21100000
      1000B28F
      0C00B18F
      0800B08F
      0400BF8F
      1000BD27
      0800E003
      00000000
      F4FFBD27
      0400BFAF
      0800B0AF
      0C00B1AF
      00009020
      21880000
      00000422
      00002522
      CD81050C
      21300000
      01003126
      1000292E
      F9FF2015
      00000000
      0C00B18F
      0800B08F
      0400BF8F
      0C00BD27
      0800E003
      00000000
   </Location>
  </Patch>


Source:


#This code will generate a skillset with up to 16 unique abilities
#sourced from player controlled monsters in battle.
#Any non-R/S/M abilities in the selected skillset will be overwritten.

##############################################################

entry:
[0x00160600] addiu sp,sp,-0x0004
[0x00160604] sw ra, 0x0004(sp)

[0x00160608] li t0, 0x0016029C               #ptr to reserved data area
[0x00160610] lbu a0, 0(t0)                  #load skillset to overwrite, default 94
[0x00160614] nop
[0x00160618] jal generateskillset
[0x0016061c] nop
[0x00160620] lw ra, 0x0004(sp)
[0x00160624] addiu sp,sp,0x0004
[0x00160628] jr ra
[0x0016062c] nop

##############################################################

generateskillset:
[0x00160630] addiu sp,sp,-0x001C
[0x00160634] sw ra, 0x0004(sp)
[0x00160638] sw s0 ,0x0008(sp)
[0x0016063c] sw s1, 0x000C(sp)
[0x00160640] sw s2, 0x0010(sp)
[0x00160644] sw s3, 0x0014(sp)
[0x00160648] sw s4, 0x0018(sp)
[0x0016064c] sw s5, 0x001C(sp)

[0x00160650] move s5, a0                  #s5 skillset to overwrite

[0x00160654] sltiu t1, s5, 0x00B0
[0x00160658] beq t1, zero, exit               #leave if monster skillset or invalid
[0x0016065c] nop

[0x00160660] jal eraseskillset               #erase current abilities
[0x00160664] move a0, s5

[0x00160668] li s0, 0x801924CC               #s0 ally unit ptr
[0x00160670] clear s1                     #s1 ability counter (for saving)

unitloop:
[0x00160674] lbu t0, 0x0001(s0)
[0x00160678] ori t1, zero, 0x00ff            #increment if not exist
[0x0016067c] beq t1, t0, unitincrement
[0x00160680] lbu t0, 0x0000(s0)
[0x00160684] ori t1, zero, 0x0082            #increment if not monster
[0x00160688] bne t1, t0, unitincrement
[0x0016068c] lbu s2, 0x0012(s0)               #s2 primary skillset
[0x00160690] nop
[0x00160694] sltiu t1, s2, 0x00B0            #increment if not monster skillset
[0x00160698] bne t1, zero, unitincrement
[0x0016069c] clear s3                      #Got monster skillset - skillset ctr in s3


transferloop:                     
[0x001606a0] move a0, s2                  #a0 skillset to read
[0x001606a4] jal 0x0005a568                  #load ability from skillset
[0x001606a8] move a1, s3                  #a1 ability index (read)
[0x001606ac] move s4, v0                  #s4 loaded ability
[0x001606b0] beq s4, zero, transferincrement   #branch if ability blank
[0x001606b4] sltiu t1, s4, 0x01a7   
[0x001606b8] beq t1, zero, transferincrement   #branch if not an ability
[0x001606bc] move a0, s5                  #a0 skillset to overwrite
[0x001606c0] jal abilityinskillset
[0x001606c4] move a1, s4                  #a1 loaded ability
[0x001606c8] bne v0, zero, transferincrement   #branch if duplicate ability

[0x001606cc] move a0, s5                  #a0 skillset to overwrite
[0x001606d0] move a1, s1                  #a1 ability index (write)
[0x001606d4] jal saveability      
[0x001606d8] move a2, s4                  #a2 ability
[0x001606dc] addu s1, s1, v0               #Increment ability counter if saved

[0x001606e0] sltiu t1, s1, 0x0F
[0x001606e4] beq t1, zero, exit               #leave if 0x10 skills saved

transferincrement:
[0x001606e8] addiu s3, s3, 1
[0x001606ec] sltiu t1, s3, 0x16
[0x001606f0] bne t1, zero, transferloop         #loop through skills 0 - 0x16
[0x001606f4] nop

unitincrement:
[0x001606f8] addiu s0, s0, 0x01c0
[0x001606fc] andi t0, s0, 0xFFFF;
[0x00160700] sltiu t1, t0, 0x2BCD
[0x00160704] bne t1, zero, unitloop            #loop through player controlled units
[0x00160708] nop

exit:
[0x0016070c] lw s5, 0x001C(sp)
[0x00160710] lw s4, 0x0018(sp)
[0x00160714] lw s3, 0x0014(sp)
[0x00160718] lw s2, 0x0010(sp)
[0x0016071c] lw s1, 0x000C(sp)
[0x00160720] lw s0, 0x0008(sp)
[0x00160724] lw ra, 0x0004(sp)
[0x00160728] addiu sp,sp,0x001C
[0x0016072c] jr ra
[0x00160730] nop

##############################################################

saveability:  #a0 skillset, a1 ability index, a2 ability, v0 save success (boolean)
[0x00160734] clear v0
[0x00160738] sltiu t1, a2, 0x0200
[0x0016073c] beq t1, zero, exitsa            #leave if invalid ability
[0x00160740] sltiu t1, a1, 0x0010
[0x00160744] beq t1, zero, exitsa            #leave if index >= 0x010 (no RSM support for now)
[0x00160748] sltiu t1, a0, 0x00B0
[0x0016074c] beq t1, zero, exitsa            #leave if monster skillset or invalid

[0x00160750] li t3, 0x80064a94               #t3 ptr to skillsets
[0x00160758] ori t0, zero, 0x19
[0x0016075c] multu a0, t0
[0x00160760] mflo t0                              
[0x00160764] addu t3, t3, t0               #t3 ptr to skillset   

[0x00160768] addu t2, a1, t3
[0x0016076c] sb a2, 3(t2)                  #save ability

[0x00160770] lbu t2, 0(t3)                  
[0x00160774] sll t2, t2, 8
[0x00160778] lbu t0, 1(t3)                  
[0x0016077c] or t2, t2, t0                  #t2 ability flags

[0x00160780] ori t0, zero, 0x8000
[0x00160784] srlv t0, t0, a1                #t0 ability flag bitmask

[0x00160788] sltiu t1, a2, 0x100
[0x0016078c] bne t1, zero, noflag            #branch on no flag
[0x00160790] nop
[0x00160794] or t2, t2, t0                  #set bit
[0x00160798] b saveflags
noflag:
[0x0016079c] not t0, t0
[0x001607a0] and t2, t2, t0                  #unset bit
saveflags:
[0x001607a4] sb t2, 1(t3)                  
[0x001607a8] srl t2, t2, 8
[0x001607ac] sb t2, 0(t3)                   #save updated flags
[0x001607b0] ori v0, zero, 1               #success
exitsa:
[0x001607b4] jr ra
[0x001607b8] nop

##############################################################

abilityinskillset: #a0 skillset, a1 ability, v0 ability exists in skillset (boolean)
[0x001607bc] addiu sp,sp,-0x0010
[0x001607c0] sw ra, 0x0004(sp)
[0x001607c4] sw s0 ,0x0008(sp)
[0x001607c8] sw s1, 0x000C(sp)
[0x001607cc] sw s2, 0x0010(sp)

[0x001607d0] sltiu t1, a0, 0x0200
[0x001607d4] beq t1, zero, exitais            #leave if invalid skillset
[0x001607d8] sltiu t1, a1, 0x0200
[0x001607dc] beq t1, zero, exitais            #leave if invalid ability
[0x001607e0] move s0, a0                  #s0 skillset
[0x001607e4] move s1, a1                  #s1 ability
[0x001607e8] clear s2                     #s2 ability counter

abilityloop:
[0x001607ec] move a0, s0                  #a0 skillset
[0x001607f0] jal 0x0005a568                  #load ability from skillset
[0x001607f4] move a1, s2                  #a1 ability index
[0x001607f8] bne v0, s1, nomatch

[0x001607fc] ori v0, zero, 1               #ability found
[0x00160800] b exitais

nomatch:
[0x00160804] addiu s2, s2, 1
[0x00160808] sltiu t1, s2, 0x16
[0x0016080c] bne t1, zero, abilityloop         #loop through skills 0 - 0x16
[0x00160810] clear v0

exitais:
[0x00160814] lw s2, 0x0010(sp)
[0x00160818] lw s1, 0x000C(sp)
[0x0016081c] lw s0, 0x0008(sp)
[0x00160820] lw ra, 0x0004(sp)
[0x00160824] addiu sp,sp,0x0010
[0x00160828] jr ra
[0x0016082c] nop

##############################################################

eraseskillset: #a0 skillset
[0x00160830] addiu sp,sp,-0x000C
[0x00160834] sw ra, 0x0004(sp)
[0x00160838] sw s0 ,0x0008(sp)
[0x0016083c] sw s1, 0x000C(sp)

[0x00160840] move s0, a0
[0x00160844] clear s1
eraseloop:                              #erase all action abilities
[0x00160848] move a0, s0
[0x0016084c] move a1, s1
[0x00160850] jal saveability
[0x00160854] clear a2
[0x00160858] addiu s1, s1, 1
[0x0016085c] sltiu t1, s1, 0x10
[0x00160860] bne t1, zero, eraseloop         #loop through skills 0 - 0x10      
[0x00160864] nop

[0x00160868] lw s1, 0x000C(sp)
[0x0016086c] lw s0, 0x0008(sp)
[0x00160870] lw ra, 0x0004(sp)
[0x00160874] addiu sp,sp,0x000C
[0x00160878] jr ra
[0x0016087c] nop

##############################################################



BigManStan

Hello all,

I am trying to code some junk related to skillsets.  I was wondering, is there an area in memory that identifies a unit that is currently selected?  I have scoured the data location information and haven't seen anything for this.

I would like to override the 'Load Ability from Skillset' routine, and have it do different things depending on what unit the skillset is being loaded for.  However, I have not yet found a reliable way to identify the unit.  The 'acting unit' ID locations have worked somewhat, but they fail in cases like when I'm viewing a unit's skills in the status menu when it's not that unit's turn.

If anyone knows anything regarding this, help is appreciated.  I might be barking down the wrong tree, I know that the unit ID is not something that is officially passed along to the 'Load Ability...' routine, so it might be impossible for me to 100% determine the unit the skillset is being loaded for in all cases.

Thanks!

Xifanie

Really not sure what to say... it's hard to suggest anything not knowing exactly what you're trying to code.
I have personally worked with that section a month ago (I think, or will have to eventually), and there would at least always be the address for the learned abilities of the currently affected unit in an active register.
  • 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

BigManStan

March 21, 2016, 07:43:26 pm #8 Last Edit: March 21, 2016, 07:51:24 pm by BigManStan
Hmm, okay, I'll bite. 

I am trying to create a new skillset with a theme of synergy between the skillset's user and allied monsters on the team.  (Unsure of the name, was thinking 'Empathy' or 'Beast Mastery')

The skillset will consist of a 'normal', fixed set of skills (at least 1, up to 4 I was thinking), and the rest of the skill slots being always blank on the world screens but able to be dynamically filled with monster skills of allied monsters in battle.

The main driver of the skillset, and first fixed skill is a 'Bond' ability which allows the user to apply a 'Bond' status, with only allowed targets being allied monsters ('bondees').  When a monster is under 'Bond' status, it's non Monster Skill abilities will be available for the caster that applied Bond to the unit (the 'bonder').  I was also planning on the other 3 fixed abilities for this skillset to only target allied monsters as well, and have additional enhancements if the monster is Bonded to the caster.

The issue that I was getting at, is that if there are multiple units with this skillset, or multiple 'bonders', each instance of their available skills may differ depending on the 'bondees' that each 'bonder' has.  I have a table in memory that stores the relationships between bonders and bondees, and if I was able to determine the requesting unit, when the game asks for an ability from that skillset, I could consult the bond table to determine the correct skills to provide when the routine is called.

I have been making an alpha version of this with the Bond status and table mechanics working correctly (I can post the code if anyone is curious) and I have been developing this using a routine that just overwrites a skillset with the bonded abilities when Bond is applied/removed so that the game can just read the altered skillset, and it works good.  The problem here is that I would need a free skillset for every unit in battle that wants to use this.

tl;dr:
I want to have a single skillset that can behave differently in battle depending on the unit that it is assigned to.  Therefore it would be necessary for me to determine the unit that is making the load request, for a skill from the skillset.


If anyone is interested, there are more details and ideas that I have for this here:


Skillset:  'Empathy', 'Monster Empathy', 'Beast Mastery'


Mechanics of Bond:

- A unit with the skillset may apply 'Bond' status to allied monsters using the Bond ability.  Have not determined the parameters for this, but I was thinking a melee range no charge, 100% success rate skill.

- Only allied, 'true' monsters with monster skillsets can be Bonded.

- A unit under Bond status benefits the 'bonder'.  The bonder has access to all monster skills of the 'bondee'.

- A bonder may have multiple bondees.  Bondees can only have a single 'bonder'.

- 12 ability slots will be available for bondee skills, they will be listed in order of CT remaining for Bond status on each bondee (newest bonded units skills listed first)

- Bond will have a finite CT.  Positive-status dispelling abilities should remove it.

- When Bond status removed, the bondee skills will no longer be available to bonder.  A different bonder applying Bond to an already Bonded unit will remove the existing bond and create a new bond to itself.

- Not sure yet if the bond should go away on bondee death, bonder death, both or none.


Other Ability Ideas:

'Swap', 'Save', ...: 
- Target allied monsters.  Invalid units not targetable.  Caster will exchange position with the targeted unit, dealing damage equal to the difference between target unit HP and caster HP in an AoE around the targeted unit.

- Percent success of Swap will decrease based on distance between the units.  Will always have 100% success rate if units are Bonded, and always 0% success rate if either positions of the exchanged units are illegal.


'Sacrifice', 'Martyr':
- Target allied monsters.  Invalid units not targetable.  Caster dies on successful resolution of ability.  Target unit HP/MP healed to full and unit receives Quick status.  25% chance of adding each of Haste / Protect / Shell.

- If units are Bonded, target receives Haste, Protect and Shell 100% in addition to other effects.


Support Ability:  'Initial Bond'
- Starts a battle with 1 ally unit already Bonded to this unit.  The ally to bond is determined by closest bondable unit on the formation screen.  Ties are randomly determined.


Reaction Ability:  (no idea what to call it)
- May react using the reaction abilities of any bonded units.  Precedence may be determined by using the reaction stacking hack (I think)

Xifanie

Well, how I coded the bonus skillset for the ARH2 was making an exception for a unique skillset (Bonus Skillset), and have it parse every single ability in the game (0x000-0x16F); if the conditions matched, it would add the ability to the list of available skills (I don't know if you've seen/found that yet), if not, it would just try the next ability.

I could potentially share my spreadsheet, but it's a big hack and it might not be simple to find what you're looking for... how I work is that I take a lot of temporary notes that I just discard permanently because well, I'm done with them. In fact I'm not sure if my hack itself writes to the available abilities or just transfers the ability ID... it's been too long. ¯\(°_o)/¯
  • 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

BigManStan

Cool, I would take a look if you had it available.  I'm a bit of an Excel doofus so it may be difficult for me to examine, is the assembly backing the spreadsheet accessible from within the spreadsheet to look at?

I remember seeing the 'Bonus Abilities' section; looks cool; I was wondering what the 'requirements' for an ability are, exactly?  Might be similar to what I'm looking for, if the Bonus Ability skillset has a single skillset id but can display lists that are different from unit to unit...regardless, thanks for the feedback.

Xifanie

Actually, both regular skillsets and the bonus skillset skills have custom, different requirements event. With the ARH2 you can give Fire the "Flame Rod equipped" requirement for the bonus skillset, while keeping the regular skillset one perfectly intact... just like you can a skill permanently available to a special character no matter the job, or have Holy Sword Skills require a sword (just like in vanilla) while giving access to all Holy Sword skills when Excalibur is equipped.

I'll PM you the spreadsheet because it might not be ready for public release (since 22 people downloaded my sheet, and none reported it was, in fact, not working), but I left a bunch of notes to describe what sections does what... it's all in ASM format. So, yeah.
  • 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

BigManStan

Hello again,

I was wondering if there is any description of the contents of save files?  I've been scouring the wiki and there is tons of info about in-game memory but I can't find a lot about save file contents.  I may not be looking in the right places though, if there is any info please let me know.  I was looking at story progression data specifically, since FFTastic doesn't seem to handle that.

Xifanie

  • 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