Persona 5

Functions found in all versions of Persona 5.

These functions are automatically included when using the P5 library of AtlusScriptCompiler. They are also found in P5R & P5EX libraries.

See here for a list of all functions and their arguments. Here are some of the most common commands, in order of usefulness.

Message Boxes

These functions are a simple way to display information to the player. Try it out!

void MSG_WND_DSP();

This function comes before a message box function. It lets the game know to open the message before a message is loaded.

void MSG_WND_CLS();

This function comes after a message box function. It lets the game know to close the message box after messages are loaded.

void MSG(int msgID, int unused);

The MSG() function shows a basic message box onscreen. This is usually used for characters having a verbal conversation. The first argument is the index of the message in the .msg file. The second argument is always 0 and serves no purpose. You can use the name of the message in place of the index, and AtlusScriptCompiler will automatically interpret it.

// Imports messages from a nearby .msg file
import("messages.msg");

// Example of a basic text box
MSG_WND_DSP();
MSG(firstMessage, 0); // same as MSG(0,0);
MSG(secondMessage, 0); // Same as MSG(1,0);
MSG(thirdMessage, 0); // Same as MSG(2,0);
MSG_WND_CLS();

void MSG_MIND(int msgID, int unused);

The MSG_MIND() function shows a thought bubble containing some text onscreen. This is usually used for the protagonist's inner thoughts. This works exactly the same as MSG().

// Example of a thought bubble message
MSG_WND_DSP();
MSG_MIND(firstMessage, 0);
MSG_MIND(secondMessage, 0);
MSG_WND_CLS();

void MSG_SYSTEM(int msgID);

The MSG_SYSTEM() function shows a square grey box containing some text onscreen. This is usually used for game-related messages, such as tutorials or settings confirmation. This works exactly the same as MSG() and MSG_MIND() but lacks the unused argument.

// Example of a system message
MSG_WND_DSP();
MSG_SYSTEM(firstMessage);
MSG_WND_CLS();

These functions allow you to get some input from the player.

int SEL(int msgID);

The SEL() function takes a message index as an argument, just like MSG(). The message must be of type [sel] and not [msg]/[dlg]. It returns an integer-- the index of the option the user selected.

If used after a message box function, and before MSG_WND_CLS(), the message will stay onscreen in the background of the menu, providing context to the player.

The type of message box used will determine the appearance. For instance, MSG() (or no messagebox) will display the protagonist's portrait on the side of the screen. Meanwhile, MSG_MIND() will display the options as thought bubbles in the middle of the screen, and for MSG_SYSTEM(), the options will appear in grey boxes next to the system message.

import("messages.msg");
import("menus.msg");

// Example of a basic menu
MSG_WND_DSP();
MSG(firstMessage, 0); // Shows dialog first
int selection = SEL(firstMenu); // Opens menu and records player's answer
MSG_WND_CLS();

// Use the selection variable to do different things
if (selection == 0)
{
    // do stuff if player selected first option
    MSG_WND_DSP();
    MSG_SYSTEM(optionOneMessage);
    MSG_WND_CLS();
}
else if (selection == 1)
{
    // do stuff if player selected second option
    MSG_WND_DSP();
    MSG_SYSTEM(optionTwoMessage);
    MSG_WND_CLS();
}
// etc ...

int SEL_GENERIC(int msgTitleID, int msgOptionsID);

This function has several variants that work the same with minor differences. It is used to display a large menu with a scrollbar that covers most of the screen, so it's not ideal to pair it with a MSG() or similar function. It's best to use when you have a lot of options.

The first argument is the message index to use for the title, which is a small white box with black text that appears at the top of the menu. Use something short that describes the purpose of the menu. This message must be of type [dlg]/[msg].

The second argument, like other selection functions, is the index of the [sel] type message where each line is a menu option.

// Example of a generic menu
MSG_WND_DSP();
int selection = SEL_GENERIC(firstMenuTitle, firstMenu);
MSG_WND_CLS();

if (selection == -1)
{
    // do stuff if player cancelled selection
}
else if (selection == 0)
{
    // do stuff if first option selected
}
// etc.

Note that the user is able to press the cancel button on their gamepad to select nothing, resulting in the function returning -1. You can prevent this behavior if it is unwanted by using a similar function, listed below.

Variants

Function NameDescription

SEL_GENERIC_NOT_HELP

Generic menu but without description text for each menu option.

SEL_GENERIC_NOT_CANCEL

Generic menu but without the ability to press the cancel button to exit the menu without selecting anything.

SEL_GENERIC_EX

??? takes an extra two integer arguments?

Unless using SEL_GENERIC_NOT_HELP(), a cool feature of these functions is to display some extra text onscreen that describes the highlighted menu item. Each description is its own msg entry of type [dlg]/[msg].

However, it is a bit tricky to set this up properly. It seems that these msg entries must immediately follow the [sel] with the options that it's describing. The description entries must come in the same order as the options.

Not only that, but each menu option must end with a msg function with arguments denoting the index of the option and the message index of the description. See below for an example.

Finally, it seems that message description names must start with GENERIC_HELP_, but anything after that doesn't matter. It's recommended to name these after the message index to prevent your own confusion.

[sel Options_ModMenu]
Phone/Auto-Recover[ref 0 1][e]
Player[ref 1 2][e]
Teleport[ref 2 3][e]
Call...[ref 3 4][e]
Calendar[ref 4 5][e]
Camera[ref 5 6][e]
Flags[ref 6 7][e]
Spawn[ref 7 8][e]
About[ref 8 9][e]
Royal[ref 9 10][e]

[dlg GENERIC_HELP_1]
View your IM messages[n]or auto heal the party,
[n]just like the [clr 18]IM button[clr 0]
[n]normally does.[e]

[dlg GENERIC_HELP_2]
Change social stats, items,
[n]Personas, Skills, model,
[n]animations, money or name.[e]

...

In this example, GENERIC_HELP_1 is the description for the option Phone/Auto-Recover. GENERIC_HELP_1 is at message index 1, since it is the second msg entry in the file (indices start counting at 0). Therefore, the numbers in [ref 0 1] refer to Phone/Auto-Recover being the 0th option of the menu (the first), and GENERIC_HELP_1 being at index 1 (the second message entry). You can see how for the next option, these numbers increase by 1, and so on forth.

If this seems redundant, that's because it is! Unfortunately, if any of these conventions aren't followed, the menu will not display a description in-game and you'll be left with a blank white box where one should be. It's frustrating, but this is the best we can do.

Calling Functions

Functions that "call" certain elements of the game are very useful! Use the Amicitia wiki to find out what ID numbers correspond to what you're trying to call.

void CALL_BATTLE(int battleIndex);

The CALL_BATTLE() function does exactly what you'd imagine-- start a battle using its index as the argument. You can find a battle's index in the game's ENCOUNT.TBL file (found in battle/table.pac).

Use p5_tbl.bt or p5r_tbl.bt as a template in 010 Editor to easily navigate and/or change the data in ENCOUNT.TBL!

You may also want to immediately follow this function with another function, WAIT_BATTLE(), which takes no args and helps prevent softlocks. When the battle is over, you will return to the field the function was called from.

// starts encounter 25 and waits for battle to end before continuing
CALL_BATTLE(25);
WAIT_BATTLE();

Variants

Function NameDescription

CALL_EVENTBATTLE(int eventID, int subID, int encounterID);

Calls a battle attached to an event. Plays the event first.

FLD_START_BOSS(int bossID);

Starts a boss/midboss battle. Argument is the number of the procedure in boss.bf that starts the battle. May alter story progression.

void CALL_FIELD(int majorID, int minorID, int entrance, int unknown);

The CALL_FIELD() func can be used to warp to another area in the game. This can be a town, dungeon, safe room, or even special places like the Velvet Room or title screen. Mementos and non-existant fields crash, so use caution.

Entrance refers to which spawn point to start the player's position at. These are usually set in the field's .FBN file. Use 0 if you're not sure. The unknown value is usually set to 0 as well.

// Warp to the Velvet Room
CALL_FIELD(10,3,0,0);

Variants

Function NameDescription

CALL_AT_DUNGEON(int area, int floor, int entrance);

Warps to a certain floor of a certain Mementos area.

FLD_MY_PALACE_ENTER();

Royal only. Enters the Theives Den. Only seems to work on saves where the Theives Den is unlocked.

void CALL_EVENT(int eventMajor, int eventMinor);

CALL_EVENT() is a function for starting a story event scene (the kind where you can fast-forward and view the conversation log). Returns to the field the function was called from after the event is over.

There's a variant called CALL_KF_EVENT() that takes an extra 2 arguments (usually 0?). This one is for field events where you often have a party member NPC following you around, for instance.

// Start the event where Ryuji takes you to the weapons shop
CALL_KF_EVENT( 701, 101, 0, 820);
// Start the event before the Morgana chase scene in Mementos
CALL_EVENT( 334, 1 );

Miscellaneous Calling Functions

The following are very self-explanatory.

Function NameDescription

CALL_PUBLIC_SHOP(int shopID);

Opens up a shop window.

CALL_CHAT_ARRIVAL(int chatID);

Starts a certain cellphone chat conversation.

CALL_CALENDAR();

Starts the calendar sequence leading to the next day.

BGM(int waveID);

Change BGM to a certain track from bgm.awb

CALL_BATTING_CENTER();

Starts the batting minigame.

CALL_FISHING_POND();

Starts the fishing minigame.

CALL_TITLE();

Go to the title screen.

CALL_STAFF_ROLL();

Starts playing the credits.

CALL_WEAPON_SHOP();

Opens weapon shop menu.

CALL_ITEM_SHOP();

Opens the medicine shop menu.

CALL_COMBINE_SHOP();

Opens the Velvet Room fusion menu.

CALL_NAME_ENTRY(); CALL_PHANTOM_NAME_ENTRY();

Opens the player/team naming menus. Use INIT_IME_DRIVER(); before and END_IME_DRIVER(); after to prevent crashes.

Stats

There's a function that can add points to a player's social stats.

ADD_PC_ALL_PARAM(knowledge, charm, proficiency, guts, kindness);

Each argument listed above is an integer. It takes hundreds of points to max out a given stat, so usually a small number is awarded at a time. If 0 is used, no points will be awarded for that type.

Follow the command with DISP_PC_PARAM_METER(); to bring up the visual that shows the points being added and the stat levelling up.

Money

You can add or subtract yen from the player by using the following functions.

// Take 540 yen from the player
int yen = -540;
CHANGE_GLOBAL_MONEY(yen, 0);

// Add 154,000 yen and show it being added
yen = 154000;
GET_MONEY_WINDOW(yen, 0);
CALL_GLOBAL_MONEY_PANEL();
CHANGE_GLOBAL_MONEY(yen, 0);
DEL_GLOBAL_MONEY_PANEL();

Personas

Unfortunately, there are no (known) ways to remove a specific Persona, check which Persona is equipped, change the equipped Persona, or change a party member's Persona using flowscript.

Function NameDescription

ADD_PERSONA_STOCK(int personaID);

Adds a specific Persona to your current set.

CLEAR_PERSONA_STOCK();

Removes all Personas from your current set.

PERSONA_EVOLUTION(int partyMember, int personaID);

Evolves a party member's Persona to tier 2.

SET_PERSONA_LV(int partyMember, int stockIndex, int level);

Sets a party member's Persona (or the protag's Persona at a specific slot) to a level from 1 to 99.

CHK_PERSONA_EXIST(int lowerRange, int upperRange);

Returns 1 if a Persona is found in the player's stock, returns 0 if not. I think it takes a range of Persona IDs?

Skills

Use the function PERSONA_SKILL_ADD(int partyMember, int personaID, int skillID); to give a desired skill to a character's Persona. Conversely, use REMOVE_PERSONA_SKILL for the opposite effect.

There's also SKILL_ADD(int partyMember, int skillID); which will do the same thing without providing a persona ID. In the case of the protagonist, it'll add the skill to the currently equipped Persona.

// Give Joker's equipped Persona the skill Agi
SKILL_ADD(1, 10);
// Show the skill being added
FADEIN(0, 10);
FADE_SYNC();
FLD_REQ_FLASHBACK(152, 51);
FLD_END_FLASHBACK();

Items

Giving the player items can seem a little complicated, but follow the table below and it should help.

Type IDItem Type

0x0

Melee Weapons

0x1000

Armor

0x2000

Accessories

0x3000

Consumables

0x4000

Key Items

0x5000

Materials

0x6000

Skill Cards

0x7000

Outfits

0x8000

Ranged Weapons

// Receive 4 of the key item "Morgana's Scarf"
ItemGet(0x4000, 72, 4);
// Show the item type, name and amount being received
GET_ITEMS_WINDOW(0);

// You can borrow this procedure to easily add items
void ItemGet(int type, int itemId, int amount)
{
    GET_ITEM_BUF_RESET();
    GET_ITEM_BUF_SET(type + itemId, amount);
    SET_ITEM_NUM(type + itemId, GET_ITEM_NUM(type + itemId) + amount);
}

Last updated