Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/pmret/papermario/llms.txt

Use this file to discover all available pages before exploring further.

The battle system drives every turn-based encounter in Paper Mario. When a battle begins, the game loads a dedicated battle section overlay, creates actor objects for Mario, his active partner, and all enemies, and hands control to a large state machine implemented in src/battle/battle.c and src/battle/btl_states_actions.c. Understanding this system is essential for working on any of the 47+ battle areas in the project.

State machine overview

The battle state machine is documented in full in src/battle/states_flowchart.md. Every battle begins in BATTLE_STATE_START, set during load_battle_section. After all actors are created the machine enters BATTLE_STATE_BEGIN_TURN and loops until one of three terminal conditions is met:
Ending conditionDetection functionTarget state
All enemies defeatedbtl_check_enemies_defeatedBATTLE_STATE_VICTORY
Player HP reaches zerobtl_check_player_defeatedBATTLE_STATE_DEFEAT
Run Away succeedsStrategies menu flagBATTLE_STATE_END_BATTLE
Each turn visits player, partner, and enemy phases in order. The player and partner may swap their action order via the Swap command, and BATTLE_STATE_TRANSFER_TURN arbitrates which actor acts next.
BEGIN_TURN
  → BEGIN_PLAYER_TURN → SWITCH_TO_PLAYER → PREPARE_MENU → PLAYER_MENU
      → SELECT_TARGET → PLAYER_MOVE → END_PLAYER_TURN
  → BEGIN_PARTNER_TURN → SWITCH_TO_PARTNER → PREPARE_MENU → PARTNER_MENU
      → SELECT_TARGET → PARTNER_MOVE → END_PARTNER_TURN
  → TRANSFER_TURN
      → NEXT_ENEMY → ENEMY_MOVE (repeated for each enemy)
  → END_TURN → BEGIN_TURN
Peach battles swap the player and partner roles and route through TRANSFER_TURN after the player acts. See states_flowchart.md for the Peach-specific edges omitted from the summary above.

Key source files

FileRole
src/battle/battle.cCore battle loop, actor creation, loading
src/battle/btl_states_actions.cState handlers for player, partner, and enemy moves
src/battle/btl_states_menus.cMenu state handlers (player menu, partner menu, target selection)
src/battle/actors.cActor data tables
src/battle/actor_api.cActor manipulation API used by EVT scripts
src/battle/actor_rendering.cActor display list construction
src/battle/action_cmd.cAction command framework
src/battle/player_events.cStandard player event scripts
src/battle/standard_events.cShared enemy event scripts
src/battle/use_moves.cMove execution helpers
src/battle/use_items.cItem use during battle
src/battle/use_star_powers.cStar power execution
src/battle/level_up.cLevel-up sequence
src/battle/camera.cBattle camera control

Actor types

The battle system defines three actor roles. Every actor that participates in combat — whether Mario, a partner, or an enemy — is one of these types. Player actor (ACTOR_TYPE_MARIO / ACTOR_TYPE_PEACH) — controlled by the human player. The player actor’s turn script is EVS_ExecuteMarioAction (or EVS_ExecutePeachAction). Phase handling runs via EVS_Mario_HandlePhase. Partner actor — one partner is active at a time. Partner entry and exit scripts are EVS_BtlBringPartnerOut and EVS_BtlPutPartnerAway. Partner-specific move logic lives under src/battle/partner/. Enemy actors — each enemy in a formation is its own actor. Enemies bind a takeTurn script via BindTakeTurn and respond to damage events via BindHandleEvent. Enemy actor data is defined in the corresponding area/ subdirectory.

Actor positions

Positions on the battlefield use the BattlePositions enum (src/battle/battle.h):
enum BattlePositions {
    BTL_POS_GROUND_A = 0,  // front ground slot
    BTL_POS_GROUND_B = 1,
    BTL_POS_GROUND_C = 2,
    BTL_POS_GROUND_D = 3,
    BTL_POS_AIR_A    = 4,  // airborne slots
    BTL_POS_AIR_B    = 5,
    // ... up to BTL_POS_TOP_D = 15
    BTL_POS_CENTER   = 16,
};

Action commands

Action commands are defined in src/battle/action_cmd.c and src/battle/action_cmd.h. Each action command is a mini-game that runs during a player or partner move. The framework exposes the current button state to EVT scripts through callables such as CheckButtonPress, CheckButtonHeld, and CheckButtonDown. The quality result is read back with GetPlayerActionQuality or GetPartnerActionQuality.

Battle areas

Battle stage data lives under src/battle/area/. Each subdirectory corresponds to one BTL_AREA_* constant defined in src/battle/battle.h:
ConstantDirectoryRegion
BTL_AREA_KMR_1BTL_AREA_KMR_3area/kmr_1area/kmr_3Goomba Road
BTL_AREA_MACarea/macToad Town
BTL_AREA_HOSarea/hosShooting Star Summit
BTL_AREA_NOKarea/nokKoopa Bros. Fortress
BTL_AREA_TRD_1BTL_AREA_TRD_3area/trd_1area/trd_3Dry Dry Ruins
BTL_AREA_IWAarea/iwaMt. Rugged
BTL_AREA_SBKarea/sbkDry Dry Desert
BTL_AREA_ISK_1, BTL_AREA_ISK_2area/isk_1, area/isk_2Dry Dry Ruins interior
BTL_AREA_MIMarea/mimForever Forest
BTL_AREA_ARNarea/arnBoo’s Mansion
BTL_AREA_DGBarea/dgbGusty Gulch
BTL_AREA_OMOBTL_AREA_OMO3area/omoarea/omo3Shy Guy’s Toy Box
BTL_AREA_KGRarea/kgrKoopa Village
BTL_AREA_JAN, BTL_AREA_JAN2area/jan, area/jan2Jade Jungle
BTL_AREA_KZN, BTL_AREA_KZN2area/kzn, area/kzn2Mt. Lavalava
BTL_AREA_FLO, BTL_AREA_FLO2area/flo, area/flo2Flower Fields
BTL_AREA_TIKBTL_AREA_TIK3area/tikarea/tik3Tubba Blubba’s Castle
BTL_AREA_SAM, BTL_AREA_SAM2area/sam, area/sam2Shiver Region
BTL_AREA_PRABTL_AREA_PRA3area/praarea/pra3Crystal Palace
BTL_AREA_KPABTL_AREA_KPA4area/kpaarea/kpa4Bowser’s Castle
BTL_AREA_KKJarea/kkjPeach’s Castle
BTL_AREA_DIGarea/digLavalava depth

EVT battle scripting API

Move scripts and enemy AI call into the battle system through callables declared in include/script_api/battle.h. The most frequently used are:
API_CALLABLE(SetGoalToHome);         // set move goal to actor's home position
API_CALLABLE(SetGoalToTarget);       // set move goal to targeted actor
API_CALLABLE(GetActorPos);           // read actor world position
API_CALLABLE(SetActorPos);           // teleport actor to position
API_CALLABLE(JumpToGoal);            // animated jump to goal position
API_CALLABLE(RunToGoal);             // animated run to goal position
API_CALLABLE(FlyToGoal);             // animated fly to goal position
API_CALLABLE(PlayerDamageEnemy);     // deal damage from player to target
API_CALLABLE(EnemyDamageTarget);     // deal damage from enemy to target
API_CALLABLE(PartnerDamageEnemy);    // deal damage from partner to target
API_CALLABLE(PlayerTestEnemy);       // test whether attack hits
API_CALLABLE(EnemyTestTarget);       // enemy hit test
API_CALLABLE(AfflictActor);          // apply status effect to actor
API_CALLABLE(GetLastDamage);         // read damage dealt in last hit
API_CALLABLE(UseBattleCamPreset);         // switch to a camera preset
API_CALLABLE(SetBattleCamTarget);         // set explicit camera target
API_CALLABLE(BattleCamTargetActor);       // lock camera on an actor
API_CALLABLE(MoveBattleCamOver);          // smoothly move camera
API_CALLABLE(SetBattleCamDist);           // set camera distance
API_CALLABLE(FreezeBattleCam);            // lock camera in place
API_CALLABLE(BindTakeTurn);      // bind the actor's take-turn EVT script
API_CALLABLE(BindIdle);          // bind idle animation script
API_CALLABLE(BindHandleEvent);   // bind event handler (hit, death, etc.)
API_CALLABLE(BindHandlePhase);   // bind phase handler
API_CALLABLE(YieldTurn);         // give up remaining turn

World and map system

Learn how areas, rooms, and map transitions work outside of battle.

NPCs and entities

Understand the NPC and entity object systems used in both worlds and battles.

Build docs developers (and LLMs) love