But what is a skill system? (and this is where a wizard calls me out for being wrong)
Skill System is a suite of changes to FE8, most famous for the actual system of skills itself. The Skill System buildfile comes with:
- The buildfile and its assembler, found in the root folder
- Event Assembler (god bless)
- A test boss rush map in .tmx form, along with tmx2ea to allow for easy editing (Maps folder), along with its actual events (Events folder)
- A collection of tables, most of which are used in various engine hacks (Tables folder)
- A text assembler, along with a text buildfile required for the new engine hacks (Text folder)
- A set of tools used in assembling the buildfile (Tools folder)
- And most importantly, the Engine Hacks folder (organized by @Sme for our convenience god bless)
Now, I won’t be getting into how to actually use a buildfile. @Snakey1 is creating an amazing buildfile tutorial here, and I couldn’t go five minutes into explaining how a buildfile works without making an elitist statement:
But the main folder we’ll be focusing on is the Skill System folder, found in Engine Hacks.
When you open up Skill System’s folder (as of April 9th, 2020), it will look like this:
Each of these event files designates a certain thing for a skill:
- skill_animations.event contains the skill animation table, important for proc skills
- skill_definitions.event lets you change the definitions of skills, and by extent, which 254 skills you deem worthy for your hack (changing a skill’s definition to 255 will “disable” it by making it always come up as false when checked for)
- skill_descriptions.event assigns each skill ID a text ID for its description when R is pressed
- skill_icons.event does the same thing as descriptions, except with icons
- skill_lists.event lets us create new skill lists that can be given to characters and classes to use when leveling up (we won’t be touching this most likely, but it’s important for bigger hacks)
- SkillSystemInstaller.event includes every one of these event files into the buildfile
- Remember!.txt and SkillSwapping.txt are messages by Darrman, Sme, and Leonarth giving commentary on editing/adding skills
As for the folders, we won’t be touching the RemoveSkillMenu folder: there’s no reason for us to and the assembly in there is super spooky. The Internals folder contains everything that makes Skill System work: we most likely won’t be touching anything in there either. The SkillIcons folder is exactly what it says on the tin, we’ll touch on that when we make a skill. And finally, the Skills folder contains almost every single skill in Skill System. (some of the stragglers, i.e. Rally and stat boosting skills are in ./Necessary/StatGetters)
Anatomy of a Skill
A skill is a set of ASM instructions, usually attached to a calculation loop that triggers whenever something happens. (PreBattleCalcLoop will trigger during combat forecast, HPRestorationLoop triggers at start of turn) Before we get to editing and creating new skills, let’s get used to how a skill actually looks. Open up the Skills folder and head to PreBattleSkills. There are a lot of skills here, but the one we’re looking for is Fiery Blood. Why Fiery Blood? It’s a simple skill that’s easy to understand, is why. Open up the .s file in your text editor to open the skill and see its instructions. It’ll look like this (as of April 9th, 2020):
Now, if this is your first time looking at ASM, this is probably intimidating as hell. But don’t worry, I’m here to help you break down what this skill is actually doing. Not only that, but the generous creator of this skill (who remains unknown) left some comments so we can understand what’s going on. So let’s do an analysis of what this skill does.
First off, let’s actually understand what Fiery Blood does. Fiery Blood is a skill that gives +4 damage if the unit’s HP is not full. Looking at the skill, you’ll notice the lines at the top.
.thumb
.equ FieryBloodID, SkillTester+4
.thumb is just to let the game know that this code is THUMB code, not ARM code. You can learn about the difference between the two in Teq’s guide, linked in the first post.
Meanwhile, .equ FieryBloodID, SkillTester+4 has a very important function, but we’ll mention what exactly this does later.
After this, we’re introduced to something that’s common to all Pre-Battle skills: this set of lines:
push {r4-r7, lr}
mov r4, r0 @ atkr
mov r5, r1 @ dfdr
All this does is push the registers r4 to r7, along with LR (r14). Then, the values of r4 and r5 are moved to r0 and r1. The values stored in r4 and r5 are the attacker and defenders’ character structures, which will be used to check the conditional, and later give the bonuses. A detailed deconstruction of the character structure can be found here, courtesy of Teq.
After that, we get to the HP conditional of this skill, nicely marked so by its creator.
@ hp not at full
ldrb r0, [r4, #0x12] @ max hp
ldrb r1, [r4, #0x13] @ curr hp
cmp r0, r1
ble End @ skip if max hp <= curr hp
You might be able to figure out what this does from the comments, but I’ll cover it anyways to be complete. The value located at r4+0x12 (the unit’s maximum HP) is moved into r0, and the value at r4+0x13 (the unit’s current HP) is moved into r1. Then, the value in r1 is subtracted from the value in r0 (r1 - r0). This comparison will set any of four flags, which are then checked in the branch opcode. Again, if you don’t understand the flags or the comparison, I would recommend taking a look at Teq’s guide to assembly in the first post, but you don’t have to. BLE (branch if less than or equal to) actually checks whether certain flags or set, but I’m not gonna get into that because flags always rack my brain. It basically moves to the end of the instructions, giving no bonuses, if the maximum HP is less than or equal to the current HP.
Moving on from that, we get to a common operation in every skill: checking whether the unit actually has the skill. You don’t need to know much about it, but you should make the skill ID in the function whatever the skill you’re working on is. The reason why attacker data is done here is because Pre-Battle skills are actually checked twice: during the second time, r4 and r5 are switched so that both units are checked.
@ has FieryBlood
ldr r0, SkillTester
mov lr, r0
mov r0, r4 @ attacker data
ldr r1, FieryBloodID
.short 0xf800
cmp r0, #0
beq End
Then, we get to the actual bonuses of the skill. This is pretty simple: move the value 0x5a to r1, load in the halfword value at r4+r1 (unit’s attack), add 4, and then store it back at the same place. The reason why we don’t just load r4+0x5a is because we’re not really supposed to do super high values in the additive part of the loading.
@ add 4 damage
mov r1, #0x5a
ldrh r0, [r4, r1] @ atk
add r0, #4
strh r0, [r4,r1]
Finally, we get to the End: label. We push the registers back, and that is it. After the pushing though, we do have some extra things to put at the end of the assembly file.
End:
pop {r4-r7, r15}
.align
.ltorg
SkillTester:
@ POIN SkillTester
@ WORD FieryBloodID
I’m not actually sure what .align exactly does, but you should put it there. Maybe a wizard can tell me. .ltorg creates a literal pool at the end of your assembly, in case you need to call a value that could end up changing as you work on it. This is important, because in a buildfile, the values we use always change. After the .ltorg, we place a label to SkillTester, for a very important reason: we need to place these values somewhere. The comments afterwards indicate a very important thing: these are where the values of SkillTester and FieryBloodID will be put. This is exactly why the .equ FieryBloodID, SkillTester+4 is so important: it tells us where FieryBlood is, as a pointer is 4 bytes, FieryBloodID will be located 4 bytes after SkillTester. Now, you might be wondering, “That’s great Runa, but where are these values stored anyways?”
I’m glad you asked! Return to the PreBattleSkills folder and open PreBattleSkills.event. You’ll want to CTRL+F for FieryBlood, and find this:
ALIGN 4
FieryBlood:
#incbin “FieryBlood/FieryBlood.dmp”
POIN SkillTester
WORD FieryBloodID
Notice how the comments in the assembly instructions are exactly how it looks in the actual event file. Of course, if you look closely, you’ll notice that the .s file is not used, but rather the .dmp file is. You get the .dmp file by running the .s file through Assemble ARM.bat, as that program turns the .s file into hex code, which can then be inserted into the rom easily. (This can be a source of frustration if you make a fix to a faulty skill, and forget to run Assemble ARM.bat, as you may think the fix doesn’t work when in reality you just forgot to update the .dmp file.)
Of course, you can’t just include the skill here to have it work, but we’ll get into how to make a skill actually work in Skill System in our first project. I hope this can help you understand how a skill in Skill System actually functions! :OOO