So I’ve spent the last two months or so learning ASM and ModularStatScreen, with a LOT of help from the wonderful folks in the #hacking-help and #spell-academy discord channels. I thought writing up a guide to compile these notes might help other folks who’d like to do cool things with their stat screen but don’t feel brave enough to tackle MSS on their own.
Quick disclaimer, I’m far from an expert on this. I know a lot more than I did a few months ago, but please feel free to chime in with extra information or corrections and I’ll add to or modify the main post to accommodate them.
There’s WAY more to cover here than in my last few write ups, so let’s get cracking!
ModularStatScreen is included with the standard SkillSystem hack, and you can find MSS on GitHub here, or learn more about installing SkillSystem itself here, or learn more about using other elements of SkillSystem here. This guide will be assuming you’re building off of the SkillSystem setup, but if you aren’t using SkillSystem you can just skim past the bits that aren’t relevant to you. In all cases, the main install file you need to include is
Note that if you’re installing MSS without using some or all of SkillSystem, you’re going to need to custom tailor some of the files to avoid errors about things like undefined identifiers. There’s a thread talking about doing some of this stuff here, but what you need for your specific build will vary somewhat, so take it with a grain of salt.
Good initial observation. I’ll be going into the code inside some of these files and discussing ways to alter it in more depth later, but I think a short overview covering the different things in here will help a lot with getting a basic understanding of what’s going on, hopefully make the hack in its entirety more approachable.
In here are the files you’re probably the least likely to interact with. This contains extra ASM code that handles some of the MSS functionality that isn’t covered in the pages section, like the native page 4 RText or a fix to stop the left side of the stat screen from redrawing when you change pages. You don’t need to edit any of these unless you really know what you’re doing, but it’s good to know they’re here.
Shockingly this contains options for the display growths part of the hack. The thing you’re most likely to want to make changes to is
GrowthColorsTable.event, which lets you set different thresholds for stat colours based on their growth values. The file itself has more details for how to do this.
Note that if you want an easy way to turn this off and just use the default colours, you’ll find a setting for that in the
Config.event file of SkillSystem:
// If true, the stat colors for player units will reflect their growth in the stat. #define USE_STAT_COLORS False
This is likely where you’re going to spend 90% of your time working with ModularStatScreen, and I’ll be going through this in detail later on. This contains all of the code behind what is being drawn on each stat screen page and where, across a number of different cases; there are separate files to handle whether or not you’re using the Str/Mag split, leadership stars, biorhythm, or skills, which is why it looks like there are more files than there need to be.
For now the takeaway is just that there are versions of some pages that can handle different setups separately, and this is where you’ll go to modify the layouts of those pages.
There are three extra “loose” files here. The two I’m going to ignore for now are
RText.event, which will each get their own section later; this is the main installation file, and the file handling all stat screen RText.
The only other file hanging out here is
RemoveGlowy.png, which is used to remove the breathing glow effect from the top right of the vanilla stat screen.
I thought a lot about how best to order all of these elements to talk about them in more detail in a way that’d be easy to follow, and I think this is the best place to start because you can visually see the things you’re changing, and can make some sense of what the code is doing in isolation. We’ll talk about how these are incorporated into your hack with
ModularStatScreen.event later on, but for now we’re going to focus on messing with the page layouts, which is likely the thing you’re looking for most anyways.
I also want to point out that the more complicated the things you’re trying to do with MSS are, the more likely it becomes that you’re going to need to start getting comfortable with ASM. If you find that to be the case I strongly recommend you go through Teq’s introductory tutorial, it’s my vote for the best place to start.
Before we get to have fun making changes with page layouts, there’s something technical we need to set up first. If this next section sounds scary and you just want to move your stats around, bear with me, I promise it isn’t that bad and then you can move your stats to your heart’s content.
I’m gonna talk briefly about what this is and how to use it, but I’m linking a bunch of external readings I’d highly recommend if you want to understand this in more detail. You need to install devkitPro to your machine, which you can find here, read about from the devkitPro wiki here, and read about for our purposes in Stan’s thread here. To be clear you don’t need to know how this works if you don’t care about it, but you need it installed regardless.
You also need lyn installed, which you can find and learn about in another of Stan’s threads
here. Again I’d really recommend you read through it to understand what you can, but functionally for this all you need is the download.
Let’s now take a look inside
@echo off SET startDir="C:\devkitPro\devkitARM\bin\" SET as="%startDir%arm-none-eabi-as" SET LYN="C:\devkitPro\lyn.exe" @rem Assemble into an elf %as% -g -mcpu=arm7tdmi -mthumb-interwork %1 -o "%~n1.elf" if exist "Definitions.s" ( @rem Assemble definitions into a .elf if exists %as% -g -mcpu=arm7tdmi -mthumb-interwork "Definitions.s" -o "Definitions.elf" @rem Assebmle into a .lyn.event with definitions %LYN% "%~n1.elf" "Definitions.elf" > "%~n1.lyn.event" echo y | del "%~dp0Definitions.elf" ) else ( @rem Assemble into a .lyn.event %LYN% "%~n1.elf" > "%~n1.lyn.event" ) echo y | del "%~n1.elf" pause
The very short version of what’s going on here is that you’re using devkitPro to assemble you
.s files to
.elf files, and then using lyn to get those into
.event files that can be included into your buildfile to work with Event Assembler. If you’ve done Teq’s ASM tutorial you’ve seen something similar, where devkitARM is used to assemble
.s files into
.dmp files, which then get included in your buildfile with an
“Okay but how is this relevant to using ModularStatScreen?” You’re going to be editing the nice readable scripts in the
.s files, then dragging and dropping them onto
AssembleLynEvent.bat, which will convert them into new versions of the corresponding
.event files, which are included in ModularStatScreen.event for you already. This might sound hard, but your workflow will generally follow:
- Make a change to a page, say
- Save the changed file, and drag it onto
- Rebuild your ROM to see how the change you made has affected the stat screen.
Not too bad, right? Importantly though, you need to make sure the directories being referenced in AssembleLynEvent.bat are correct, or compiling won’t work. These lines here:
SET startDir="C:\devkitPro\devkitARM\bin\" SET as="%startDir%arm-none-eabi-as" SET LYN="C:\devkitPro\lyn.exe"
Just navigate to wherever these directories are in your machine, and paste your filepaths in instead of these ones.
I also want to note that it turns out that depending on what version of devkitPro you’re using you may get errors when you do the drag-and-drop compiling, in the form of:
Necessary\ModularStatScreen\pages\mss_page2_original.s:13: Error: bad expression -- ldr r0,=#0x8A02204
Turns out this isn’t that difficult to fix. It’s a problem being caused by using
=# rather than just
= when loading literals; to fix this, open up the relevant
mss_defs.s file (there’s one in the pages folder, and one in the strmag folder, which we’ll talk about very soon I promise), and replace
= only in cases you’re referring to literals. If you don’t know what that means, just use the list of error messages as your guide and replace those cases.
Now we can finally get to making changes to our stat screen!
I’m including this just before going through the pages for you to use as a reference while reading, so you can check out what each macro is doing as you encounter it. I wouldn’t recommend just reading through this section first, but come back here to check out how specific macros work as you’re going through the rest. I’m going to skip over “helper macros” like
blh to as they aren’t very relevant to the purposes of this guide, and if they’re relevant to you you’re likely already comfortable enough with ASM to understand what they’re doing on your own.
Want to note that in all cases the x and y coordinates are written as tiles, where each tile is an 8 x 8 pixel square, counted from the top left corner of the screen.
Some of these are really self explanatory, but this can at least serve as a quick lookup for what options are available to you.
Start and End: page_start | leftpage_start | page_end
Short macro that… starts the page. Not something you’re ever likely to call yourself, but this needs to be at the top of each page, before you start doing things to the screen itself. It loads relevant structures and unit data into appropriate registers.
Specific version of
page_start used in
mss_leftstatscreen.s, not much else remarkable to say about it. It gets its own start macro because you want it drawn on every page. Unlikely you’ll want to mess with this, but like
page_start just make sure all the things you’re changing on the left page are beneath it.
Ends the page. Pops back values that were pushed in
page_start and returns to whatever was going on before
page_start got called. Again, not something you’re likely to call yourself, but make sure this is after everything you’re doing to the start screen.
Text: draw_textID_at | draw_trv_text_at | draw_talk_text_at | draw_status_text_at
draw_textID_at tile_x, tile_y, textID=0, width=3, colour=3, growth_func=-1
Draws a specified text ID at a specified location. You can also specify colour here, with Green, Yellow, Blue, Grey, and White being defined inputs by default.
I want to specifically shout out the amazing power of:
draw_textID_at 21, 13, 0x0001 @" "
This just draws a blank space to the screen. This reason this is so powerful is that it’ll draw a blank space on top of anything that’s above it in the code, and anything beneath it in the code will be drawn on top. For example, if you draw the text for move, then a blank, then the text for str, the next result will just draw str to the screen. Can be really handy to make kind of hacky but perfectly functional and simple solutions to problems you may encounter, so keep it in mind.
draw_trv_text_at tile_x, tile_y, colour=Blue
Draws the Trv text, and also handles drawing the correct unit name or — after it.
draw_talk_text_at tile_x, tile_y, colour=Blue
Draws the Talk text, and also handles drawing the correct unit name or — after it.
draw_status_text_at tile_x, tile_y, colour=Blue
Draws the Cond text, and also handles drawing the correct unit status after it.
Bars: draw_xyz_bar_at | draw_xyz_reduced_bar_at
draw_xyz_bar_at bar_x, bar_y
Draws a stat bar at a specified location, where the bar is dictated by what stat value (str, mag, etc.) you indicate in the macro title. There are more generic helper functions associated with this that you likely won’t use for more general purposes, but if you’re working with custom bars they’re worth looking at. Note that move and con have unique macros,
draw_con_bar_with_getter_at, bar_x, bar_y
draw_xyz_reduced_bar_at bar_x, bar_y
Very similar to
draw_xyz_bar_at, this draws a reduced version of the bar that’s used by default for shortening up the speed and skill bars used when rescuing. Again, there are some helper functions associated with it that you’ll want to consult if you’re trying to make custom bars.
Numbers: draw_growth_at | draw_xyz_number_at | draw_charge_at
draw_growth_at bar_x, bar_y
This is used to draw the growths when the stat screen is in growths mode rather than stats mode, toggled between using select by default. You’ll notice that you don’t actually specify the growth you want to draw in the macro itself; using this requires a few extra lines, which you can see in the default
mss_page1.s files. You just need to load the appropriate stat getter ahead of time:
ldr r0,[sp,#0xC] ldr r0,[r0,#4] @str growth getter draw_growth_at 18, 3
This is an example of the three lines that are required for the strength growth, though again I’d recommend just using the default setup for these and only changing the x and y values if you want to move the growths around the screen.
draw_xyz_number_at tile_x, tile_y
This behaves very much like draw_xyz_bar_at, where you have a specific macro for each of the standard numbers that get drawn to the first page of the stat screen. Reference the
draw_number_at helper macro if you’re interested in doing your own custom things with this beyond moving the existing numbers around.
draw_charge_at num_x, num_y, colour=2
This is used for the laguz bars hack to draw the charge value at a specified location. Unused otherwise to the best of my knowledge.
Skills: draw_skill_icon_at | draw_skillname_at
draw_skill_icon_at tile_x, tile_y, number=0
Draws the current unit’s skill icon that corresponds to the provided number, if one exists. Similar to the growths macro this requires some extra work around the macro, though as with that case you should use the existing setup as your reference. Here’s an example for the second icon:
ldrb r0,[r6,#1] cmp r0,#0 beq SkillsEnd draw_skill_icon_at 24, 15
draw_skillname_at tile_x, tile_y, textID=0, width=14, colour=3, growth_func=-1
This is supposed to work like
draw_textID_at, except for skillnames. It… doesn’t actually work out of the box. I spent a while writing a fixed version of this, which you can find on my ASM page here with instructions on how to install and use it.
Icons: draw_affinity_icon_at | draw_left_affinity_icon_at | draw_aid_icon_at | draw_icon_at
draw_affinity_icon_at tile_x, tile_y
Draws the icon corresponding to the current unit’s affinity at a particular location.
draw_left_affinity_icon_at tileX, tileY
Draws the icon corresponding to the current unit’s affinity on the left stat screen just to the right of the unit’s name.
draw_aid_icon_at tile_x, tile_y
Draws the aid icon appropriate for a unit’s class, if one exists, at the given location.
draw_icon_at tile_x, tile_y, number=0
This is a good reference for trying to draw you own icons, but is currently only used to draw the icon for leadership stars. Check the appropriate files for reference, as making any changes to the behaviour here other than the location can get a bit more complicated.
Inventory Page: draw_stats_box | draw_items_text
Draws the “Equipment” box seen on page 2 in vanilla, as it is in vanilla. You can make changes to the macro itself here to switch out which values you’d like drawn in which locations, but this kind of alteration is beyond the scope of this guide. You’ll need some ASM knowledge under your belt and also probably the Teq Doc open. It might be worth just drawing overtop of whatever is here depending on your needs; either way, I’m going to link my range to attack speed hack, as it might be a useful reference.
Draws the unit’s inventory.
Left Page: draw_character_name_at | draw_class_name_at | draw_lv_icon_at | draw_exp_icon_at | draw_hp_icon_at | draw_ui_slash_at | draw_level_at | draw_exp_at | draw_hp_at | draw_max_hp |
draw_character_name_at tile_x, tile_y
Draws the current unit’s name at a given location.
draw_class_name_at tile_x, tile_y
Draws the current unit’s class name at a given location.
draw_lv_icon_at tile_x, tile_y
Draws the current unit’s level at a given location.
draw_exp_icon_at tile_x, tile_y
Draws the EXP text at a given location.
draw_hp_icon_at tile_x, tile_y
Draws the HP text at a given location.
draw_ui_slash_at tile_x, tile_y
Draws the / between current health and max health at a given location.
draw_level_at tile_x, tile_y
Draws the current unit’s level at a given location.
draw_exp_at tile_x, tile_y
Draws the current unit’s EXP value at a given location.
draw_hp_at tile_x, tile_y
Draws the current unit’s current HP at a given location.
Draws current unit’s maximum HP. Doesn’t accept a location at this point unfortunately.
Other: draw_weapon_rank_at | draw_gaiden_spells_at
draw_weapon_rank_at tile_x, tile_y, weapon, id
Manually draw the specified weapon’s weapon rank information at a given location.
draw_gaiden_spells_at tile_x, tile_y, gaidenStatScreenRoutine
Used to draw your Gaiden spells if you’re using that hack. I’m not using Gaiden magic so really haven’t used this at all to provide much further explanation. If you’ve got anything you’d like to add, let me know!
Relevant Non-Macros: DrawSupports | DrawBWLNumbers
This will draw the vanilla support layout to the vanilla location beneath the weapon ranks on page 2, though moving this command will let you draw it in the vanilla location on other pages instead.
This will draw the vanilla battles / wins / losses statistics to the vanilla location near the bottom of the stat screen. Note that these won’t show at all until you’ve beaten the game, unless you apply the following patch generously provided by gamma:
PUSH ORG $86fe4 SHORT $46C0 $46C0 POP
Taking a look in the pages folder, you can see there are a tonne of mss_page1 files. You should know which one you want to use based on your
Config.event SkillSystem settings, and
ModularStatScreen.event will handle using the appropriate file based on those settings, as we’ll see later. Your options are:
mss_page1.s, the standard vanilla version
mss_page1_skills.s, also includes skills
mss_page1_skills_biorhythm.s, also includes both skills and biorhythm
mss_page1_skills_conmag.s, functions as a strmag split where con is replaced with mag
mss_page1_skills_leadership.s, includes both skills and leadership stars
Further, you’ve got strength / magic split versions of some of these in the strmag folder as well. If you’re using it, you’ll want to use these files instead for page 1, and the
mss_defs.s file in this subfolder will be used exclusively by your strmag page 1.
I’ll be using the
mss_page1_skills_leadership.s in the strmag folder for this discussion to maximize the stuff I can talk about, though again use whichever is appropriate for your case. Crack open the file and we’ll find quite a bit of stuff, probably more than the other three pages combined by default. You’ll immediately see why knowing some ASM will help you here, but as you’ll see it’s not necessary for the basic stuff. Let’s go through what this file is doing, and talk about some of the ways you can make changes as we go.
Holding off on the growths part for a moment, the first exciting thing to make changes to that we’ll find is a group of lines near the top:
draw_textID_at 13, 3, textID=0x4fe, growth_func=2 @str draw_textID_at 13, 5, textID=0x4ff, growth_func=3 @mag draw_textID_at 13, 7, textID=0x4EC, growth_func=4 @skl draw_textID_at 13, 9, textID=0x4ED, growth_func=5 @spd draw_textID_at 13, 11, textID=0x4ee, growth_func=6 @luck draw_textID_at 13, 13, textID=0x4ef, growth_func=7 @def draw_textID_at 13, 15, textID=0x4f0, growth_func=8 @res
This is responsible for drawing the text associated with each stat value. You can move these around or reorder them just by changing the x and y coordinate values, no need to move around the code itself. The same holds for growths:
ShowGrowths: ldr r0,[sp,#0xC] ldr r0,[r0,#4] @str growth getter draw_growth_at 18, 3 ldr r0,[sp,#0xC] ldr r0,[r0,#8] @mag growth getter draw_growth_at 18, 5 ldr r0,[sp,#0xC] ldr r0,[r0,#12] @skl growth getter draw_growth_at 18, 7 ldr r0,[sp,#0xC] ldr r0,[r0,#16] @spd growth getter draw_growth_at 18, 9 ldr r0,[sp,#0xC] ldr r0,[r0,#20] @luk growth getter draw_growth_at 18, 11 ldr r0,[sp,#0xC] ldr r0,[r0,#24] @def growth getter draw_growth_at 18, 13 ldr r0,[sp,#0xC] ldr r0,[r0,#28] @res growth getter draw_growth_at 18, 15 ldr r0,[sp,#0xC] ldr r0,[r0] @hp growth getter (not displaying because there's no room atm) draw_growth_at 18, 17 draw_textID_at 13, 17, textID=0x4E9, growth_func=1 @hp name
You can move these around as you like by again just changing the x and y coordinates you provide. Also worth noting that all of this code will only be reached if the stat screen is in show growths mode; this means you can overwrite whatever other text you want with your growth text within this structure, and when you’re not in growths mode nothing will be affected. Here’s an example of what I mean, where in normal mode I show Move and in growths mode I show the HP growth and text in the same location.
Example Gif and Script
draw_growth_at 26, 7 ldr r0,[sp,#0xC] ldr r0,[r0] @hp growth getter (not displaying because there's no room atm) draw_growth_at 26, 9 draw_textID_at 21, 13, 0x0001 @" " draw_textID_at 22, 13, 0x0001 @" " draw_textID_at 23, 13, 0x0001 @" " draw_textID_at 24, 13, 0x0001 @" " draw_textID_at 21, 9, textID=0x4E9, growth_func=1 @hp name
There are a bunch of one off macros further down in the file for things like affinity icon or talk text that I’m not going to touch on specifically, but you can also move them around by changing their coordinates or remove them entirely. Check the macro references above if you want more details.
Before getting into changing the skill icons themselves, if you want to move this to a completely different page, there’s some “initialization” code that you’ll also want to make sure to copy over directly above the icons:
startSkills: .set NoAltIconDraw, 1 @this is the piece that makes them use a separate sheet mov r0,r8 ldr r1,=Skill_Getter mov r14,r1 .short 0xF800 mov r6,r0
This loads up a buffer with the appropriate information for the currently selected unit. By default the section that draws the white text that says “Skill” is here too:
ldr r0,=SkillsTextIDLink ldrh r0, [r0] draw_textID_at 21, 13, colour=White @skills
Beneath all of that you’ll find the skill icons themselves. Each of these macro calls requires a few lines to iterate to the next skill slot beforehand, and to skip the rest if the current unit is out of skills.
ldrb r0,[r6] cmp r0,#0 beq SkillsEnd draw_skill_icon_at 21, 15 ldrb r0,[r6,#1] cmp r0,#0 beq SkillsEnd draw_skill_icon_at 24, 15 ldrb r0,[r6,#2] cmp r0,#0 beq SkillsEnd draw_skill_icon_at 27, 15
These are the first three skill slots. You can see the
ldrb line counting up to indicate which skill it’s talking about, but generally all you’ll be doing here is either moving all of your skills to another page in which case you want to copy everything from the top of this section, or changing the locations of the skill icons, where you’d be changing the x and y coordinates.
Unlike page 1 there’s only one default file available for page 2. page 2 isn’t as intricately interacted with or documented either, so more dramatic changes to what’s going on with its elements can be tricky to implement. Moving things around from page to page still works just fine, but the elements in vanilla page 2 are often less immediately customizable. This is super short:
MSS_page2: page_start draw_stats_box draw_items_text page_end
You can take a look at the macro references section for some details about the stats box macro, but editing these macros will definitely require knowledge of ASM as you can see from the lack of available variables. You can move these to other pages as I said, but they’ll be in their vanilla state and their vanilla location on whatever page you move them to.
For page 3 you’ve got two versions to choose from:
mss_page3_original.s, the standard vanilla page 3
mss_page3_newranks.s, modified to display only weapon ranks that the current unit is proficient with
mss_page3_original.s, the more basic of the two, you’ll find this section:
draw_weapon_rank_at 1, 1, Anima, 0 draw_weapon_rank_at 1, 3, Light, 1 draw_weapon_rank_at 9, 1, Dark, 2 draw_weapon_rank_at 9, 3, Staff, 3 b EndRanks .ltorg NotMag: draw_weapon_rank_at 1, 1, Sword, 0 draw_weapon_rank_at 1, 3, Lance, 1 draw_weapon_rank_at 9, 1, Axe, 2 draw_weapon_rank_at 9, 3, Bow, 3 EndRanks:
These are split into two groups based on whether current unit uses magic or not. There are ways you can rewrite this ASM to just have one lump of all of them displaying at once, but if learning ASM is scary to you there’s nothing stopping you from just putting them all into one big list and copying it to both places if you want to always display them all. Otherwise these behave as you’d expect, a location and the specific rank you’d like to draw.
Taking a look at `mss_page3_newranks.s’ way of handling this, you’ll really want to learn some ASM to be able to read and modify this to draw where you’d like it. You can copy paste the entire thing onto another page, but having it draw anything other than columns or giving each entry a unique y coordinate will require some work on your part.
Page 4 also has two versions:
mss_page4.s, empty page except for the Donate line
mss_page4_runa.s, used for drawing Runa’s personal information setup
Like Page 2, the setup for the basic version of the file is really simple:
MSS_page4: page_start draw_textID_at 17, 9, 0xd4b, 16, Green draw_gaiden_spells_at 13, 13, GaidenStatScreen @ GaidenStatScreen is a pointer to the routine, GaidenStatScreen. page_end
The only fancy thing this page is doing is drawing Gaiden spells, if you have that hack installed and enabled in
Config.event. Runa’s version of the page has a lot more going on, and making changes to most of the default setup of anything other than the
draw_textID_at calls will require learning some ASM. You can change where the text is being drawn without that though. If we take a look at the “first like” section, we find this line:
ldr r1, =(tile_origin+(0x20*2*3)+(2*17))
which, if we check the format of some of our macros in
ldr r1, =(tile_origin+(0x20*2*\tile_y)+(2*\tile_x))
We find that there’s a value in there we can change up to slide these around manually. Anything beyond this kind of movement change though will need some ASM.
The left page is just large enough that I’m not going to paste the whole thing in here, but it’s extremely clear to see what’s going on in it. It’s just a series of single macro calls, and you can move them around with the coordinates as usual.
Do note that anything else you move to this page will get drawn on every other stat screen page as well.
ModularStatScreen.event is the main installer file for this hack overall, but you’re very unlikely to touch it unless you already know what you’re doing enough that you don’t really need to reference this guide. It’s grabbing all of the relevant files from across the other folders and including them into one easy to access location.
I will note that if you’re not using SkillSystem, you’re going to have to remove a bunch of things that don’t exist from here that are undefined, like most of the #ifdef checks. I removed all the ones I wasn’t using even with SkillSystem just to make the file more readable, but this is obviously optional.
The last big section of material to cover is all in the
RText.event file, and deals with RText as you probably expect. There’s quite a lot in here, but it’s not as much as it looks initially. Sections for page 1 and page 4 are included with ModularStatScreen by default.
This file has a done of
#ifdef checks that correspond to settings in
Config.event like the pages do. You only need to concern yourself with editing the section that’s relevant to what you’re doing, and can ignore (or delete, for cleanliness) the rest. This is also a file you’ll need to remove quite a bit from if you aren’t using SkillSystem.
Let’s take a look at how to make some RText:
#define RMenu(up,down,left,right,xcoord,ycoord,TID) "POIN up down left right;BYTE xcoord ycoord; SHORT TID; WORD 0 0;" #define RMenu(up,down,left,right,xcoord,ycoord,TID,Getter) "POIN up down left right; BYTE xcoord ycoord; SHORT TID; POIN 0 Getter|1" #define RMenu(up,down,left,right,xcoord,ycoord,SlotID,Looper,Getter) "POIN up down left right; BYTE xcoord ycoord; SHORT SlotID; POIN Looper|1 Getter|1"
These are three different definitions for RMenu, each of which can be used in different cases. You don’t need to understand the extra things on the right, but now we know what each of the terms represent in our labelled RMenu calls below. Let’s take a look at a simple one:
This means that the Str RText is above this, Spd is below, the unit name is to the left, and Trv is to the right. Then we’ve got the coordinates of x = 0x66 and y = 0x28; in decimal, these are 102 and 40; when divided by 8, these are now 12.5 and 5. If we check where the Skl text is being drawn in page 1, we’ll find it at 13, 5. This is a good showcase of why it’s important to remember that tiles are each 8 pixels, because it’ll matter for converting a location in one of the pages into an RText location.
Lastly we’ve got a textID, which is just the textID of the description. Not bad! We can move this around, change what other RTexts it refers to when you move the cursor, and the description it uses.
What about skills? Here’s the “Skills” word RText, and the first three skill icon RTexts.
ST_Skills: RMenu(ST_Talk,ST_Skill1,ST_Res,0,0xA6,0x68,SS_SkillsRText) ST_Skill1: rMenu(ST_Skills,ST_Skill4,ST_Mov,ST_Skill2,0xa6,0x78,0,RTextLoop,SkillDescGetter) ST_Skill2: RMenu(ST_Skills,ST_Skill5,ST_Skill1,ST_Skill3,0xbe,0x78,1,RTextLoop,SkillDescGetter+4) ST_Skill3: RMenu(ST_Skills,ST_Skill6,ST_Skill2,0,0xd6,0x78,2,RTextLoop,SkillDescGetter+8)
These are more complicated, as they’re using the more involved version of RMenu. After the coordinates you have an indicator of which skill icon you’re using, then the loop and description getter to find the one that matches the unit’s particular skill in the specified slot. Most of the time you’ll be messing with the front half of these, changing coordinates and what other RTexts this one points to; if you change them more dramatically, be careful to keep the ID and the SkillDescGetter increment consistent.
It’s also worth noting here that if ever an RText would refer to a nonexistent skill (ie. Skill1 has Skill4 listed as the "below’ connection by default, and the unit may not have 4 skills), the RText will instead move to ST_Skills, the RText for the Skill text itself. Just worth keeping in mind as you organize things.
Adding your own new RText is as easy as adding a new RMenu label and entry, following the format of the definition as these ones are. If you want to put it on a specific page, make sure it’s in the appropriate section as well; the RText for page 4 is labelled, and page 2 and 3 aren’t here at all by default but you can find them below.
While these aren’t included in
RText.event in the initial installation, you can add them in without issue thanks to gamma figuring this out and sharing it. Just paste these into your RText file, and you can manipulate them the same was as any of the others.
Page 2 RText
#define ItemMenuRtextGetter 0x88A00 #define ItemMenuRtextLooper 0x88B40 ORG $A00D14 //sidebar IT_Name: RMenu(0,IT_Class,0,InventoryRtext4,0x18,0x50,0x0,NameDescGetter) IT_Class: RMenu(IT_Name,IT_Level,0,Inventory_Rng,0x6,0x68,0x6E8,ClassDescGetter) IT_Level: RMenu(IT_Class,IT_HP,0,IT_Exp,0x6,0x78,0x542) IT_Exp: RMenu(IT_Class,IT_HP,IT_Level,Inventory_Atk,0x26,0x78,0x543) IT_HP: RMenu(IT_Level,0,0,Inventory_Hit,0x6,0x90,0x544) ORG $A00DA0 //items start here InventoryRtext1: RMenu(0,InventoryRtext2,IT_Name,0,0x68,0x18,0x00,ItemMenuRtextLooper,ItemMenuRtextGetter) InventoryRtext2: RMenu(InventoryRtext1,InventoryRtext3,IT_Name,0,0x68,0x28,0x0001,ItemMenuRtextLooper,ItemMenuRtextGetter) InventoryRtext3: RMenu(InventoryRtext2,InventoryRtext4,IT_Name,0,0x68,0x38,0x0002,ItemMenuRtextLooper,ItemMenuRtextGetter) InventoryRtext4: RMenu(InventoryRtext3,InventoryRtext5,IT_Name,0,0x68,0x48,0x0003,ItemMenuRtextLooper,ItemMenuRtextGetter) InventoryRtext5: RMenu(InventoryRtext4,Inventory_Atk,IT_Name,Inventory_Rng,0x68,0x58,0x0004,ItemMenuRtextLooper,ItemMenuRtextGetter) ORG $A00E2C //bottom thing with atk/crit/etc Inventory_Atk: RMenu(InventoryRtext5,Inventory_Hit,IT_Exp,Inventory_Crt,0x76,0x78,0x55C) Inventory_Hit: RMenu(Inventory_Atk,0,IT_HP,Inventory_Avo,0x76,0x88,0x55D) Inventory_Rng: RMenu(InventoryRtext5,Inventory_Crt,IT_Class,0,0xae,0x68,0x55E) Inventory_Crt: RMenu(Inventory_Rng,Inventory_Avo,Inventory_Atk,0,0xae,0x78,0x55F) Inventory_Avo: RMenu(Inventory_Crt,0,Inventory_Hit,0,0xae,0x88,0x560)
Page 3 RText
ORG 0xA00EB8 ST_Name3: RMenu(0,ST_Class3,0,0,0x18,0x50,0x0,NameDescGetter) ST_Class3: RMenu(ST_Name3,ST_Level3,0,0,0x6,0x68,0x6E8,ClassDescGetter) ST_Level3: RMenu(ST_Class3,ST_HP3,0,ST_Exp3,0x6,0x78,0x542) ST_Exp3: RMenu(ST_Class3,ST_HP3,ST_Level3,0,0x26,0x78,0x543) ST_HP3: RMenu(ST_Level3,0,0,0,0x6,0x88,0x544)
LOTS of credits on this one, want to acknowledge everyone who’s either helped me out with this stuff or provided material. MSS has been around a long time, so let me know if I’m missing anyone who should be named.
Hopefully you found this guide useful! Don’t hesitate to reach out with any suggested additions or corrections below. Happy stat screening!