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.
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?