BASIC KNOWLEDGE TO THE DEFAULT RMVXA BATTLE FLOW IMPLEMENTATIONS

Share my understandings to the default RMVXA battle flow implementations(only share basic stuffs here)

  • DoubleX
  • 06/14/2015 05:23 AM
  • 970 views
You're assumed to have at least:
- Little scripting proficiency(having written at least few basic Ruby codes)
- Basic knowledge to the default RMVXA battle flow on the user level(At least you need to know what's going on on the surface when playing it as a player)

Battle Phases
For the basics, you'll need to know a battle consists of an action input phase and an action execution phase. There are actually also initialization, turn end, and aborting, but they'll only be briefly covered here.

Battle Initialization Phase
It's the phase where the battle's setting up. There are lots of stuffs going on, like setting up the troop in the battle, whether losing and/or party escape's allowed, whether the battle starts normally, preemptively or under surprise, and some other stuffs.
When the battle starts preemptively, the party has a free turn at the start of the battle; When it starts under surprise, the troop has a free turn at the start of the battle instead. A free turn is a turn where the opponents can't input nor execute actions.
After finishing the battle initializations, the battle will proceed to the Action Input Phase.

Action Input Phase
It's the phase where players can either try to escape the battle, or input actions for all inputable actors. An actor is said to be inputable if he/she/it's alive and has no Restrictions enforced by states and no special flag auto battle. The action input phase will proceed as follows:
1. A party command window shows, letting players choose between fight and escape.
2a. If they choose to escape, then the party will either escape if the attempt's successful, or wasted its turn otherwise, as players won't be able to input anything for that turn. If the party escapes, the battle will proceed to the Abort Battle Phase before actually quitting the battle.
2b. If they choose to fight, then they can input actions for all inputable actors.
3. They'll first input actions for the 1st inputable party member, then the 2nd, 3rd, and finally the last inputable party member. Players won't be able to break that input sequence.
4. Each alive actor has his/her/its own action slots, with its size determined by his/her/its Action Times+. As long as he/she/it's also inputable, players will first input actions for the 1st action slot, then the 2nd, 3rd, ..., and finally the last action slot. Again, players won't be able to break that input sequence.
5. When inputting actions for inputable actors, players can either use the ok command or the cancel command. Using the former and the latter eventually proceeds to the next input and prior input respectively. Next input and prior input eventually proceeds to the Action Execution Phase and the party command window respectively.
The below flowchart illustrates the flow within the action input phase(even though it's ultra ugly lol):


Action Execution Phase
It's the phase where all battlers' actions are processed and all valid ones are executed. An action is said to be valid upon execution if it's forced or its user can use it upon execution. The action execution phase will proceed as follows:
1. The battle turn count will be increased by 1. This moment is also regarded as the start of the battle turn. Stuffs needing to happen upon turn start will be triggered here.
2. An action order queue including all battlers will be made. The higher the speed of the battler at that moment, the more up front that battler will be positioned in that queue. The speed of the battler's determined by his/her/its agi and all his/her/its inputted actions' speed.
3. The most up front battler in the action order queue will execute all of his/her/its actions, and then leave that queue. This process repeats until the action order queue's empty.
4. As long as that battler's movable(unless he/she/it's force actions), he/she/it'll first process the action in his/her/its 1st action slot, then the one in 2nd, 3rd, ..., and finally the one in the last action slot. All actions that are valid at that moment will be executed.
5. When the last action of that battler's executed, action end processing will be done, and stuffs needing to happen upon action end will be triggered there.
6. When all actors or enemies are dead, the battle will proceed to battle defeat or victory processing respectively. The battle will then be ended.
7. When the action order queue's empty, the battle will proceed to the Turn End Phase.

Turn End Phase
It's the phase where the battle turn ends. Stuffs needing to happen upon turn end will be triggered here. After that, the battle will proceed to the Action Input Phase.

Abort Battle Phase
It's the phase where the party successfully escapes the battle. The battle will end after processing battle abort.

Related Codes
For the basics, you just need to know which methods are directly involved in the battle flow. You just need to know what they do locally, but not how they work locally, let alone how they work as a whole.

BattleManager
These methods process the Battle Initialization Phase:
#--------------------------------------------------------------------------
  # * Setup
  #--------------------------------------------------------------------------
  def self.setup(troop_id, can_escape = true, can_lose = false)
    init_members
    $game_troop.setup(troop_id)
    @can_escape = can_escape
    @can_lose = can_lose
    make_escape_ratio
  end
  #--------------------------------------------------------------------------
  # * Initialize Member Variables
  #--------------------------------------------------------------------------
  def self.init_members
    @phase = :init              # Battle Progress Phase
    @can_escape = false         # Can Escape Flag
    @can_lose = false           # Can Lose Flag
    @event_proc = nil           # Event Callback
    @preemptive = false         # Preemptive Attack Flag
    @surprise = false           # Surprise Flag
    @actor_index = -1           # Actor for Which Command Is Being Entered
    @action_forced = nil        # Force Action
    @map_bgm = nil              # For Memorizing Pre-Battle BGM
    @map_bgs = nil              # For Memorizing Pre-Battle BGS
    @action_battlers = []       # Action Order List
  end

#--------------------------------------------------------------------------
  # * Create Escape Success Probability
  #--------------------------------------------------------------------------
  def self.make_escape_ratio
    @escape_ratio = 1.5 - 1.0 * $game_troop.agi / $game_party.agi
  end

These methods checks the current battle phase:
#--------------------------------------------------------------------------
  # * Determine if Turn Is Executing
  #--------------------------------------------------------------------------
  def self.in_turn?
    @phase == :turn
  end
  #--------------------------------------------------------------------------
  # * Determine if Turn Is Ending
  #--------------------------------------------------------------------------
  def self.turn_end?
    @phase == :turn_end
  end
  #--------------------------------------------------------------------------
  # * Determine if Battle Is Aborting
  #--------------------------------------------------------------------------
  def self.aborting?
    @phase == :aborting
  end

These methods process the next input and prior input in the Action Input Phase:
#--------------------------------------------------------------------------
  # * To Next Command Input
  #--------------------------------------------------------------------------
  def self.next_command
    begin
      if !actor || !actor.next_command
        @actor_index += 1
        return false if @actor_index >= $game_party.members.size
      end
    end until actor.inputable?
    return true
  end
  #--------------------------------------------------------------------------
  # * To Previous Command Input
  #--------------------------------------------------------------------------
  def self.prior_command
    begin
      if !actor || !actor.prior_command
        @actor_index -= 1
        return false if @actor_index < 0
      end
    end until actor.inputable?
    return true
  end

This method judges if the battle defeat or victory's come:
#--------------------------------------------------------------------------
  # * Determine Win/Loss Results
  #--------------------------------------------------------------------------
  def self.judge_win_loss
    if @phase
      return process_abort   if $game_party.members.empty?
      return process_defeat  if $game_party.all_dead?
      return process_victory if $game_troop.all_dead?
      return process_abort   if aborting?
    end
    return false
  end

This method judges if the party escape succeeded:
#--------------------------------------------------------------------------
  # * Escape Processing
  #--------------------------------------------------------------------------
  def self.process_escape
    $game_message.add(sprintf(Vocab::EscapeStart, $game_party.name))
    success = @preemptive ? true : (rand < @escape_ratio)
    Sound.play_escape
    if success
      process_abort
    else
      @escape_ratio += 0.1
      $game_message.add('\.' + Vocab::EscapeFailure)
      $game_party.clear_actions
    end
    wait_for_message
    return success
  end

This method judges if the battle should proceed to the Action Input Phase and prepares for that if it should:
#--------------------------------------------------------------------------
  # * Start Command Input
  #--------------------------------------------------------------------------
  def self.input_start
    if @phase != :input
      @phase = :input
      $game_party.make_actions
      $game_troop.make_actions
      clear_actor
    end
    return !@surprise && $game_party.inputable?
  end

This method proceed the battle to the Action Execution Phase and prepares for that:
#--------------------------------------------------------------------------
  # * Start Turn
  #--------------------------------------------------------------------------
  def self.turn_start
    @phase = :turn
    clear_actor
    $game_troop.increase_turn
    make_action_orders
  end

This method proceed the battle to the Turn End Phase and clears the preemptive/surprise starting flag:
#--------------------------------------------------------------------------
  # * End Turn
  #--------------------------------------------------------------------------
  def self.turn_end
    @phase = :turn_end
    @preemptive = false
    @surprise = false
  end

This method builds up the action order queue:
#--------------------------------------------------------------------------
  # * Create Action Order
  #--------------------------------------------------------------------------
  def self.make_action_orders
    @action_battlers = []
    @action_battlers += $game_party.members unless @surprise
    @action_battlers += $game_troop.members unless @preemptive
    @action_battlers.each {|battler| battler.make_speed }
    @action_battlers.sort! {|a,b| b.speed - a.speed }
  end

This method removes the most up front battler in the action order queue and returns that battler:
#--------------------------------------------------------------------------
  # * Get Next Action Subject
  #    Get the battler from the beginning of the action order list.
  #    If an actor not currently in the party is obtained (occurs when index
  #    is nil, immediately after escaping in battle events etc.), skip them.
  #--------------------------------------------------------------------------
  def self.next_subject
    loop do
      battler = @action_battlers.shift
      return nil unless battler
      next unless battler.index && battler.alive?
      return battler
    end
  end


Scene_Battle
These methods process the next input and prior input in the Action Input Phase:
#--------------------------------------------------------------------------
  # * To Next Command Input
  #--------------------------------------------------------------------------
  def next_command
    if BattleManager.next_command
      start_actor_command_selection
    else
      turn_start
    end
  end
  #--------------------------------------------------------------------------
  # * To Previous Command Input
  #--------------------------------------------------------------------------
  def prior_command
    if BattleManager.prior_command
      start_actor_command_selection
    else
      start_party_command_selection
    end
  end

This method opens the party command window in the Action Input Phase:
#--------------------------------------------------------------------------
  # * Start Party Command Selection
  #--------------------------------------------------------------------------
  def start_party_command_selection
    unless scene_changing?
      refresh_status
      @status_window.unselect
      @status_window.open
      if BattleManager.input_start
        @actor_command_window.close
        @party_command_window.setup
      else
        @party_command_window.deactivate
        turn_start
      end
    end
  end

These methods process the fight command and escape command in the party command window in the Action Input Phase:
#--------------------------------------------------------------------------
  # * [Fight] Command
  #--------------------------------------------------------------------------
  def command_fight
    next_command
  end
  #--------------------------------------------------------------------------
  # * [Escape] Command
  #--------------------------------------------------------------------------
  def command_escape
    turn_start unless BattleManager.process_escape
  end

This method lets players input the currently selected action slot of the currently selected actor in the Action Input Phase:
#--------------------------------------------------------------------------
  # * Start Actor Command Selection
  #--------------------------------------------------------------------------
  def start_actor_command_selection
    @status_window.select(BattleManager.actor.index)
    @party_command_window.close
    @actor_command_window.setup(BattleManager.actor)
  end

These methods proceed the battle to the Action Execution Phase and Turn End Phase respectively:
#--------------------------------------------------------------------------
  # * Start Turn
  #--------------------------------------------------------------------------
  def turn_start
    @party_command_window.close
    @actor_command_window.close
    @status_window.unselect
    @subject =  nil
    BattleManager.turn_start
    @log_window.wait
    @log_window.clear
  end
  #--------------------------------------------------------------------------
  # * End Turn
  #--------------------------------------------------------------------------
  def turn_end
    all_battle_members.each do |battler|
      battler.on_turn_end
      refresh_status
      @log_window.display_auto_affected_status(battler)
      @log_window.wait_and_clear
    end
    BattleManager.turn_end
    process_event
    start_party_command_selection
  end

These methods process all battlers' actions and the action ends in the Action Execution Phase:
#--------------------------------------------------------------------------
  # * Battle Action Processing
  #--------------------------------------------------------------------------
  def process_action
    return if scene_changing?
    if !@subject || !@subject.current_action
      @subject = BattleManager.next_subject
    end
    return turn_end unless @subject
    if @subject.current_action
      @subject.current_action.prepare
      if @subject.current_action.valid?
        @status_window.open
        execute_action
      end
      @subject.remove_current_action
    end
    process_action_end unless @subject.current_action
  end
  #--------------------------------------------------------------------------
  # * Processing at End of Action
  #--------------------------------------------------------------------------
  def process_action_end
    @subject.on_action_end
    refresh_status
    @log_window.display_auto_affected_status(@subject)
    @log_window.wait_and_clear
    @log_window.display_current_state(@subject)
    @log_window.wait_and_clear
    BattleManager.judge_win_loss
  end


That's all for now. I hope this can help you grasp these basic knowledge. For those comprehending the default RMVXA battle flow implementations, feel free to correct me if there's anything wrong
For those wanting to have a solid understanding to the default RMVXA battle flow implementations, I might open a more advanced topic for that later