CGFalco
Introduction
Since Phantom Wings and Kryal created great tools, a lot of custom characters have been developed by many hackers. They have useful ability to attack or recover from outside of the stage,but no CPs could intentionally use them. You can make CPs use them by making custom AI.
Overview
AI files can be found in FitCharEtc.pac or Fighter.pac. The AI of Fighter.pac defines default AI of CP and the AI of each character override them.
There are three kinds of AI files(AIPD,AIMain,ATKD). AIMain is the main file which defines the character's move. AIMain can be divided into some routines. Each routine has following things.
AIScriptpad[stable]
[IMGHLF]http://img59.imageshack.us/img59/6650/aiscriptpad1.png[/IMGHLF]
AIScriptpad is a program to make custom AI. This program uses JavaScript as scripting language,but you don't have to worry about not knowing it. Though it's JavaScript, all you have to do is calling functions which are defined already. You can program AI like programing in PSA.
Params
Temporary Variables 0x0000-0x0018
internally stored as floats
Functions 0x1000->
ASM routines that return a float value
Script Constants 0x2000->
You can add them with "AddGlobal" function in AIScriptpad.
Commands and their usage
[COLLAPSE="Commands"]
Name|Arguments|Description
Finish||Stops executing current routine.
SetVar|1:ID 2:Value|Sets value of internal array.
Label||Sets a label so that "Seek" can find it.
|1:ID|Sets a label with ID
Return||Returns to previous label in the next frame. If there are no labels above this, stops executing current routine.
Seek||Seeks a label. If the game reaches "Return" after using this, next time the game goes to the found label.
|1:ID|Seeks a label specified with an ID.
If|1:Requirement ...|Creates an If block. If the requirement is true,the game executes commands inside of the block.
IfNot|1:Requirement ...|Creates an If block. If the requirement is false,the game executes commands inside of the block.
Else||This command must be located inside of an If block. If the If block is not executed,commands after this are executed alternatively.
EndIf||Ends an If block.
Stick|1:X(-1 to 1)|Inputs stick. X coordinate stretches from the rear to the front.
|1:X(-1 to 1) 2:Y(-1 to 1)|
Button|1:Flag|Inputs buttons specified with the argument. You can input multiple buttons. Bit1: A, Bit2: B, Bit3: R or L, Bit4: X or Y
Add|1:ArrayID 2:value|Adds value to the internally stored value,and restores it into the same place.
|1:ArrayID 2:value 3:value|
Sub|1:ArrayID 2:value|Subtracts value to the internally stored value,and restores it into the same place.
|1:ArrayID 2:value 3:value|
Mul|1:ArrayID 2:value|Multiplies value to the internally stored value,and restores it into the same place.
|1:ArrayID 2:value 3:value|
Div|1:ArrayID 2:value|Divides value to the internally stored value,and restores it into the same place.
|1:ArrayID 2:value 3:value|
Jump||Jumps to the label found by "Seek" in the same frame.
Or|1:Requirement ...|Additional OR requirement for If/IfNot.
OrNot|1:Requirement ...|Additional OR/NOT requirement for If/IfNot.
And|1:Requirement ...|Additional AND requirement for If/IfNot.
AndNot|1:Requirement ...|Additional AND/NOT requirement for If/IfNot.
CallAI||Calls another AI routine specified with SetAIDest.
|1:TrueID|Calls another AI routine specified with the argument.
Seek2||The same usage as "Seek".
TargetStick|1:X(-1 to 1)|Inputs stick. X coordinate stretches from left to right.
|1:X(-1 to 1) 2:Y(-1 to 1)|
SetTimeout|1:Frames|Sets timeout frames. If you set this to 0,timeout is removed.
SetAIDest|1:TrueID|Sets CallAI destination.
[/COLLAPSE]
Requirements and their usage
[COLLAPSE="Requirements"]
Name|Arguments|Description
Distance|1:Distance|If the distance between the character and the opponent is shorter than the argument,it returns true.
Frames|1:Frames|If the frame count which has passed since the current routine started being executed is larger than the argument,it returns true.
Idle||If both the character and the opponent is normal state,it returns true.
Dashing||If the character is dashing, it returns true.
InAir||If the character is in the air,it returns true.
GT|1:value 2:object of comparison|arg1>arg2
LT|1:value 2:object of comparison|arg1<arg2
GE|1:value 2:object of comparison|arg1>=arg2
LE|1:value 2:object of comparison|arg1<=arg2
Throughable||If the current plane can be fell through,it returns true.
CalledAs|1:TrueID|If the current routine was called as the ID,it returns true.
IsCounterChance|1:0x1 or 0x2|If the argument is 1,it returns whether or not the character is spotdodging. If 2,returns whether or not the character was attacked during guarding.
IsInvincible||If the character is invincible(star,final smash),it returns true.
IsGrabbing||If the character is grabbing and able to throw the opponent,it returns true.
OAttacking||If the opponent is attacking,it returns true.
OWiring||If the opponent is using wire(samus,zero suit,link,etc),it returns true.
OInAir||If the opponent is in the air,it returns true.
TurnRunBraking||If the character is "TurnRunBrak"ing,it returns true.
IsCharOf|1:ID|If the character is the character specified with the argument,it returns true.
OIsCharOf|1:ID|If the opponent is the character specified with the argument,it returns true.
CharID
[/COLLAPSE]
Functions and their usage
[COLLAPSE="Functions"]
Name|Description
Direction|If the character is looking right,returns -1,looking left,1.
OPosition|If the opponent is right of the character,returns -1 ,left ,1.
XCoord|Returns the character's X coordinate.
OXCoord|Returns the opponent's X coordinate.
DistToOEdge|Returns distance to the opponent-side edge.
FrameCount|Returns frame count from beginning of the current routine.
XAcceleration|Returns X acceleration.
YCoord|Returns the character's Y coordinate.
OYCoord|Returns the opponent's Y coordinate.
YAcceleration|Returns Y acceleration.
JumpCount|Returns the character's remained jump count.
DistToLookedEdge|Returns distance to the edge looked by the character.
OXSpeed|Returns X speed of the opponent.
OYSpeed|Returns Y speed of the opponent.
ExactXCoord|Returns the character's exact X coordinate.
ExactYCoord|Returns the character's exact Y coordinate.
ExactOXCoord|Returns the opponent's exact X coordinate.
ExactOYCoord|Returns the opponent's exact Y coordinate.
DamageAmount|Returns the character's damage amount.
ODamageAmount|Returns the opponent's damage amount.
ODirection|If the opponent is looking right,returns -1,looking left,1.
OJumpCount|Returns the opponent's remained jump count.
DistToNotLookedEdge|Returns distance to the edge not looked by the character.
BBoundary|Returns distance to the bottom boundary.
TBoundary|Returns distance to the top boundary.
LBoundary|Returns distance to the left boundary.
RBoundary|Returns distance to the right boundary,
DistBetPlaneTBoundary|Returns distance between the current plane and the top boundary.
[/COLLAPSE]
Resources
[COLLAPSE="Debugging codes"]
This code forces the game load only one routine.
This code visualizes CPU input.
[/COLLAPSE]
AI process image
http://opensa.dantarion.com/ai_dumps/x.png
Coding idioms
Approach to the opponent(walk)
Special thanks
Dantarion: Thank you for helping me looking into AI system. Your suggestion was always correct.
Kryal: Author of BrawlLib. AIScriptpad uses modded BrawlLib.
Jint develop team:I used Jint.dll to interpret JavaScripts.
WPG develop team:I used WPF property grid for property editor.
Phantom Wings:He made File Patch Code. Without it,any SSBB modding wouldn't have been achieved.
See Also
OpenSA-AIScript Notes
In conclusion,this is the source code of CG Falco. I used Force AI Into Routine v2.0 and CPU GFX to record CG Falco video.
Introduction
Since Phantom Wings and Kryal created great tools, a lot of custom characters have been developed by many hackers. They have useful ability to attack or recover from outside of the stage,but no CPs could intentionally use them. You can make CPs use them by making custom AI.
Overview
AI files can be found in FitCharEtc.pac or Fighter.pac. The AI of Fighter.pac defines default AI of CP and the AI of each character override them.
There are three kinds of AI files(AIPD,AIMain,ATKD). AIMain is the main file which defines the character's move. AIMain can be divided into some routines. Each routine has following things.
- ID
- Commands
- Floating point values
AIScriptpad[stable]
[IMGHLF]http://img59.imageshack.us/img59/6650/aiscriptpad1.png[/IMGHLF]
AIScriptpad is a program to make custom AI. This program uses JavaScript as scripting language,but you don't have to worry about not knowing it. Though it's JavaScript, all you have to do is calling functions which are defined already. You can program AI like programing in PSA.
Params
Temporary Variables 0x0000-0x0018
internally stored as floats
Functions 0x1000->
ASM routines that return a float value
Script Constants 0x2000->
You can add them with "AddGlobal" function in AIScriptpad.
Commands and their usage
[COLLAPSE="Commands"]
Finish||Stops executing current routine.
SetVar|1:ID 2:Value|Sets value of internal array.
Label||Sets a label so that "Seek" can find it.
|1:ID|Sets a label with ID
Return||Returns to previous label in the next frame. If there are no labels above this, stops executing current routine.
Seek||Seeks a label. If the game reaches "Return" after using this, next time the game goes to the found label.
|1:ID|Seeks a label specified with an ID.
If|1:Requirement ...|Creates an If block. If the requirement is true,the game executes commands inside of the block.
IfNot|1:Requirement ...|Creates an If block. If the requirement is false,the game executes commands inside of the block.
Else||This command must be located inside of an If block. If the If block is not executed,commands after this are executed alternatively.
EndIf||Ends an If block.
Stick|1:X(-1 to 1)|Inputs stick. X coordinate stretches from the rear to the front.
|1:X(-1 to 1) 2:Y(-1 to 1)|
Button|1:Flag|Inputs buttons specified with the argument. You can input multiple buttons. Bit1: A, Bit2: B, Bit3: R or L, Bit4: X or Y
Add|1:ArrayID 2:value|Adds value to the internally stored value,and restores it into the same place.
|1:ArrayID 2:value 3:value|
Sub|1:ArrayID 2:value|Subtracts value to the internally stored value,and restores it into the same place.
|1:ArrayID 2:value 3:value|
Mul|1:ArrayID 2:value|Multiplies value to the internally stored value,and restores it into the same place.
|1:ArrayID 2:value 3:value|
Div|1:ArrayID 2:value|Divides value to the internally stored value,and restores it into the same place.
|1:ArrayID 2:value 3:value|
Jump||Jumps to the label found by "Seek" in the same frame.
Or|1:Requirement ...|Additional OR requirement for If/IfNot.
OrNot|1:Requirement ...|Additional OR/NOT requirement for If/IfNot.
And|1:Requirement ...|Additional AND requirement for If/IfNot.
AndNot|1:Requirement ...|Additional AND/NOT requirement for If/IfNot.
CallAI||Calls another AI routine specified with SetAIDest.
|1:TrueID|Calls another AI routine specified with the argument.
Seek2||The same usage as "Seek".
TargetStick|1:X(-1 to 1)|Inputs stick. X coordinate stretches from left to right.
|1:X(-1 to 1) 2:Y(-1 to 1)|
SetTimeout|1:Frames|Sets timeout frames. If you set this to 0,timeout is removed.
SetAIDest|1:TrueID|Sets CallAI destination.
Requirements and their usage
[COLLAPSE="Requirements"]
Distance|1:Distance|If the distance between the character and the opponent is shorter than the argument,it returns true.
Frames|1:Frames|If the frame count which has passed since the current routine started being executed is larger than the argument,it returns true.
Idle||If both the character and the opponent is normal state,it returns true.
Dashing||If the character is dashing, it returns true.
InAir||If the character is in the air,it returns true.
GT|1:value 2:object of comparison|arg1>arg2
LT|1:value 2:object of comparison|arg1<arg2
GE|1:value 2:object of comparison|arg1>=arg2
LE|1:value 2:object of comparison|arg1<=arg2
Throughable||If the current plane can be fell through,it returns true.
CalledAs|1:TrueID|If the current routine was called as the ID,it returns true.
IsCounterChance|1:0x1 or 0x2|If the argument is 1,it returns whether or not the character is spotdodging. If 2,returns whether or not the character was attacked during guarding.
IsInvincible||If the character is invincible(star,final smash),it returns true.
IsGrabbing||If the character is grabbing and able to throw the opponent,it returns true.
OAttacking||If the opponent is attacking,it returns true.
OWiring||If the opponent is using wire(samus,zero suit,link,etc),it returns true.
OInAir||If the opponent is in the air,it returns true.
TurnRunBraking||If the character is "TurnRunBrak"ing,it returns true.
IsCharOf|1:ID|If the character is the character specified with the argument,it returns true.
OIsCharOf|1:ID|If the opponent is the character specified with the argument,it returns true.
Code:
0 Mario
1 Donkey
2 Link
3 Samus
4 Yoshi
5 Kirby
6 Fox
7 Pikachu
8 Luigi
9 Falcon
A Ness
B Bowser
C Peach
D Zelda
E Shiek
F Popo
10 Nana
11 Marth
12 G&W
13 Falco
14 Ganondorf
15 Wario
16 Metaknight
17 Pit
18 Zerosuit Samus
19 Pikmin
1A Lucas
1B Diddy
1D Lizardon
1E Zenigame
1F Fushigisou
20 DDD
21 Lucario
22 Ike
23 Robot
25 Purin
29 Toonlink
2C Wolf
2E Snake
2F Sonic
Functions and their usage
[COLLAPSE="Functions"]
Direction|If the character is looking right,returns -1,looking left,1.
OPosition|If the opponent is right of the character,returns -1 ,left ,1.
XCoord|Returns the character's X coordinate.
OXCoord|Returns the opponent's X coordinate.
DistToOEdge|Returns distance to the opponent-side edge.
FrameCount|Returns frame count from beginning of the current routine.
XAcceleration|Returns X acceleration.
YCoord|Returns the character's Y coordinate.
OYCoord|Returns the opponent's Y coordinate.
YAcceleration|Returns Y acceleration.
JumpCount|Returns the character's remained jump count.
DistToLookedEdge|Returns distance to the edge looked by the character.
OXSpeed|Returns X speed of the opponent.
OYSpeed|Returns Y speed of the opponent.
ExactXCoord|Returns the character's exact X coordinate.
ExactYCoord|Returns the character's exact Y coordinate.
ExactOXCoord|Returns the opponent's exact X coordinate.
ExactOYCoord|Returns the opponent's exact Y coordinate.
DamageAmount|Returns the character's damage amount.
ODamageAmount|Returns the opponent's damage amount.
ODirection|If the opponent is looking right,returns -1,looking left,1.
OJumpCount|Returns the opponent's remained jump count.
DistToNotLookedEdge|Returns distance to the edge not looked by the character.
BBoundary|Returns distance to the bottom boundary.
TBoundary|Returns distance to the top boundary.
LBoundary|Returns distance to the left boundary.
RBoundary|Returns distance to the right boundary,
DistBetPlaneTBoundary|Returns distance between the current plane and the top boundary.
Resources
[COLLAPSE="Debugging codes"]
This code forces the game load only one routine.
Code:
Force AI Into Routine v2.0 [Dantarion]
C29188B0 00000002
3B40XXXX B3590078
60000000 00000000
Where XXXX = Routine ID
Code:
CPU GFX [Shanus]
4A000000 90000000
1619F000 000003F0
00000000 FFFFFFFF
00000006 00000030
00000000 00000000
00000000 00000001
00000000 00000000
00000001 00000000
00000001 000493E0
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 0000EA60
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000003 00000000
00000006 00000030
00000000 00000001
00000000 00000003
00000000 00000000
00000001 00000000
00000001 00075300
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 0000EA60
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000003 00000000
00000006 00000030
00000000 00000002
00000000 00000005
00000000 00000000
00000001 0003A980
00000001 000493E0
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 0000EA60
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000003 00000000
00000006 00000030
00000000 00000003
00000000 0000000C
00000000 00000000
00000001 0003A980
00000001 00075300
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 0000EA60
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000003 00000000
00000000 0000001E
00000000 00000000
00000005 000003F5
00000005 000003FA
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 0000EA60
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000001 00000000
00000003 00000000
00000001 0000EA60
00000000 00000001
00000003 00000000
00000003 00000000
00000000 00000003
00000003 00000000
00000003 00000000
00000000 00000005
00000003 00000000
00000003 00000000
00000000 0000000C
00000003 00000000
00000003 00000000
00000000 0000001E
00000003 00000000
00000003 00000000
00040100 9019F000
000A0200 9019F008
11001000 9019F018
000F0000 00000000
000A0200 9019F098
11001000 9019F0A8
000F0000 00000000
000A0200 9019F128
11001000 9019F138
000F0000 00000000
000A0200 9019F1B8
11001000 9019F1C8
000F0000 00000000
11001000 9019F248
00010100 9019F2C8
11050300 9019F2D0
11050300 9019F2E8
11050300 9019F300
11050300 9019F318
11050300 9019F330
00050000 00000000
1819F400 9019F348
21FF0004 00000000
0689D858 00000008
3C609019 6063F448
AI process image
http://opensa.dantarion.com/ai_dumps/x.png
Coding idioms
Approach to the opponent(walk)
Code:
SetVar(var0,OPosition);
Mul(var0,0.5);
TargetStick(var0,0);
Return();
Special thanks
Dantarion: Thank you for helping me looking into AI system. Your suggestion was always correct.
Kryal: Author of BrawlLib. AIScriptpad uses modded BrawlLib.
Jint develop team:I used Jint.dll to interpret JavaScripts.
WPG develop team:I used WPF property grid for property editor.
Phantom Wings:He made File Patch Code. Without it,any SSBB modding wouldn't have been achieved.
See Also
OpenSA-AIScript Notes
In conclusion,this is the source code of CG Falco. I used Force AI Into Routine v2.0 and CPU GFX to record CG Falco video.
Code:
//True ID:1120
//Set AIID
SetID(0x1120);
//Set Unknown
SetUnknown(0x40000);
//Strings
//Set Globals
AddGlobal(2);//0
AddGlobal(0);//1
AddGlobal(5);//2
AddGlobal(-1);//3
SetTimeout(0x2002);
//Commands
Label();//Approach routine
If(IsGrabbing);
Seek(0x0);
Return();
EndIf();
IfNot(Distance,0x2000);
IfNot(LT,DistToOEdge,0x2000);
TargetStick(OPosition);
EndIf();
Else();
Seek(0x1);
EndIf();
Return();
Label(0x1);//Grabbing routine
Button(0x5);
Return();
Label(0x0);//Throwing routine
//Stick(0x2001,0x2003);//Down
TargetStick(0x2001,0x2003);
Finish();
Return();
Return();