Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Tirlititi

Pages: [1]
1
Scripting and Reverse Engineering / FF9 script syntax
« on: 2015-12-13 23:28:45 »
Hello everyone !

I'm going smoothly with the update of my tool, but I would like your opinions about how I should establish scripting conventions.
You don't need to know of Final Fantasy IX or anything to give your opinion, so I ask it here.

I'm about to choose what should be the final syntax for FF9 coding scripts. Up to now, I used a syntax which was thought to look like assembly, but I don't think that's relevant anymore. I naturally came, without thinking too much about it, to this :

1) code control keywords are lower case
Examples : if, then, while

2) function names are capitalized. Most of the time, the first part of the name is a verb, but that's not the case for very fundamental functions of one of the game's system.
Examples : AddItem, MoveCamera, RunScript
Other examples : Battle, Field, Menu

3) unknown variable names look like "VAR_AX_Y" where X and Y are numbers, and A is a letter (A, B, C or D).
Examples : VAR_A1_10, VAR_B7_95, VAR_C3_1816

4) known global variable names are capitalized and can be prefixed either with their category, or with something they are related to.
Examples : SV_PlayerTeam, SV_Target, MV_WorldPositionX
Other examples : Chocobo_BeakLevel, Global_ScenarioCounter, World_CurrentTransport

5) there are also getters, for which the syntax is like the one of a variable (ie. with no parenthesis) but with no prefix and a "Get" instead.
Examples : GetTime, GetDialogProgression, GetRandom

6) known local variable names are lower case.
Examples : i, attackamount, attacklist1

7) some operations are a bit obscure and not in the standard operation list of many programming languages. The boolean XOR operation is noted ^ and there are list operators which are normal operators with a $ appended.
Examples : =$, >$, >=$

8 ) unknown functions and operations obviously have gibberish names, but if you have an idea to make them more convenient, you're also welcome.
Examples : 0x0E, 0xA4, 0x39
Other examples : Op43, Op2B, OpF

Here is a sample of 3 functions (2 from an IA and 1 from a world map character creation) written with these conventions, as they would be displayed in the tool.
Code: [Select]
Function Adamantoise_Init
    set attackamount = 6
    set attacklist1 = 262144L
    set attacklist2 = 130
    set attackmplist1 = 3145728L
    set attackmplist2 = 1300
    set i = 0
    while ( i < attackamount ) {
        set tmp1 |= ( i << ( i * 3 ) )
        set i++
    }
    set i = attackamount
    while ( i > 1 ) {
        set tmp2 = ( GetRandom % i )
        set tmp3 = ( 7 << ( tmp2 * 3 ) )
        set tmp3 &= tmp1
        set attackshuffledlist |= ( tmp3 << ( ( ( i - tmp2 ) - 1 ) * 3 ) )
        set tmp2 = ( ( 1 << ( tmp2 * 3 ) ) - 1 )
        set tmp3 = ( tmp2 & tmp1 )
        set tmp2 ^= 16777215L
        set tmp1 = ( ( tmp1 >> 3 ) & tmp2 )
        set tmp1 |= tmp3
        set i--
    }
    set attackshuffledlist |= ( tmp1 & 7 )
    return

Function Adamantoise_ATB
    set attacklistselection = ( attackshuffledlist & 7 )
    set tmp2 = GetRandom
    set tmp3 = 128
    set i = ( attackamount - 1 )
    while ( i >= 0 ) {
        if ( tmp2 > tmp3 ) {
            break
        }
        set tmp3 >>= 1
        set i--
    }
    if ( i == 65535 ) {
        set i = ( attackamount - 1 )
    }
    if ( i == ( attackamount - 1 ) ) {
        set attackshuffledlist = ( ( attackshuffledlist >> 3 ) & 2097151L )
        set attackshuffledlist |= ( attacklistselection << ( i * 3 ) )
    } else {
        if ( i ) {
            set tmp1 = ( attacklistselection << ( i * 3 ) )
            set tmp2 = ( ( 1 << ( ( i + 1 ) * 3 ) ) - 1 )
            set tmp3 = ( ( tmp2 & attackshuffledlist ) >> 3 )
            set tmp3 |= tmp1
            set tmp2 ^= 16777215L
            set attackshuffledlist &= tmp2
            set attackshuffledlist |= tmp3
        }
    }
    set i = attackamount
    while ( i >= 0 ) {
        switch 8 ( attacklistselection ) from 0 {
        case +0:
            set #( SV_Target = RandomInTeam(SV_PlayerTeam) )
            break
        case +1:
            set #( SV_Target = RandomInTeam(SV_PlayerTeam) )
            break
        case +2:
            set #( SV_Target = RandomInTeam(SV_PlayerTeam) )
            break
        case +3:
            set #( SV_Target = RandomInTeam(SV_PlayerTeam) )
            break
        case +4:
            set #( SV_Target = SV_PlayerTeam )
            break
        case +5:
            set #( SV_Target = SV_PlayerTeam )
            break
        case +6:
            set #( SV_Target = SV_FunctionEnemy )
            break
        case +7:
            set #( SV_Target = SV_FunctionEnemy )
        }
        if ( attacklistselection >= 4 ) {
            set tmp2 = ( ( attackmplist2 >> ( ( attacklistselection - 4 ) * 6 ) ) & 63 )
        } else {
            set tmp2 = ( ( attackmplist1 >> ( attacklistselection * 6 ) ) & 63 )
        }
        set tmp1 = ( #SV_Target )
        set tmp3 = Op2B(SV_FunctionEnemy[MP])
        if ( tmp1 && ( tmp2 <= tmp3 ) ) {
            break
        }
        if ( i <= 0 ) {
            break
        }
        set attacklistselection = ( attackshuffledlist & 7 )
        set attackshuffledlist = ( ( attackshuffledlist >> 3 ) & 2097151L )
        set attackshuffledlist |= ( attacklistselection << ( ( attackamount - 1 ) * 3 ) )
        set i--
    }
    if ( attacklistselection >= 4 ) {
        set selectedattack = ( ( attacklist2 >> ( ( attacklistselection - 4 ) * 6 ) ) & 63 )
    } else {
        set selectedattack = ( ( attacklist1 >> ( attacklistselection * 6 ) ) & 63 )
    }
    if ( ( #( SV_FunctionEnemy[HP] ==$ 1 ) ) && ( #( SV_FunctionEnemy[MP] >$ 10 ) ) ) {
        set #( SV_Target = RandomInTeam(SV_PlayerTeam) )
        set selectedattack = 3
    }
    Attack( selectedattack )
    return

Function World_Zidane_Init
    0x3B( 1 )
    SetModel( 310, 100 )
    0x93( 5 )
    SetObjectLogicalSize( 0, 50, 100 )
    SetObjectSize( 7, 67, 67, 67 )
    SetStandAnimation( 4724 )
    SetWalkAnimation( 4727 )
    SetRunAnimation( 4727 )
    MoveInstant( 241934L, -1254, 4294713142L )
    TurnInstant( 77 )
    return

What do you think?

2
Gameplay Releases / [FF9] Alternate Fantasy (v3.2 & v4.3)
« on: 2015-08-26 18:21:40 »
Final Fantasy IX : Alternate Fantasy is a mod aiming to increase the difficulty and, above all, to give a new experience of FF9 for those who already know the game well.

┌──────────────────────┐
§  PlayStation Version (US)  §
└────┬────────────┬────┘
§ Steam Version §
└────────────┘

For the PSX version, you install it by applying a PPF patch to the original game files. You can use the tool PPF-O-MATIC that is included in the mod archive.

For the Steam version, you directly replace some of the game's files by the modded ones.

What are the modifications?
A lot of them. Most are gameplay related but a few of them are also scenaristical. There are two kinds of scenaristical changes :
1) A few dialogs that were suppressed during the game's development were put back in this mod. It includes the dialogs from the "Hidden Dialogs" patch plus a few others for which only the texts were kept.
2) Beatrix can be permanently recruited after getting the airship (optional). Cutscenes are changed from this point onward to include Beatrix in them (Steam version only).

The main things now.

Abilities, be it the player characters' or the enemies' ones, have been modified.
One of the point of the mod is too enhance the statuses. Some basic spells deal statuses additionnally to their damage.

Here is a list of the principal changes in the player's abilities :

Zidane
Trance skills deal much less damage
What's that?! inflicts Blind to everyone now
Annoy has been replaced by Free Energy : a regular attack with 100% accuracy and no backrow reduce
Sacrifice has been replaced by Regenerate : use an ether on the team
Lucky Seven has been replaced by Warm Up : increase Zidane's strength by 25%
Thievery has been replaced by Transcend : bring Zidane to Trance

Vivi
Fire spells have a chance to inflict Heat (base : 5%, 10% and then 20%)
Ice spells have a chance to inflict Freeze (base : 5%, 10% and then 20%)
Thunder spells have a chance to inflict Slow (base : 10%, 20% and then 40%)
Slow has been replaced by Annoy (80% of inflicting trouble)
Demi has been balanced from 30% of max HP with 40% accuracy to 25% of max HP for 80% accuracy
Death has been replaced by Gradual Petrify (75% accuracy)
Break is now an Earth elemental attack in addition to inflicting Petrify (30% accuracy)
Water sometimes inflict Shell to its targets
Meteor has been replaced by Waterga : Water damage plus Silence (50% accuracy)

White Magic
Panacea only cures Poison but is multi-targeting
Stona only cures Gradual Petrify but is multi-targeting
Confuse and Berserk are now magical attacks in addition to inflicting statuses
Most of status-inflicting spells have their accuracy upscaled
Holy sometimes inflict Regen to its target

Dagger
The full powered Ark now deal damage twice, allowing to deal more than 9999

Eiko
Fenril is a wind eidolon by default

Quina
LV5 Death has been replaced by LV5 Flare : inflict non-elemental damage to enemies with lvl multiple of 5
LV4 Holy has been replaced by LV4 Def-less : randomly decrease defence of enemies with lvl multiple of 4
LV3 Def-less has been replaced by LV3 Aerial Slash : inflict Wind damage to enemies with lvl multiple of 3
Doom has been replaced by Lightning : Thunder damage plus Silence to one target (50% accuracy)
Roulette has been replaced by Self-Destruct : convert Quina's current HP into damage on all the enemies
Aqua Breath has 75% accuracy instead of 50%
Matra Magic has been replaced by Zombie Breath : non-elemental damage plus Zombie on one target (20% accuracy)
Limit Glove has been replaced by HP Switching : switch Quina's current HP with an ally's ones
Twister has 50% to inflict Float in addition to its Wind damage
Earth Shake has 100% to inflict Slow in addition to its Earth damage
Frog Drop has been replaced by Devil's Snack : use a Dead Pepper on all enemies
Freeze has been replaced by Cocytos : Ice damage and inflict Slow on one target (100%)
Mustard Bomb has been replaced by Phlegethon : Fire damage and inflict Haste on one target (100%)

Freya
Lancer's damage are increased, as well as its MP cost
Dragon Breath has been replaced by Dragon Life : apply Auto-Life on Freya
Six Dragons has became single-targeting for 15 MP
Cherry Blossom is more powerful
Dragon's Crest has been replaced by Ikari : deal physical damage and Trouble to all the enemies (50%)

Amarant
Aura has been replaced by Starburst : deal 60 times an enemy's level as damage
Demi Shock's accuracy has been upscaled from 50% to 80%
Countdown has been replaced by Concentrate : increase an ally's Magic by 33% for 28 MP

Steiner
Iai Strike has been replaced by Quadraslash : a physical attack using the elemental power of Fire, Ice, Thunder and Water
The accuracy of the 4 break abilities have been upscaled
Thunder Slash now inflict 21% of target's max HP as thunder damage
Climhazzard has been replaced by a weaker Shock : deal 2 times the physical damage on one target
Shock has been replaced by Sword Dance : deal 2 times the physical damage on all enemies ; it's a magical attack

Marcus
Added 2 abilities for the time he is with you on the disc 2 : Strong Hit (more damage but harm Marcus) and Contaminate (100% to inflict Poison)

Also,
Ragtime Mouses Quizz has been refreshed
The enemies are stronger and more resistant
The most frustrating bug of the game has been corrected : the last Tetra Master rank displays properly
Few weapons can be used by several characters (for instance, Dagger can use the... dagger)
The ultimate weapons give a big boost to main characteristics (Strength, Magic, Speed and Spirit)
Enemies' spells have been modified using similar principles as the player's spells
Phoenix Pinions now cure Doom ; they also cost and sell cheaper
A mini-game has been re-added at the beginning of disc 3. It was half present in the game's code and had the following comment in the japanese version :
Quote
また制作途中なのでバグレポート不要で〜す
Which means in short that it was too much buggy and boring to be in the final game. While the bugs have been corrected, it will likely not keep you on tenterhooks for hours ^^"
Excalibur II can now be acquired by two different methods :
1) Reach and beat Hades in less than 14 hours,
2) Get all the treasures of the game (there are 3 little mistakes allowed) to obtain the higher treasure rank. Some particular cases don't count (Stilzkin's sells and Ragtime Mouses's/Ozma/Hades rewards mainly). Kupo Nuts don't count by theirself but all the one-time rewards count (roughly 1 per disc from disc 2). Similarly, Chocographs don't count when you unearth them but the treasure themselves count. Also, Mimics count. In the end, that makes 404 unique treasures to find.

And much more... I won't tell you everyting but let you discover it by yourself  :mrgreen:


Enjoy !

3
Hey !

The last tool of mine is a FF randomizer. It's a kind of tools that quickly refreshes the game by randomizing some of its content. That's a bit popular in the speedrunning scene where there are already runners taking a break on randomized versions of other Final Fantasies (I discovered it myself with FFX, as there's a tool for randomizing the sphere grids).

The spells are randomized among the spells used by the party in the vanilla game. For instance, Vivi can get Stock Break or Dagger can get Doomsday.
The weapons and armors also teach random abilities.

Another thing it can do is randomizing both the cards that the enemies drop and the cards used by the opponents during Treno's tournament.

Here is the download link :
Meteor On Final Fantasy IX

It only works with the american version of the game. Don't forget to apply the changes on all the 4 discs !

Have fun  8-)

4
Troubleshooting / Modeling quads
« on: 2013-09-12 20:33:38 »
Hi.

I've got some problems exporting 3D models for my program. I use .obj as the output format and I thought it would support quads for its faces.
But it doesn't work well...

So I have several questions : does .obj really support quads? May the problem comes from my 3D editing tool (Blender) ? Or is that my graphic card that doesn't support quads (how do I check it?)

When trying to open .obj with quads (TITS lines like "f 1/1 2/2 3/3 4/4"), I end up with those quads being displayed with glitches. I attached screenshots...
It may also be because of the ordering of the vertices in the faces (it should be standardized though)... I'll test it tomorrow.

Quads displayed in "Solid" mode


Quads displayed in "Texture" mode


Quads as they should be displayed


What do you guys think?

5
Tools / [FF9] General editor - Hades Workshop (0.38)
« on: 2013-06-06 17:51:30 »
Hi there !

I'm working on a Final Fantasy IX modding tool called Hades Workshop. It is aiming to allow to edit most of Final Fantasy IX's content. Quite a big project and I don't know if I will ever decide when it's finished  ;D

//============== THE TOOL =================//

The features so far :
- Can open Final Fantasy IX PSX files, in .bin format and in any language version,
- Now works with the Steam version,
- Read and edit datas about :
--- Spells the party can cast,
--- Supporting abilities the party can use,
--- Commands the party has,
--- Default stats of the party members,
--- Items' features,
--- Items sold in shops,
--- Statistics, attacks and AI of enemies,
--- Tetra Master cards,
--- Text, dialogs and charmap,
--- Game's script,
--- MIPS script and CIL script,
--- Model exporting (Battle Scenes only for PSX, more for Steam),
--- Backgrounds (view only in PSX, view/replace in Steam),
--- Steam resources exporter/importer,
--- Spell animation sequencing.
- Works under Windows only (you may recompile the source code I redistribute or use wine under linux).

It may be a good idea to have a look at the help (F2).

Also, I recommend to the new Steam users to go easy with this tool. Several features are easy to get familiar with, but due to the power of this program and the complexity of FF9, there are subtilities and traps to avoid.
You should read this post to get to know some of them.
Important : Hades Workshop doesn't work if Albeoris's Memoria tool was used. The other tool called Memoria (seriously Albeoris...) by gjoerulv works just fine.

Credits :
I made the program, obviously, but I got helped a lot by your wiki (http://wiki.qhimm.com/view/FF9) for cluster datas format and by http://finalfantasy.wikia.com/ occasionally.

Other than that, LandonRay and Zande made quiet an useful work in data finding, Zidane_2 wrote most of the other tools about FFIX before me.

The background image has been drawn by Maxa'. You can check his Deviant-Art page here.

Please tell me if you get any suggestion/bug report/feedback to share ^^

Here are the download links :

HADES WORKSHOP

Github project

The older versions can be found here

Thank you for your attention  :)

//=============== THE MODS =================//

Here are Final Fantasy IX mods made using Hades Workshop. I won't speak of LandonRay's mod because it is not related to it, but it's also worth a look ^^
Difficulty Tweak : Made by Iamthehorker, this mod increases the MP cost of the abilities and make the battles tougher. The gameplay itself is preserved, so it really is an increase of difficulty for an augmented playthrough. If you think that the boss battles end too quickly or if you never saw the use of the ethers/elixirs, this mod is a way to go. It also allows Steiner to equip the Save of the Queen in the end-game.
Final Fantasy Formula IX : A mod made by Aidolu with completly different spells and commands. I particulary like how commands have been re-invested to make spells like Songs or Cooking moves. The new spells are mostly taken from other Final Fantasy with few changes sometimes because of the limitation of my program or of FFIX battle mechanics.
Save The Queen : A mod made by ThisGuyAreSick2. It allows Steiner to use the allmighty Save The Queen. It also changes the way you synthesize it (it's made in the Black Mage Village in disc 4).
FF9.2.2 : A mod made by Vir to improve the Perfect Stats challenge balancing. It removes the forced exp battle so a true lvl 1 game can be made. It also fixes the Thunder Slash glitch. Vir also made a Fixed Stats Mod which removes the primary stat variations from games to games and have a normalized stat progression.
Alternate Fantasy : My own mod. It modifies a bit of everything in the game but mostly change the abilities and the gameplay in battles.

Also, you can find here the different tiny mods I made over the years.

//============== HELP AND TIPS =================//

This topic is now more than 30 pages long. Different people asked for help at different points and I always tried to give a complete answer. You can thus find details in this topic about subtilities of the game, or how a feature of HW works, or how to do some precise thing. Since I don't want everyone to read the whole topic thoroughly, here are links to answers to these kind of questions.

Side effects of Initial/Auto-statuses
A list of spells specially handled by the engine
Bypass the enemies' Max HP limit
Checking if a character is in the team in-battle
Enabling an enemy attack depending on the party stats
Make Zorn & Thorn battle more difficult
About the random encounter rate
Removing Dagger's depression effect in-battle
About Ragtime Mouse quizz and reward script
Unlocking manually a few of the "Hidden Scenes"
Skipping the script that makes Dagger unlearn her summons
Make Mini-Theater Ship obtainable as a key item
Removing Excalibur II time condition manually
Making temporary characters available in the party menu (1)
Making temporary characters available in the party menu (2)
Changing properly the content of a chest
Ensure that characters enter the party at level 1
How to use "GetRandom" to generate a random number in a range
List of animation IDs and who use them
Declaring local and global variables in scripts
Typical NPC dialog script
Add NPC and PC on the field
Manually extracting a Beatrix mod out of Alternate Fantasy
How to mix some of the standard mods
A word about background and walkmeshes
HW format for text file batching
Helping with the development of HW
Bug when making a multi-hit spell animation (PSX)
Adding custom text font (PSX)
Using Memory card saves after modding (PSX)
Fixing "The Collector" Tetra Master bug (PSX)
Change the initial items + hex-hack to give supporting abilities to Beatrix (PSX)
MIPS editing + controlling someone else than Zidane in fields for PSX
Grudge's MIPS spell formula (PSX)
Using the Background Editor (Steam)
Properly adding a new enemy to a battle (Steam)
Removing (some of) the bubbles appearing when you get close to NPC on Steam
Removing the stat growth of characters (Steam)
Modding Magic Stone growth of characters (Steam)
Modding spell effect: explanation (Steam)
Modding Supporting Abilities: HP/MP +X% (Steam)
Modding Supporting Abilities: Auto-status and Immunes (Steam)
Skipping the last two cinematics of the game (Steam)

//================ BONUS =================//

Simplified Game Scripts

Here are some scripts of systems or mini-games that are of some interest if you wish to know how the game works in-depth.
FFIX Code Folder

Hidden dialogs

Here are some few interesting secret dialogs, never used in the game.
I've also made a patch to enable some of them in-game :
Hidden Dialogs (PSX)
Hidden Dialogs (PC)
And a video showing the patch's content.

Don't hesitate to tell me if you find more unused dialogs : I'll add them to the list ^^

Alexandria [Over the roofs...] :
Puck “So, Vivi... Is this your first time in Alexandria?”
Vivi “Uh...  Um...  Yeah. I bought my ticket from a moogle wearing a hat...”
Puck “Bad luck!  If I ever find that moogle, I'll hurt him plenty!”
Vivi “Uh... Thanks...”
Puck “Alright!  Just a little farther 'til we can see the stage!”

Ruined Prima Vista [Steiner's bitterness] :
[1/3]
Steiner “Those bastards... If they plan to demand a ransom, they're wasting their time.  I'll see to it that they receive nothing!”
[2/3]
Steiner “Wretched thieves... I'll see them all hanged!”
[3/3]
Steiner “Those bastards... They will never get away with this!”

Observatory Mountain [Good and Evil with Grampa Morrid] :
Steiner “Alexandria, off course! Burmecia started the war, and we lost our king as a result.”
Morrid “Many wars were fought before the Lindblum Airship Revolution.”
Morrid “Alexandria intiated some of the wars against Burmecia. Now, can you tell me who was right or wrong?”
Steiner “I-I am not talking about the past! I am talking about the future!”
Morrid “What will you do if Alexandria starts a war?”
Steiner “When will the cargo ship arrive!?”

Gizamaluke's Grotto [Entering Burmecia] :
Burmecian Soldier “This is the Gizamaluke's Grotto. It is Burmecia's border.”
Burmecian Soldier “No one is allowed inside without the king's permission.”

Cleyra [Meeting with the King and the High Priest] translated from japanese by luksy :
Freya “It has been some time, Your Majesty.”
King of Burmecia “Ah, Freya, well met.”
King of Burmecia “The High Priest and I welcome you.”
High Priest of Cleyra “My Lady.”
High Priest of Cleyra “It would appear that this predicament no longer concerns Burmecia alone.”
Freya “I understand, Your Holiness.”
Freya “And yet...”
Freya “I fear my strength alone may not suffice.”
King “Freya...I know what troubles you.”
King “I must apologize for earlier.”
King “Can you ever forgive me?”
King “No! off course you cannot.”
King “But the fate of the people of Burmecia now hangs by but a thread.”

Occupied Lindblum Castle [Reaching Cid] :
Don't get caught by the enemy!
Jump out when she looks away!
Man “The regent is waiting for you at the Base Level.”
Man “The enemy is busy loading supplies. Go down on the lift, now!”
Man “Once you get on the lift, my comrades will take care of the rest.”
Zidane “So, I just take the lift to the Base Level without getting caught?”
Yeah...
Zidane “Piece o' cake! Leave everything to me.”
Huh?
Is anybody there...?
A tail?
Meeow!
Oh, it's only a cat...
Zidane (Wow, that was a close one.)
Man “(You idiot!)”
Man “Whatever you do, don't get caught!”
Man “What's wrong? The regent is waiting at the Base Level.”
Man “Go now, or you'll get caught!”
Zidane “I gotta run while she's looking away.”

Occupied Lindblum Castle [The Ancient World Map] :
Regent Cid “That is a national treasure of Lindblum!”
Regent Cid “It was passed down through my ancestors, since the days of the first regent.”
Regent Cid “It was probably made before our continent was covered in the Mist...”
Regent Cid “That is an ancient map of the entire world!”

Alexandria [Balloon Mini-game] translated from french by me :
Girl “You want to play with us?”
Girl “You've got some time to gather balloons and give them to the boys behind us!”
Girl “You get more time depending on the color of the balloon that you bring.”
Green → 5 more seconds
Yellow → 10 more seconds
Blue → 15 more seconds
Red → 30 more seconds
Girl “All the three of us have a balloon and we are somewhere on the square.”
Girl “Well... Start!”
Boy “X more seconds! You have Y points!”

Final [The 2 worlds' fusion] :
The Iifa Tree could not be stopped...
Gaia and Terra's fusion
caused global chaos,
destroying many cities and
taking many lives...

Pages: [1]