
SPT file modification tutorial
          ————By Lee Catalpa Tien
		  
Welcome to the Character SPT tutorial! This tutorial will explain some concepts and applications in SPT from simple to complex! You can look at the original SPT while referring to the tutorial to understand it.
Some conceptual things can not be understood temporarily, just use them, and understand them naturally.

Directory: (press Ctrl+G to transfer to the specified line)
Symbols and formats: 39
Some basic concepts: 75
Official start of the tutorial: 243
     
	  1. Action: 243
       01. Skill button setting chapter: 355|02, action frame chapter: 604|03, action group chapter: 778|04, creating new skill chapter: 1438|05, key sequence chapter: 1898|06, action transplant chapter: 2138

      Two, basic parameters: 2158
       01. Simple basic parameters chapter: 2167|02, War recruitment related parameters chapter: 2229|03, skin binding chapter: 2270

      Three, frame entry: 2441
       01. End Frame: 2449|02, Demolition: 2477|03, Frame Delay: 2769|04, Copy Frame: 2783|05, Simple Parameter: 3071
      
      Four, frame articles: 3091
	   01. Limit articles: 3096|02, body articles: 3114|03, defense judgment articles: 3148|04, attack articles: 3165|05, attack data articles: 3201
	   
	   06, cre props articles: 3303|07, find key frames articles: 3344|08, texture introduction articles: 3373

	  Five, frame advanced articles: 3389
	   01. Texture Setting: 3396|02, Texture Display: 3494|03, Texture Separation: 3531|04, Texture Migration: 3730|05, fSpec: 3832

      Sixth, advanced skills:
       01. Transformation actions: 3855|02, Transformation stickers: 4349|03, Transformation magical articles: 4425







symbol:

First of all, we have to understand the symbol, which is very important. If the symbol is wrong, the file will not be able to be used normally.
Next are some basic symbols. To help understand, I will set some fictitious parameters, such as "value 1", which have nothing to do with the SPT in the original game.

Basic symbols:

Double quotation marks (must be English double quotation marks) "" When setting a parameter, the parameter name must be enclosed in double quotation marks, for example: "value 1"           

Colon (English): When assigning a value to a parameter, a colon must be added in front of the value. The assigned value can be a number or a small parameter contained in the original parameter, for example: "Value 1": 1.0
Points that need special attention: ①The pure value must be added to the decimal point, and the decimal point can be 0, but it cannot be missing; ②The colon and the value must be separated by a space, for example: "value 1": 1.0 √; "Value 1": 1.0 ×; "Value 1": 1 ×

Comma (English),    
If there are multiple parameters of the same level side by side,
It needs to be separated by a comma, and the last parameter in a brace does not need or is not allowed to use a comma.
E.g:

"Value 1": 1.0,
"Value 2": 3.0,
"Value 3": 10.0,
"Value 4": 12.0 <--------Note that there is no comma here, because there is no new sibling parameter below.

big parantheses{ }    
When the assigned value is not a simple number but multiple elements or new parameters,
Braces will be used,
E.g:

"Value 9": {<-----------The colon and the braces must also be separated by spaces.
       "HFW_ArrayLenXXX": 3,        
         "0": 3.0,
		 "1": 6.0,
		 "2": 5.0                
} <------------The upper brace is used before, and the lower brace must be used here, otherwise the file will be wrong.



basic concepts:

Multi-level parameters: There are often multiple elements under one parameter,
These elements may be pure numbers,
It may also be a new parameter, for example:

 "Value 9": {
       "HFW_ArrayLenXXX": 3,         
         "0": 3.0, <------------Note that the preceding "0" is an element and not a value. If it is a value, it should be expressed as "0.0", and the latter 3.0 is a specific Numerical value
		 "1": 6.0,
		 "2": 5.0 <------------It can be seen that the size of the value does not necessarily have to be in order, the order is determined by other factors, which will be explained in detail later.
 }                         



<------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------------------------>




"Value 9": {
       "HFW_ArrayLenXXX": 3,        
         "0": 3.0,
		 "1": 6.0,
		 "2": 5.0                
}, <------------ Parameters containing multiple elements should also be separated by commas
"Value 10": {
       "HFW_ArrayLenXXX": 3,        
         "0": 3.0,
		 "1": 8.0,
		 "2": 9.0
}

<------------It should be noted that although there are three elements here, the essence of these three elements is exactly the same, they are all about the "value 10" element

Here I introduce a concept of "similar elements" and "heterogeneous elements" to help understand (just my own name, not a professional term)

Similar elements: elements with the same nature. For example, in action, 0 to 100 are different actions, but their properties are all the same. They are all actions, which can be understood as a total of N actions, and their parameters are divided into N Copies.

Heterogeneous elements: multiple elements that are fundamentally different. For example, in the "1" (standing action) of action, "nextAti" and "a_keyTgr" are two different elements. They play different roles and assign different values. .

Generally speaking, a large parameter contains only heterogeneous elements,
Either it contains only similar elements, it’s easy to distinguish them,
We can look at the element name. If it is a serial number such as "0", "1", and "2", then it is a similar element; if it is a specific name such as "nextAti" and "a_keyTgr", it is a heterogeneous element.

E.g:

"action": {
"HFW_ArrayLenXXX": 4, <------------When the elements under a parameter are of the same kind, "HFW_ArrayLenXXX" must be added: n, (n indicates how many elements there are, there is 0 , 1, 2 three elements, then n=3, this is the number of elements, not the value, so no quotes are needed) 
"0": {
                "HFW_classNameXXX": "Data.Action",
            ......
            ......
			},
"1": {<------------As you can see, the elements here have no specific names, only serial numbers, because although these elements represent different actions, they are essentially the same, and they are all actions ( action), so they are similar elements
                "HFW_classNameXXX": "Data.Action",
            ......
            ......
			},
"2": {
                "HFW_classNameXXX": "Data.Action",
            ......
            ......
			},
"3": {
                "HFW_classNameXXX": "Data.Action",
            ......
            ......
			}			

<------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------------------------>


The element can be a value or a new parameter
E.g:



"action": {
       "HFW_ArrayLenXXX": 220,     
               "0": {<-------------At this time, the element under "15" is no longer a number, but a new parameter
                "HFW_classNameXXX": "Data.Action", <-------------At this time, the elements in "0" represent many different meanings (essentially different), so they are heterogeneous elements.
                "selfLoop": true, so instead of "HFW_ArrayLenXXX", use "HFW_classNameXXX": "·······" to indicate,
                "nextAi": -1.0, "······" is determined according to the nature of this element. For example, here "0" belongs to "action", it is represented by "Data.Action".
                "allowTurnFace": true,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "AVATAR",
                "a_keyTgr": {<-------------The internal elements can be further divided into multiple elements.
                    "HFW_ArrayLenXXX": 1, <-------------It can be seen here that the elements under "a_keyTgr" are similar elements, because these elements belong to "a_keyTgr", so they are more and more than "a_keyTgr" "a_keyTgr" elements at the same level are one level lower.
                    "0": {<-------------The "0" here belongs to "a_keyTgr" and should be distinguished from the "0" under "action".
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gua"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 1.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 1.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            },
			"1":·······,
			"2":·······,
			"3":·······,
			·············
			·············
			"219":·······


When looking at the SPT, we often see words such as "null" and "true". Here is a general outline of the concepts of these words.

true: true, if a parameter has only two possibilities of "yes" or "no", true and false will be used to determine whether it is yes or not, for example: "isSoldier", this is the value that controls whether the character is a soldier, if" isSoldier": true, then this character is a soldier.
false: Negative, opposite to true, for example: "isSoldier": false, then this character is not a soldier.
null: does not exist. If you want a parameter to be ineffective, you can use null, for example: "a_keyTgr": null.
Null and false must be distinguished, the former is used for parameters with specific settings, and the latter is used for "yes" and "no" parameters.
If used correctly, the true, false, and null fonts will turn blue

x: horizontal axis, that is, the left and right positions, positive numbers are right, negative numbers are left
z: vertical axis, which is the up and down position, positive numbers are down, negative numbers are up
y: height, positive number is low, negative number is high
hp: HP
mp: energy value
g (guard): defense
u (up): up
j (jump): jump
a (attack): attack
l (left): to the left
r (right): to the right
d (down): down

As the parameters related to them are often used in SPT, let's talk about it in advance.

The meaning of the value:
When assigning values, we will use numbers, these numbers usually have two meanings

①The specific quantity and size, for example: "x": 230.0 represents the position of the horizontal axis is 230 units to the right of the character
If set to a negative number, it is on the left of the character

②Correspond to a sequence number in another parameter, for example: "frameIndex": 53.0 means that the starting frame corresponding to this action is frame 53
If it is set to a negative number, this parameter will not work. It has the same properties as null, but the usage is different

Generally, the values ​​after the parameters with "x", "y", and "z" are all specific sizes, while "int1", "int2", "int3" and "index" are all serial numbers
The size can be changed freely, but the serial number cannot be changed randomly, otherwise an error will occur

Official tutorial:

1. Action.

After understanding the basic format and concepts, we can begin to try to modify the file, we can start with the relatively simple action (action).
Next, I will list the role of each parameter in the action, and then modify it exemplarily.

Ctrl+F can search the document, you can quickly find the location of the action.

(PS: agi (actionGroupIndex), ati (actionIndex), ai (action) are more complicated things, which can be selectively ignored first, and will be explained in detail later.)
"action": {
            "HFW_ArrayLenXXX" (the number after HFW_ArrayLenXXX represents how many values ​​there are, for example, here is 220, which means there are 220 actions): 220,
			"0": ······,
            "1" (the serial number of the value, here is the serial number of the action, corresponding in agi-->ati-->ai): {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop" (action loop, changed to true will restart from the first frame after all frames of the action are over, for example, drew's Overlord Charge must be used with mpBurn and nextAgi, nextAti, nextAi, otherwise it will not stop automatically): false,
                "nextAi" (after the action is over, enter the action corresponding to this ai, only for skill actions and some attacks): -1.0,
                "allowTurnFace" (whether it is allowed to turn around, change it to true will turn around freely like Shawn's five consecutive arrows): false,
                "nextAti" (after the action is over, enter the action corresponding to the ai under this ati, only for skill actions and some attacks): -1.0,
                "frame" (the parameters of the action frame, the function is unknown in the action, the original version is not used, you can explore by yourself): null,
                "special" (characteristics of the skill, explained later): -1.0,
                "landAti" (after landing, enter the action corresponding to the ai under this ati, suitable for landing skills in the air such as the Dragon Slash, only for skill actions and some attacks): -1.0,
                "landAi" (after landing, enter the action corresponding to this ai, only for skill actions and some attacks): -1.0,
                "nextAgi" (after the action is over, enter the action corresponding to the ai under the ati under this agi, only for skill actions and some attacks): -1.0,
                "name" (action name is also the ac code in the story, should try to avoid repetition): "STAND", <-------------action names are all uppercase, this is for Distinguish, can be written in lowercase.
                "a_keyTgr" (the skill button in this action): {<-------------The T of keyTgr is capitalized, because this is a phrase, the second word starts, and the first word of each word Use uppercase letters for a letter, such as "allowTurnFace". This cannot be changed to uppercase or lowercase, otherwise it will be invalid, and it must be distinguished from the name.
                    "HFW_ArrayLenXXX": 2 (2, which means that two skills can be used in standing movements),
                    "0" (Serial numbers, must be arranged in order, almost all serial numbers start from "0", not from "1"): {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai" (action serial number, which is different from the serial number under action, is the serial number set in actionGroup, which will be explained in detail later.): 0.0,   
                        "atf" (whether it is allowed to send skills backwards, for example, when Ryusuke runs and attacks, he can turn around to fly dragons immediately, but when Tailai runs and attack, he can only receive the light cannon forward): false,
                        "hp" (HP consumed by the skill, the character cannot release the skill when the hp is lower than this value): 0.0,
                        "ati" (actionIndex to which the action belongs): 3.0,
                        "pollhp" (com will release this skill only when it is lower than this percentage of HP. For example, Tylai’s healing is 45, which is invalid for the player, 0 means unlimited): 0.0,
                        "kl" (The number of buttons must be the same as the actual number of buttons, otherwise the skill cannot be released. Too many buttons will also cause the skill not to be released): 3.0,
                        "k" (the skill button when the character moves to the right): "gua",
                        "mp" (skill cost mp): 275.0,
                        "agi" (actionGroupIndex to which the action belongs): 0.0,
                        "rkt" (whether it will be restricted by "allowKeyTrigger", change it to false, the skill can be used at any time under this action, if true, it needs to be set in the frame before it can be used normally, it will be explained in detail in the frame article): false,
                        "kr" (the skill button when the character moves to the left, can be the same as when the character moves to the right): "gua"
					 },
					 (The new parameters also need to be enclosed in curly braces, I will delete the line break of the second skill below to facilitate understanding)
                    "1": {"HFW_classNameXXX": "Data.A_KeyTgr","ai": 3.0,"atf": true,"hp": 0.0,"ati": 3.0,"pollhp": 0.0,"kl": 3.0 ,"k": "gra","mp": 90.0,"agi": 0.0,"rkt": false,"kr": "gla"}
					Note that there is also a brace, which corresponds to the brace after the "0" in the next two lines of action. The number of upper and lower brackets must be the same.
					----------------------> }, <----------------------
                "landAgi" (after landing, enter the action corresponding to the ai under the ati under this agi, only for skill actions and some attacks): -1.0,
                "frameIndex" (frame represents a frame, there are hundreds of frames for all actions of a character, and this parameter represents the frame at which the action starts): 1.0,
                "mpBurn" (when the action is in progress, the amount of mp consumed every 0.1 seconds, if it is a skill, after consuming mp and completing the action of this round, enter the nextAi corresponding action, if it is not a skill or no nextAi is set, the original action will be kept): 20.0,
                "index" (sequence number, corresponding to the sequence number under action, the inconsistency of the sequence number and index in the action has little effect): 1.0,
				"nextActionName" (the name of the action after the end of the action, just as a mark, you don’t need to write it): null,
				"type" (type, used to set the character's nature, it will not be used in the action, so all are -1.0): -1.0,
				"aiz2" (com's determination range below the Z axis, com will use this skill when it detects an enemy within the Z axis range of aiz1 to aiz2): 200.0,
				"aiz1" (com's judgment range above the Z-axis, com will use this skill when it detects an enemy within the Z-axis range of aiz1 to aiz2): -200.0,
                "aix2" (the right edge of com's X-axis determines the right boundary, com will use this skill when it detects an enemy within the X-axis range of aix1 to aix2): 500.0,
				"aix1" (the right side of com's X axis determines the left boundary, com will use this skill when it detects an enemy within the range of the X axis from aix1 to aix2): 100.0,
                "aix2b" (com's X-axis left to determine the right boundary, com will use this skill when it detects an enemy within the X-axis range from aix1b to aix2b): -100.0,
				"aix1b" (com's X-axis left to determine the left boundary, com will use this skill when it detects an enemy within the X-axis range from aix1b to aix2b): -500.0,
                "landActionName" (the name of the action after landing, just as a mark, you don’t need to write it): null
				}		
            },
			
			For parameters such as aix2, it may not be easy to understand, so I drew a sketch to help understand.			
———————————————————————————————————————————————— ———————————————————————————————————————————————— ———
		  aix1b aix2b aix1 aix2
            | | Character Location | |
	  aiz1 |<------------->| || |<----------->| aiz1
			|<------------->| || |<----------->|
		    |<------------->| || |<----------->|
			|<------------->| |||| |<----------->|
			|<------------->| || || |<----------->|
			|<------------->| || || |<----------->|
			|<------------->| || || |<----------->|
			|<------------->| || || |<----------->|
	  aiz2 |<------------->| || || |<----------->| aiz2
			| | | |
			| | | |
		The two | here represent the left and right range of the map, and the dotted line is the com judgment range. When there is an enemy at the dotted line, com will release this skill.
———————————————————————————————————————————————— ———————————————————————————————————————————————— ——


It can be seen that the value with 2 is always greater than the value of 1, such as the value of aix2 is greater than aix1, then, as shown in the figure below, what if they are reversed to make aix1 larger? You can think about it first.


———————————————————————————————————————————————— ———————————————————————————————————————————————— ———
		  aix2b aix1b aix2 aix1
            | | Character Location | |
	  aiz2 |<------------->| || |<----------->|aiz2
			|<------------->| || |<----------->|
		    |<------------->| || |<----------->|
			|<------------->| |||| |<----------->|
			|<------------->| || || |<----------->|
			|<------------->| || || |<----------->|
			|<------------->| || || |<----------->|
			|<------------->| || || |<----------->|
	  aiz1 |<------------->| || || |<----------->|aiz1
			| | | |
			| | | |
———————————————————————————————————————————————— ———————————————————————————————————————————————— ——

If you carefully observe the actions of Tailai's healing skills, you will find that the ai range set by the healing skills is as shown in Figure 2, because the teammates are to be healed, not the enemies.
Therefore, if the size of 1 and 2 is reversed, com will release the skills when it detects teammates (including itself) in the range, instead of detecting the enemy.


After knowing the function of each parameter in action, we can start to change files. Please open Long Jie's SPT (442), and then follow me to operate.


Types and functions of special:

10: When running, it will control the generation of smoke (such as Xianglong) to prevent the continuous generation of smoke. At the same time, if this action has nextAi set, pressing the opposite direction key will directly jump to the action corresponding to nextAi.

20: During the course of the skill, speed can be applied, such as drew's spin quenching punch and Gordon's rock breaking. The applied speed is determined jointly by jumpSpeedX and speedXRate.

30: Rebound, such as surging meat bombs, regardless of the direction of the enemy's displacement caused by the attack, it will bounce back to the upper side.

01. Skill button setting chapter.

First use Ctrl+F to search for "STAND" (case sensitive) to quickly find the position of the standing action. We first try to modify the keys and mp consumption of Thang Long Zhan. (If you have already mastered the skills to modify the skill button and mp consumption, you can skip this part, and the other chapters will be the same)
PS: When changing, please follow the tutorial strictly for the operation and the modified value, do not modify at will, otherwise it may make mistakes.

① Modify the "gua" button of Thang Long Chop to "a".

"1": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": true,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "STAND",
                "a_keyTgr": {<------------First of all, find the parameter of this control skill key
                    "HFW_ArrayLenXXX": 2,
                    "0": {<------------The range set by the Thang Long Slash skill button can be determined by the braces, just click the space to the right of the brace, and you can observe at the left red line To the parameter range.
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0, (change to 1.0) <------------The number of buttons has changed from three to one, so "kl" (number of buttons) has to be changed from 3.0 to 1.0, we What needs to be changed is the "kl" of Shenglongzhan, so this "kl" must be in braces with the "k" of Shenglongzhan.
                        "k": "gua", (change to "a") <------------It is the quickest way to distinguish skills by pressing the key. We can see that the key here is g (anti- ) U (upper) a (attack), naturally it is Dragon Slash, we try to change it to "a".
                        "mp": 275.0,   
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gua" (changed to "a") <------------The left button should also be changed to "a". Please do not increase or decrease any symbols when changing.
                    }, 
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 1.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 1.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            }
After the modification, it will be like the following parameters, then save the file, drag it into the compressed package of Longsuke SPT, replace the original file through HFW, and export the exe,
After opening the game, press the attack button while Ryusuke is standing, and Ryusuke will be released directly!
"1": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": true,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "STAND",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a", <------------Note that this has been changed to "a".
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "a"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 1.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 1.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            }
			
②Modify the MP consumption of Thang Long Slash.

Let’s keep the button we just changed and don’t change it back (the reason will be explained later),
Then find the key position of Thang Long Zhan again.
"1": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": true,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "STAND",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",  
                        "mp": 275.0, (change to 100.0) <------------Because the button has been changed to "a", it may become difficult to find Thang Long Zhan by pressing the button, but we also You can find the Dragon Slash by mp consumption, because the mp consumption of the same character's skills will rarely be the same, and it will be changed to 100.0 when found.
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "a"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 1.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 1.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            }		
<-----------------The following are the changed parameters------------------>
"1": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": true,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "STAND",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",  
                        "mp": 100.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "a"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 1.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 1.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            }
After importing it again, enter the game, press the attack button to release the Dragon Slash, and you will find that the MP consumption is greatly reduced.

Since the character can release the Dragon Slash skill in multiple actions, it is often necessary to change the button and mp consumption in multiple positions. This also means that the button and mp consumption of the same skill under different actions It can be different. For example, you need to press gra to release the Dragon Slash in the standing movement, but you only need to press a to release the new Dragon Slash in the Dragon Slash movement.
A button like gra (defensive right attack) will first enter the defensive action, then enter the defensive walk, and then press the attack to release the skill. Or first enter the defensive action, resume standing and then walk, and then press the attack to release the skill. Therefore, we need to add the same button settings to the standing, walking, defense, and defensive walking actions, otherwise the skill will often not be pressed.
This is also the reason why players were allowed to retain the "a" button of the Dragon Slash, because the single "a" will not enter the walking or defense state, and it can be guaranteed to release the Dragon Slash while standing.

02, action frame

Frame is a frame. Each frame can have different judgments, such as attack, defense, release of props, etc. The character's texture, special effects, etc. are also set in the frame.
An action generally consists of 5 to 30 frames, and some frames have a pause effect (duration), such as the explosion of the Big Three.
Some frames will release props (for example, Ryusuke’s Flying Dragon Slash), and the released props can also release props (for example, after the fireball of Akagi is destroyed, it will release a big explosion)
The character's body collision range, attack range, skill displacement, etc. are also set in the frame.
The frame is very complicated, so here is only a brief explanation of the technique of setting the frame in the action, and then the frame itself will be explained in detail.

①Find the start and end frames

In the action, we can use "frameIndex" to set the sequence number of the corresponding frame of the action. This frame is the start frame of the action. There is no end frame setting in the action, because this is set in the frame.
For example, the frame of Long Jie Fei Long Zhan 1 is 316 to 330, then 330 is the end frame. Within 316 to 330, no matter where you set the start frame, the end frame will not change. If you set the start If the frame is set to 330, Ryusuke will end the action after one frame, and if it is set to 331, if the end frame of 330 is missed, the action will start from 330 until the next end frame.
To find the end frame, you need to search for "last" in the frame. If "last" is true, then this frame is the end frame. If "last" is false, then this frame is not the end frame, and you need to continue to look down.
It is troublesome to find the end frame in the frame every time. If you are familiar with the name of the action and the number of frames, you can infer the end frame directly from the action, but the premise is that you need to have a certain understanding of the frame. .
If we are looking for all the frames of Flying Dragon Slash 1 (ball), we can first find Flying Dragon Slash 1 (ball) and its next action, which is Flying Dragon Slash 2 (ball2). (Note that the "next action" here refers to the lower part of the action, that is, the action of the next number, not the action of the flying dragon cut, but their serial numbers are just connected)
"94": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL",
                "a_keyTgr": null, <-----------------For the sake of brevity, I deleted the skill keys for easy browsing.
                "landAgi": -1.0,
                "frameIndex": 316.0,<-----------------We found that the starting frame of Flying Dragon Slash 1 is 316, write it down, and then flip through the next action.
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            },
            "95": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL2",
                "a_keyTgr": null,
                "landAgi": -1.0,
                "frameIndex": 331.0,<-----------------You can see that the starting frame of the next action of Flying Dragon Slash 1 is 331, then his previous frame 330 is likely to be The last frame of the previous action.
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 95.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }
			From this, we can deduce that the frames of Flying Dragon Slash 1 are 316 to 330, and the final 330 is naturally the end frame.
			If the start frame of the second action is changed to 333, and the two frames 331 and 332 are not used, it will not affect the end frame of the previous action, which is still 330.
			But in this way, it will become difficult for us to find the end frame. However, it is worth noting that almost all the original abandoned frames are placed at the end of all frames, which will not affect our guessing of the end frame.
			But there is another special case, that is, sometimes the two actions will repeatedly use some frames, but the starting position is different. For example, Ryusuke’s ball2to1 is 315 to 330, and the ball is 316 to 330. The purpose of this setting is to make the ball The starting hand is shorter than ball2to1.
			"93": {
			 "name": "BALL2TO1",
                "a_keyTgr": null,
                "landAgi": -1.0, <-----------------For brevity, most irrelevant parameters have been deleted. (It cannot be deleted when the file is actually changed)
                "frameIndex": 315.0
				},
			"94": {
				"name": "BALL",
                "a_keyTgr": null,
                "landAgi": -1.0,
                "frameIndex": 316.0
				},
			"95": {
                "name": "BALL2",
                "a_keyTgr": null,
                "landAgi": -1.0,
                "frameIndex": 331.0,
                }
			At this time, we are looking for the ending frame of ball2to1, naturally we can’t find it in the ball, but we will move on to the next action and find it in ball2.
			Generally speaking, if the difference between the starting frames of the two actions is less than 5, it is necessary to suspect that they are the same group of frames. Another way is to look at the name.
			Like ball2to1, it is the flying dragon cut 2 to the flying dragon cut 1, the essence is still the flying dragon cut 1, so it is the same action as the flying dragon cut 1 (ball), but the starting hand is different.
			Therefore, to quickly launch the end frame, we need to have a certain understanding of the action name and the total number of frames of the action.
			When it is really impossible to judge, we can only find it in the frame. The "last" of the end frame is true, and the "last" of the non-end frame is false. We only need to find "last" from the start frame, Until true appears, it is generally not necessary to use this method, because the frames corresponding to the original action are almost all arranged in ascending order.
			
		② Modify the value of the starting frame.
			
	    Let's first try to change the starting frame of the stand action to the starting frame of the flying dragon chop 1 (ball).
		
		Find the standing "frameIndex", and then find the "frameIndex" of Flying Dragon Slash
			
			"1": {
                "HFW_classNameXXX": "Data.Action",  
                "name": "STAND", <-----------------The irrelevant parameters are also deleted here, which is convenient for browsing (cannot be deleted when the file is actually changed)
                "frameIndex": 1.0
            },
            "2": {
                "HFW_classNameXXX": "Data.Action",
                "name": "WALK",
                "frameIndex": 5.0
            },
            "3": {
                "HFW_classNameXXX": "Data.Action",
                "name": "RUN",
                "frameIndex": 20.0
            },
			············
			············
			"94": {
				"name": "BALL",
                "frameIndex": 316.0
			}
			
			We see that the standing "frameIndex" is 1.0, and the flying dragon is 316.0
			Change the "frameIndex" of the standing action to 316
			"1": {
                "HFW_classNameXXX": "Data.Action",  
                "name": "STAND", 
                "frameIndex": 316.0
            },
            "2": {
                "HFW_classNameXXX": "Data.Action",
                "name": "WALK",
                "frameIndex": 5.0
            },
            "3": {
                "HFW_classNameXXX": "Data.Action",
                "name": "RUN",
                "frameIndex": 1.0
            },
			············
			············
			"94": {
				"name": "BALL",
                "frameIndex": 316.0
			}
			After importing and entering the game, you will find that Ryuusuke is constantly sending out flying dragons while standing.
			
			③ Speed ​​up the flying dragon cut out (skip some starting frames)
			"94": {
				"name": "BALL",
                "frameIndex": 316.0
				},
			"95": {
                "name": "BALL2",
                "frameIndex": 331.0,
                }
			We see that the starting frame of Flying Dragon Slash is 316, change it to 321
			"94": {
				"name": "BALL",
                "frameIndex": 321.0
				},
			"95": {
                "name": "BALL2",
                "frameIndex": 331.0,
                }
			After importing into the game, when using Flying Dragon Slash, you will find that the starting hand becomes faster because the first few frames are skipped.
			But this method has certain flaws, that is, it will affect the fluency of the action, and in the frame, the speed of the start can be increased without affecting the fluency, which will be explained in detail later.
			
———————————————————————————————————————————————— ———————————————————————————————————————————————— ——————————————————————————			
			
			
03, action group articles		
 
The more complex frameIndex and button settings in action have been introduced, and the remaining parameters (except those related to actionGroup) are relatively simple, so no detailed explanation is given.
Next, we start to learn the action group (actionGroup). Compared with the previous content, the next content may be more complicated and difficult to understand, but it is still the basic part. If you understand it with your heart, it will definitely be understandable.
			
First of all, we must understand that if the actions in the action are scattered and unmodified, they have no effect. The role of actionGroup is to integrate them and modify them.
We can compare action to furniture, and actionGroup to a house. If there is no house, no matter how beautiful and rich the furniture is, it has no effect.
And a house (actionGroup) can arrange the furniture (action) neatly, allowing them to perform their own functions.
At the same time, the location of the furniture (action) is also very important. If you put the quilt in the kitchen and the range hood on the bed, they will not be able to perform their functions normally, or even cause serious problems.
The same is true for actions. In actionGroup, except for skills, the function corresponding to each value is fixed and will not change due to the change of action.
After probably knowing the meaning of actionGroup, we will officially start to explain actionGroup. Next, I will list the actionGroup in the normal state of Longsuke. Please browse it first.
"actionGroup": {
            "HFW_ArrayLenXXX": 10,
            "0": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "action": {<-----------------This action is useless in the original version. You can see that the following values ​​are all null, and the useful ones are in the back.
                    "HFW_ArrayLenXXX": 4,
                    "0": {
                        "HFW_ArrayLenXXX": 31,
                        "0": null, <-----------------I wanted to list them all, but there are too many values, so the middle one is folded.
                        "1": null,
                        ······
						······
                        "30": null
                    },
                    "1": {
                        "HFW_ArrayLenXXX": 58,
                        "0": null,
                       ······
                        "57": null
                    },
                    "2": {
                        "HFW_ArrayLenXXX": 19,
                        "0": null,
                        ······
                        "18": null
                    },
                    "3": {
                        "HFW_ArrayLenXXX": 11,
                        "0": null,
                        ······
                        "10": null
                    }
                },
                "ite_dura": 0.0,
                "ite_duraD": 0.0,
                "ite_obstacle": false,
                "ite_atk1": -1.0,
                "ite_sfx1": 0.0,
                "ite_atkName1": "",
                "ite_lifeTime": 0.0,
                "ite_reboundable": false,
                "name": "normal", <-----------------This is the name of the action group. There are five action groups in the original ordinary characters, which will be discussed in detail later.
                "ite_landBreak": true,
                "ite_screen": false,
                "ite_atk2": -1.0,
                "index": 0.0,
                "ite_standable": false,
                "ite_weight": 1.0,
                "type": 0.0,
                "ite_hitable": true,
                "actionIndex": {<-----------------This is the most important parameter, abbreviated as ati. NextAti seen in action refers to this, except for this parameter. It's useless.
                    "HFW_ArrayLenXXX": 4,
                    "0": {
                        "HFW_ArrayLenXXX": 31,
                        "0": 1.0,
                        ······
                        "30": 109.0
                    },
                    "1": {
                        "HFW_ArrayLenXXX": 58,
                        "0": 18.0,
                       ······
                        "57": 108.0
                    },
                    "2": {
                        "HFW_ArrayLenXXX": 19,
                        "0": 73.0,
                        ······
                        "18": -1.0
                    },
                    "3": {
                        "HFW_ArrayLenXXX": 11,
                        "0": 91.0,
                       ······
                        "10": 101.0
                    }
                },
                "speedYRate": 1.0,<--------------The ratio of the y-axis speed, set to 1 to double, 2 to double, acting on the basic movement action, with jumpspeedy and other parameters as Unit speed.
                "shield1": 0.0,<-------------Back defense, if it is set to 0.8, the actions under the entire actiongroup will have automatic defense. The principle is in the body section.
                "ite_gr": 1.0,
                "ite_lo": 0.0,
                "keyTriggerRef": null,
                "speedXRate": 1.0,<-------------The ratio of x-axis speed, set 1 to double, 2 to double, acting on basic movement actions, such as weightlifting walking and weightlifting running The principle of slowing down is based on parameters such as walkspeedx as the unit speed.
                "keyTrigger": {
                    "HFW_ArrayLenXXX": 0
                },
                "ite_atkName2": "",
                "mpBurn": 0.0,
                "keyTriggerRefIndex": -1.0,
                "ite_blastBreak": true,
                "piece": {
                    "HFW_ArrayLenXXX": 0
                },
                "ite_vo": 0.0,
                "ite_sfx2": 0.0
            },
            "1": {
                ······
				},
            "2": {
                ······
				},
            "3": {
                ······
                },
            "4": {
                ······
                },
			"5": null,
			"6": null,
			"7": null,
			"8": null,
			"9": null
			},

After reading it, we can find that in actionGroup, only a few parameters are useful, and most of the other parameters are used to set props. No modification is required in the character SPT. Generally speaking, parameters with the word ite It is used to set up props, some of the parameters without ite are used to set the character, and some are used to set up the props,
Next, I will omit these irrelevant parameters and other uncomplicated useful parameters, focusing on actionGroup and actionIndex.

From actionGroup to actionIndex is the whole to the details, actionInedx belongs to actionGroup, so I first explain the overall actionGroup.
The following is Longsuke's actionGroup, you can browse it first, and then guess the role by name.
"actionGroup": {
            "HFW_ArrayLenXXX": 10,
            "0": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "name": "normal", 
                "actionIndex": {
                  ······ <-----------------This is to explain actionGroup, so the content of actionIndex is temporarily omitted, and I will expand it later.
                    }
            },
             "1": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "name": "gua",
                "actionIndex": {
                    ······
                    }
            },
            "2": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "name": "cat",
                "actionIndex": {
                    "HFW_ArrayLenXXX": 4,
                ······
                    }
            },
            "3": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "name": "hea",
                "actionIndex": {
                ·······
                    }     
            },
            "4": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "name": "rid",
                "actionIndex": {
                    ······
                }
            },
			"5": null,
			"6": null,
			"7": null,
			"8": null,
			"9": null

In the original version of HF, the character’s actiongroups are used up to five, namely standing, defending, grabbing, lifting, and riding. The hero has five actiongroups, while the soldiers only have two to four. Most soldiers can’t lift weights and can lift weights. If you delete the hero's 4th actionGroup (riding), the hero will not be able to ride, even if the riding action is still there.
Standing here is a state, not an action. All the actions and skills used in the natural state belong to standing, while the actions and skills used in the riding state naturally belong to riding, such as the Tailai riding shield, Riding a blazing light gun, although they are different skills, they are all riding skills, and the agi are all 4.
The full name of agi is "actionGroupIndex", which is the serial number of the actionGroup. 0 is standing, 1 is defense, 2 is grabbing, 3 is weightlifting, 4 is riding, and the serial number is fixed and cannot be changed. Even if the name is changed, it will not work.
In the original version, agi numbers 5 to 9 are not used, but we can use it to realize the transformation function, which will be introduced later.
Observe the action of riding and standing, you will find that all the agi of the skills in it are 4, and if you use the skill with agi of 0, the character will fall off the horse while using the standing skills.
"65": {
                "HFW_classNameXXX": "Data.Action",
                "name": "_RID_STAND",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 3,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gla",
                        "mp": 90.0,
                        "agi": 4.0, <-----------------
                        "rkt": false,
                        "kr": "gra"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 275.0,
                        "agi": 4.0, <-----------------
                        "rkt": false,
                        "kr": "gua"
                    },
                    "2": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 1.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 4.0, <-----------------
                        "rkt": false,
                        "kr": "gla"
                    }
                }
            },
Therefore, when setting the agi corresponding to the skill, we have to figure out what action this is. Under normal circumstances, the agi corresponding to the skill is 0 or 4, that is, standing and riding, and the skills in the catching state are except for Chu Ying Very rare outside.
If it is a riding skill, then the agi under the button (A_KeyTgr) is set to 4, if it is a normal skill, it is set to 0, and if it is a catching skill like Chu Ying, it is set to 2.
The same is true for nextAgi and landAgi. Here we should pay attention to the difference between 0 and -1, 0 means standing; -1 means not existing, that is, no agi will be entered after the action is over or landing, and the two values ​​should not be confused.

After clarifying agi, let’s talk about ati and ai. This is the actionIndex under Ryusuke's standing state (agi=0)
"actionIndex": {
                    "HFW_ArrayLenXXX": 4,
                    "0": {<-----------------"0" are basic actions, such as running, jumping, backflip, etc. These actions usually have no special effects (except kneel and pickitem), unless special effects are set in the frame.
                        "HFW_ArrayLenXXX": 31,
                        "0": 1.0, <-----------------ati means ai inside, where "0" means ai=0, ai=0 means standing.
                        "1": 2.0,
                        "2": -1.0,
                        "3": -1.0,
                        "4": 3.0,
                        "5": -1.0,
                        "6": -1.0,
                        "7": 13.0,
                        "8": 6.0,
                        "9": 6.0,
                        "10": 7.0,
                        "11": 7.0,
                        "12": 8.0,
                        "13": 6.0,
                        "14": 6.0,
                        "15": 14.0,
                        "16": 16.0,
                        "17": 15.0,
                        "18": 17.0,
                        "19": 8.0,
                        "20": 4.0,
                        "21": 5.0,
                        "22": 9.0,
                        "23": 10.0,
                        "24": -1.0,
                        "25": 8.0,
                        "26": -1.0,
                        "27": -1.0,
                        "28": 6.0,
                        "29": 8.0,
                        "30": 109.0
                    },
                    "1": {<-----------------"1" is a basic action with a special nature, such as being hit, falling to the ground, being frozen, etc.
                        "HFW_ArrayLenXXX": 58,
                        "0": 18.0,
                        "1": 19.0,
                        "2": 22.0,
                        "3": 20.0,
                        "4": 21.0,
                        "5": 22.0,
                        "6": 28.0,
                        "7": 29.0,
                        "8": 30.0,
                        "9": 31.0,
                        "10": 32.0,
                        "11": 33.0,
                        "12": 38.0,
                        "13": 39.0,
                        "14": -1.0,
                        "15": -1.0,
                        "16": 36.0,
                        "17": 37.0,
                        "18": -1.0,
                        "19": -1.0,
                        "20": -1.0,
                        "21": -1.0,
                        "22": -1.0,
                        "23": -1.0,
                        "24": -1.0,
                        "25": -1.0,
                        "26": 40.0,
                        "27": 41.0,
                        "28": 42.0,
                        "29": 11.0,
                        "30": -1.0,
                        "31": -1.0,
                        "32": -1.0,
                        "33": 34.0,
                        "34": 8.0,
                        "35": -1.0,
                        "36": -1.0,
                        "37": 4.0,
                        "38": 4.0,
                        "39": 12.0,
                        "40": -1.0,
                        "41": -1.0,
                        "42": -1.0,
                        "43": 35.0,
                        "44": -1.0,
                        "45": 43.0,
                        "46": 44.0,
                        "47": 43.0,
                        "48": -1.0,
                        "49": 23.0,
                        "50": 24.0,
                        "51": 26.0,
                        "52": 25.0,
                        "53": 27.0,
                        "54": -1.0,
                        "55": 106.0,
                        "56": 107.0,
                        "57": 108.0
                    },
                    "2": {<-----------------"2" is the basic attack, such as running attack, rushing attack, general attack, etc.
                        "HFW_ArrayLenXXX": 19,
                        "0": 73.0,
                        "1": 74.0,
                        "2": 75.0,
                        "3": 76.0,
                        "4": 73.0,
                        "5": 73.0,
                        "6": 73.0,
                        "7": 77.0,
                        "8": 77.0,
                        "9": 77.0,
                        "10": 77.0,
                        "11": 78.0,
                        "12": 78.0,
                        "13": 78.0,
                        "14": 78.0,
                        "15": 77.0,
                        "16": 76.0,
                        "17": -1.0,
                        "18": -1.0
                    },  
                    "3": {<-----------------"3" is the skill. Compared with the previous ati, the skill is more free and you can change the position at will, but after the change, the ai is also Follow the exchange.
                        "HFW_ArrayLenXXX": 11,
                        "0": 91.0,
                        "1": 92.0,
                        "2": 89.0,
                        "3": 94.0,
                        "4": 95.0,
                        "5": 93.0,
                        "6": 102.0,
                        "7": 103.0,
                        "8": 104.0,
                        "9": 105.0,
                        "10": 101.0
                    }
                },
ati is relatively easy to understand, but ai may not be easy to understand, because the value on the left is also an action, and the value on the right is also an action, which requires a certain amount of brain to sort out.
The following are the actions corresponding to ai, and then I will explain how ai and action correspond.
ati:0
ai:
0 stand   
1 walk
4 run <-----------------There are a lot of skipped sequence numbers, because they are unimportant or useless ai
7 run_stop/rid_turn
8 jump_start
9 jump_forward_start
10 jump
11 jump_forward
12 jump_land
13 dash_start
14 dash_back_start
15 dash
16 dash_back
17 dash_air
18 dash_back_air
19 dash_land
20 roll
21 sky_roll
22 somersault
23 somersault2
24 rotate_end/rid_get_on
25 final_land
26 basic_guard
27 basic_catch
28 pick_item
29 picked_item
30 kneel

ati:1
ai:
0 hit1
1 hit2
2 hit3
3 hit1_back
4 hit2_back
5 hit3_back
6 fall1
7 fall2
8 fall3
9 fall4
10 fall5
11 fall6
12 fall7
13 fall8
16 fall_back1
17 fall_back2
26 fall_spin1
27 fall_spin2
28 fall_spin3
29 breakfall
33 lie
34 getup
37 lie_roll_up
38 lie_roll_down
39 lie_turn
43 lie_hit
45 breakguard
46 breakguard_sky
47 stepback
49 dizzy
50 caught
51 caught_struggle
52 caught_hit
53 fall_hit_wall
55 fall_ice
56 fall_fire
57 fall_thunder

ati:2
ai:
0 attack1
1 attack2
2 attack3
3 attack4 <---------------It can be found that there is no attack5 here, so how did Chu Ying make the fifth attack? Put the answer at the end of this article.
4 up_attack
5 down_attack
6 forward_attack
7 jump_attack/rid_catch_attack
8 jump_up_attack/rid_catch_up_attack
9 jump_down_attack/rid_catch_down_attack
10 jump_forward_attack/rid_catch_forward_attack
11 dash_attack/rid_run_attack
12 dash_up_attack/rid_run_up_attack
13 dash_down_attack/rid_run_down_attack
14 dash_forward_attack/rid_run_forward_attack
15 dash_back_attack
16 run_attack
17 rotate
18 back_attack
 
 ati:3
 ai corresponding skills


If you have a button to observe the standing action, you will find that there is no button setting for moving, jumping, or attacking, but the character can jump, attack, and move freely. This is because the action "STAND" corresponds to ai: "0", which gives it the nature of "standing".
If the "STAND" corresponds to the walking ai, that is, the "1" ai, then this "STAND" is standing on the surface, but in fact it is walking, and it looks like a person is sliding.
Action modifies the frame to give it the properties of turning and looping, while ai modifies the action to give it properties such as movement and free keystrokes.
The two actions of "RUN" and "WALK" do not have any displacement. It is precisely because the ai corresponding to run and walk has the moving speed. If "BALL" and the ai of walk correspond to each other, then walking It will make a flying dragon cut movement, but it still has a movement speed. If you can’t understand it, you can actually try it out, which will make it easier to understand.
Next, explain the corresponding method of ai and action.

Here I use the 0 ati in the normal state as an example
"0": {<----------------This is agi
                "HFW_classNameXXX": "Data.ActionGroup",
                "name": "normal", 
                "actionIndex": {
                    "HFW_ArrayLenXXX": 4,
                    "0": {<----------------This is ati
                        "HFW_ArrayLenXXX": 31,
This is the serial number of ai------> "0": 1.0,<----------------This is the serial number of the action corresponding to ai.
                        "1": 2.0, <----------------As you can see, the serial number on the left is 1, which means ai=1, and the value on the right is 2.0, which means that the action is the 2nd action , Which is walk,
                        "2": -1.0,
                        "3": -1.0,
                        "4": 3.0,
                        "5": -1.0,
                        "6": -1.0,
                        "7": 13.0,
                        "8": 6.0,
                        "9": 6.0,
                        "10": 7.0,
                        "11": 7.0,
                        "12": 8.0,
                        "13": 6.0,
                        "14": 6.0,
                        "15": 14.0,
                        "16": 16.0,
                        "17": 15.0,
                        "18": 17.0,
                        "19": 8.0,
                        "20": 4.0,
                        "21": 5.0,
                        "22": 9.0,
                        "23": 10.0,
                        "24": -1.0,
                        "25": 8.0,
                        "26": -1.0,
                        "27": -1.0,
                        "28": 6.0,
                        "29": 8.0,
                        "30": 109.0 <--------------------------------agi=0, ati=0, the 30th ai represents kneel action, kneel has two properties, one is meeting Change the team (set up teammates in the story), the second is not to be actively attacked by the enemy,
						    }, The transformation team is set in the frame, and if it is not attacked by the enemy, it is set in ai, that is, the 30th ai in the 0 ati under the 0 agi, no matter which action it corresponds to, it will not be taken by the enemy attack.
						"1":······, you can try to change the action corresponding to the 30th ai from 109 to the flying dragon cut 94, so that the flying dragon cut will be automatically released when kneeling, and will not be attacked at the same time.
						"2":······,
						"3":······
						           },
						"1":······,                      
						"2":······,
						"3":······,
						"4":······
                    }
Therefore, when we want to set the action after the skill ends or after landing, we need to find the agi, ati, ai corresponding to the next action,
For example, if the sequence number of the knee action is 109, search for 109.0 in actionIndex and find the corresponding agi (kneel is 0), ati (kneel is 0) and ai (kneel is 30), then change nextAgi, nextAti, and nextAi to the same as kneel ,
For example, if the nextAgi of Flying Dragon Slash is set to 0, nextAti is set to 0, and nextAi is set to 30, after the Flying Dragon Slash action ends, it will enter the kneeling action. The actual modification example is as follows:
	"94": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": 30.0,
                "allowTurnFace": false,
                "nextAti": 0.0,
                "frame": null,
                "aiz2": 60.0,
                "spe cial": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": 0.0,
                "name": "BALL",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 316.0,
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }
It should be noted that if the dragon cut enters other actions before the end by pressing the key, then this nextAi will no longer take effect. Only when the "last": true end is passed, nextAi and landAi can take effect.
Like Chu Ying’s overlord charge, pressing the attack button will receive an uppercut, and when it ends naturally, it will enter another set ending action.
As mentioned earlier, ati=3 corresponds to skills. Because everyone’s skills are different in nature, the ai in ati3 will not change its nature due to the serial number. Therefore, it is often used when transplanting skills or creating new skills. The ai is set in ati=3,
In addition, if the new skill is expanded to ati=0 or ati=1, ati=2, this skill will lose some properties, such as displacement and nextAi. But if you replace the original ai, you can retain some properties, such as displacement.
Whether to choose to replace the ai in ati=0, ati=1, ati=2 needs to be determined according to needs. For example, if you want to create a new running action, you can replace the original running action number with the new action number in ati This function can also be achieved by modifying the frame corresponding to the action.
As mentioned in the action article, parameters such as nextAi are only applicable to skills (the action corresponding to ai in ati=3), and the actions in ati=0, ati=1, ati=2 are not applicable, this should be noted.
The principles of landAgi, landAti, and landAi are the same as those of nextAgi, nextAti, and nextAi, so they will not be described in detail.
The fifth hit of drew is essentially a skill. Set the key to this skill under the action of attack4, and you can achieve the effect of attack5.
Through the knowledge of this agi and the knowledge of the previous button settings, we can not only modify the blue consumption and the buttons, but we can also modify the actions corresponding to the buttons.		
The following are the buttons under Longsuke's standing action. We try to change the button corresponding to Flying Dragon Slash to correspond to Flying Dragon Slash 2 (ball2)			
			

       "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0, <----------------ai is 0, then this button leads to the action corresponding to 0 ai
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0, <---------------- ati is 3, then this button leads to skills
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 275.0,
                        "agi": 0.0,<----------------agi is 0, then this button leads to actionGroup 0, which is the standing state
                        "rkt": true,
                        "kr": "gua" ↑Connecting the above three paragraphs, we can conclude that this button leads to skill 0 in the standing state, and Ryusuke's skill 0 is Thang Long Slash
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,<----------------And this button leads to skill 3, which is Flying Dragon Slash, we try to change it to 4.0, which is Flying Dragon Chop 2 (ball2)
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    }
                },
				
"a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,   
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0, 
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"      
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,<----------------Only ai has changed
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    }
                },

After importing, you will find that the Flying Dragon Slash that Ryusuke used while standing has become Flying Dragon Slash 2


4. Create new skills

After understanding the meaning and application of agi, ati, ai, we can create new skills
This is just to explain the new skills action and actionGroup settings, the knowledge of the frame is behind

①Add new action

To make new skills, we need to add new actions. Since there are many parameters in the action, we can copy an original action first and then modify it. Here we use Long Jie Fei Long Zhan as an example

"94": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 316.0,
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            },<------------------------Do not copy this comma, delete it if it is copied
We start with the quotation mark before the action number and select the brace at the end (Shift+left mouse button can quickly select)
Copy it, be careful not to copy it to the comma, because it is used to connect two actions, not part of the action
We paste it after the last action (usually kneel) and change the serial number

"109": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "KNEEL",
                "a_keyTgr": null,
                "landAgi": -1.0,
                "frameIndex": 418.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 109.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            },<---------------------------Don't forget to separate with commas
"94": {<-------------------------------------------- ---------At this time, the action number is still the original 94, we need to change it to 110 which is the number after 109
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,<--------------------Some actions will have nextAi, need to be changed to -1.0, if necessary, you can also choose to keep it
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL",<--------------------The name also needs to be changed, you can name it freely
                "a_keyTgr": {<--------------------The keys here can be kept if needed, and remember to delete if not needed
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 316.0, <----------------This is the starting frame of the new action. Since we haven't mentioned the knowledge of frame yet, we just put it back 5 frame
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }


"109": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "KNEEL",
                "a_keyTgr": null,
                "landAgi": -1.0,
                "frameIndex": 418.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 109.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            },
"110": {<-------------------------------------------- ---------Serial numbers must be in order, if you skip a number, an error will occur
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALLFAST",<--------------------This name is the new ac code in the story. If the ac code is repeated, the following action will be used Prevail
                "a_keyTgr": null,<--------------------Note that the delete button must be changed to the form of null, not "HFW_ArrayLenXXX": 0, otherwise it may cause Caton
                "landAgi": -1.0,
                "frameIndex": 321.0,<--------------------Frames 316 to 320 have been skipped, starting directly from 321, so the starting point will be faster
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }

②Add the new action to the actionGroup
First find the actionGroup in the standing state and find the position of ati3
"actionGroup": {
            "HFW_ArrayLenXXX": 10,
            "0": {
                "HFW_classNameXXX": "Data.ActionGroup",
                ······
				"name": "normal",
				······
                "actionIndex": {     
                    "HFW_ArrayLenXXX": 4,
                    "0": {
                        "HFW_ArrayLenXXX": 31,
                        ······
                    },
                    "1": {
                        "HFW_ArrayLenXXX": 58,
                        ······
                    },
                    "2": {
                        "HFW_ArrayLenXXX": 19,
                        ······
                    },
                    "3": {
                        "HFW_ArrayLenXXX": 11,
                        "0": 91.0,
                        "1": 92.0,
                        "2": 89.0,
                        "3": 94.0,
                        "4": 95.0,
                        "5": 93.0,
                        "6": 102.0,
                        "7": 103.0,
                        "8": 104.0,
                        "9": 105.0,
                        "10": 101.0<------------------Here, 0 to 10 are Ryuusuke's original skills, don't change it, expand the new skills to the back of 10.
                    }
                },
                ······
				······
            }	

         After expansion:

			
			"actionGroup": {
            "HFW_ArrayLenXXX": 10,
            "0": {
                "HFW_classNameXXX": "Data.ActionGroup",
                ······
				"name": "normal",
				······
                "actionIndex": {     
                    "HFW_ArrayLenXXX": 4,
                    "0": {
                        "HFW_ArrayLenXXX": 31,
                        ······
                    },
                    "1": {
                        "HFW_ArrayLenXXX": 58,
                        ······
                    },
                    "2": {
                        "HFW_ArrayLenXXX": 19,
                        ······
                    },
                    "3": {
                        "HFW_ArrayLenXXX": 11,
                        "0": 91.0,
                        "1": 92.0,
                        "2": 89.0,
                        "3": 94.0,
                        "4": 95.0,
                        "5": 93.0,
                        "6": 102.0,
                        "7": 103.0,
                        "8": 104.0,
                        "9": 105.0,
                        "10": 101.0,
						"11": 110.0
                    }
                },
                ······
				······
            }
			Here, 11 refers to the 11th skill in Ryusuke's standing state, and 110 corresponds to the sequence number of the action, which means that when using this skill, the action performed is the 110th action.
			
②Set the button in the action

We first think of a button for the skill according to our own ideas, here we set it as grj, which means defense, right, and jump
The button of a skill needs to be set in multiple actions, because each button setting can only affect one action.
And we can’t avoid defense, movement, and running when we use the skills. Therefore, standing, walking, running, defensive standing, defensive walking, and defensive running all need to set a button before this skill can be used normally.
For general ground skills, setting buttons in these six actions is enough, but if you need to use them in the air, rolling, or attacking, you need to add buttons.	
Let’s add the button to the stand action first, and first find Ryusuke’s standing action (stand)
			
	"1": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": true,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "STAND",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua", 
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gua"
                    },
                    "1": {<---------------------------------There were two sets of buttons originally, we want to add one Group new buttons, you can directly copy the original buttons and then modify them
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 1.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 1.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            }		
			The code after joining is as follows
			
			"1": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": true,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "STAND",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 3, <------------------------ After adding new buttons, the number of skill buttons will naturally increase. However, when there is no need to use any tools, the number of labels less than the actual number has no effect, but it can only be less, not more, otherwise an error will occur.
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua", 
                        "mp": 275.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gua"
                    },
                    "1": {     
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,
                        "kr": "gla"
                    },
					"2": {<------------------------------The copied skill button can be copied to the back and then change the serial number, also You can copy to the front, and then change the serial number of the original button, here are some tricks, I will talk about it later
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 11.0, <-----------------------The ai corresponding to the action just added is 11, so here is changed to 11
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0, <-----------------------The original Dragon Slash is a skill, ati=3, the new Dragon Slash is also a skill, so ati Still 3, no need to change 
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "grj",<------------------------------The button is changed to grj, and in general, it cannot be compared with the original Key repeat
                        "mp": 90.0,
                        "agi": 0.0,<-----------------------Although they are different skills, they are all activated while standing, so there is no need to change the agi.
                        "rkt": false,
                        "kr": "glj"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 1.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 1.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            }		
			
Starting from the second action, there is no need to copy and rewrite one by one. We can directly copy the newly added keys, and then expand them to the keys of other actions. Note that the serial number should be adjusted.	
Follow the above format and add the buttons to stand, walk, run, gua_run, gua_walk, gua_stand, and the skills can be used normally.
If you want to use it on the ground, add a button to the ground action (roll),
If it is an aerial skill, add buttons to jump and anti-jump (gua_jump) instead of adding buttons to ground actions.
The same is true for rushing, catching people, etc. The need to add buttons depends on the nature of the skill and your thoughts.

In addition, it is also very important that there is an "rtk" in the skill button. If the setting is wrong, the skill will not be released or be released early.		
			"2": {     
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 11.0, 
                        "atf": true,
                        "hp": 0.0,
                        "ati": 3.0, 
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "grj",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": false,<----------------All skill buttons under standing action, "rtk" should be false
                        "kr": "glj"
                    }
The specific mechanism of "rtk" is more complicated, so I don’t need to understand it for the time being, just need to be clear: Under normal circumstances, rtk is false under normal action, rtk under attack or skill action is true, and the key of "rtk" is false can be Released at any time during this action			
		
5. Key sequence			
			
The order of the buttons is of great significance. If the order is not correct, the skills cannot be released.
For example, we set up a set of buttons in the flying dragon slash action, leading to the flying dragon slash action.
 "94": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 250.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    },
					"2": {<----------------Here is a new Flying Dragon Slash button. The setting of this button is actually no problem, but he will never let it go. Come out, you can think about the reason first
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gla"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 316.0,
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }			
			
			Here is the issue of the key sequence.
			         "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",<-------------------There is already a "a" button here, and the new button is "gra", press If you press "gra", you will inevitably press "a"
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    },
					"2": {         
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gla"
                    }
                }
				
			In the case of key conflicts, the priority of the skill key is determined by the serial number of the key. In the case of sufficient mp, when the keys conflict, only the keys with the first sequence number will take effect.	
			Therefore, we can change the positions of the two buttons to solve the problem of button conflicts.
			Normally, skill buttons with a smaller number of buttons will be placed behind, because when you press "gra", the "a" button will be triggered, but conversely, when you press "a", the "gra" button will not be triggered ,	
			The code after modification is as follows.
			 "94": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL",
			    "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 250.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
					"1": {<------------------Both positions and serial numbers have been swapped
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gla"
                    },
                    "2": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    }
					
                },
                "landAgi": -1.0,
                "frameIndex": 316.0,
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }	
			In this way, the "a" key cannot affect "gra".
			
			In addition, using the sequence of buttons and the setting of mp consumption, we can set multiple different skills for the same button under the same action.
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 3,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra", 
                        "mp": 400.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gla"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 200.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gla"
                    },
					"2": {        
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 3.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gra",
                        "mp": 0.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gla"
                    }
                }
			The same three sets of buttons just now, but the buttons corresponding to all the skills have been changed to gra. In this way, can I still release the skills corresponding to the buttons other than 0?			
			
			The answer is yes.
			It can be seen that the mp of button 0 is set to 400, then when there is 400mp, the skill corresponding to button 0 will naturally be triggered;
			And if there is no 400mp but 200mp, the skill corresponding to button 1 will be triggered automatically;
  If there is no 200mp, the skill corresponding to the 2nd button will be triggered, because the remaining blue amount can only meet the requirements of the 2nd skill button.
    
    
    
06. Action transplant:	

The difficulty of this chapter is relatively high, you can skip it first and learn later.

Action transplantation is similar to the new skill creation mentioned earlier, but the frame of the new skill is copied from the frame of other characters.
The first step is the same as creating a new skill. We need to add an action first, set this action into the actionGroup, and then set the buttons.
The second step is a bit different. Instead of using the character's own frame, we copy the frames of other characters and set the starting frame.

In the traditional version, most characters have different texture positions, so action transplantation does not just need to copy the frame.
But in the HF-EX version, most of the characters’ texture locations have been unified, so they can be ported without barriers (in fact, they are not 100% barrier-free)
			
The following points need to be paid attention to when moving actions		
			
The textures set in some frames are not bound in the role of the transplant action. For these textures, delete or add binding processing.
Some frames have refIndex set, and direct transplantation will cause confusion. You need to find the frame corresponding to refIndex in the role frame of the transplanted action to replace it.
The number of the same textures for different characters may be different. For example, Chu Ying's head texture has one more side view than Longsuke, and Longsuke will have bugs because of the lack of this image.			
Some skills have more than one action. For example, Falling Dragon Slash is a combination of two actions, and only one action cannot be transplanted.
			
			
			
2. Basic parameters:

The basic parameters are the parameters at the first level of the spt. These parameters are relatively simple except for actiongroup, action, and frame. Most of them can be directly changed to the value or directly to the value of the lower-level parameters.
Basic parameters can be roughly divided into three categories. One is simple basic parameters. The characteristic of this parameter is that it has only one value or only needs to be set to true or false, which is the easiest to modify.
The second type is ordinary basic parameters. There are certain lower-level parameters below this basic parameter, but its lower-level parameters are the same as simple basic parameters, with only one value.
The third type is complex basic parameters. Only actiongroup, action, and frame in the character spt can be called complex basic parameters, because they contain a lot of parameters, especially frame.


	 
 01. Simple basic parameters:	
			
		"teamApp": false, (Whether the skin will change with the team, the heroes of the original game are all false)
        "walkGrab": false, (Whether it will automatically grab the soldier when walking, such as drew)
        "id": "jenny", (The role id must be consistent with the character file location. For example, if you want to change the role in the lucas location to drew, you must change the "id" in the spt of drew to lucas)
        "mHp": 440.0, (HP without level, if the character does not have level data, it will also affect the level of HP at the same time, the characters in the original character list all have level data, and the characters that are not in the character list There is no level data, and some mods have additional level data for some characters not in the character list)
        "rHp": 1.0, (recovery speed, change in spt is invalid, so don't care about it)
        "mSt": 500.0, (the sp value of the role, regardless of level)
        "rMp": 1.0, (Return to blue speed, change in spt has no effect, it should be a parameter left by the old version)
        "rSt": 1.0, (sp reply speed)
        "mMp": 500.0, (the amount of mana under non-levelization, if the character does not have level data, it will also affect the amount of mana when there is a level. The characters in the original character list all have level data, and the characters that are not in the character list There is no level data, and some mods have additional level data for some characters not in the character list)
      
        "defBody" can be understood as a template for the character body, the character will use this template in some actions, "defBody" will affect the automatic defense, which will be mentioned later
		
		"defBodyW": 110.0, (length of body template)
        "defBodyH": 240.0, (the height of the body template)
        "defBodyT": 60.0, (the width of the body template)
		
		"refSpt": "model0", (borrowed texture data, when the borrowed character data is wrong, the character will also go wrong, which will be explained in detail later)
        "type": 1.0, (type, there are humans, mounts, props, special effects, etc., can not be changed at will)
        "wisdom": 50.0, (wisdom, will affect the com IQ in war)
        "st_rate": 1.0850694444444444, (sp consumption rate, the higher the rate, the easier it is to consume sp)
		"weight": 1.0, (weight, the larger the value, the harder it is to be knocked into the air, it is also harder to push, and it is easier to push heavy objects)
        "walkSpeedX": 17.0, (walking speed)
        "runSpeedX": 25.0, (movement speed of running and tumbling)
        "jumpSpeedY": -63.0, (upward speed during take-off)
        "jumpSpeedX": 29.0, (forward/backward speed when jumping forward/backward, it will also affect the speed of some special skills)
        "dashSpeedY": -38.0, (upward speed when rushing to jump)
        "dashSpeedX": 72.0, (the forward speed when jumping)
		"airDashSpeedX": 61.0, (movement speed of backflip)
		
		"hasHorse": false, (whether you have a horse, change it to true to start with your own horse, such as a cavalry. If the character is a soldier, the horse will run away after dismounting, and a new horse will be automatically summoned after a while. If the character is a hero, dismount The back horse will not run away and will no longer automatically summon horses)
		"name": "Jenny", (name, can be changed freely, it will be displayed when the game is settled)
		"meleeDx": 280.0, (the x-axis determination range of com's general attack, when there is an enemy in this range, com will launch a general attack, similar to the skill's ai)
        "soldierNumber": 1.0, (as a soldier added in vs, the number of each group, for example, the infantry is 4, the cavalry is 2)
        "soldierReserved": 1.0, (when used as a soldier added to vs, the reserve of each group, for example, 4 infantry and 2 cavalry)
        "meleeDz": 80.0, (the z-axis judgment range of com's general attack, when there is an enemy in this range, com will launch a general attack, similar to the skill's ai)
        "brk0": 0.0 (When the defense value is reduced to this value, the defense will be broken. The higher the value, the easier it is to break. All heroes in the original version are 0, and the soldiers will be higher. Changing it to a negative number can enhance the defense)
		"isSoldier": false, (Whether it is a soldier, decide whether there is a health bar, whether it can be directly caught by Chu Ying, etc.)
		"sfxHurt": 45.0, (the sound made when injured, refer to the group file-HFSE story code-ac code supplement the latest version for specific values)
        "guardSfx": 0.0, (the sound made when defending against an attack. For example, lucas is 0, which is the sound of sword collision; drew is 1, which is the sound of physical blocking; the iceman is 4, which is the sound of crushing ice. At the same time, the value is At 4 o'clock, ice cubes will be exploded like an iceman, and disappear directly when the blood volume is 0.)
        "shadowR": 1.0, (the area of ​​the shadow can be changed to 0)
        "RQ": 800.0, (the range of deterrence, com will walk around you in this range, the RQ of the long-range character will be significantly greater than that of the melee character)
        "HQ": 0.8, (when riding, the deterrent range = character RQ + mount RQ * character HQ, and it is also the range where the character finds a mount. For example, the HQ of Lux is 0 and it will not automatically find a mount)
        "STQ": 0.1, (the ratio of the SP durability during weightlifting to normal, the smaller the value, the faster SP will be consumed during weightlifting)
		"soldierQ": 70.0, (The price of war resurrection also determines the number of free resurrects at the start. There are 20 free resurrects within 50, 10 from 50 to 70, 5 from 70 to 100, 3 from 100 to 200, 200 The above is 1 time)
		"HGQ": 0.1, (the range for the character to find heavy objects, change to 0 will not find heavy objects, and it is related to AI. It is speculated that the impact is the AI ​​when riding and catching people)
		
		The following are parameters whose specific functions are unknown. You can explore by yourself according to the name, and you are welcome to add
		
		"boxScale": 1.0,
		"auraColor": 16777215.0, (this value represents the color code of pure white, but there will be no change if it is changed, all characters are this value)
		"horseApp": "0",
		"defense": 50.0, (defense, similar to wisdom in the setting method, but the specific function is unknown)
		"attack": 50.0, (attack, similar to wisdom in the setting method, but the specific effect is unknown)
		"leadership": 50.0, (Leadership, similar to wisdom in the setting method, but the specific function is unknown, and it is speculated to be related to the ability to lead troops)
		"cropApp": "0",
		"fh": null,
		"fn": null,
        "gravityRate": 1.0, (From the name, it is related to gravity, but directly changing it has no effect)
		
		
2. Related parameters of war recruitment:		
	
	
The recruiting of war mode involves common basic parameters. These common basic parameters are slightly more complicated than simple basic parameters, but it is not complicated to change numbers and id.
There are not many common basic parameters, only skin binding and war recruitment data are more important
The following are the parameters related to the recruitment of war mode		
		
        "hire_id": {(The type of soldiers that this character summons in the war can be repeated, and the high-level soldiers can be before the low-level soldiers)
            "HFW_ArrayLenXXX": 4,
            "0": "z_infantry01",
            "1": "z_archer01",
            "2": "z_woman01",
            "3": "z_cavalry01"
        },
		"hire_max": {(The maximum number of soldiers that this character can summon in the war corresponds to the soldiers in hire_id. For example, 5 here corresponds to z_infantry01 in hire_id, which is infantry, which means that the infantry can call up to five groups)
            "HFW_ArrayLenXXX": 4,
            "0": 5.0,
            "1": 2.0,
            "2": 1.0,
            "3": 4.0
        },
		"hire_h": {(The riding carried by the soldiers summoned by this character in the war, "h" is a horse, "m" is a monster, and "t" is a triceratops)
            "HFW_ArrayLenXXX": 4,
            "0": null,
            "1": null,
            "2": null,
            "3": "h"
        },
		"hire_price": {(The price required for the soldiers summoned by this character in the war. For example, here is 100 for infantry and 150 for women)
            "HFW_ArrayLenXXX": 4,
            "0": 100.0,
            "1": 100.0,
            "2": 150.0,
            "3": 160.0
        },
		These 4 sets of parameters jointly determine the recruitment of the war. Normally, their element amounts must be the same. If you need to expand new units, you must expand 4 parameters at the same time.
		Otherwise, it won’t work. Even if this unit does not have a ride, add null to the serial number of the new unit in hire_h.
		
	

	
3. Skin binding articles:				
		
The parameter of the skin binding is: "spriteLimb", here I list the skin binding of Longsuke		
		
"spriteLimb": {
            "HFW_ArrayLenXXX": 45,
            "0": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limbNames": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbName": "Lucas_00Head", (here is the name of the texture group bound to this serial number, here is the head of Ryusuke)
                "limbType": 0.0, (type, only as a mark)
                "xScale": 0.99,
                "limb": null,
                "yScale": 0.99,
                "limbTypeName": null
            },
            "1": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limbNames": {(This role has different bindings under different teams, a is team 1, b is team 2, c is team 3, d is team 4, e and f are dedicated to the story in the original version, and this is also the skin setting Principle, if teamapp is true, the character will change the skin according to the team)
                    "HFW_ArrayLenXXX": 0,
                    "b": "z_bandit01_01ChestB" (It can be seen here that the second team of the original Ryusuke is bound to the thieves’ jackets, which are the skins of the jailer’s clothes in the fifth episode, but since the teamapp of the original Ryusuke is false, the player does not The skin will change depending on the team)
                },
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbName": "Lucas_01Chest",
                "limbType": 1.0,
                "xScale": 1.0,
                "limb": null,
                "yScale": 1.0,
                "limbTypeName": null
            },
            ······
            "28": {(28 is usually the position of the cloak, because Ryusuke does not have a cloak, so it is not bound)
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limbNames": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbName": "",
                "limbType": 28.0,
                "xScale": 1.0,
                "limb": null,
                "yScale": 1.0,
                "limbTypeName": null
            },
           ······
        },

In the original version, the different parts of all characters will be neatly placed in a fixed serial number. For example, everyone’s head is number 0, body is number 1, and weapon is number 20. This also provides the possibility for skill transplantation. Sex.
The following are the texture parts corresponding to each serial number in the original game. Left and right refer to the left or right side of the screen when the character stands to the right, not the left or right side of the character.

"0": Head
"1": Chest body
"2": The original version is not used
"3": Hips crotch
"4": LeftShoulder
"5": UpperArm left arm
"6": LowerArm left forearm
"7": LeftFist left hand
"8": LeftFistCover left finger
"9": RightShoulder
"10": UpperArm right arm
"11": LowerArm right forearm
"12": RightFist
"13": RightFistCover right finger
"14": UpperLeg left thigh
"15": LowerLeg left leg
"16": Foot
"17": UpperLeg right thigh
"18": LowerLeg right leg
"19": Foot
"20": Sword is the left hand weapon, the weapons of normal characters are placed in this position
"21": The original version is not used
"22": icefire special effects
"23": Collar
"24": Sword right hand weapon, only Shawn of the original characters can use
"25": The original version is not used
"26": icefire special effects
"27": The position of Cape's cape bound to a small number of characters
"28": The position where most of Cape's characters are bound to the cape
"29": Skirt
"30": Hair
"31": The original version is not used
"32": The original version is not used
"33": belt
"34": HipsGuard crotch
"35": The original version is not used
"36": The original version is not used
"37": LegGuard left leg armor
"38": LegGuard
"39": The original version is not used
"40": The original version is not used
"41": The handle of the left hand weapon, used to cover the hand
"42": The handle of the right hand weapon, used to cover the hand
"43": effect The afterimage of a weapon or fist swing
"44": effect The afterimage of a weapon or fist swing

Although these texture parts are bound according to the serial number in the original version, sometimes they can not be bound according to the serial number, but the prerequisite for this is that certain settings are made in the frame. This is more complicated content and will be explained later.
From the above data, we can know that most of the positions are used, but they are used by different characters, for example, leo, eason, and jenny have hair bindings, but most characters do not.
It is impossible for a normal character to have both hair bindings, skirts, leg armors, two-handed swords, and cloaks. Therefore, the normal role will only use about half of the position.
Therefore, we can use the spare position to bind some additional textures, but it will not work after binding. We also need to set the new textures in the frame.
But if you simply replace the original binding instead of adding a new binding, the texture will be displayed directly.

To change the binding, just change the "limbName". For example, if you want to change Ryusuke’s body to the one of Chengying, we have to copy the limb name of the body part in the spt of Chengying.
like this:
"1": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limbNames": {
                    "HFW_ArrayLenXXX": 0,
                    "b": "z_bandit01_01ChestB"
                },
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbName": "Lucas_01Chest",
                "limbType": 1.0,
                "xScale": 1.0,
                "limb": null,
                "yScale": 1.0,
                "limbTypeName": null
            },
After the change
 "1": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limbNames": {
                    "HFW_ArrayLenXXX": 0,
                    "b": "z_bandit01_01ChestB"
                },
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbName": "Shawn_01Chest",
                "limbType": 1.0,
                "xScale": 1.0,
                "limb": null,
                "yScale": 1.0,
                "limbTypeName": null
            },

(However, not all characters can be directly exchanged and bound, because the position and size of different characters' textures are different, and direct exchange may cause misalignment, but there are also textures with similar positions and sizes. These textures can be replaced and bound with each other. .
For specific characters and which parts can be interchangeably bound, please go to the HFW group to download the file: "HFW Interchangeable Binding.docx". )
However, this problem has been resolved. The newly released HF-EX version sets the location and size of most of the characters' textures to be the same. In this version, the bindings can be exchanged freely.
"limbName" corresponds to the name written in the character's lmi file. The limb is a set of textures, such as Ryusuke's head texture, including the front, side, and head textures when knocked down.
If we want to make a new skin, we need to add a limb file. For specific operations, you can download "HFW replacement skin binding.docx" in the HFW group.

 Except for skin binding and war recruiting, the remaining common basic parameters are relatively unimportant. The following are the remaining common basic parameters. These parameters have no effect, and may be used as comments or obsolete code left over from the old version.      		
		
		"lmiFiles": {(The lmi used by this role is just for recording and has no effect)
            "HFW_ArrayLenXXX": 2,
            "0": "lmi_data/global.lmi",
            "1": "lmi_data/jenny.lmi"
        },
		"cad": {(Changing it will not have any effect, it may be a parameter similar to the comment)
		"keyTgr": {(Key, different from A_keyTgr, this change will have no effect, it may be used as a comment)
		
		The following are the unknown parameters.
		"renderedPic": {
		"renderedPic_2": {
		"renderedPicH": {
		"renderedPic_2H": {	
		
		
		
Three, frame entry:

After mastering the knowledge of actiongroup and action, you can start to learn frame. Frame is the most important part of spt, accounting for more than 98% of the entire file.
At the same time, it is also the most complicated part of this spt, some of the small details may be more complicated than many previous parameters. It can be said that if you master the frame, you will master the role change.	
A frame is actually a frame, just like a video frame, but the difference is that in addition to the picture, the frame in HF also needs to be set for body, attack and other judgments.	
It may be a little difficult to understand the knowledge of the frame, but as long as you have patience and willingness to use it, it is only a matter of time to master it.
Because there are too many frame parameters, so instead of listing all the parameters directly like action, we will explain them one by one.

01. End frame:
		
There is a "last" parameter in the frame, which is used to end the action. When the last of this frame is false, it means that the action has not ended. When this frame ends, it will automatically proceed to the next frame.		
And if "last" is true, it means this is the last frame of this action, when this frame ends, the action will end, if nextAi is set, it will enter the next action, if it is not set, it will return Stand up, and return to jumping state if it’s an aerial action,
"last" is not complicated, but it is very important. Through "last", all frames of an action can be found, multiple actions can be combined into one action, or one action can be split into multiple actions.
For example, Ryusuke’s Flying Dragon Slash starts from frame 316, and the "last" of frames 316 to 329 is false, because they are not the end frames, and when it comes to frame 330, "last" changes To be true, this means that frame 330 is the last frame of Flying Dragon Slash. 
"329": {
                "HFW_classNameXXX": "Data.Frame",
				······
                "last": false,
				······
                 },
"330": {
                "HFW_classNameXXX": "Data.Frame",
				······
                "last": true,
				······
                 },
"331": {
                "HFW_classNameXXX": "Data.Frame",
				······
                "last": false,
				······
                 }
Frame 331 happens to be the start frame of ball2. Therefore, if the "last" of frame 330 is changed to false, the flying dragon cut action will not end, and it will not end until the end frame of flying dragon cut 2.
In this way, what the Flying Dragon Slash action performs is all the frames of Flying Dragon Slash + Flying Dragon Slash 2, which is equivalent to combining the two actions into one action. However, in the original Flying Dragon Slash 2 action, the frame starting from No. 331 has not been changed, so it is not. Will be affected.
If you can’t understand it, try to actually change it once.

02. Demolition:

It is not difficult to combine two consecutive actions into one action, but it is relatively troublesome to split one action into two actions because of the connection of actions.
But this can also be used to try the knowledge about action connection that you learned before.
If one action is split into two actions, it will not slow down due to the change in the number of actions, because the actions are seamlessly connected and there is no delay, so in theory, one action per frame is also feasible.
The dismantling action is of great significance, such as skipping the starting hand when activating the skill under a certain action, setting different buttons for the previous frame and the following frame, lending the starting or closing action to other actions to save space, etc. .
For example, Eason0 in PMM divides the four consecutive cuts into four actions, and can release the dragon at the end of the first three swords, but cannot release the flying car. And when the last knife is finished, you can either release the dragon or catch the flying car.
However, compared to the actual meaning, the greater advantage of the dismantling action is that it can help you better understand the connection between the last and the action.

Let’s take Ryusuke’s Flying Dragon Slash as an example. Longsuke’s Flying Dragon Slash starts at frame 316 and ends at frame 330. Among them, frame 323 will release a Flying Dragon Slash prop.
Therefore, we can set frame 316 to frame 322 as a separate action, and use it as the starting action. In this way, frame 322 becomes the end frame of this action, so "last" should be changed to true
In this way, the action that originally started from No. 316 and ended at No. 330 will end when it becomes No. 322. Therefore, it becomes a starting action. And for the frame from 323 to 330, we need to set another one. action.

We first copy the original ball action to the end of the original last action, and then change the sequence number
"109": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "KNEEL", (the last action of the original Ryusuke is kneel)
                "a_keyTgr": null,
                "landAgi": -1.0,
                "frameIndex": 418.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 109.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            },
			"110": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 250.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 316.0,
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }	
			
Then modify the "frameIndex" so that the frame corresponding to this action is the second half of the frame.			
			The actual modification is as follows
			
	"109": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 0.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "KNEEL", (the last action of the original Ryusuke is kneel)
                "a_keyTgr": null,
                "landAgi": -1.0,
                "frameIndex": 418.0,
                "aix1b": 0.0,
                "mpBurn": 0.0,
                "index": 109.0,
                "aix2": 0.0,
                "aiz1": 0.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": 0.0,
                "aix1": 0.0,
                "landActionName": null
            },
			"110": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": -1.0,
                "allowTurnFace": false,
                "nextAti": -1.0,
                "frame": null,
                "aiz2": 60.0,
                "special": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": -1.0,
                "name": "BALL1B", (It is better to change the name)
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 250.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 323.0, (here 316 has been changed to 323)
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }

	We change the starting frame of this new action from 316 to 323, then the frame corresponding to this action is the second half of Flying Dragon Slash, which is 323 to 330. At this point, just connect the original action (frames 316 to 322) and the newly added action (frames 323 to 330) to complete the split of the action.
	First set the new action (you can see that the serial number of this new action is 110) into the actiongroup, otherwise it will not work.
			
			 "0": {
                "HFW_classNameXXX": "Data.ActionGroup",
                ······
                "name": "normal", (Since Flying Dragon Slash is a standing skill, it is set into the standing actiongroup)
                ······
                "actionIndex": {
                    "HFW_ArrayLenXXX": 4,
                    "0": {
                        "HFW_ArrayLenXXX": 31,
                        "0": 1.0,
                        ······
                    },
                    "1": {
                        "HFW_ArrayLenXXX": 58,
                        "0": 18.0,
                        ······
                    },
                    "2": {
                        "HFW_ArrayLenXXX": 19,
                        "0": 73.0,
                        ······
                    },
                    "3": {(New actions are often skills, so the ati of skills is expanded, which is the 3rd ati)
                        "HFW_ArrayLenXXX": 11,
                        "0": 91.0,
                        "1": 92.0,
                        "2": 89.0,
                        "3": 94.0,
                        "4": 95.0,
                        "5": 93.0,
                        "6": 102.0,
                        "7": 103.0,
                        "8": 104.0,
                        "9": 105.0,
                        "10": 101.0,
						"11": 110.0 (we expand the new action to the end, and then push the serial number of ai backwards, you can see that the 11th ai now corresponds to the 110th action)
                    }
                },
               ······
            },
			
After setting, we remember this ai (11), and then set the connection to this action in the original action			
	 "94": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": false,
                "nextAi": 11.0, (the ai of the new action is 11, so nextAi is set to 11)
                "allowTurnFace": false,
                "nextAti": 3.0, (connected to the skill action, so nextAti is 3)
                "frame": null,
                "aiz2": 60.0,
                "s pecial": -1.0,
                "landAti": -1.0,
                "landAi": -1.0,
                "nextAgi": 0.0, (connected to the action in the standing state, so nextAgi is 0, which should be distinguished from -1)
                "name": "BALL",
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 0.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 3.0,
                        "k": "gua",
                        "mp": 250.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "gua"
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "ai": 4.0,
                        "atf": false,
                        "hp": 0.0,
                        "ati": 3.0,
                        "pollhp": 0.0,
                        "kl": 1.0,
                        "k": "a",
                        "mp": 90.0,
                        "agi": 0.0,
                        "rkt": true,
                        "kr": "a"
                    }
                },
                "landAgi": -1.0,
                "frameIndex": 316.0,
                "aix1b": -600.0,
                "mpBurn": 0.0,
                "index": 94.0,
                "aix2": 600.0,
                "aiz1": -60.0,
                "nextActionName": null,
                "type": -1.0,
                "aix2b": -70.0,
                "aix1": 70.0,
                "landActionName": null
            }

After setting, even if the flying dragon cut action is disassembled, you can try to directly connect the handless flying dragon cut in some actions, because it is very basic knowledge, so I won't explain it in detail.

03, frame delay articles:

If you observe carefully in the game, you will find that some characters will hold for a while when they make some actions, such as the Big Three blew up, and some closing or starting actions. (The action here refers to the visual action, and has nothing to do with the action)
In fact, this is because some frames have a delay, which will be kept for a period of time before entering the next frame.
Delay, expressed as "duration" in the frame, the larger the value, the longer the delay. When the duration is 1, it is equivalent to extending this frame by the same length as the original one, that is, this The frame hold time is doubled, and the duration of 2 is tripled, 3 is quadrupled, and so on.
When the character is in the delayed state of the frame, the attack, the range of the body hit, and the character map will remain unchanged. If there is a release prop in this frame, the prop will only be released once.
Delay is not a patent for the start and end actions. In fact, a large part of the frames are delayed because the number of frames for each action in the original version is not many. If there is no delay, the action will be very fast. past.
Excluding the frames that are accumulated, starting, ending, and stiff, the "duration" of ordinary frames is generally 0 or 1, a small part is 2, and most of them are special frames (start, close, stiff, etc.)			
For example, Ryusuke's attack1 and attack4 have a total number of frames of 8, but their speeds are completely different. This is because of the difference in "duration".
The "duration" of the eight frames of Ryusuke attack1 are: "0.1.0.0.0.0.1.2". A total of 4 frames are delayed, plus the original time value of the frame, and the action took a total of 12 frames. .		
The "duration" of the eight frames of Ryusuke attack4 are: "0.1.1.1.1.5.1.1", a total of 11 frames delayed, plus the original time value of the frame, the action took a total of 23 frames. .
The two actions in the same eight frames have almost doubled the speed due to the different delays. It can be seen that "duration" is also a very important parameter.
However, although "duration" is important, it is not difficult to change it. You only need to change the value. We can use it to speed up the character, slow down the character, or individually speed up an action, set up a charge action, etc.			
			
04. Copy frames:

Using "duration", we can delay a certain frame. However, in the process of delay, the judgment of this frame cannot be adjusted, and only one set of props can be released at the same time.
If we want a certain action of a character (visual action, non-action) to have different judgments in the previous period and the next period of time, or to release the props in order, we have to use another method to do it Delay.

This method is copying. We can copy the original frame once, so that this frame is performed twice, which is equivalent to doubling the time.
Compared with "duration", the advantage of copying frames is that it can be finely adjusted, but the disadvantage is that it is more troublesome.
As mentioned before, no matter frame, action or actiongroup, they must be arranged in order. If a frame is copied once, the number of the copied frame must be changed.
If the copied frame is at the end, it will be fine after changing the serial number, but if it is in the middle, because the copied frame occupies a serial number, all subsequent serial numbers will be messed up and need to be re-arranged manually. Unless there are some discarded frames later, a sequence number can be vacated.
Simply put, the frame in the middle or the front is not suitable for this method, but generally the frame of the new skill will be added to the end of the frame, so the copy method is still very useful when creating new skills.

The following is an actual copy demonstration. Because there are too many parameters in the frame, I will delete all the parameters first and only keep "index"
······
"305": {
              ······
                "index": 305.0,
              ······
				},
"306": {
              ······
                "index": 306.0,
              ······
				},
"307": {
              ······
                "index": 307.0,
              ······
				},
"308": {
              ······
                "index": 308.0,
              ······
				}		
······		
	
As you can see, there are four frames shown here. If we need to copy frame 306 twice, copy the entire content of frame 306 to the back of frame 306.

······
"305": {
              ······
                "index": 305.0,
              ······
				},
"306": {
              ······
                "index": 306.0,
              ······
				},
"306": {<-----------------------Here, frame 306 has been copied twice, but the serial number has not been changed, it is useless , So we have to change the serial number
              ······
                "index": 306.0,
              ······
				},
"306": {
              ······
                "index": 306.0,
              ······
				},				
"307": {
              ······
                "index": 307.0,
              ······
				},
"308": {
              ······
                "index": 308.0,
              ······
				}		
······		

↑The above is the first step: copy

······
"305": {
              ······
                "index": 305.0,
              ······
				},
"306": {
              ······
                "index": 306.0,
              ······
				},
"307": {
              ······
                "index": 307.0,<--------------------"index" should also be changed
              ······
				},
"308": {<--------------------The copied frame has its serial number changed
              ······
                "index": 308.0,
              ······
				},				
"307": {<--------------------Due to the increase in the number of previous frames, the serial number here is messed up, so you need to manually adjust it
              ······
                "index": 307.0,
              ······
				},
"308": {
              ······
                "index": 308.0,
              ······
				}		
······	

↑The above is the second step: reorder the copied frames

······

"305": {
              ······
                "index": 305.0,
              ······
				},
"306": {
              ······
                "index": 306.0,
              ······
				},
"307": {
              ······
                "index": 307.0,
              ······
				},
"308": {
              ······
                "index": 308.0,
              ······
				},				
"309": {
              ······
                "index": 309.0,
              ······
				},
"310": {<--------------------All the frames down here need to be adjusted.
              ······
                "index": 310.0,
              ······
				}		
······	
	
↑The above is the third step: reorder the subsequent frames			
		
Here we are copying frames for delay and fine adjustment at the same time.
If it is a frame that has been delayed with "duration", we can also copy it, but reduce the value of "duration" to keep the total time value of the frame unchanged.
E.g:

"305": {
              ······
                "index": 305.0,
				"duration": 0.0,
              ······
				},
"306": {
              ······
                "index": 306.0,
				"duration": 5.0,<-------------The "duration" of this frame is 5, plus the time occupied by itself, which is equivalent to 6 frames of time.
              ······
				},
"307": {
              ······
                "index": 307.0,
				"duration": 0.0,
              ······
				},

After copying:
"305": {
              ······
                "index": 305.0,
				"duration": 0.0,
              ······
				},
"306": {\
              ······ \
                "index": 306.0, \
				"duration": 1.0, \
              ······ \
				}, \
"307": {>------------After copying, the original frame becomes three frames, and the time value of the frame itself is also increased from 1 to 3, so the total "duration" The value is no longer 5, but 3, and the total time value of the frame itself is still 6.
              ······ /
                "index": 307.0, /
				"duration": 1.0, /
              ······ /
				}, /
"308": {/
              ······
                "index": 308.0,
				"duration": 1.0,<--------------"duration" does not have to be evenly distributed. Here, it is divided into 003, 012, 111, 120, 210, 030, etc., which are all possible. The specific allocation depends on the specific situation.
              ······
				},		
"309": {<-------------------Change the serial number and "index" by the way
              ······
                "index": 309.0,<-------------- Two frames are copied, then the sequence number is pushed back by two, which is +2.
				"duration": 0.0,
              ······
				},

In addition, when copying frames, we also need to pay attention: if the frame we copied is the last frame of the action, and "last" is true, then after copying, the "last" of the original frame should be changed to false, because It is postponed to end, and only the last true is kept.
E.g:

"305": {
              ······
                "index": 305.0,
				"last": false,
              ······
				},
"306": {<-------------------Copy this frame twice
              ······
                "index": 306.0,
				"last": true,
              ······
				},
"307": {
              ······
                "index": 307.0,
				"last": false,
              ······
				},

	After copying:
	
"305": {
              ······
                "index": 305.0,
				"last": false,
              ······
				},
"306": {
              ······
                "index": 306.0,
				"last": true, \
              ······ \
				}, \
"307": {\
              ······ \
                "index": 307.0, \
				"last": true, >------------There are three trues here. When the action is in progress, it will end when the first true is encountered, but we hope that frames 307 and 308 will also start Function, the true here must be changed to false
              ······ /
				}, /
"308": {/
              ······ /
                "index": 308.0, /
				"last": true, /
              ······
				},				
"309": {
              ······
                "index": 309.0,
				"last": false,
              ······
				},		
		
	
After modification:

"305": {
              ······
                "index": 305.0,
				"last": false,
              ······
				},
"306": {
              ······
                "index": 306.0,
				"last": false,  		
              ······				 
				},					  
"307": {							   
              ······					
                "index": 307.0,          
				"last": false,			 
              ······					 
				},						
"308": {							   
              ······  				  
                "index": 308.0,		 
				"last": true,		
              ······
				},				
"309": {
              ······
                "index": 309.0,
				"last": false,
              ······
				},	


05. Simple parameters:

There are also some very simple parameters in the frame, because they are easy to understand, so I will take them here in one stroke.

"name": "jump_attack", (name, as a marker, and also as a location for other characters to refer to the texture, which will be explained in detail later)
"vx": 0.0, (the character's x-axis speed when the character is in this frame)
"vy": 0.0, (the y-axis speed of the character when the character is in this frame)
"attackMany": 5.0, (the maximum number of enemies hit by the attack, only affects the main body attack)
"footY": 96.0, (the greater the height of standing, the higher the standing, the bigger the figure will float)
"onGround": true, (Whether it is on the ground, if it is, it will enter the stand after the action is completed, if not, it will enter the jump after the action is completed, it should be set according to the actual situation)
			




	




Four, frame articles:

At this point, we have officially started to learn frame. The starting parameter does not need to change a number like duration and last. It is difficult to change multiple small parameters within one parameter.
But as long as you remember the role of each small parameter, it is also easy to understand.

01. Limit articles:

The judgment of the character is divided into the in-body judgment and the on-body judgment. The in-body judgment is the item to be launched, such as flying dragon chop, bow and arrow, and gale drill.
Except for the skills of Cheng Ying, most of the skills with props are the combination of the main body determination and the out-of-body determination. For example, Ryusuke Feilongzhan will have a very weak body attack. In addition to the main body attack of the E Thang Longba A beam of light.
Judgment not only refers to the attack judgment, but also a judgment of defense, being hit, and being caught, and these are all ontological judgments, that is, the judgments issued by the character itself and can be fed back to the character itself.
And these ontological judgments have a limit (best). Beyond this limit, no matter whether it is collision, defense, attack, or attack judgment, it will not work. Therefore, when expanding the scope of judgment, we have to expand this limit at the same time.
Limit is best in English, so the x-axis limit is naturally bestx. For brevity, it is expressed as bx in the frame.
In the same way, bz is the z-axis limit, and by is the y-axis limit.
Since the xyz axis is bidirectional, there are two parameters to control the xyz limit, a total of 6: "bx1", "bx2", "bz1", "bz2", "by1", "by2".

"bx1": the left limit of the x-axis
"bx2": the right limit of the x-axis
"bz1": the upper limit of the z axis
"bz2": the lower limit of the z axis
"by1": the upper limit of the y-axis
"by2": the lower limit of the y-axis


02. Body articles:

There is a "body" in the frame, which is a parameter that controls the character's body. If there is no body, the character will not be hit (except for attack and collision) and will not be caught.
The parameters in the body determine the size of the character's attack range. For example, the attack range and collision size of the triceratops and the magic dragon are much larger than that of ordinary characters.
The collision range and the attack range are independent of each other. You can set a character that has a large attack range but cannot collide; you can also set a character with a large collision range but a small attack range.

"body": {
                    "HFW_ArrayLenXXX": 1,
                    "0": {
                        "HFW_classNameXXX": "Data.Body",
                        "x1": -55.0,<-----------The left boundary of the body being hit
                        "z1": -30.0,<-----------body hit the upper boundary
                        "x2": 55.0,<------------the right border of the body being clicked
                        "g0": 0.0,<-------------Frontal defense judgment, explained in detail later
                        "z2": 30.0,<------------body hit the upper boundary
                        "y1": -212.0,<----------the upper boundary of the y-axis of the body being hit
                        "cy": -92.0,
                        "y2": 28.0,<------------The lower boundary of the y-axis of the body being hit
                        "w": 110.0,<------------Left and right range of body collision volume
                        "g1": 0.0,<-------------Defensive judgment on the back side, explained in detail later
                        "h": 240.0,<------------The height of body collision volume
                        "j": 0.0,
                        "cx": 0.0,
                        "l": 1.0,
                        "t": 60.0<--------------Upper and lower range of body collision volume
                    }
                },

The effect of the unspecified parameters is unknown, and it is inferred that the effect is little or no effect

In addition, there is an "editBody" in the frame, which is to make certain corrections to the body. This parameter has been determined to be useful, but the specific effect has not been studied.
PS: The positional parameters in "body" are affected by bx, bz, and by


03. Defense Judgment:

When a character is defending, there will be a defensive judgment on the front, and some special skills (such as the Big Three’s self-detonation charge) will have both front and back defensive judgments. These defensive judgments are actually set in the body.

There are two defense-related parameters in the body, namely "g0" and "g1". "g0" stands for frontal defense. As long as the value is changed to a number greater than 0, such as 0.1, the front side will bring the defense judgment, and the back side The same is true.
For characters other than Legg in the original version, the "g0" of the frame with defensive judgment is 0.8 and Legg is 0.9. So far, no difference between different values ​​has been found. Therefore, when setting the defensive judgment, follow the 0.8 of ordinary characters. That's it.
In addition, there is a "UseDefBody" parameter in the frame. If defense determination is required, this parameter must be set to false.

If you want the entire actiongroup to have defense judgments, there is a simple way to modify the "shield0" (frontal defense judgment) and "shield1" (backward defense judgment) in the actiongroup.
Change the value of "shield0" or "shield1" to a number greater than 0, and then "g0" and "g1" in the body of all frames of all actions under the entire actiongroup will automatically be judged to be the same as "shield0", " the same value as shield1"
For example, if you change the "shield1" of the normal action group to 0.7, and then belong to normal actions, such as stand, run, jump, etc., the body "g1" of all frames of them is still 0.0, but it will be in the actual game. Was judged to be 0.7

If you observe carefully, you will find that the characters' defense actions, such as gua_stand and gua_run, the "g0" of the "body" in their frame are all 0.0, but they have a positive defense judgment, precisely because they are set in the actiongroup" shield0"




04. Attack articles:
	
"attack" is an important parameter in the frame, which controls the character's attack determination.
The following is the attack judgment of the third frame of Longsuke's running attack
	
	"attack": {
                    "HFW_ArrayLenXXX": 1,
                    "0": {
                        "HFW_classNameXXX": "Data.Box",
                        "x1": 15.0,<====================== Attack to determine the left boundary
                        "y2": -69.0,<======================= Attack determination y-axis lower boundary
                        "j": 1.0,
                        "ref": 15.0,<======================= The serial number of the attack judgment used, as a mark
                        "z2": 40.0,<====================== Lower boundary of attack determination
                        "y1": -207.0,<======================= Attack determination y-axis lower boundary
                        "refName": "hard",<======================= The name of the attack judgment used, must be filled in correctly, the next article will explain in detail
                        "x2": 197.0,<====================== Attack judgment right border
                        "l": 20.0,
                        "z1": -40.0<====================== upper boundary of attack determination
                    }
                },
	
The effect of the unspecified parameters is unknown, and it is inferred that the effect is little or no effect	
	
Like the body, there is also an "editAttack" in the frame, which is the editing and correction of the attack determination. The specific effect is unknown, but the influence of "editAttack" on the "attack" is often negative. Therefore, when there is a problem with the determination range, delete it. Drop "editAttack" may solve this problem.	
PS: The position parameters in "attack" are affected by bx, bz, and by	
	
In addition, there are two parameters about attack in the frame, they are "newAttack" and "attackMany".
"attackMany" is the number of group injuries that are attacked. If it is changed to 3, it will attack up to three targets, and it only affects the main body.
"newAttack" is to determine whether this attack is a new attack. For example, both frames 226 and 227 of Ryusuke’s run attack have attack determinations, but only one damage can be caused to the same target, precisely because frame 227 is not new. attack.
This attack can be understood as a whole. The "attack" of frame 226 and frame 227 together constitutes an attack that lasts for two frames. The target that has been attacked cannot be hit again, but it can hit a new one. the goal.
And if you change "newAttack" to true, the attack determination in this frame is a new attack. It can not only attack the new target, but also hit the target that has already been hit. This is the principle that Jace's wheels can continue to damage. In addition, , If "newAttack" is set to true, "attackMany" will be reset, and the target hit by the previous old attack will not be counted into the group damage limit.
There is also a special case, if an attack lasts too long, even without "newAttack": true, it can still hit the target that was already hit.
"newAttack" may be relatively difficult to understand, but as long as you try it yourself, you will quickly understand.


05. Attack data:
	
142-Data.Global_globalDat is the location where the attack data is stored. There are two files, ptWithName_xxx.json and Attack_xxx.json (xxx represents the serial number), and ptWithName_xxx.json is temporarily ignored.
Attack_xxx.json is the attack data, xxx is the serial number, and this serial number is filled in the "ref" of "attack". The data such as the break, damage, and knock-up when the character attacks are also determined by the bound attack data.
For example, the 15th attack: The content of Attack_15.json is as follows
PS: The introduction to the role of attack data parameters comes from the HFW group—"Tutorial-attack.json" (by Not Hungry Baidi)
{
    "Data.Attack": {
        "hp": 45.0, (The damage caused by the attack. If set to a negative value, you can increase the blood of the enemy.)
        "fall": 200.0, (The knockdown value deducted for this attack. The full value of the knockdown value of normal heroes is 180.)
        "brk": 130.0, (the defense value deducted from the attack. The defense value of a normal hero is 180 at full)
        "name": "hard", (the name of the attack, the name cannot be repeated between each attack, the name is important binding data when the character binds damage)
        "ref": -1.0,
        "z1": 60.0,
        "dizzy": 30.0, (when the fall is less than 180, the stun time caused when stun the enemy, the maximum is 60)
        "x1": 0.0,
        "stun": 2.0, (the time when the opponent's action is frozen when hitting the enemy)
        "x2": 150.0,
        "z2": 0.0,
        "y1": 0.0,
        "type": 0.0, (different attack effect only when effect=0 or 1)
        "y2": 150.0,
        "selfStun": 2.0, (when hitting an enemy, the time when one's actions are frozen)
        "effect": 0.0, (type of attack, all listed below)
        "vx": 33.0, (the x-axis speed at which the enemy flies when knocking down the enemy. When vx is large enough, the enemy will be knocked into the air (fall_spin1), for example: whirlwind throw)
        "dxMirror": false, (Determine whether the attack direction is symmetrical with the character as the center, for example: White Aurora, Demon God Roar is true, the attack direction is two-way, the magic is in the world is false, and the attack direction is one-way)
        "vy": -40.0, (when knocking the enemy, the enemy's y-axis speed, when vy is less than -85, the enemy will be knocked into the air by rotation (fall_spin3), for example: the devil is in the world)
        "i": 15.0, (the serial number of the attack)
        "vz": 0.0, (the z-axis speed at which the enemy flies out when knocking the enemy away)
        "j": 0.0,
        "dx": 0.0,
        "refName": null,
        "l": 1.0,
        "aaa": true (determines whether the attack can be collided. For example: Demon is true, so it can be hit by a rising dragon whose fall and brk are greater than its own. The white aurora and stone breaking shock are false, so you can ignore the fall and brk Rules hit the soaring dragon)
    }
}
What is not explained is irrelevant data, and there is no change in all the attacks.
	
In addition, fall and brk have some special functions:

		When the fall is greater than 180, the enemy will be knocked into the air directly, and when the fall is less than 180, the enemy's knockdown value will be deducted and the enemy will be stunned after a few hits. When the knockdown value is 0, the enemy can be captured. Reciprocal.
        
        When fall=300, it is "fallstrong". When attacking, it will directly knock into the air if the "fall" and "brk" are smaller than the body attack. Example: Charge hits the general attack, wheel, and most of the main body attacks are hit by the demon in the world.
        
        When fall=500, it is "fallsuperatk". Based on the characteristics of fall=300, your defense value will not be reduced when you attack a confrontation, and your blood volume will not be reduced.
	
		When brk is greater than 180, the enemy will enter a short-term stiff state caused by breaking the defense after a defense or an attack. When brk is less than 180, the opponent's defense value will be deducted.
       
        When brk=500, the opponent’s defense will be ignored and the opponent’s defense value will not be deducted. For example: 破空
The following are some of the available values ​​for effect:
		  effect = 0 effectNormal normal attack
          
          effect = 1 effectAttackToCatch catch attack
          
          effect = 7 effectAttackItemOnly is an attack that only has an effect on item projectiles. For example, e0 Shenglong can be charged to bounce arrows, and eason can bounce items when using qigong waves. And it can play a defensive effect when attacking.
          
          effect = 9 effect SinanCircle hovering attack, ignoring the rules of fall and brk to hover the enemy, for example: sinan original version of the star
          
          effect = 100 effectHeal treatment
          (Note: When set to treatment, "hp" is the amount of HP that can be recovered, and "fall" is the percentage of HP that can be recovered.
          For example: the fall of taylor treatment is 50, so he can only heal allies whose blood volume is less than 50%)
          
          effect = 200 Become a teammate. Only the role of team2 can be changed to team1, which is the principle set for teammates in the story.
		  
		  effect = 8 effectAttackNonBlastOnly cannot hit the attack of offensive items, such as cavalry stab and HFE Legg's general attack.
		  
		  effect = 6 effectCanBeStanded can't hit the enemy's attack, but it can attack and collide. Only one's brk and hp will be reduced when colliding, which can be used to simulate the body.
		  
		  The following are the types of attacks that are not used in the original version and have bugs, so use caution
		  
          effect = 2 effectCatch force to catch people. After touching the enemy, it will catch the enemy and immediately stop the current action to enter the catching action. Even if the brk can't fight the opponent, it can be forced to catch, and an error will occur when hitting the item.
		  
		  effect = 3 effectRide riding attack. When hitting an enemy, it will mount the enemy like a mount and transform the enemy into his teammate. After the ride is released, he will remain his teammate.
		  
		  effect = 4 effectCanBePicked is used for props. After setting, it can be picked up and then turned into stone. The nature of the stone is different from ordinary stone.
		  
		  effect = 5 effectPick is a weightlifting attack. When hitting a heavy object, it will be lifted, and an error will occur when hitting an enemy.
Here are some available values ​​for type:
        type = 0 TypeSword sound effect is a sharp weapon attack
        
        type = 1 TypeFist sound effect is a blunt weapon attack
        
        type = 2 TypeCatch sound effect is a grab attack
        
        type = 3 TypeBat's effect is a blood-sucking attack
        
        type = 4 TypeIceGuard is temporarily unknown, suspected to be related to the ice puppet
        
        type = 100 TypeIce Freeze Attack
        
        type = 101 TypeFire fire attack
        
        type = 102 TypeThunder Thunder attack
        
        type = 111 TypeFireInfect fire conduction
        
        type = 112 TypeThunderInfect electrical conduction
          
As mentioned before, the "ref" in "attack" is the serial number of the attack, which is only used as a marker, and the "refName" is the parameter that really binds the attack. Therefore, the wrong setting of "ref" has no effect.
But in order to find the attack data more convenient, it is better to write "ref".

	
06, cre props articles:	
	
	
When the character performs some actions, props will be released. These props are judged out of the body, so they are not affected by the limits (bx, bz, by).
Set the prop parameter to "cre", which is also in the frame.
Multiple props can be released in one frame. There is no upper limit (provided that the computer can support it). These props appear at the same time. If you want them to appear in turn, you can set the props into multiple different frames.
The following are the props released by Long Jie Fei Long Zhan, in frame 323.


"cre": {
                    "HFW_ArrayLenXXX": 1,
                    "0": {
                        "HFW_classNameXXX": "Data.Pt",
                        "sx": 160.0,
                        "ref": 33.0, (the set prop template, corresponding to ptWithName in 142, will use the vx and other parameters in the template to overwrite the parameters in cre, so you must change "ref" to a negative number (without using the template) to directly Edit the speed and other settings in cre.)
                        "facing": 0.0, (the direction the prop faces, 0 is front, 1 is back)
                        "vx": 45.0, (the x-axis movement speed of the item)
                        "sy": -10.0,
                        "refName": null,
                        "x": 255.0, (the x-axis position of the prop relative to the character)
                        "o": 0.0, (rotation angle of props texture)
                        "y": -121.0, (the y-axis position of the props relative to the character. Note that it is best not to set a positive number for the released props on the ground, because some props will explode when they land)
                        "int2": 0.0, (special effect when the prop is launched, 1 means no difference or healing, 2 means the texture rotates as the player presses up and down, 3 means follow the prop, 4 means the clone (must be matched with int3), 6 means increase Large z-axis displacement)
                        "vz": 0.0, (the z-axis movement speed of the props)
                        "j": 1.0,
                        "int3": 0.0, (if int2 is 4 (clone), int3 determines the character to be separated, and there is a record in the HFW group)
                        "vy": 0.0, (the y-axis movement speed of the item)
                        "ai": 2.0,
                        "z": 2.0, (the z-axis position of the props relative to the character, changing it to a positive number map will block the character, and changing it to a negative number map will be blocked by the character)
                        "l": 7.0,
                        "int1": 5.0 (The serial number corresponding to the item, different serial numbers launch different items, corresponding to the actiongroup in itemspt, there are statistics corresponding to each serial number in the HFW group)
                    }
                },
		
		
The frames of Ryusuke’s flying dragon cut action are from 316 to 330, but only 323 has cre, because he only released one flying dragon. If the cre in frame 323 is copied to frame 322 and frame 324, Ryusuke will be different. Release three flying dragons.
And if cre is added to every frame from 316 to 330, Ryusuke will continue to release Flying Dragon Slash when using Flying Dragon Slash.
To add props to a skill without props, we can copy the frame of cre to the skill to add props in the frame where the props are released.
However, there are so many frames for a skill, which frame is the most appropriate to add? Do you want to try one by one?
No, I will share some methods to find "key frames" next.

07. Finding key frames:

Sometimes, we want to add props to the skill, but we don't know which frame to add. We want to add attack determination or displacement to the character, but we don't know where to add it.
And some frames suitable for adding props, displacement, and judgment, we will call them "key frames" for the time being. The position of the "key frame" is naturally different as the content to be added is different.

1. Visual estimation method

By observing the position of the current frame in all frames and the "duration" of the current frame, the key frame can be directly obtained.
Novices are more difficult to control, only suitable for long-term pause skills such as self-destruction.

2. Attack determination method

When the attack is determined, the character's weapon is often just swung out. At this time, the effect of adding props is very good.
We can choose to add the props in the frame before the attack determination appears, or the frame where the attack determination appears, so that it is like the character has swung the props out.

3. Observation displacement method

Observe the status of the character in the current frame by observing the parameters such as vx and vy in the frame.
For example, the x-axis displacement (vx) of each frame of Chu Ying's Hengtianquan skill is as follows:
14,14,14,0,0,0,0,0,0,0,0,37,0,37,0,0,0,0
It can be seen intuitively that the first three frames are starting movements, while frames 4 to 11 are charged movements (no displacement), frame 12 is the movement to start punching after the charging is completed, and frame 14 is the fist swing The movement of going out, the last four frames are the fist pause movement and the closing movement.

Four, one by one destroying method

If none of the previous methods work, there is a final method-to defeat them one by one.
As long as we record the actions of each frame, we can naturally find the most suitable frame.
But the frame speed is too fast, it is not easy to record each frame, therefore, we can use "duration"
Change the "duration" of the skill to 20 or higher, and the speed of each frame will be very slow. You can take a screenshot slowly, observe, and record the position of the current frame while taking the screenshot, and finally get a suitable frame.

08. Getting started with stickers:
If frame is the most important content in Spt, then texture is the most important content in frame. This article will briefly introduce some texture-related parameters.

"effect": The color effect of the texture in this frame, there are 1, 2, 3 (ice), 10, 11 (fire), 20, 21 (thunder), which will change the color of the character texture, such as fall_ice.
"uz": Control the parameters of the texture data, the character texture is set here.
"refIndex": Refers to the data of a certain frame "uz", and the display position and display range are also based on the referenced frame.
"index": serial number, when refindex points to this frame, what is actually referenced is the texture data of the frame pointed to by "index" of this frame, so make sure that "index" is the same as the actual serial number.

"r1": The zoom ratio of the texture in this frame. The larger the value, the larger the texture. This is the production principle of the giant.
"lz": Lower body texture. It is also a parameter to control textures, but it is rarely used. Generally, the upper and lower parts of the body are placed in "uz" at the same time, but it can make interesting actions when used well, so the mod version often Used.
"refIndex_2": Refer to the data of a certain frame "lz", and the display position and display range are also subject to the referenced frame.
"lowAtBottom": Whether the bottom body texture is at the bottom, explain in detail later.
"ULseparate": The upper and lower body textures are separated, which will be explained in detail later.
"lp1": Scale, rotate, and move the entire referenced texture.


Five, frame advanced articles

If you understand all of the above knowledge, you will have a certain position in the HFW world. It is equivalent to a second-line player of vs. Props, attacks, and displacements will not hinder you.
But if you want to become a strong player in the HFW world, you still need to go through the test of textures. It is not easy to understand the textures, so you must be patient in the next study.
Before learning the knowledge of textures, it is recommended to understand the principle of skin binding, otherwise it is difficult to understand, even if it is understood, it is difficult to apply.
The knowledge of skin binding is no longer explained here, and you can read other information on your own.

01. Sticker settings:
The number of textures in "uz" generally ranges from 10 to 20, but here is reduced to two for easy reading.
"uz": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 1.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 1.094973516681288,
                            "b": 0.29339726952821754,
                            "c": -0.2903949686050283,
                            "tx": -3.559217632682902,
                            "d": 1.0837687770963347,
                            "ty": -3.941936243722864
                        },
                        "x": 0.0,
                        "p": 2.0,
                        "y": 0.0
						},
                    "1": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 0.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": -0.974959675482086,
                            "b": 0.1719116958902611,
                            "c": 0.1719116958902611,
                            "tx": 64.04427819315168,
                            "d": 0.974959675482086,
                            "ty": -28.433773789806907
                        },
                        "x": 0.0,
                        "p": 17.0,
                        "y": 0.0
						}
                    }


As you can see, there are five parameters "i", "m", "x", "p", and "y" in the parameters in "uz".

Among them, "i" corresponds to the serial number of the bound texture, we can first go back to the position where the texture is bound to observe
"spriteLimb": {
            "HFW_ArrayLenXXX": 45,
            "0": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limbNames": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbName": "Lucas_00Head",
                "limbType": 0.0,
                "xScale": 0.99,
                "limb": null,
                "yScale": 0.99,
                "limbTypeName": null
            },
            "1": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limbNames": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                },
                "limbName": "Lucas_01Chest",
                "limbType": 1.0,
                "xScale": 1.0,
                "limb": null,
                "yScale": 1.0,
                "limbTypeName": null
            },
			···
			···
			}
As you can see, number 0 corresponds to the head texture, and number 1 corresponds to the body texture.
And "i": 0.0 is naturally the set head texture

And "p", when "i" is confirmed, it controls which texture in the texture group of "i" is displayed.
For example, Longsuke "i": 0.0 "p": 1.0 corresponds to the normal head texture, and "i": 0.0 "p": 9.0 is the head texture when hit

"x" and "y" are the dynamic blur of the texture on the x-axis and y-axis. The larger the value, the more blurry it is. In addition, if the "x" is changed to -10.0, the color filter effect will be triggered.
"m" is to edit the texture again
"m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 1.094973516681288, (the length of the texture, or the zoom ratio of the x-axis)
                            "b": 0.29339726952821754, (bevel angle of texture)
                            "c": -0.2903949686050283, (the rotation angle of the texture)
                            "tx": -3.559217632682902, (the x-axis position of the texture)
                            "d": 1.0837687770963347, (the width of the texture, or the scaling of the y-axis)
                            "ty": -3.941936243722864 (the y-axis position of the texture)
                        },

Among them, the four parameters "a", "b", "c", and "d" are not modified, because once modified, the position of the texture will change, and the position must be manually modified to return to normal.
tx and ty are generally modified when the display range is expanded.

02. Sticker display chapter:

The display of character maps is limited in scope, so some skins will not be displayed fully, and some new skills with modified textures will also be displayed incompletely.
In order to solve this problem, we must understand the knowledge of texture display.


There are four parameters in the frame to control the display of the texture:
"cx1": The texture shows the left border
"cx2": The texture shows the right border
"cy1": The map shows the upper boundary
"cy2": The texture shows the bottom border

In this way, to expand the display range of the texture, you only need to reduce the values ​​of "cx1" and "cy1" and increase the values ​​of "cx2" and "cy2". How difficult is this?

No, you are all wrong (shake your finger).
The display position of the texture is calculated based on "cx1" and "cy1". That is to say, if "cx1" is subtracted by 100 (left shifted by 100 units), then although the boundary is shifted to the left by 100 units, The display position of the texture also moved 100 units to the left, which not only failed to expand, but also caused the texture position to be wrong.
Therefore, we need to modify the "tx" in "uz" to restore the original position of the texture. In this way, the border moves to the left, but the texture is still in its original position, and the display range is naturally enlarged.
The amount of change in the values ​​of "tx" and "cx1" caused the texture to move exactly the same distance. An increase of 100 in "cx1" will move the texture 100 units to the right, and an increase of 100 in "tx" will also move the texture 100 to the right. For each unit, the amount of change in position is the same.
However, most frames zoom in and out of the texture, and the value that controls the zoom is "r1". Therefore, when "tx" is modified, the actual effect will also be affected by "r1".

But this effect is very easy to calculate, just multiply "tx" by the value of "r1". For example, if "r1" is 2.0 in a certain frame, if the value of "tx" increases by 100, it actually moves the texture 200 units to the right. If you want it to move only 100 units, "tx" increases The value of should be replaced by 50.
Therefore, when expanding the display range of the texture, pay attention to the value of "r1". Fortunately, there are only three values ​​for "r1" of the original character: 1.0, 2.0, 4.0 
Among them, 1.0 is the value used only for standing frames and some discarded frames. If you look carefully, you will find that the textures of the character when standing are much clearer than the textures of other actions, because the standing texture is originally this size, and the other textures Originally it didn't have this size, but it was enlarged to this size by "r1", so it was blurry.
4.0 is a value that only fall_spin will use. If you look closely, you will find that the texture of fall_spin is very blurry.
And 2.0 is the "r1" value for all frames except standing and fall_spin.

Assuming that we want to expand the display range of 100 units to the left, we need to reduce "cx1" by 100, and then add the value of (100/r1) to all "tx" in this frame "uz", for example, if "r1" : 2.0, the value of "tx" increased (100/2) = 50
It is worth noting that if "r1" has been artificially modified (such as giant), the calculation of the change in "tx" should be based on the original value of "r1" (the value before modification)

"cy1" and "cx1" are the same, so I won't repeat them, and "cx2" and "cy2" will not affect the display position, so they can be added directly.
But be careful not to increase too much. Generally, the overall expansion amount should be controlled within 200, and the single frame expansion amount should be controlled within 400. (Actually, for a normal skin, an expansion of 100 in each of the four directions is more than enough)
If you need a larger texture, we can set a small texture first, and then enlarge it.

However, a character has hundreds of frames, and a frame has more than ten or twenty "tx"s. If you want to change them one by one, you have to change them tens of thousands of times. Therefore, to expand the display range of the textures, you generally use tools directly.
I have created the "Texture Display Range Expansion Tool", which can be downloaded to the HFW group. This tool will automatically include "r1" when modifying "tx". You only need to enter the expanded range to expand it with one click.
Although the tools are now available, I still hope that you can understand the principle of clearly displaying the scope, so that you can learn more profound knowledge in the future.

03. Separation of Textures:

In the frame, in addition to "uz", there is a parameter named "lz".
The original meaning of "lz" is the lower body texture, but in fact it is not limited to the lower body texture. It can be understood as an additional texture storage point.

Separating the texture, although the content has not changed, it also has a lot of meaning.
For example, you can combine the texture of the legs when jumping with the texture of the upper body of the ground skills, so that you can make some new aerial actions, such as fisting fist in the air, thunder cannon in the air, etc.
In addition, after separation, the upper or lower body stickers can be rotated separately to achieve the effect of attacking diagonally upwards/diagonally downwards.

To use "lz", we must first modify a parameter: "ULseparate"
Change "ULseparate" to true, and the textures in "lz" will be displayed, otherwise they will not be ignored. At the same time, if there is no texture in "lz", "ULseparate" should be set to false, otherwise a bug will be triggered

"lz" and "uz" can be transplanted to each other, but pay attention to the display position. (The transplantation method will be explained later)
The principle of "lz" display and "uz" display parameters are exactly the same, but their display parameters are not shared.
"lz" uses a new set of parameters to control the display range, they are "cx1_2", "cx2_2", "cy1_2", "cy2_2"
"cx1_2" corresponds to "cx1", "cx2_2" corresponds to "cx2", "cy1_2" corresponds to "cy1", "cy2_2" corresponds to "cy2"
The two sets of display parameters use exactly the same algorithm, but they are independent of each other and do not interfere with each other.

To separate the texture, we need to change the value of the parameters such as "cx1_2" in the frame to be the same as "cx1", then directly migrate part of the data in "uz" to "lz", and then delete this part of data from "uz" .
In addition, because some of the textures are separated into "lz", "ULseparate" needs to be changed to true for the separated textures to take effect.

for example:
The following is the third frame of Renxun attack1, the texture itself is not separated in this frame.
Let's take a look at the content of this frame first. I deleted irrelevant parameters (such as attack) for brevity.

"181": {
                "HFW_classNameXXX": "Data.Frame",
                "lowAtBottom": false,
                "ULseparate": false,
                "uz": {
                    "HFW_ArrayLenXXX": 3, (Here reduces the number of textures to three for easy viewing)
                    "0": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 28.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 1.0864571746546516,
                            "b": 0.17207791154425398,
                            "c": -0.17989963479626547,
                            "tx": 6.765972909367832,
                            "d": 1.1358415916844085,
                            "ty": 24.36529215566813
                        },
                        "x": 0.0,
                        "p": 0.0,
                        "y": 0.0
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 10.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 0.855819112405483,
                            "b": -0.8862266340172167,
                            "c": 0.34636211386306054,
                            "tx": -5.9865019031373095,
                            "d": 0.3344780053760072,
                            "ty": 80.56685327497604
                        },
                        "x": 9.0,
                        "p": 0.0,
                        "y": 0.0
                    },
                    "2": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 11.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": -0.5444722215136419,
                            "b": -0.5444722215136417,
                            "c": 1.022829958986336,
                            "tx": 43.126585347878915,
                            "d": -1.0228299589863366,
                            "ty": 137.40958124651252
                        },
                        "x": 0.0,
                        "p": 0.0,
                        "y": 16.0
                    }
                },
				"cx1": 444.0, (the display range of the original texture)
				"cx2": 655.0,
				"cy1": 250.0,
                "cy2": 505.0,
				"cx1_2": -1.0, (there is no texture and naturally does not need to be displayed, so the display range is -1)
                "cx2_2": -1.0,
				"cy1_2": -1.0,
                "cy2_2": -1.0,
				"lz": null, (there is no separate texture originally, so "lz" is empty)
            },
            
Suppose we need to separate the textures of "i": 10.0 and "i": 11.0 into "lz",
After processing, get the following code.

"181": {
                "HFW_classNameXXX": "Data.Frame",
                "lowAtBottom": false,
                "ULseparate": false,
                "uz": {
                    "HFW_ArrayLenXXX": 3,
                    "0": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 28.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 1.0864571746546516,
                            "b": 0.17207791154425398,
                            "c": -0.17989963479626547,
                            "tx": 6.765972909367832,
                            "d": 1.1358415916844085,
                            "ty": 24.36529215566813
                        },
                        "x": 0.0,
                        "p": 0.0,
                        "y": 0.0
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.LZ", (deleting the texture data will often change the original sorting, resulting in a lot of trouble in the separation process, so the texture data is not deleted directly here)
                        "i": -10.0, (but make sure that the separated texture is no longer valid in "uz", so we can change the original "i": 10.0 to a negative number, which means it is an invalid value and the texture will not be displayed )
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 0.855819112405483,
                            "b": -0.8862266340172167,
                            "c": 0.34636211386306054,
                            "tx": -5.9865019031373095,
                            "d": 0.3344780053760072,
                            "ty": 80.56685327497604
                        },
                        "x": 9.0,
                        "p": -1.0, (Of course, changing "p" to a negative number can also achieve the effect of not displaying the texture)
                        "y": 0.0
                    },
                    "2": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": -11.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix", (This negative number can be the opposite of the original value, or any negative number, such as -1, but I suggest changing it to the opposite of the original value. To restore the separated texture, you can easily change the "i" back to the original value)
                            "a": -0.5444722215136419,
                            "b": -0.5444722215136417,
                            "c": 1.022829958986336,
                            "tx": 43.126585347878915,
                            "d": -1.0228299589863366,
                            "ty": 137.40958124651252
                        },
                        "x": 0.0,
                        "p": 0.0,
                        "y": 16.0
                    }
                },
				"cx1": 444.0,
				"cx2": 655.0,
				"cy1": 250.0,
                "cy2": 505.0,
				"cx1_2": 444.0, (change the display range of "lz" to the same value as the display range of "uz")
                "cx2_2": 655.0,
				"cy1_2": 250.0,
                "cy2_2": 505.0,
                "lz": {
                    "HFW_ArrayLenXXX": 2, (The textures of "i": 10.0 and "i": 11.0 have been copied to "lz". Since the display range is set to the same value as "uz", there is no need to change "lz" after migration Any modification of the data in the data (except the serial number of course))
                    "0": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 10.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 0.855819112405483,
                            "b": -0.8862266340172167,
                            "c": 0.34636211386306054,
                            "tx": -5.9865019031373095,
                            "d": 0.3344780053760072,
                            "ty": 80.56685327497604
                        },
                        "x": 9.0,
                        "p": 0.0,
                        "y": 0.0
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 11.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": -0.5444722215136419,
                            "b": -0.5444722215136417,
                            "c": 1.022829958986336,
                            "tx": 43.126585347878915,
                            "d": -1.0228299589863366,
                            "ty": 137.40958124651252
                        },
                        "x": 0.0,
                        "p": 0.0,
                        "y": 16.0
                    }
                }
            },
			
After transplanting, you can control whether the lower body texture is at the bottom by modifying "lowAtBottom". If it is changed to true, the lower body texture will be covered by the upper body texture, otherwise the lower body texture will cover the upper body texture.
These processes have been implemented with tools. There is a "upper and lower body texture separation tool" in the HFW group. You only need to enter the range of the frames to be separated, and the tool can automatically separate these frames and set the relevant parameters.
But if you want to keep improving, you should understand its principle. After you understand the principle, you can use "lz" to do more magical things, not just separate textures.


04. Texture transplantation:

As we all know, the original version of Longao did not have a cloak bound, and Super Ryusuke's actions are exactly the same as Longao, and it also has a cloak binding.
Therefore, if Super Ryusuke's cloak data is transplanted to Longao's Spt, Longao will have the cloak.
However, the display positions ("cx1" and "cy1") of each frame of Super Ryusuke and Longao are different, so direct transplantation will cause dislocation.

At this time, we will use the knowledge we will learn next-texture transplantation.
The so-called texture migration is to transplant one or more texture data in one frame to another frame.

for example:

"102":
  {
    "cx1": 200.0,
    "cy1": 100.0
    "uz": {
                    "HFW_ArrayLenXXX": 1,
                    "0": {
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 28.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 0.9205048534524404,
                            "b": 0.39073112848927377,
                            "c": -0.386823817204381,
                            "tx": 22.464704088149944,
                            "d": 0.911299804917916,
                            "ty": 7.717228700728185
                        },
                        "x": 0.0,
                        "p": 2.0,
                        "y": 0.0
                    }
                  }
},
"103":
  {
    "r1": 2.0,
    "cx1": 300.0,
    "cy1": 150.0
    "uz": {
                    "HFW_ArrayLenXXX": 0
                  }
    }

As you can see, there are two frames on it. If we want to move the texture of frame 102 into frame 103, texture migration will be used.
"103":
  {
    "r1": 2.0,
    "cx1": 300.0,
    "cy1": 150.0,
    "uz": {
                    "HFW_ArrayLenXXX": 1,
                     "0": {(<----------First copy the texture intact)
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 28.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 0.9205048534524404,
                            "b": 0.39073112848927377,
                            "c": -0.386823817204381,
                            "tx": 22.464704088149944,
                            "d": 0.911299804917916,
                            "ty": 7.717228700728185
                        },
                        "x": 0.0,
                        "p": 2.0,
                        "y": 0.0
                    }
                  }
 }
At the same time, we can see that the cx1 of frame 102 is 200 and the cx1 of frame 103 is 300, which makes the position of this texture move 100 units to the right.
So we have to shift these 100 units to the left, which is -100, which can be achieved with tx in uz.
Counting the effect of r1 on the change in the position of the texture, the actual reduction of "tx" should be 100/2=50.


"103":
  {
    "r1": 2.0,
    "cx1": 300.0,
    "cy1": 150.0,
    "uz": {
                    "HFW_ArrayLenXXX": 1,
                     "0": {(<----------First copy the texture intact)
                        "HFW_classNameXXX": "Data.LZ",
                        "i": 28.0,
                        "m": {
                            "HFW_classNameXXX": "flash.geom.Matrix",
                            "a": 0.9205048534524404,
                            "b": 0.39073112848927377,
                            "c": -0.386823817204381,
                            "tx": -27.54, (It is not necessary to calculate too precise, the error should be controlled within 1.)
                            "d": 0.911299804917916,
                            "ty": -17.29 (ty also needs to be reduced)
                        },
                        "x": 0.0,
                        "p": 2.0,
                        "y": 0.0
                    }
                  }
 }

05, fSpec articles:

fSpec is an important parameter in the frame, which has a great influence on the character's skill nature.
The modification of fSpec is actually very simple. You only need to change a number, but because it involves some other concepts, it is still difficult to use it well, so I will talk about it later.


The role of the value of the character fSpec:

0: Normal frame, no effect.
1: The z-axis speed is cleared. If the whole process is set to 1, there will be no z-axis speed in the whole process.
2: Make the launched tracking props have the tracking effect, otherwise even the tracking props will not be tracked, and it is invalid for ordinary props. It is only effective if it is set in the skill. (E.g. Chengying Arrow Rain)
20: When attacked by props, the damage of the props against itself is halved, such as the original Tornado Shield.
30: Cut the character's current x-axis speed by half.
40: Clear the current x-axis speed of the character.
50: No friction, speed will not automatically decrease, such as Akagi Flame Fist.
80: When a non-collision attack is received, the break defense of this attack is reduced, and the break defense received when an attack collides at a far distance is reduced, which is the nature of the original Legge attack.

Sixth, advanced skills:

With the above knowledge, you can make a lot of interesting characters, and the next thing to talk about is some advanced skills that can make you even more powerful.
Of course, the prerequisite for learning the next knowledge is to have a good grasp of the previous knowledge, otherwise it is difficult to understand clearly.

01. Transformation actions:

Many players have imagined that Ryusuke turned into a super Ryusuke in actual combat, and with HFW, we can truly realize it.
There are two ways to make transformations. The first is to make all the actions such as standing and moving after transformation into skills, and then connect them with nextAi through buttons. This is how the transformations of super dragon and zous in CW are realized.
However, since it is troublesome to set up and cannot be operated as normal after being transformed, this method is generally no longer used to make transformed characters.
The second method is to use actionGroup. As I said before, an actionGroup corresponds to a state of a character. If you copy the actionGroup in the standing state, you will have a new state, and then modify the actionGroup to achieve the change. body.
However, there are certain disadvantages in doing so, that is, the transformed character cannot defend or ride, grabbing and lifting weights will cause the character to be untransformed, and if the character is caught, it will also cause the untransformed.
But in general, the transformation realized by this method can be operated normally as normal, so the problem is not big.

In the original HF, actionGroups 0 to 4 have their own specific functions, and actionGroups 5 to 9 have not been specially set, so we can put the actions after the transformation into actionGroups 5 to 9.
In fact, directly adding a No. 10 actionGroup is no different from No. 5-9, because the original game did not set the No. 5-9 actionGroup.
Therefore, a character can theoretically have countless transformation states, that is, you can take all the characters of the entire game as a character transformation. A typical example is the imitator of HFT, which can be transformed into a blade. Xun, Longao, Livermo, Lei Yin.

The following is the actionGroup of Ryuusuke's standing state.

"0": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "ite_atk2": -1.0,
                "ite_lifeTime": 0.0,
                "ite_vo": 0.0,
                "ite_lo": 0.0,
                "keyTriggerRef": null,
                "index": 0.0,
                "ite_atkName2": "",
                "ite_atk1": -1.0,
                "ite_sfx2": 0.0,
                "name": "normal",
                "ite_sfx1": 0.0,
                "shield1": 0.0,
                "keyTrigger": null,
                "ite_weight": 1.0,
                "actionIndex": {
                    "HFW_ArrayLenXXX": 4,
                    "0": {
                        "HFW_ArrayLenXXX": 31,
                        "0": 1.0, (0# ai corresponds to stand action)
                        "1": 2.0,
                        "2": -1.0,
                        "3": -1.0,
                        "4": 3.0,
                        "5": -1.0,
                        "6": -1.0,
                        "7": 13.0,
                        "8": 6.0,
                        "9": 6.0,
                        "10": 7.0,
                        "11": 7.0,
                        "12": 8.0,
                        "13": 6.0,
                        "14": 6.0,
                        "15": 14.0,
                        "16": 16.0,
                        "17": 15.0,
                        "18": 17.0,
                        "19": 8.0,
                        "20": 4.0,
                        "21": 5.0,
                        "22": 9.0,
                        "23": 10.0,
                        "24": -1.0,
                        "25": 8.0,
                        "26": -1.0,
                        "27": -1.0,
                        "28": 6.0,
                        "29": 8.0,
                        "30": 109.0
                    },
                    "1": {
                        "HFW_ArrayLenXXX": 58,
                        "0": 18.0,
                        "1": 19.0,
                        "2": 22.0,
                        "3": 20.0,
                        "4": 21.0,
                        "5": 22.0,
                        "6": 28.0,
                        "7": 29.0,
                        "8": 30.0,
                        "9": 31.0,
                        "10": 32.0,
                        "11": 33.0,
                        "12": 38.0,
                        "13": 39.0,
                        "14": -1.0,
                        "15": -1.0,
                        "16": 36.0,
                        "17": 37.0,
                        "18": -1.0,
                        "19": -1.0,
                        "20": -1.0,
                        "21": -1.0,
                        "22": -1.0,
                        "23": -1.0,
                        "24": -1.0,
                        "25": -1.0,
                        "26": 40.0,
                        "27": 41.0,
                        "28": 42.0,
                        "29": 11.0,
                        "30": -1.0,
                        "31": -1.0,
                        "32": -1.0,
                        "33": 34.0,
                        "34": 8.0,
                        "35": -1.0,
                        "36": -1.0,
                        "37": 4.0,
                        "38": 4.0,
                        "39": 12.0,
                        "40": -1.0,
                        "41": -1.0,
                        "42": -1.0,
                        "43": 35.0,
                        "44": -1.0,
                        "45": 43.0,
                        "46": 44.0,
                        "47": 43.0,
                        "48": -1.0,
                        "49": 23.0,
                        "50": 24.0,
                        "51": 26.0,
                        "52": 25.0,
                        "53": 27.0,
                        "54": -1.0,
                        "55": 106.0,
                        "56": 107.0,
                        "57": 108.0
                    },
                    "2": {
                        "HFW_ArrayLenXXX": 19,
                        "0": 73.0,
                        "1": 74.0,
                        "2": 75.0,
                        "3": 76.0,
                        "4": 73.0,
                        "5": 73.0,
                        "6": 73.0,
                        "7": 77.0,
                        "8": 77.0,
                        "9": 77.0,
                        "10": 77.0,
                        "11": 78.0,
                        "12": 78.0,
                        "13": 78.0,
                        "14": 78.0,
                        "15": 77.0,
                        "16": 76.0,
                        "17": -1.0,
                        "18": -1.0
                    },
                    "3": {
                        "HFW_ArrayLenXXX": 11,
                        "0": 91.0,
                        "1": 92.0,
                        "2": 89.0,
                        "3": 94.0,
                        "4": 95.0,
                        "5": 93.0,
                        "6": 102.0,
                        "7": 103.0,
                        "8": 104.0,
                        "9": 105.0,
                        "10": 101.0
                    }
                },
                "keyTriggerRefIndex": -1.0,
                "speedXRate": 1.0,
                "shield0": 0.0,
                "ite_reboundable": false,
                "ite_standable": false,
                "speedYRate": 1.0,
                "ite_blastBreak": true,
                "ite_gr": 1.0,
                "piece": null,
                "ite_landBreak": true,
                "ite_dura": 0.0,
                "ite_obstacle": false,
                "ite_screen": false,
                "ite_hitable": true,
                "ite_atkName1": "",
                "action": null, (ignored)
                "ite_duraD": 0.0,
                "type": 0.0,
                "mpBurn": 0.0
            },

We directly copy it into actionGroup No. 5.
Then find the action corresponding to the stand, then copy it to the end of the action, name it EX_STAND, and then modify the corresponding frame.

"110": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextActionName": null,
                "aix1": 0.0,
                "allowTurnFace": true,
                "nextAi": -1.0,
                "aix2": 0.0,
                "nextAti": -1.0,
                "aix1b": 0.0,
                "frameIndex": 5.0, (you need to add the stand frame after transforming yourself, here we first use the walking frame to test)
                "nextAgi": -1.0,
                "aix2b": 0.0,
                "index": 1.0,
                "landActionName": null,
                "aiz1": 0.0,
                "landAi": -1.0,
                "name": "EX_STAND",
                "landAti": -1.0,
                "landAgi": -1.0,
                "aiz2": 0.0,
                "special": -1.0,
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "kl": 3.0,
                        "pollhp": 0.0,
                        "k": "gua",
                        "atf": false,
                        "ai": 0.0,
                        "kr": "gua",
                        "ati": 3.0,
                        "hp": 0.0,
                        "agi": 0.0,
                        "mp": 300.0,
                        "rkt": false
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "kl": 3.0,
                        "pollhp": 0.0,
                        "k": "gra",
                        "atf": true,
                        "ai": 3.0,
                        "kr": "gla",
                        "ati": 3.0,
                        "hp": 0.0,
                        "agi": 0.0,
                        "mp": 60.0,
                        "rkt": false
                    }
                },
                "frame": null,
                "type": -1.0,
                "mpBurn": 0.0
            },



"5": {
                "HFW_classNameXXX": "Data.ActionGroup",
                "ite_atk2": -1.0,
                "ite_lifeTime": 0.0,
                "ite_vo": 0.0,
                "ite_lo": 0.0,
                "keyTriggerRef": null,
                "index": 0.0,
                "ite_atkName2": "",
                "ite_atk1": -1.0,
                "ite_sfx2": 0.0,
                "name": "exA",
                "ite_sfx1": 0.0,
                "shield1": 0.0,
                "keyTrigger": null,
                "ite_weight": 1.0,
                "actionIndex": {
                    "HFW_ArrayLenXXX": 4,
                    "0": {
                        "HFW_ArrayLenXXX": 31,
                        "0": 110.0, (after adding an action, you can correspond to the new action)
                        "1": 2.0,
                        "2": -1.0,
                        "3": -1.0,
                        "4": 3.0,
                        "5": -1.0,
                        "6": -1.0,
                        "7": 13.0,
                        "8": 6.0,
                        "9": 6.0,
                        "10": 7.0,
                        "11": 7.0,
                        "12": 8.0,
                        "13": 6.0,
                        "14": 6.0,
                        "15": 14.0,
                        "16": 16.0,
                        "17": 15.0,
                        "18": 17.0,
                        "19": 8.0,
                        "20": 4.0,
                        "21": 5.0,
                        "22": 9.0,
                        "23": 10.0,
                        "24": -1.0,
                        "25": 8.0,
                        "26": -1.0,
                        "27": -1.0,
                        "28": 6.0,
                        "29": 8.0,
                        "30": 109.0
                    },
                    "1": {
                        "HFW_ArrayLenXXX": 58,
                        "0": 18.0,
                        "1": 19.0,
                        "2": 22.0,
                        "3": 20.0,
                        "4": 21.0,
                        "5": 22.0,
                        "6": 28.0,
                        "7": 29.0,
                        "8": 30.0,
                        "9": 31.0,
                        "10": 32.0,
                        "11": 33.0,
                        "12": 38.0,
                        "13": 39.0,
                        "14": -1.0,
                        "15": -1.0,
                        "16": 36.0,
                        "17": 37.0,
                        "18": -1.0,
                        "19": -1.0,
                        "20": -1.0,
                        "21": -1.0,
                        "22": -1.0,
                        "23": -1.0,
                        "24": -1.0,
                        "25": -1.0,
                        "26": 40.0,
                        "27": 41.0,
                        "28": 42.0,
                        "29": 11.0,
                        "30": -1.0,
                        "31": -1.0,
                        "32": -1.0,
                        "33": 34.0,
                        "34": 8.0,
                        "35": -1.0,
                        "36": -1.0,
                        "37": 4.0,
                        "38": 4.0,
                        "39": 12.0,
                        "40": -1.0,
                        "41": -1.0,
                        "42": -1.0,
                        "43": 35.0,
                        "44": -1.0,
                        "45": 43.0,
                        "46": 44.0,
                        "47": 43.0,
                        "48": -1.0,
                        "49": 23.0,
                        "50": 24.0,
                        "51": 26.0,
                        "52": 25.0,
                        "53": 27.0,
                        "54": -1.0,
                        "55": 106.0,
                        "56": 107.0,
                        "57": 108.0
                    },
                    "2": {
                        "HFW_ArrayLenXXX": 19,
                        "0": 73.0,
                        "1": 74.0,
                        "2": 75.0,
                        "3": 76.0,
                        "4": 73.0,
                        "5": 73.0,
                        "6": 73.0,
                        "7": 77.0,
                        "8": 77.0,
                        "9": 77.0,
                        "10": 77.0,
                        "11": 78.0,
                        "12": 78.0,
                        "13": 78.0,
                        "14": 78.0,
                        "15": 77.0,
                        "16": 76.0,
                        "17": -1.0,
                        "18": -1.0
                    },
                    "3": {
                        "HFW_ArrayLenXXX": 11,
                        "0": 91.0,
                        "1": 92.0,
                        "2": 89.0,
                        "3": 94.0,
                        "4": 95.0,
                        "5": 93.0,
                        "6": 102.0,
                        "7": 103.0,
                        "8": 104.0,
                        "9": 105.0,
                        "10": 101.0
                    }
                },
                "keyTriggerRefIndex": -1.0,
                "speedXRate": 1.0,
                "shield0": 0.0,
                "ite_reboundable": false,
                "ite_standable": false,
                "speedYRate": 1.0,
                "ite_blastBreak": true,
                "ite_gr": 1.0,
                "piece": null,
                "ite_landBreak": true,
                "ite_dura": 0.0,
                "ite_obstacle": false,
                "ite_screen": false,
                "ite_hitable": true,
                "ite_atkName1": "",
                "action": null, (ignored)
                "ite_duraD": 0.0,
                "type": 0.0,
                "mpBurn": 0.0
            },

After setting, we set a button to transform.

"1": {
                "HFW_classNameXXX": "Data.Action",
                "selfLoop": true,
                "nextActionName": null,
                "aix1": 0.0,
                "allowTurnFace": true,
                "nextAi": -1.0,
                "aix2": 0.0,
                "nextAti": -1.0,
                "aix1b": 0.0,
                "frameIndex": 0.0,
                "nextAgi": -1.0,
                "aix2b": 0.0,
                "index": 1.0,
                "landActionName": null,
                "aiz1": 0.0,
                "landAi": -1.0,
                "name": "EX_STAND",
                "landAti": -1.0,
                "landAgi": -1.0,
                "aiz2": 0.0,
                "special": -1.0,
                "a_keyTgr": {
                    "HFW_ArrayLenXXX": 2,
                    "0": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "kl": 3.0,
                        "pollhp": 0.0,
                        "k": "gua",
                        "atf": false,
                        "ai": 0.0,
                        "kr": "gua",
                        "ati": 3.0,
                        "hp": 0.0,
                        "agi": 0.0,
                        "mp": 300.0,
                        "rkt": false
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "kl": 3.0,
                        "pollhp": 0.0,
                        "k": "gra",
                        "atf": true,
                        "ai": 3.0,
                        "kr": "gla",
                        "ati": 3.0,
                        "hp": 0.0,
                        "agi": 0.0,
                        "mp": 60.0,
                        "rkt": false
                    },
                    "1": {
                        "HFW_classNameXXX": "Data.A_KeyTgr",
                        "kl": 3.0,
                        "pollhp": 0.0,
                        "k": "guj",
                        "atf": true,
                        "ai": 0.0,
                        "kr": "guj",
                        "ati": 0.0,
                        "hp": 0.0,
                        "agi": 5.0, (the state of transformation is set to actionGroup No. 5, so press the button to set No. 5 agi, you can also make another transformation skill, and then use nextAgi to turn to the transformation)
                        "mp": 450.0,
                        "rkt": false
                    }
                },
                "frame": null,
                "type": -1.0,
                "mpBurn": 0.0
            },

02. Transformation stickers:

After some characters are transformed, the texture will remain unchanged (for example, the first four of soldiers), and there is no need to set the texture at this time.
Later new characters may also change a small number of textures. For example, only the weapon is changed after the transformation. We only need to bind a new weapon in the empty space inside the spriteLimb, and then modify the "i" in the texture of the frame after the transformation. .

But there is another situation where a lot of textures (such as imitators) need to be changed after the transformation. At this time, the texture settings are more troublesome.
But it is not impossible, we can add bindings in spriteLimb.

"44": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limb": null,
                "limbName": "weapon_effect_white",
                "limbTypeName": null,
                "xScale": 1.0,
                "limbType": 44.0,
                "limbNames": {
                    "HFW_ArrayLenXXX": 0,
                    "b": "weapon_effect_white",
                    "a": "weapon_effect_white",
                    "c": "weapon_effect_white",
                    "d": "weapon_effect_white",
                    "e": "weapon_effect_white",
                    "f": "weapon_effect_white"
                },
                "yScale": 1.0,
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                }
            }

The textures of all characters in the original version are bound to No. 44, so we can change the No. 0 texture used by the character after the transformation to No. 45, just like this.

        "44": {
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limb": null,
                "limbName": "weapon_effect_white",
                "limbTypeName": null,
                "xScale": 1.0,
                "limbType": 44.0,
                "limbNames": {
                    "HFW_ArrayLenXXX": 0,
                    "b": "weapon_effect_white",
                    "a": "weapon_effect_white",
                    "c": "weapon_effect_white",
                    "d": "weapon_effect_white",
                    "e": "weapon_effect_white",
                    "f": "weapon_effect_white"
                },
                "yScale": 1.0,
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                }
            },
        "45": {(Here, the head texture of the thief is changed from No. 0 to No. 45 and added to Longsuke spt.)
                "HFW_classNameXXX": "Data.SpriteLimb",
                "limb": null,
                "limbName": "z_bandit01_00Head",
                "limbTypeName": null,
                "xScale": 1.0,
                "limbType": 0.0,
                "limbNames": {
                    "HFW_ArrayLenXXX": 0
                },
                "yScale": 1.0,
                "limbs": {
                    "HFW_ArrayLenXXX": 0
                }
            },

By analogy, the body of No. 1 is changed to No. 46, and the weapon of No. 20 is changed to No. 65...

Then replace all "i" in the frame.

These settings can be very troublesome to complete manually, especially for characters with multiple transformation states like imitators.
So I made a tool that can be set and transformed with one click, and it will be released in the near future.

03. Transformation magical articles:

Next, let's talk about the special gameplay of the transformation function.

1. Forced transformation and forced untransformation.

Sometimes, we need a character position to place the new character, but the characters in all the current character positions are still useful. At this time, the transformation function comes in handy.
With the transformation function, one character can be set as another character's transformation, so that a character position is vacated.

Of course, there must be shortcomings in doing so. Transfiguration characters cannot defend, ride, lift weights, or grab people. Therefore, we can give priority to infantry, who cannot ride, lift weights, or grab people.
For some characters with the same texture position and similar body shapes (such as HFE Gordon and Soth), we can make the character not change the texture when transforming, and then set the texture through the skin in the story.

So, how to achieve forced transformation? We can use the buttons.

When com releases the skill, it actually needs to press the key, but the time required to press the key is extremely short.
If we set the number of buttons to 1, such as a, j, g, u, d, l, r, com will force the button to be triggered when these buttons are pressed, and the same is true for the player.
We can set a button "a", so that once com wants to attack, it will force the button to be triggered, and then we can set the action pointed by this button to the action of transforming into standing.
And if you set all the seven basic buttons again, then the com will definitely trigger the skill no matter what button you press, and what is presented to the player is when he first saw this com, he was already in a state of transformation.

We can set the amount of blue required for these buttons to be higher than the total amount of blue of the character, and then set <mmp></mmp> in the story to determine whether the com will transform.


The same is true for the forced release of the transformation. PMM’s Ryusuke used this method to release the transformation, clearing the blue amount when turning, and then slowly returning to blue. The button needs to be full blue to trigger, and when it is full blue, it triggers. Press the button to release the transformation.





		    |
		   /|
		  / |
		 / |—————————————————————————|
		/ | 
	   《To Be Continued |
		\ |
		 \ |—————————————————————————|
		  \ |
		   \|
		    |