Solid understanding to the default RMMV battle flow implementations

● ARCHIVED · READ-ONLY
Started by DoubleX 20 posts View original ↗
  1. This topic aims to share my understandings to the default RMMV battle flow implementations, and I'll share more advanced stuffs in details here. So you're assumed to have at least:
    - Some battle related javascript coding proficiency(inexperienced junior plugin developer having written at least several easy, simple and small battle related plugins without nontrivial bugs)
    - Basic knowledge to the default RMMV battle flow implementations

    Contents
    I. Battle Frame Update
    1. Battle Phases
    2. Detailed Flow Reasoning
    3. Summary
    II. Battle Start
    1. Init Phase
    2. Start Phase
    3. Detailed Flow Reasoning
    4. Summary
    III. Action Input Phase
    1. Input Phase
    2. Party Command Window
    3. Party Escape
    4. Actor Command Window
    5. Detailed Flow Reasoning
    6. Summary
    IV. Action Execution Phase
    1. Turn Phase
    2. Action Phase
    3. Turn End Phase
    4. Battle Log Window
    5. Spriteset Battle
    6. Detailed Flow Reasoning
    7. Summary
    V. Battle End
    1. Aborting Phase
    2. Battle End Phase
    3. Null Phase
    4. Detailed Flow Reasoning
    5. Summary
    VI. Summary

    Before actually covering any of the above contents, I want to explain why this topic's structured this way:
    1. An effective and efficient way to quickly grasp the big picture of the default RMMV battle flow implementations is to simulate a turn covering all important details.
    2. The battle flow's run by the Battle Frame Update per frame, so it's natural to explore that part first.
    3. The battle always have a starting phase, which can have a slight impact on the battle flow before it actually runs, so it needs to be explored too.
    4. The battle almost always starts in the Action Input Phase and ends in the Action Execution Phase, both of which are the most important parts of the battle, so the former will be explored before the latter.
    5. The battle always have an ending phase as long as it ends normally, so it's better to explore it as well.
    I'll start to talk about the contents in the upcoming replies in this topic. For now, let's cite the simplified battle flowchart as both a preparation on what I'm going to cover and a revision on what you're assumed to know already:
    Spoiler
    Simplified Default RMMV Battle Flow.JPG
  2. This is good stuff. I recently wrote a script for button casting skills between turns (using Yanfly's ATB system) and had to figure out a ton of this battle flow stuff. I consulted your original post on battle flow to get a better idea of what I was dealing with and it was very helpful.
  3. I've just finished drawing a flowchart for each part of the contents:

    Battle Frame Update -
    Spoiler
    Default RMMV Battle Frame Update.JPG

    Battle Start -
    Spoiler
    Default RMMV Battle Start.JPG

    Action Input Phase -
    Spoiler
    Default RMMV Battle Action Input Phase.JPG

    Action Execution Phase -
    Spoiler
    Default RMMV Battle Action Execution Phase.JPG

    Battle End -
    Spoiler
    Default RMMV Battle End.JPG

    I'll use a subsequent reply for each part to explain each of the above flowcharts in details.
  4. Now let's talk about I. Battle Frame Update in detail.

    Battle Phases
    Spoiler
    Phase Init
    It's the battle initialization phase where the battle is just triggered but not yet ready to start as it needs to be prepared first. The battle phase will be set as init in BattleManager.initMembers:
    JavaScript:
    BattleManager.initMembers = function() {
        this._phase = 'init';
        this._canEscape = false;
        this._canLose = false;
        this._battleTest = false;
        this._eventCallback = null;
        this._preemptive = false;
        this._surprise = false;
        this._actorIndex = -1;
        this._actionForcedBattler = null;
        this._mapBgm = null;
        this._mapBgs = null;
        this._actionBattlers = [];
        this._subject = null;
        this._action = null;
        this._targets = [];
        this._logWindow = null;
        this._statusWindow = null;
        this._spriteset = null;
        this._escapeRatio = 0;
        this._escaped = false;
        this._rewards = {};
    };
    The details of this phase will be covered in II. Battle Start.

    Phase Start
    It's the start of the battle when it just becomes prepared and ready. The battle phase will be set as start in BattleManager.startBattle:
    JavaScript:
    BattleManager.startBattle = function() {
        this._phase = 'start';
        $gameSystem.onBattleStart();
        $gameParty.onBattleStart();
        $gameTroop.onBattleStart();
        this.displayStartMessages();
    };
    The details of this phase will be covered in II. Battle Start.

    Phase Input
    It's the Action Input Phase. The battle phase will be set as input in BattleManager.startInput:
    JavaScript:
    BattleManager.startInput = function() {
        this._phase = 'input';
        $gameParty.makeActions();
        $gameTroop.makeActions();
        this.clearActor();
        if (this._surprise || !$gameParty.canInput()) {
            this.startTurn();
        }
    };
    The details of this phase will be covered in III. Action Input Phase.

    Phase Turn
    The Action Execution Phase consists of 2 parts - Setting Up Action Execution Subjects and Executing Actions. The phase turn is the former part.
    The battle phase will be set as turn in BattleManager.startTurn:
    JavaScript:
    BattleManager.startTurn = function() {
        this._phase = 'turn';
        this.clearActor();
        $gameTroop.increaseTurn();
        this.makeActionOrders();
        $gameParty.requestMotionRefresh();
        this._logWindow.startTurn();
    };
    The details of this phase will be covered in IV. Action Execution Phase.

    Phase Action
    The Action Execution Phase consists of 2 parts - Setting Up Action Execution Subjects and Executing Actions. The phase action is the latter part.
    The battle phase will be set as action in BattleManager.startAction:
    JavaScript:
    BattleManager.startAction = function() {
        var subject = this._subject;
        var action = subject.currentAction();
        var targets = action.makeTargets();
        this._phase = 'action';
        this._action = action;
        this._targets = targets;
        subject.useItem(action.item());
        this._action.applyGlobal();
        this.refreshStatus();
        this._logWindow.startAction(subject, action, targets);
    };
    The details of this phase will be covered in IV. Action Execution Phase.

    Phase Turn End
    It's the Turn End Phase, which is the transition from the Action Execution Phase to the Action input Phase. The battle phase will be set as turn end in BattleManager.endTurn:
    JavaScript:
    BattleManager.endTurn = function() {
        this._phase = 'turnEnd';
        this._preemptive = false;
        this._surprise = false;
        this.allBattleMembers().forEach(function(battler) {
            battler.onTurnEnd();
            this.refreshStatus();
            this._logWindow.displayAutoAffectedStatus(battler);
            this._logWindow.displayRegeneration(battler);
        }, this);
    };
    The details of this phase will be covered in IV. Action Execution Phase.

    Phase Abort
    It's the phase where the battle's going to be aborted. The battle phase will be set as abort in BattleManager.abort:
    JavaScript:
    BattleManager.abort = function() {
        this._phase = 'aborting';
    };
    The details of this phase will be covered in V. Battle End.

    Phase Battle End
    It's the phase where the battle ends. The battle phase will be set as battle end in BattleManager.endBattle:
    JavaScript:
    BattleManager.endBattle = function(result) {
        this._phase = 'battleEnd';
        if (this._eventCallback) {
            this._eventCallback(result);
        }
        if (result === 0) {
            $gameSystem.onBattleWin();
        } else if (this._escaped) {
            $gameSystem.onBattleEscape();
        }
    };
    The details of this phase will be covered in V. Battle End.

    Phase Null
    It's the phase where the battle has completely ended. The battle phase will be set as null in BattleManager.updateBattleEnd:
    JavaScript:
    BattleManager.updateBattleEnd = function() {
        if (this.isBattleTest()) {
            AudioManager.stopBgm();
            SceneManager.exit();
        } else if ($gameParty.isAllDead()) {
            if (this._canLose) {
                $gameParty.reviveBattleMembers();
                SceneManager.pop();
            } else {
                SceneManager.goto(Scene_Gameover);
            }
        } else {
            SceneManager.pop();
        }
        this._phase = null;
    };
    The details of this phase will be covered in V. Battle End.

    Detailed Flow Reasoning
    Spoiler
    Consider the below detailed Battle Frame Update flowchart(even though it still doesn't literally show all details):
    Default RMMV Battle Frame Update.JPG
    Relevant codes will be explained in detail when the corresponding parts of the flowchart's covered.

    Scene_Battle.prototype.updateBattleProcess

    Scene_Battle.prototype.updateBattleProcess is called per frame(technically there are some exceptions but they're irrelevant to the battle flow):
    JavaScript:
    Scene_Battle.prototype.updateBattleProcess = function() {
        if (!this.isAnyInputWindowActive() || BattleManager.isAborting() ||
                BattleManager.isBattleEnd()) {
            BattleManager.update();
            this.changeInputWindow();
        }
    };
    So BattleManager.update and Scene_Battle.prototype.changeInputWindow will be called when no input windows are active and the battle's not going to be ended.
    BattleManager.isAborting and BattleManager.isBattleEnd checks if the battle phase's aborting and battle end respectively:
    JavaScript:
    BattleManager.isAborting = function() {
        return this._phase === 'aborting';
    };
    JavaScript:
    BattleManager.isBattleEnd = function() {
        return this._phase === 'battleEnd';
    };
    Scene_Battle.prototype.changeInputWindow will make at least 1 input window active when the battle's in the Action Input Phase, and make them all inactive when that's not the case:
    JavaScript:
    Scene_Battle.prototype.changeInputWindow = function() {
        if (BattleManager.isInputting()) {
            if (BattleManager.actor()) {
                this.startActorCommandSelection();
            } else {
                this.startPartyCommandSelection();
            }
        } else {
            this.endCommandSelection();
        }
    };
    It's because BattleManager.isInputting returns whether the battle's in the Action Input Phase:
    JavaScript:
    BattleManager.isInputting = function() {
        return this._phase === 'input';
    };
    So either the actor or party command window will be setup to let players trigger a party escape attempt or input actions for inputable actors(their details will be covered in III. Action Input Phase):
    JavaScript:
    Scene_Battle.prototype.startActorCommandSelection = function() {
        this._statusWindow.select(BattleManager.actor().index());
        this._partyCommandWindow.close();
        this._actorCommandWindow.setup(BattleManager.actor());
    };
    Code:
    Scene_Battle.prototype.startPartyCommandSelection = function() {
        this.refreshStatus();
        this._statusWindow.deselect();
        this._statusWindow.open();
        this._actorCommandWindow.close();
        this._partyCommandWindow.setup();
    };
    Since the only things that can happen in the Action Input Phase is inputting actions for inputable actors and trigger a party escape attempt, checking if there are active input windows is basically the same as checking if the battle's in the Action Input Phase.

    BattleManager.update
    BattleManager.update is called per frame when the battle's in the Action Execution Phase(and called once when the battle's just started in the prepared and ready manner):
    Code:
    BattleManager.update = function() {
        if (!this.isBusy() && !this.updateEvent()) {
            switch (this._phase) {
            case 'start':
                this.startInput();
                break;
            case 'turn':
                this.updateTurn();
                break;
            case 'action':
                this.updateAction();
                break;
            case 'turnEnd':
                this.updateTurnEnd();
                break;
            case 'battleEnd':
                this.updateBattleEnd();
                break;
            }
        }
    };
    BattleManager.isBusy is vital in coordinating action executions(its details will be covered in IV. Action Execution Phase):
    Code:
    BattleManager.isBusy = function() {
        return ($gameMessage.isBusy() || this._spriteset.isBusy() ||
                this._logWindow.isBusy());
    };
    BattleManager.updateEvent will be covered in the next section.
    When the battle phase is start, BattleManager.startInput will be called to change the battle phase to Action Input Phase:
    Code:
    BattleManager.startInput = function() {
        this._phase = 'input';
        $gameParty.makeActions();
        $gameTroop.makeActions();
        this.clearActor();
        if (this._surprise || !$gameParty.canInput()) {
            this.startTurn();
        }
    };
    Each battler will make action slots for inputting actions, and BattleManager.clearActor is called to ensure the party command window will be setup(it'll be further explained in III. Action Input Phase):
    Code:
    BattleManager.clearActor = function() {
        this.changeActor(-1, '');
    };
    However, if the battle has just started, with the surprise start case, or there are no inputable actors, will battle will directly transit to the Action Execution Phase due to the call of BattleManager.startTurn(the former case will be further explained in II. Battle Start):
    Code:
    BattleManager.startTurn = function() {
        this._phase = 'turn';
        this.clearActor();
        $gameTroop.increaseTurn();
        this.makeActionOrders();
        $gameParty.requestMotionRefresh();
        this._logWindow.startTurn();
    };
    When the battle phase is turn, BattleManager.updateTurn, which setups the Action Execution Subject as the 1st battler in the Action Order Queue and removes that battler from the queue, will be called(its details will be covered in IV. Action Execution Phase):
    Code:
    BattleManager.updateTurn = function() {
        $gameParty.requestMotionRefresh();
        if (!this._subject) {
            this._subject = this.getNextSubject();
        }
        if (this._subject) {
            this.processTurn();
        } else {
            this.endTurn();
        }
    };
    When the battle phase is action, BattleManager.updateAction, which removes the 1st target from the Action Target List and invoke the Currently Executing Action on that target by the Action Execution Subject or ends that action execution if the Action Target List's empty, will be called(its details will be covered in IV. Action Execution Phase):
    Code:
    BattleManager.updateAction = function() {
        var target = this._targets.shift();
        if (target) {
            this.invokeAction(this._subject, target);
        } else {
            this.endAction();
        }
    };
    When the battle phase is turn end, BattleManager.updateTurnEnd, which transits the battle to the Action Input Phase or Action Execution Phase if there are inputable actors and no inputable actors respectively, will be called:
    Code:
    BattleManager.updateTurnEnd = function() {
        this.startInput();
    };
    When the battle phase is battle end, BattleManager.updateBattleEnd, which changes the scene from Scene_Battle to the previous one and transit the battle phase to null, will be called(its details will be covered in V. Battle End):
    Code:
    BattleManager.updateBattleEnd = function() {
        if (this.isBattleTest()) {
            AudioManager.stopBgm();
            SceneManager.exit();
        } else if ($gameParty.isAllDead()) {
            if (this._canLose) {
                $gameParty.reviveBattleMembers();
                SceneManager.pop();
            } else {
                SceneManager.goto(Scene_Gameover);
            }
        } else {
            SceneManager.pop();
        }
        this._phase = null;
    };

    BattleManager.updateEvent
    Note that BattleManager.updateEvent won't be called if BattleManager.isBusy returns true.
    BattleManager.updateEvent is vital in processing forced actions and updating events per frame:
    Code:
    BattleManager.updateEvent = function() {
        switch (this._phase) {
        case 'start':
        case 'turn':
        case 'turnEnd':
            if (this.isActionForced()) {
                this.processForcedAction();
                return true;
            } else {
                return this.updateEventMain();
            }
        }
        return this.checkAbort();
    };
    Note that it'll only check if the battle should be aborted during the Executing Action part of the Action Execution Phase(it'll be further explained in IV. Action Execution Phase).
    BattleManager.checkAbort checks if the party's escaped via individual actor escape or party escape:
    Code:
    BattleManager.checkAbort = function() {
        if ($gameParty.isEmpty() || this.isAborting()) {
            this.processAbort();
            return true;
        }
        return false;
    };
    The Battle Frame Update will stop if it returns true and continue to run otherwise.
    BattleManager.processAbort ends the battle via calling BattleManager.endBattle(which will be further explained in V. Battle End):
    Code:
    BattleManager.processAbort = function() {
        this.replayBgmAndBgs();
        this.endBattle(1);
    };
    On the other hand, in the Setting up Action Execution Subject part of the Action Execution Phase, BattleManager.processForcedAction will be called when BattleManager.isActionForced returns true:
    Code:
    BattleManager.isActionForced = function() {
        return !!this._actionForcedBattler;
    };
    Code:
    BattleManager.processForcedAction = function() {
        if (this._actionForcedBattler) {
            this._subject = this._actionForcedBattler;
            this._actionForcedBattler = null;
            this.startAction();
            this._subject.removeCurrentAction();
        }
    };
    Forced actions will be further explained in IV. Action Execution Phase.
    If there are no forced actions to be processed, BattleManager.updateEventMain will be called:
    Code:
    BattleManager.updateEventMain = function() {
        $gameTroop.updateInterpreter();
        $gameParty.requestMotionRefresh();
        if ($gameTroop.isEventRunning() || this.checkBattleEnd()) {
            return true;
        }
        $gameTroop.setupBattleEvent();
        if ($gameTroop.isEventRunning() || SceneManager.isSceneChanging()) {
            return true;
        }
        return false;
    };
    Game_Troop.prototype.updateInterpreter updates the interpreter running the battle events, and Game_Troop.prototype.setupBattleEvent tries to setup a new battle event(Their details are irrelevant to the battle flow due to separation of concerns).
    BattleManager.checkBattleEnd checks if the battle should be ended:
    Code:
    BattleManager.checkBattleEnd = function() {
        if (this._phase) {
            if (this.checkAbort()) {
                return true;
            } else if ($gameParty.isAllDead()) {
                this.processDefeat();
                return true;
            } else if ($gameTroop.isAllDead()) {
                this.processVictory();
                return true;
            }
        }
        return false;
    };
    If the battle's going to be aborted, or all party or troop members are dead, which lead to defeat and victory respectively, the battle will be ended.
    Note that if all battlers die at the exact same frame, the battle will be lost, as $gameParty.isAllDead is checked before checking $gameTroop.isAllDead.
    Both BattleManager.processDefeat and BattleManager.processVictory changes the battle phase to battleEnd via calling BattleManager.endBattle:
    Code:
    BattleManager.processVictory = function() {
        $gameParty.removeBattleStates();
        $gameParty.performVictory();
        this.playVictoryMe();
        this.replayBgmAndBgs();
        this.makeRewards();
        this.displayVictoryMessage();
        this.displayRewards();
        this.gainRewards();
        this.endBattle(0);
    };
    Code:
    BattleManager.processDefeat = function() {
        this.displayDefeatMessage();
        this.playDefeatMe();
        if (this._canLose) {
            this.replayBgmAndBgs();
        } else {
            AudioManager.stopBgm();
        }
        this.endBattle(2);
    };
    In short, if some events are already running or the battle should be ended, the Battle Frame Update will stop. Otherwise it'll try to setup a new battle event and stops the Battle Frame Update if there's any or let it continue if there's none.

    Summary
    Spoiler
    The battle consists of the below phases:
    init - The battle's just triggered but not yet ready to start before finishing preparations
    start - The battle's just started in a prepared and ready manner
    input - The Action Input Phase
    turn - The Setting Up Action Execution Subject part of the Action Execution Phase
    action - The Executing Action part of the Action Execution Phase
    turnEnd - The Turn End Phase
    abort - The battle's going to be aborted
    battleEnd - The battle ends
    null - The battle's completed ended

    The Battle Frame Update first checks if there are active input windows or the battle's going to be ended. If that's the case, it'll just stop, otherwise it'll continue to run to handle various battle phase updates and the input window updates. Note that checking if there are active input windows is basically the same as checking if the battle's in the Action Input Phase.
    If the Battle Frame Update continues to run:
    If the battle's busy, it'll just stop. Otherwise if the battle's executing actions, Battle Frame Update will stop if the battle's going to be aborted, or continue to run otherwise.
    On the other hand, if the battle's not executing actions, the forced actions, if any, will be executed, or event setups and updates and the battle end checking will be proceeded instead.
    If forced actions will be executed, events will be setup, or the battle should be ended, the Battle Frame Update will stop.
    If the Battle Frame Update continues to run:
    If the battle phase's start, it'll transit to the Action Input Phase, unless the battle starts with surprise or there are no inputable actors, in which it'll transit to the Action Execution Phase instead.
    If the battle phase's turn, it'll setup the Action Execution Subject as the 1st battler in the Action Order Queue and remove that battler from the queue.
    If the battle phase's action, it'll remove the 1st target from the Action Target List and invoke the Currently Executing Action on that target by the Action Execution Subject or ends that action execution if the Action Target List's empty.
    If the battle phase's turn end, it'll transit to the Action Input Phase and Action Execution Phase if there are inputable actors and no inputable actors respectively.
    If the battle phase's battle end, the battle the change the scene from Scene_Battle to the previous one and transit the battle phase to null.
  5. Now let's talk about II. Battle Start in detail.

    Init Phase
    Spoiler
    Preparations
    Recall that the init phase is to prepare the battle to make it ready to start.
    BattleManager.initMembers transits the battle phase to init:
    JavaScript:
    BattleManager.initMembers = function() {
        this._phase = 'init';
        this._canEscape = false;
        this._canLose = false;
        this._battleTest = false;
        this._eventCallback = null;
        this._preemptive = false;
        this._surprise = false;
        this._actorIndex = -1;
        this._actionForcedBattler = null;
        this._mapBgm = null;
        this._mapBgs = null;
        this._actionBattlers = [];
        this._subject = null;
        this._action = null;
        this._targets = [];
        this._logWindow = null;
        this._statusWindow = null;
        this._spriteset = null;
        this._escapeRatio = 0;
        this._escaped = false;
        this._rewards = {};
    };
    Note that these variables will be reinitialized at the start of every battle.
    After that, the remaining contents of BattleManager.setup will be run:
    JavaScript:
    BattleManager.setup = function(troopId, canEscape, canLose) {
        this.initMembers();
        this._canEscape = canEscape;
        this._canLose = canLose;
        $gameTroop.setup(troopId);
        $gameScreen.onBattleStart();
        this.makeEscapeRatio();
    };
    Note that BattleManager.makeEscapeRatio is this:
    JavaScript:
    BattleManager.makeEscapeRatio = function() {
        this._escapeRatio = 0.5 * $gameParty.agility() / $gameTroop.agility();
    };

    Why this phase's needed
    Recall that upon battle start(with phase start rather than init), the Battle Frame Update will update battle events when the battle's not busy. If the Battle Frame Update can continue to run, either the Action Input Phase or the Action Execution Phase will be called right afterwards. Which one will be called depends on whether there are inputable actors and the battle starts with surprise, which can't be predetermined before battle start(Check I. Battle Frame Update for details).
    All these mean that the battle at least have to be prepared to run battle events, the Action Input Phase and the Action Execution Phase. That's why there has to be a phase between triggering a battle and actually starting it to ensure it's ready.

    Start Phase
    Spoiler
    Start sequence
    Recall that the start phase is to indicate that the battle's prepared to be started in a ready manner.
    BattleManager.startBattle changes the battle phase to start:
    JavaScript:
    BattleManager.startBattle = function() {
        this._phase = 'start';
        $gameSystem.onBattleStart();
        $gameParty.onBattleStart();
        $gameTroop.onBattleStart();
        this.displayStartMessages();
    };
    Note that BattleManager.displayStartMessages is this:
    JavaScript:
    BattleManager.displayStartMessages = function() {
        $gameTroop.enemyNames().forEach(function(name) {
            $gameMessage.add(TextManager.emerge.format(name));
        });
        if (this._preemptive) {
            $gameMessage.add(TextManager.preemptive.format($gameParty.name()));
        } else if (this._surprise) {
            $gameMessage.add(TextManager.surprise.format($gameParty.name()));
        }
    };
    Recall that BattleManager.update is this:
    JavaScript:
    BattleManager.update = function() {
        if (!this.isBusy() && !this.updateEvent()) {
            switch (this._phase) {
            case 'start':
                this.startInput();
                break;
            case 'turn':
                this.updateTurn();
                break;
            case 'action':
                this.updateAction();
                break;
            case 'turnEnd':
                this.updateTurnEnd();
                break;
            case 'battleEnd':
                this.updateBattleEnd();
                break;
            }
        }
    };

    So at the next Battle Frame Update, if the battle's busy(like the battle start message's still displaying), the battle will wait until it's not busy.
    When it's not busy, BattleManager.updateEvent will run all battle events that will be run upon battle start(Check I. Battle Frame Update for details).
    After that, BattleManager.startInput will be called:
    JavaScript:
    BattleManager.startInput = function() {
        this._phase = 'input';
        $gameParty.makeActions();
        $gameTroop.makeActions();
        this.clearActor();
        if (this._surprise || !$gameParty.canInput()) {
            this.startTurn();
        }
    };
    If the battle starts with surprise or there are no inputable actors, the battle will transit to the Action Execution Phase, otherwise it'll transit to the Action Input Phase.

    Why this phase's needed
    Without changing the rest of the default RMMV battle flow implementations, removing the start phase would mean changing BattleManager.startBattle to something like this:
    JavaScript:
    BattleManager.startBattle = function() {
        $gameSystem.onBattleStart();
        $gameParty.onBattleStart();
        $gameTroop.onBattleStart();
        this.displayStartMessages();
        this.startInput();
    };
    This will pose lots of issues which are too advanced to be explained in detail here(basically it'll break quite some battle flow invariants), but I'll still list some of them:
    1. The party command window can be setup when the battle start message's still displaying
    2. The battle events that should be called upon battle start can become never called at that timing
    So in short: This phase's needed to ensure the battle start message followed by the battle events that should be called upon battle start will indeed be processed right after the battle's prepared to start in a ready manner but right before the battle transits to the Action input Phase or the Action Execution Phase.

    Detailed Flow Reasoning
    Spoiler
    Consider the below detailed battle start flowchart(even though it still doesn't literally show all details):
    Default RMMV Battle Start.JPG
    Just reading the codes in BattleManager and Scene_Battle won't suffice, as you'd end up wondering where is BattleManager.setup called, even though you know it's called before calling BattleManager.startBattle, which is called by Scene_Battle.prototype.start:
    JavaScript:
    Scene_Battle.prototype.start = function() {
        Scene_Base.prototype.start.call(this);
        this.startFadeIn(this.fadeSpeed(), false);
        BattleManager.playBattleBgm();
        BattleManager.startBattle();
    };
    To really get what's going on ,you'd have to read the codes in Scene_Map and Game_Player as well, since battles can be started in Scene_Map having actor sprites controlled by Game_Player.
    Scene_Map.prototype.updateEncounter transits the scene into Scene_Battle if Game_Player.prototype.executeEncounter return true:
    JavaScript:
    Scene_Map.prototype.updateEncounter = function() {
       if ($gamePlayer.executeEncounter()) {
           SceneManager.push(Scene_Battle);
       }
    };
    Game_Player.prototype.executeEncounter calls BattleManager.setup and BattleManager.onEncounter if a battle can be triggered(this check itself is a separation of concern):
    JavaScript:
    Game_Player.prototype.executeEncounter = function() {
        if (!$gameMap.isEventRunning() && this._encounterCount <= 0) {
            this.makeEncounterCount();
            var troopId = this.makeEncounterTroopId();
            if ($dataTroops[troopId]) {
                BattleManager.setup(troopId, true, false);
                BattleManager.onEncounter();
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    };
    Code:
    BattleManager.onEncounter = function() {
        this._preemptive = (Math.random() < this.ratePreemptive());
        this._surprise = (Math.random() < this.rateSurprise() && !this._preemptive);
    };
    Note that BattleManager.setup must be called before calling BattleManager.onEncounter, otherwise what's set in the latter will be reinitialized by the former.

    SceneManager.push transits the scene to the one passed to it:
    JavaScript:
    SceneManager.push = function(sceneClass) {
        this._stack.push(this._scene.constructor);
        this.goto(sceneClass);
    };
    Going back to Scene_Map.prototype.updateEncounter, while goto appears as a keyword in at least some javascript editors, it's actually referring to SceneManager.goto:
    JavaScript:
    SceneManager.goto = function(sceneClass) {
        if (sceneClass) {
            this._nextScene = new sceneClass();
        }
        if (this._scene) {
            this._scene.stop();
        }
    };
    While Scene_Battle.prototype.createDisplayObjects just initializes all objects to be displayed in battle and has nothing to do with the battle flow, Scene_Battle.prototype.start calls BattleManager.startBattle.
    Note that BattleManager.setup must be called before calling Scene_Battle.prototype.start. It's because:
    1. The init phase always comes before the start phase.
    2. BattleManager.setup changes the battle to the init phase.
    3. BattleManager.startBattle changes the battle to the start phase.
    4. Scene_Battle.prototype.start calls BattleManager.startBattle.
    Also, it should be crystal clear and obvious that Scene_Battle.prototype.start can only be called after the battle's prepared to be started in a ready manner.

    Combining all the aforementioned parts, the battle start sequence is this:
    1. When Scene_Map.prototype.updateEncounter calls Game_Player.prototype.executeEncounter, BattleManager.setup, which calls BattleManager.initMembers, is called, followed by calling BattleManager.onEncounter.
    2. When Game_Player.prototype.executeEncounter return true, Scene_Battle.prototype.start, which calls BattleManager.startBattle, is called.
    3. When BattleManager.displayStartMessages is called by BattleManager.startBattle, the battle start message's displayed, causing BattleManager.isBusy to return true.
    4. When the battle start message's gone, all battle events that should be run upon battle start will be triggered by BattleManager.updateEvent.
    5. When all battle events that should be run are completely processed, BattleManager.startInput, which transits the battle phase to the Action Input Phase if the battle doesn't start with surprise and there are inputable actors, and Action Execution Phase when otherwise, will be called.
    P.S.: The battle can also be started via battle test and event commands.

    Scene_Boot.prototype.start starts the battle test if DataManager.isBattleTest returns true:
    JavaScript:
    Scene_Boot.prototype.start = function() {
        Scene_Base.prototype.start.call(this);
        SoundManager.preloadImportantSounds();
        if (DataManager.isBattleTest()) {
            DataManager.setupBattleTest();
            SceneManager.goto(Scene_Battle);
        } else if (DataManager.isEventTest()) {
            DataManager.setupEventTest();
            SceneManager.goto(Scene_Map);
        } else {
            this.checkPlayerLocation();
            DataManager.setupNewGame();
            SceneManager.goto(Scene_Title);
            Window_TitleCommand.initCommandPosition();
        }
        this.updateDocumentTitle();
    };
    Game_Interpreter.prototype.command301 starts the battle as instructed by the event command:
    JavaScript:
    // Battle Processing
    Game_Interpreter.prototype.command301 = function() {
        if (!$gameParty.inBattle()) {
            var troopId;
            if (this._params[0] === 0) {  // Direct designation
                troopId = this._params[1];
            } else if (this._params[0] === 1) {  // Designation with a variable
                troopId = $gameVariables.value(this._params[1]);
            } else {  // Same as Random Encounter
                troopId = $gamePlayer.makeEncounterTroopId();
            }
            if ($dataTroops[troopId]) {
                BattleManager.setup(troopId, this._params[2], this._params[3]);
                BattleManager.setEventCallback(function(n) {
                    this._branch[this._indent] = n;
                }.bind(this));
                $gamePlayer.makeEncounterCount();
                SceneManager.push(Scene_Battle);
            }
        }
        return true;
    };
    The rest are basically the same as starting battle via Scene_Map and Game_Player.

    Summary
    Spoiler
    The battle start consists of 2 phases:
    1. init - The battle's preparing to become ready to start
    2. start - The battle's prepared to start in a ready manner
    The init phase always comes right before the start phase.

    The battle start seuqence is this:
    1. When Scene_Map.prototype.updateEncounter calls Game_Player.prototype.executeEncounter, BattleManager.setup, which calls BattleManager.initMembers, is called, followed by calling BattleManager.onEncounter.
    2. When Game_Player.prototype.executeEncounter return true, Scene_Battle.prototype.start, which calls BattleManager.startBattle, is called.
    3. When BattleManager.displayStartMessages is called by BattleManager.startBattle, the battle start message's displayed, causing BattleManager.isBusy to return true.
    4. When the battle start message's gone, all battle events that should be run upon battle start will be triggered by BattleManager.updateEvent.
    5. When all battle events that should be run are completely processed, BattleManager.startInput, which transits the battle phase to the Action Input Phase if the battle doesn't start with surprise and there are inputable actors, and Action Execution Phase when otherwise, will be called.
    Step 1 and 2 will be noticeably different if the battle's a battle test or started via event commands instead.
  6. This tutorial is really well made.


    You should be paid for this (seriously).


    To do this out of passion and helping others is an amazing feat.
  7. Now let's talk about III. Action Input Phase in detail.

    Input Phase
    Spoiler
    Recall that the input phase is the Action Input Phase.

    Transitions

    BattleManager.startInput transits the battle into the input phase:
    JavaScript:
    BattleManager.startInput = function() {
        this._phase = 'input';
        $gameParty.makeActions();
        $gameTroop.makeActions();
        this.clearActor();
        if (this._surprise || !$gameParty.canInput()) {
            this.startTurn();
        }
    };
    Note that:
    - Every battler will create new empty action slots here.
    - BattleManager.clearactor is to ensure the party command window will be setup first:
    JavaScript:
    BattleManager.clearActor = function() {
        this.changeActor(-1, '');
    };
    - The battle phase will be transited into turn if the battle's just started with surprise and/or there are no inputable actors.

    Recall that the only things that can happen during the Action Input Phase are triggering a party escape attempt and inputting actions are inputable actors.

    If the party escape attempt succeeded, the battle phase will transit to battle end; If the party escape attempt failed, the battle phase will transit to turn. These will be shown in Party Escape.
    Also, right after inputting all action slots for all inputable actors, the battle phase will transit to turn as well. This will be shown in Actor Command Window.

    Phase checks
    BattleManager.isInputting checks if the battle phase's input:
    JavaScript:
    BattleManager.isInputting = function() {
        return this._phase === 'input';
    };
    Note that it's the same as checking if there are active inputable windows, which is checked by Scene_Battle.prototype.isAnyInputWindowActive:
    JavaScript:
    Scene_Battle.prototype.isAnyInputWindowActive = function() {
        return (this._partyCommandWindow.active ||
                this._actorCommandWindow.active ||
                this._skillWindow.active ||
                this._itemWindow.active ||
                this._actorWindow.active ||
                this._enemyWindow.active);
    };
    The reasons for this are already mentioned in I. Battle Frame Update.

    Party Command Window
    Spoiler
    Setting up the window
    Recall that Scene_Battle.prototype.changeInputWindow calls Scene_Battle.prototype.startPartyCommandSelection when the battle phase's input with no actor's selected:
    JavaScript:
    Scene_Battle.prototype.changeInputWindow = function() {
        if (BattleManager.isInputting()) {
            if (BattleManager.actor()) {
                this.startActorCommandSelection();
            } else {
                this.startPartyCommandSelection();
            }
        } else {
            this.endCommandSelection();
        }
    };
    It's because BattleManager.actor returns the currently selected actor:
    JavaScript:
    BattleManager.actor = function() {
        return this._actorIndex >= 0 ? $gameParty.members()[this._actorIndex] : null;
    };
    Actor Command Window will show how BattleManager._actorIndex is used.

    Scene_Battle.prototype.startPartyCommandSelection deselects the status window, closes the actor command window and setups the party command window:
    JavaScript:
    Scene_Battle.prototype.startPartyCommandSelection = function() {
        this.refreshStatus();
        this._statusWindow.deselect();
        this._statusWindow.open();
        this._actorCommandWindow.close();
        this._partyCommandWindow.setup();
    };
    Note that opening the status window here is just to play safe, and the rest are irrelevant to the battle flow.
    Window_PartyCommand.prototype.setup first clears the old and makes the new command list. then activates and opens the party command window with the 1st command's selected:
    JavaScript:
    Window_PartyCommand.prototype.setup = function() {
        this.clearCommandList();
        this.makeCommandList();
        this.refresh();
        this.select(0);
        this.activate();
        this.open();
    };
    Window_PartyCommand.prototype.makeCommandList adds the fight and escape command, with the latter's enabled status depending on whether the battle allows party escapes:
    JavaScript:
    Window_PartyCommand.prototype.makeCommandList = function() {
        this.addCommand(TextManager.fight,  'fight');
        this.addCommand(TextManager.escape, 'escape', BattleManager.canEscape());
    };
    Window_Command.prototype.addCommand adds a command in the command list:
    JavaScript:
    Window_Command.prototype.addCommand = function(name, symbol, enabled, ext) {
        if (enabled === undefined) {
            enabled = true;
        }
        if (ext === undefined) {
            ext = null;
        }
        this._list.push({ name: name, symbol: symbol, enabled: enabled, ext: ext});
    };
    Going back to Scene_Battle, Scene_Battle.prototype.commandFight and Scene_Battle.prototype.commandEscape handles the party command window fight and escape commands respectively:
    JavaScript:
    Scene_Battle.prototype.commandFight = function() {
        this.selectNextCommand();
    };
    JavaScript:
    Scene_Battle.prototype.commandEscape = function() {
        BattleManager.processEscape();
        this.changeInputWindow();
    };
    The contents of the former will be explained in Actor Command Window and those of the latter will be explained in Party Escape.

    Handlers and callbacks
    You might wonder how they're called, as you won't find anything if you search this.commandFight() and/or this.commandEscape() in rpg_scenes.js.
    Actually, they're party command window handlers(It's so vital in the default RMMV battle flow that you're highly encouraged and recommended to have a solid understanding on this before moving on) that are set in Scene_Battle.prototype.createPartyCommandWindow:
    JavaScript:
    Scene_Battle.prototype.createPartyCommandWindow = function() {
        this._partyCommandWindow = new Window_PartyCommand();
        this._partyCommandWindow.setHandler('fight',  this.commandFight.bind(this));
        this._partyCommandWindow.setHandler('escape', this.commandEscape.bind(this));
        this._partyCommandWindow.deselect();
        this.addWindow(this._partyCommandWindow);
    };

    Window_Selectable.prototype.setHandler registers the handler symbol with its corresponding callback(It's so vital in the default RMMV battle flow that you're highly encouraged and recommended to have a solid understanding on this before moving on):
    JavaScript:
    Window_Selectable.prototype.setHandler = function(symbol, method) {
        this._handlers[symbol] = method;
    };
    All the registered handlers will be called in Window_Selectable.prototype.callHandler:
    JavaScript:
    Window_Selectable.prototype.callHandler = function(symbol) {
        if (this.isHandled(symbol)) {
            this._handlers[symbol]();
        }
    };

    Triggering a handler callback
    Recall that:
    On the user level, triggering the fight/escape command in the party command window is done by pressing the ok key.
    Window_PartyCommand is inherited from Window_Command, which is inherited from Window_Selectable.

    The below will show what happens under the hood when players select a command via pointing the cursor to it and triggers that command via pressing the ok key:

    Window_Selectable.prototype.update, which is called per frame, calls Window_Selectable.prototype.processHandling:
    JavaScript:
    Window_Selectable.prototype.processHandling = function() {
        if (this.isOpenAndActive()) {
            if (this.isOkEnabled() && this.isOkTriggered()) {
                this.processOk();
            } else if (this.isCancelEnabled() && this.isCancelTriggered()) {
                this.processCancel();
            } else if (this.isHandled('pagedown') && Input.isTriggered('pagedown')) {
                this.processPagedown();
            } else if (this.isHandled('pageup') && Input.isTriggered('pageup')) {
                this.processPageup();
            }
        }
    };
    While Window_Command.prototype.isOkEnabled always returns true, Window_ShopNumber.prototype.isOkTriggered checks if the ok key changes from not being pressed from being pressed(edge-triggered):
    JavaScript:
    Window_ShopNumber.prototype.isOkTriggered = function() {
        return Input.isTriggered('ok');
    };
    Note that now Input works is a separation of concern.

    Pressing the ok key is handled by Window_Selectable.prototype.processOk:
    JavaScript:
    Window_Selectable.prototype.processOk = function() {
        if (this.isCurrentItemEnabled()) {
            this.playOkSound();
            this.updateInputData();
            this.deactivate();
            this.callOkHandler();
        } else {
            this.playBuzzerSound();
        }
    };
    Window_Command.prototype.isCurrentItemEnabled checks if the currently selected command's enabled:
    JavaScript:
    Window_Command.prototype.isCurrentItemEnabled = function() {
        return this.currentData() ? this.currentData().enabled : false;
    };
    Window_Command.prototype.currentData returns the data of the currently selected command:
    JavaScript:
    Window_Command.prototype.currentData = function() {
        return this.index() >= 0 ? this._list[this.index()] : null;
    };
    Window_Command.prototype.callOkHandler calls the handler callback using the handler symbol of the currently selected command:
    JavaScript:
    Window_Command.prototype.callOkHandler = function() {
        var symbol = this.currentSymbol();
        if (this.isHandled(symbol)) {
            this.callHandler(symbol);
        } else if (this.isHandled('ok')) {
            Window_Selectable.prototype.callOkHandler.call(this);
        } else {
            this.activate();
        }
    };
    Note that the rest are irrelevant to the default RMMV battle flow.
    Window_Command.prototype.currentSymbol returns the handler symbol of the currently selected command:
    JavaScript:
    Window_Command.prototype.currentSymbol = function() {
        return this.currentData() ? this.currentData().symbol : null;
    };

    Party Escape
    Spoiler
    Triggering escapes
    Recall that Scene_Battle.prototype.commandEscape handles the escape command in the party command window:
    JavaScript:
    Scene_Battle.prototype.commandEscape = function() {
        BattleManager.processEscape();
        this.changeInputWindow();
    };
    Note that calling Scene_Battle.prototype.changeInputWindow here is just to play safe.

    BattleManager.processEscape aborts the battle if the party escape attempt's succeeded and transits the battle phase into Action Execution Phase if that's not the case:
    JavaScript:
    BattleManager.processEscape = function() {
        $gameParty.removeBattleStates();
        $gameParty.performEscape();
        SoundManager.playEscape();
        var success = this._preemptive ? true : (Math.random() < this._escapeRatio);
        if (success) {
            this.displayEscapeSuccessMessage();
            this._escaped = true;
            this.processAbort();
        } else {
            this.displayEscapeFailureMessage();
            this._escapeRatio += 0.1;
            $gameParty.clearActions();
            this.startTurn();
        }
        return success;
    };
    Note that:
    - The latest version of this function doesn't have $gameParty.removeBattleStates() which is clearly a bug to be included here, but as it was still there when I just finished drawing the detailed flowchart for the Action Input Phase, I'll still stick to that old version.
    - The use of BattleManager._escaped will be covered in V. Battle End.

    Battle phase transitions
    BattleManager.processAbort aborts the battle by changing the battle phase to battle end(its details will be covered in V. Battle End):
    JavaScript:
    BattleManager.processAbort = function() {
        this.replayBgmAndBgs();
        this.endBattle(1);
    };
    BattleManager.startTurn transits the battle phase into the Action Execution Phase(its details will be covered in IV. Action Execution Phase):
    JavaScript:
    BattleManager.startTurn = function() {
        this._phase = 'turn';
        this.clearActor();
        $gameTroop.increaseTurn();
        this.makeActionOrders();
        $gameParty.requestMotionRefresh();
        this._logWindow.startTurn();
    };

    Actor Command Window
    Spoiler
    Setting up the window
    Recall that Scene_Battle.prototype.changeInputWindow calls Scene_Battle.prototype.startActorCommandSelection when an actor's selected for inputting actions:
    JavaScript:
    Scene_Battle.prototype.changeInputWindow = function() {
        if (BattleManager.isInputting()) {
            if (BattleManager.actor()) {
                this.startActorCommandSelection();
            } else {
                this.startPartyCommandSelection();
            }
        } else {
            this.endCommandSelection();
        }
    };
    Scene_Battle.prototype.startActorCommandSelection selects the actor selected by BattleManager in the status window, closes the party command window and setups the actor command window for that actor:
    JavaScript:
    Scene_Battle.prototype.startActorCommandSelection = function() {
        this._statusWindow.select(BattleManager.actor().index());
        this._partyCommandWindow.close();
        this._actorCommandWindow.setup(BattleManager.actor());
    };

    Window_ActorCommand.prototype.setup marks the currently selected actor, clears the old and makes the new commands, selects the lastly selected one, and activates and opens the actor command window:
    JavaScript:
    Window_ActorCommand.prototype.setup = function(actor) {
        this._actor = actor;
        this.clearCommandList();
        this.makeCommandList();
        this.refresh();
        this.selectLast();
        this.activate();
        this.open();
    };
    Window_ActorCommand.prototype.makeCommandList makes all the command list consisting of all command available to the actor:
    JavaScript:
    Window_ActorCommand.prototype.makeCommandList = function() {
        if (this._actor) {
            this.addAttackCommand();
            this.addSkillCommands();
            this.addGuardCommand();
            this.addItemCommand();
        }
    };
    JavaScript:
    Window_ActorCommand.prototype.addAttackCommand = function() {
        this.addCommand(TextManager.attack, 'attack', this._actor.canAttack());
    };
    JavaScript:
    Window_ActorCommand.prototype.addSkillCommands = function() {
        var skillTypes = this._actor.addedSkillTypes();
        skillTypes.sort(function(a, b) {
            return a - b;
        });
        skillTypes.forEach(function(stypeId) {
            var name = $dataSystem.skillTypes[stypeId];
            this.addCommand(name, 'skill', true, stypeId);
        }, this);
    };
    JavaScript:
    Window_ActorCommand.prototype.addGuardCommand = function() {
        this.addCommand(TextManager.guard, 'guard', this._actor.canGuard());
    };
    JavaScript:
    Window_ActorCommand.prototype.addItemCommand = function() {
        this.addCommand(TextManager.item, 'item');
    };
    While the details of these functions are separation of concerns, these commands themselves are the key for players to trigger commands on the actor command window.

    Handlers and callbacks
    Similar to the party command window, Scene_Battle.prototype.createActorCommandWindow sets a handler for each of its commands:
    JavaScript:
    Scene_Battle.prototype.createActorCommandWindow = function() {
        this._actorCommandWindow = new Window_ActorCommand();
        this._actorCommandWindow.setHandler('attack', this.commandAttack.bind(this));
        this._actorCommandWindow.setHandler('skill',  this.commandSkill.bind(this));
        this._actorCommandWindow.setHandler('guard',  this.commandGuard.bind(this));
        this._actorCommandWindow.setHandler('item',   this.commandItem.bind(this));
        this._actorCommandWindow.setHandler('cancel', this.selectPreviousCommand.bind(this));
        this.addWindow(this._actorCommandWindow);
    };
    The below are all callbacks handling their respective commands on the actor command window:
    JavaScript:
    Scene_Battle.prototype.commandAttack = function() {
        BattleManager.inputtingAction().setAttack();
        this.selectEnemySelection();
    };
    JavaScript:
    Scene_Battle.prototype.commandSkill = function() {
        this._skillWindow.setActor(BattleManager.actor());
        this._skillWindow.setStypeId(this._actorCommandWindow.currentExt());
        this._skillWindow.refresh();
        this._skillWindow.show();
        this._skillWindow.activate();
    };
    JavaScript:
    Scene_Battle.prototype.commandGuard = function() {
        BattleManager.inputtingAction().setGuard();
        this.selectNextCommand();
    };
    JavaScript:
    Scene_Battle.prototype.commandItem = function() {
        this._itemWindow.refresh();
        this._itemWindow.show();
        this._itemWindow.activate();
    };
    Code:
    Scene_Battle.prototype.selectPreviousCommand = function() {
        BattleManager.selectPreviousCommand();
        this.changeInputWindow();
    };

    Action Input Sequence
    While how the action slots are actually inputted are separations of concerns, it's still important to know how the Next Command and Prior Command are called.
    Recall that inputting an action slot means selecting a skill/item(if it needs to be selected) followed by selecting targets using the target scope provided by the selected skill/item(if they need to be selected).
    Note that similar to the party command window and actor command window, the skill/item/actor/enemy selection windows also have handlers invoking callbacks which are registered upon creating these windows.


    The below functions confirms and cancels the skill/item selection:
    JavaScript:
    Scene_Battle.prototype.onSkillOk = function() {
        var skill = this._skillWindow.item();
        var action = BattleManager.inputtingAction();
        action.setSkill(skill.id);
        BattleManager.actor().setLastBattleSkill(skill);
        this.onSelectAction();
    };
    JavaScript:
    Scene_Battle.prototype.onSkillCancel = function() {
        this._skillWindow.hide();
        this._actorCommandWindow.activate();
    };
    JavaScript:
    Scene_Battle.prototype.onItemOk = function() {
        var item = this._itemWindow.item();
        var action = BattleManager.inputtingAction();
        action.setItem(item.id);
        $gameParty.setLastItem(item);
        this.onSelectAction();
    };
    JavaScript:
    Scene_Battle.prototype.onItemCancel = function() {
        this._itemWindow.hide();
        this._actorCommandWindow.activate();
    };

    The below functions transits the selections from selecting skills/items to selecting targets:
    Code:
    Scene_Battle.prototype.selectActorSelection = function() {
        this._actorWindow.refresh();
        this._actorWindow.show();
        this._actorWindow.activate();
    };
    Code:
    Scene_Battle.prototype.selectEnemySelection = function() {
        this._enemyWindow.refresh();
        this._enemyWindow.show();
        this._enemyWindow.select(0);
        this._enemyWindow.activate();
    };

    The below functions confirms and cancels the target selection:
    JavaScript:
    Scene_Battle.prototype.onActorOk = function() {
        var action = BattleManager.inputtingAction();
        action.setTarget(this._actorWindow.index());
        this._actorWindow.hide();
        this._skillWindow.hide();
        this._itemWindow.hide();
        this.selectNextCommand();
    };
    JavaScript:
    Scene_Battle.prototype.onActorCancel = function() {
        this._actorWindow.hide();
        switch (this._actorCommandWindow.currentSymbol()) {
        case 'skill':
            this._skillWindow.show();
            this._skillWindow.activate();
            break;
        case 'item':
            this._itemWindow.show();
            this._itemWindow.activate();
            break;
        }
    };
    Code:
    Scene_Battle.prototype.onEnemyOk = function() {
        var action = BattleManager.inputtingAction();
        action.setTarget(this._enemyWindow.enemyIndex());
        this._enemyWindow.hide();
        this._skillWindow.hide();
        this._itemWindow.hide();
        this.selectNextCommand();
    };
    Code:
    Scene_Battle.prototype.onEnemyCancel = function() {
        this._enemyWindow.hide();
        switch (this._actorCommandWindow.currentSymbol()) {
        case 'attack':
            this._actorCommandWindow.activate();
            break;
        case 'skill':
            this._skillWindow.show();
            this._skillWindow.activate();
            break;
        case 'item':
            this._itemWindow.show();
            this._itemWindow.activate();
            break;
        }
    };
    Note that the inputted skills/items will never be cleared upon going back from the target selection to the skill/item selection, so the only way to get rid of those inputted skills/items is to replace them with the newly inputted ones.

    Next Command
    Spoiler
    Scene_Battle.prototype.selectNextCommand calls BattleManager.selectNextCommand:
    JavaScript:
    Scene_Battle.prototype.selectNextCommand = function() {
        BattleManager.selectNextCommand();
        this.changeInputWindow();
    };
    Note that it also calls Scene_Battle.prototype.changeInputWindow, which calls Scene_Battle.prototype.startPartyCommandSelection when the battle's in the Action Input Phase and there are no actors to be selected for inputting actions. However, it's 100% crystal clear and obvious that Next Command certainly have absolutely no chance to setup the party command window at all, meaning that it's just outright impossible for Next Command to cause no actors to be selected for inputting actions in the Action Input Phase.
    BattleManager.selectNextCommand shows why:
    JavaScript:
    BattleManager.selectNextCommand = function() {
        do {
            if (!this.actor() || !this.actor().selectNextCommand()) {
                this.changeActor(this._actorIndex + 1, 'waiting');
                if (this._actorIndex >= $gameParty.size()) {
                    this.startTurn();
                    break;
                }
            }
        } while (!this.actor().canInput());
    };
    Note that BattleManager.changeActor changes the index of the actor to be selected for inputting actions:
    JavaScript:
    BattleManager.changeActor = function(newActorIndex, lastActorActionState) {
        var lastActor = this.actor();
        this._actorIndex = newActorIndex;
        var newActor = this.actor();
        if (lastActor) {
            lastActor.setActionState(lastActorActionState);
        }
        if (newActor) {
            newActor.setActionState('inputting');
        }
    };
    Game_Actor.prototype.selectNextCommand has to be explored as well in order to know what's really going on here:
    JavaScript:
    Game_Actor.prototype.selectNextCommand = function() {
        if (this._actionInputIndex < this.numActions() - 1) {
            this._actionInputIndex++;
            return true;
        } else {
            return false;
        }
    };

    Let's define Currently Inputting Action Pointer as the pointer pointing to the currently inputting action.
    Game_Actor.prototype.selectNextCommand basically tries to point the Currently Inputting Action Pointer to the next action of the actor, and returns whether such attempt's succeeded.
    Note that Game_Battler.prototype.numActions returns the number of action slots:
    JavaScript:
    Game_Battler.prototype.numActions = function() {
        return this._actions.length;
    };
    While Game_Actor.prototype._actionInputIndex indicates the index of the currently inputting action slots, as shown by Game_Actor.prototype.inputtingAction, which returns the currently inputting action;
    JavaScript:
    Game_Actor.prototype.inputtingAction = function() {
        return this.action(this._actionInputIndex);
    };

    Going back to BattleManager.selectNextCommand, it basically points the Currently Inputting Action Pointer to the next action of the same actor. If the actor has no more next actions, the Currently Inputting Action Pointer will point to the 1st action of the next inputable actor instead. If there are no next inputable actors, BattleManager.startTurn will be called to transit the battle phase to the Action Execution Phase instead.
    Therefore there's indeed no chance for Next Command to setup the party command window, as the battle will transit to the Action Execution Phase right after the BattleManager becomes selecting no actors for inputting actions, even before Scene_Battle.prototype.changeInputWindow is called. When it's called, the battle's already in the Action Execution Phase, so Scene_Battle.prototype.endCommandSelection will be called instead:

    JavaScript:
    Scene_Battle.prototype.endCommandSelection = function() {
        this._partyCommandWindow.close();
        this._actorCommandWindow.close();
        this._statusWindow.deselect();
    };

    Prior Command
    Spoiler
    Scene_Battle.prototype.selectPreviousCommand calls BattleManager.selectPriorCommand:
    JavaScript:
    Scene_Battle.prototype.selectPreviousCommand = function() {
        BattleManager.selectPreviousCommand();
        this.changeInputWindow();
    };
    Recall that Prior Command can eventually lead to setting up the party command window, which is called by Scene_Battle.prototype.changeInputWindow when the BattleManager becomes having no actors to be selected for inputting actions while the battle's still in the Action Input Phase.
    BattleManager.selectPreviousCommand shows how it's done:
    JavaScript:
    BattleManager.selectPreviousCommand = function() {
        do {
            if (!this.actor() || !this.actor().selectPreviousCommand()) {
                this.changeActor(this._actorIndex - 1, 'undecided');
                if (this._actorIndex < 0) {
                    return;
                }
            }
        } while (!this.actor().canInput());
    };
    Similar to Game_Actor.prototype.selectNextCommand, Game_Actor.prototype.selectPreviousCommand tries to point the Currently Inputting Action Pointer to the prior action of the actor, and returns whether such attempt's succeeded:
    JavaScript:
    Game_Actor.prototype.selectPreviousCommand = function() {
        if (this._actionInputIndex > 0) {
            this._actionInputIndex--;
            return true;
        } else {
            return false;
        }
    };
    So similar to BattleManager.selectNextCommand, BattleManager.selectPreviousCommand points the Currently Inputting Action Pointer to the prior action of the same actor. If the actor has no more prior actions, the Currently Inputting Action Pointer will point to the last action of the prior inputable actor instead. If there are no prior inputable actors, BattleManager.selectPreviousCommand will simply stop to let Scene_Battle.prototype.changeInputWindow setups the party command window instead.

    Detailed Flow Reasoning
    Spoiler
    Consider the below detailed battle start flowchart(even though it still doesn't literally show all details):
    Default RMMV Battle Action Input Phase.JPG

    BattleManager.startInput
    The Action Input Phase always starts with BattleManager.startInput, as it's the only timing transiting the battle phase to input.
    As this phase's to let battlers input actions, which needs new empty action slots to do so, those battlers will have to make new action slots upon the start of this phase.
    Also, in this phase, whether an actor command window or the party command window will be setup depends on whether there are actors selected for inputting actions. To ensure the latter will be setup first, BattleManager should be set to have no actors selected for inputting actions.
    Finally, if there are no inputable actors or the battle's just started with surprise, players won't be able to input actions for any actors, meaning players can't do anything in this phase. So in this case the battle will immediately transit to the Action Execution Phase instead.

    Scene_Battle.prototype.startPartyCommandSelection
    The party command window lets players either trigger a party escape attempt or input actions for inputable actors.
    Triggering a party escape attempt can either lead to a success or fail party escape attempt. The former means the end of the battle via transiting the battle phase to battle end, and the latter means the start of the Action Execution Phase without inputting actions for any inputable actor.
    Starting to input actions for inputable actors will point the Currently Inputting Action Pointer to the 1st action slot of the 1st inputable actor.

    Scene_Battle.prototype.startActorCommandSelection
    The actor command window lets players either input the action slot pointed by the Currently Inputting Action Pointer or press the cancel key, which will point the Currently Inputting Action Pointer to the prior action slot of the same actor or the last action slot of the prior inputable actor(the actor command window of that prior inputable actor will be setup in this case), or setups the party command window.
    Finishing inputting the action slot pointed by the Currently Inputting Action Pointer will point the Currently Inputting Action Pointer to the next action slot of the same actor or the 1st action slot of the next inputable actor(the actor command window of that next inputable actor will be setup in this case), or transit the battle to the Action Execution Phase.

    Doubly Linked List
    If you already have a solid understanding on doubly linked list(It's so vital in the default RMMV battle flow that you're highly encouraged and recommended to have a solid understanding on this before moving on), you might realize that the navigation between Scene_Battle.prototype.startPartyCommandSelection and BattleManager.startTurn is implemented by a special kind of doubly linked list. Specifically:
    1. The doubly linked list's created by all action slots of all inputable actors via calling $gameParty.makeActions() which is called by BattleManager.startInput
    2. The head pointer is Scene_Battle.prototype.commandFight while there's no tail pointer
    3. The head and tail sentinel nodes are Scene_Battle.prototype.startPartyCommandSelection and BattleManager.startTurn respectively, with the former having another pointer pointing to Scene_Battle.prototype.commandEscape
    4. The next and prior pointers for each node are Scene_Battle.prototype.selectNextCommand and Scene_Battle.prototype.selectPreviousCommand respectively
    5. The current pointer is the Currently Inputting Action Pointer
    6. The head and tail nodes are the 1st action slot of the 1st inputable actor and the last action slot of the last inputable actor respectively
    7. The current node is the action slot pointed by the Currently Inputting Action Pointer
    8. Nagivating from the current node to the next pointer of that node must be done by finishing inputting the current node

    The simplified battle flowchart might help you visualize this doubly linked list:
    Simplified Default RMMV Battle Flow.JPG
    Also, recall that the Action Input Phase starts by setting up the party command window and ends by finishing inputting the last action slot of the last inputable actor.
    It means that the Action Input Phase's essentially about the traversal of the aforementioned doubly linked list, and the only ways to escape this doubly linked list are to reach the pointer pointing to triggering party escape attempts via the head sentinel node, and to reach the tail sentinel node, which must be done by traserving from the head sentinel node through all the nodes in between. As the only way to traverse from the current node to the next node is to finish inputting the action slot represented by that node, navigating to a node always means all the previous ones must be already completely inputted, which implies that reaching the tail sentinel node automatically guarantees that all action slots of all inputable actors are already completely inputted.

    Summary
    Spoiler
    The input phase is the Action Input Phase, with its checking equivalent to checking whether there are active inputable windows, as the only things that can happen during this phase is to trigger a party escape attempt which always transit the battle to batlte end upon success and Action Execution Phase upon failure, and input actions for all inputable actors.
    Action Input Phase always starts by making actions for all battlers and setting up the party command window, and ends by finishing inputting the last action slot of the last inputable actor.

    The nagivation between these ends are bridged by a special doubly linked list with the below specifics:
    1. The doubly linked list's created by making all new empty action slots for all actors(only those of inputable ones matter here) upon the start of the Action Input Phase
    2. The head pointer is the fight command in the party command window while there's no tail pointer
    3. The head and tail sentinel nodes are setting up the party command window(with another pointer pointing to triggering party escape attempts) and transiting the battle phase to the Action Execution Phase
    4. The next and prior pointers for each node are Next Command and Prior Command respectively
    5. The current pointer is the Currently Inputting Action Pointer, which always points to the currently inputting action
    6. The head and tail nodes are the 1st action slot of the 1st inputable actor and the last action slot of the last inputable actor respectively
    7. The current node is the action slot pointed by the Currently Inputting Action Pointer
    8. Nagivating from the current node to the next pointer of that node must be done by finishing inputting the current node

    Inputting the current code means selecting the skill/item followed by selecting targets using the scope of the selected skill/item. These inputted skills/items can never be cleared but only be replaced by newly inputted ones.
    All commands in the party command window and actor command window are processed by handlers using callbacks, which are registered upon creating those windows and invoked upon receiving the corresponding player inputs.

    Next Command, which should never setup a party command window, works by pointing the Currently Inputting Action Pointer to the next action slot of the current actor. If there's no such action slot, the Currently Inputting Action Pointer will point to the 1st action slot of the next inputable actor instead. If there's no such actor, the battle phase will immediately transit to the Action Execution Phase instead.
    Similarly, Prior Command works by pointing the Currently Inputting Action Pointer to the prior action slot of the current actor. If there's no such action slot, the Currently Inputting Action Pointer will point to the last action slot of the prior inputable actor instead. If there's no such actor, the party command window will be setup instead.
    The only 2 ways to escape the doubly linked list are to trigger a party escape attempt in the party command window, and finish inputting the last action slot of the last inputable actor, which must be done by traversing all action slots of all inputable actors in between. As the only way to traverse from the current action slot to the next action slot is to finish inputting the current one, navigating to a action slot always means all the previous ones must be already completely inputted, which implies that all action slots of all inputable actors must be completely inputted right after finishing inputting the last action slot of the last inputable actor.
  8. You should be paid for this and do tutorials for all the systems in MV.


    You really should.. 
  9. AwesomeCool said:
    You should be paid for this and do tutorials for all the systems in MV.


    You really should.. 

    Unfortunately, so far I've been concentrating on battle related plugins, so I only know very little on aspects having nothing to do with battles :)
  10. Now let's talk about IV. Action Execution Phase in detail.

    Turn Phase
    Spoiler
    Recall that this phase is the Setting Up Action Execution Subjects part of the Action Execution Phase.

    Transitions

    BattleManager.startTurn transits the battle phase into turn:
    JavaScript:
    BattleManager.startTurn = function() {
        this._phase = 'turn';
        this.clearActor();
        $gameTroop.increaseTurn();
        this.makeActionOrders();
        $gameParty.requestMotionRefresh();
        this._logWindow.startTurn();
    };
    Note that:
    - This transition itself is Turn Start
    - Calling BattleManager.clearActor here is to reset the pose and position of the sprite of the last inputable actor(Check III. Action Input Phase for details)
    - Game_Troop.prototype.increaseTurn lets battle events with span as turn to be possible to be run right now, then increases the battle turn count by 1(how this function works is a separation of concern)

    BattleManager.makeActionOrders makes the Action Order Queue(queue is so vital in the RMMV battle flow that you're highly encouraged and recommended to have a solid understanding on it before moving on):
    JavaScript:
    BattleManager.makeActionOrders = function() {
        var battlers = [];
        if (!this._surprise) {
            battlers = battlers.concat($gameParty.members());
        }
        if (!this._preemptive) {
            battlers = battlers.concat($gameTroop.members());
        }
        battlers.forEach(function(battler) {
            battler.makeSpeed();
        });
        battlers.sort(function(a, b) {
            return b.speed() - a.speed();
        });
        this._actionBattlers = battlers;
    };
    Note that:
    - Upon battle start with preemptive and surprise, enemies and actors won't be included in the Action Order Queue respectively
    - While Game_Battler.prototype.makeSpeed and Game_Battler.prototype.speed are separation of concerns, the fact that the faster battlers are on the more up front in the Action Order Queue is still important to the RMMV battle flow
    On the other hand, BattleManager.startAction(covered in Action Phase) and BattleManager.endTurn(covered in Turn End Phase) transits the battle to the Executing Actions part of the Action Execution Phase, and Turn End Phase respectively.

    Setting Up Action Execution Subject
    BattleManager.updateTurn, which is called by BattleManager.update, tries to setup a new Action Execution Subject if there's none, then process actions of the Action Execution Subject if the attempt succeeded and ends the turn otherwise:
    JavaScript:
    BattleManager.updateTurn = function() {
        $gameParty.requestMotionRefresh();
        if (!this._subject) {
            this._subject = this.getNextSubject();
        }
        if (this._subject) {
            this.processTurn();
        } else {
            this.endTurn();
        }
    };
    Note that BattleManager.endTurn will be covered in Turn End Phase.
    BattleManager.getNextSubject returns the most up front battler in the Action Order Queue and removes that battler from it:
    JavaScript:
    BattleManager.getNextSubject = function() {
        for (;;) {
            var battler = this._actionBattlers.shift();
            if (!battler) {
                return null;
            }
            if (battler.isBattleMember() && battler.isAlive()) {
                return battler;
            }
        }
    };
    Note that only alive battlers can be the Action Execution Subject.

    BattleManager.processTurn tries to start executing the current action of the Action Execution Subject, or processes ending all action executions of the Action Execution Subject when the he/she/it's no more actions to execute:
    JavaScript:
    BattleManager.processTurn = function() {
        var subject = this._subject;
        var action = subject.currentAction();
        if (action) {
            action.prepare();
            if (action.isValid()) {
                this.startAction();
            }
            subject.removeCurrentAction();
        } else {
            subject.onAllActionsEnd();
            this.refreshStatus();
            this._logWindow.displayAutoAffectedStatus(subject);
            this._logWindow.displayCurrentState(subject);
            this._logWindow.displayRegeneration(subject);
            this._subject = this.getNextSubject();
        }
    };
    Note that:
    - Game_Action.prototype.isValid, Game_Action.prototype.prepare and Game_Battler.prototype.onAllActionsEnd are separation of concerns
    - BattleManager.startAction will be covered in Action Phase
    In short, the list of valid actions of a battler is actually the Action Execution Queue when that battler becomes the Action Execution Subject, as the ith inputted valid action in that list is supposed to be the ith one being executed, meaning the execution sequence of actions in that list is FIFO.

    Action Phase
    Spoiler
    Recall that this phase is the Executing Actions part of the Action Execution Phase.

    Transitions
    BattleManager.startAction transits the battle phase into action:
    JavaScript:
    BattleManager.startAction = function() {
        var subject = this._subject;
        var action = subject.currentAction();
        var targets = action.makeTargets();
        this._phase = 'action';
        this._action = action;
        this._targets = targets;
        subject.useItem(action.item());
        this._action.applyGlobal();
        this.refreshStatus();
        this._logWindow.startAction(subject, action, targets);
    };
    Note that:
    - While how Game_Action.prototype.makeTargets works is a separation of concern, the fact that it creates the Action Target Queue of the Currently Executing Action is still important to the RMMV battle flow
    - Calling Window_BattleLog.prototype.startAction here is vital to ensure the action start message will be displayed before actually executing the action
    On the other hand, BattleManager.endAction transits the battle phase into turn:
    JavaScript:
    BattleManager.endAction = function() {
        this._logWindow.endAction(this._subject);
        this._phase = 'turn';
    };
    Note that Window_BattleLog.prototype.performActionEnd is to reset the pose and position of the sprite of the Action Execution Subject.

    Executing Actions
    BattleManager.updateAction, which is called by BattleManager.update, tries to invoke the Currently Executing Action to the most up front battler in the Action Target Queue, or ends the Currently Executing Action if there are no more targets:
    JavaScript:
    BattleManager.updateAction = function() {
        var target = this._targets.shift();
        if (target) {
            this.invokeAction(this._subject, target);
        } else {
            this.endAction();
        }
    };
    While BattleManager.invokeAction is mostly about damage flow, which is a separation of concern, it also involves the coordination between actually applying the action to the target and displaying the action results in the battle log window:
    JavaScript:
    BattleManager.invokeAction = function(subject, target) {
        this._logWindow.push('pushBaseLine');
        if (Math.random() < this._action.itemCnt(target)) {
            this.invokeCounterAttack(subject, target);
        } else if (Math.random() < this._action.itemMrf(target)) {
            this.invokeMagicReflection(subject, target);
        } else {
            this.invokeNormalAction(subject, target);
        }
        subject.setLastTarget(target);
        this._logWindow.push('popBaseLine');
        this.refreshStatus();
    };

    The same applies to BattleManager.invokeNormalAction, BattleManager.invokeCounterAttack and BattleManager.invokeMagicReflection:
    JavaScript:
    BattleManager.invokeNormalAction = function(subject, target) {
        var realTarget = this.applySubstitute(target);
        this._action.apply(realTarget);
        this._logWindow.displayActionResults(subject, realTarget);
    };
    JavaScript:
    BattleManager.invokeCounterAttack = function(subject, target) {
        var action = new Game_Action(target);
        action.setAttack();
        action.apply(subject);
        this._logWindow.displayCounter(target);
        this._logWindow.displayActionResults(subject, subject);
    };
    JavaScript:
    BattleManager.invokeMagicReflection = function(subject, target) {
        this._logWindow.displayReflection(target);
        this._action.apply(subject);
        this._logWindow.displayActionResults(subject, subject);
    };
    The aforementioned coordination is done by calling Window_BattleLog.prototype.displayActionResults right after calling Game_Action.prototype.apply(explained in Detailed Flow Reasoning).

    Turn End Phase
    Spoiler
    Recall that this phase's the Turn End Phase, which is the transition from the Action Execution Phase to the Action input Phase.

    Transitions

    BattleManager.endTurn transits the battle phase into turn end:
    JavaScript:
    BattleManager.endTurn = function() {
        this._phase = 'turnEnd';
        this._preemptive = false;
        this._surprise = false;
        this.allBattleMembers().forEach(function(battler) {
            battler.onTurnEnd();
            this.refreshStatus();
            this._logWindow.displayAutoAffectedStatus(battler);
            this._logWindow.displayRegeneration(battler);
        }, this);
    };
    Note that:
    - Both BattleManager.preemptive and BattleManager._surprise are reset as false here to ensure no battler will be missed when making the Action Order Queue in the next turn due to the battle being started with preemptive and surprise respectively, as those flag should only be effective on the 1st turn.
    - Calling Window_BattleLog.prototype.displayAutoAffectedStatus and Window_BattleLog.prototype.displayRegeneration here are to ensure the auto affected statuses and regenerations will be completely displayed before the start of the next Action Input Phase.
    On the other hand, BattleManager.updateTurnEnd, which is called by BattleManager.update, transits the battle phase into the Action Input Phase:
    JavaScript:
    BattleManager.updateTurnEnd = function() {
        this.startInput();
    };

    Why this phase's needed
    Without this phase, BattleManager.endTurn would be something like this if the other parts of the default RMMV battle flow remains intact:
    JavaScript:
    BattleManager.endTurn = function() {
        this._preemptive = false;
        this._surprise = false;
        this.allBattleMembers().forEach(function(battler) {
            battler.onTurnEnd();
            this.refreshStatus();
            this._logWindow.displayAutoAffectedStatus(battler);
            this._logWindow.displayRegeneration(battler);
        }, this);
        this.startInput();
    };
    Recall that BattleManager.startInput will cause the party command window to be setup unless there are no inputable actors, meaning the next frame could no longer reach BattleManager.update(Check I. Battle Frame Update for details). It'd mean players can trigger a party escape attempt or input actions for inputable actors even before the auto affected status and regenerations are completed displayed, which can lead to nontrivial bugs, like some displayed information not being updated quickly enough, effectively giving players outdated information(explained in Detailed Flow Reasoning).

    Another reason for needing this phase is shown by BattleManager.isTurnEnd:
    JavaScript:
    BattleManager.isTurnEnd = function() {
        return this._phase === 'turnEnd';
    };
    As it's called by Game_Troop.prototype.meetsConditions:
    JavaScript:
    Game_Troop.prototype.meetsConditions = function(page) {
        var c = page.conditions;
        if (!c.turnEnding && !c.turnValid && !c.enemyValid &&
                !c.actorValid && !c.switchValid) {
            return false;  // Conditions not set
        }
        if (c.turnEnding) {
            if (!BattleManager.isTurnEnd()) {
                return false;
            }
        }
        if (c.turnValid) {
            var n = this._turnCount;
            var a = c.turnA;
            var b = c.turnB;
            if ((b === 0 && n !== a)) {
                return false;
            }
            if ((b > 0 && (n < 1 || n < a || n % b !== a % b))) {
                return false;
            }
        }
        if (c.enemyValid) {
            var enemy = $gameTroop.members()[c.enemyIndex];
            if (!enemy || enemy.hpRate() * 100 > c.enemyHp) {
                return false;
            }
        }
        if (c.actorValid) {
            var actor = $gameActors.actor(c.actorId);
            if (!actor || actor.hpRate() * 100 > c.actorHp) {
                return false;
            }
        }
        if (c.switchValid) {
            if (!$gameSwitches.value(c.switchId)) {
                return false;
            }
        }
        return true;
    };
    While the details of this function's separation of concerns, it should still be 100% crystal clear and obvious that this phase's needed to trigger battle events that should be triggered on turn end by reserving some Battle Frame Updates to do so.

    Battle Log Window
    Spoiler
    The role of the battle log window in the default RMMV battle flow is to coordinate the sequence and timing among showing messages, performing animations, updating battler sprites(poses, positions, damage popups) and invoking the Currently Executing Action to its current target.

    Callback Queue
    Using Window_BattleLog.prototype.startTurn as an example:
    JavaScript:
    Window_BattleLog.prototype.startTurn = function() {
        this.push('wait');
    };
    Window_BattleLog.prototype.push adds the battle log function with name methodName and arguments methodArgs as a callback into Window_BattleLog._methods, which is a Callback Queue(callback is so vital in the RMMV flow that you're high encouraged and recommended to have a solid understanding on it before moving on):
    JavaScript:
    Window_BattleLog.prototype.push = function(methodName) {
        var methodArgs = Array.prototype.slice.call(arguments, 1);
        this._methods.push({ name: methodName, params: methodArgs });
    };
    Window_BattleLog.prototype.update, which is called once per frame, executes a new callback in the Callback Queue, if any, when the battle log window isn't already executing any callback:
    JavaScript:
    Window_BattleLog.prototype.update = function() {
        if (!this.updateWait()) {
            this.callNextMethod();
        }
    };
    Window_BattleLog.prototype.updateWait calls Window_BattleLog.prototype.updateWaitCount and Window_BattleLog.prototype.updateWaitMode:
    JavaScript:
    Window_BattleLog.prototype.updateWait = function() {
        return this.updateWaitCount() || this.updateWaitMode();
    };
    JavaScript:
    Window_BattleLog.prototype.updateWaitCount = function() {
        if (this._waitCount > 0) {
            this._waitCount -= this.isFastForward() ? 3 : 1;
            if (this._waitCount < 0) {
                this._waitCount = 0;
            }
            return true;
        }
        return false;
    };
    JavaScript:
    Window_BattleLog.prototype.updateWaitMode = function() {
        var waiting = false;
        switch (this._waitMode) {
        case 'effect':
            waiting = this._spriteset.isEffecting();
            break;
        case 'movement':
            waiting = this._spriteset.isAnyoneMoving();
            break;
        }
        if (!waiting) {
            this._waitMode = '';
        }
        return waiting;
    };
    Note that spritesets will be covered in Spriteset Battle.

    Window_BattleLog.prototype.callNextMethod tries the most up front callback in the Callback Queue then removes that callback from that queue:
    JavaScript:
    Window_BattleLog.prototype.callNextMethod = function() {
        if (this._methods.length > 0) {
            var method = this._methods.shift();
            if (method.name && this[method.name]) {
                this[method.name].apply(this, method.params);
            } else {
                throw new Error('Method not found: ' + method.name);
            }
        }
    };
    Back to Window_BattleLog.prototype.startTurn, it adds Window_BattleLog.prototype.wait as a callback at the end of the Callback Queue:
    JavaScript:
    Window_BattleLog.prototype.wait = function() {
        this._waitCount = this.messageSpeed();
    };

    Timing coordination
    Window_BattleLog.prototype.isBusy checks if the currently executing callback's still executing, the Callback Queue's not empty, or the battle log window has its wait mode set:
    JavaScript:
    Window_BattleLog.prototype.isBusy = function() {
        return this._waitCount > 0 || this._waitMode || this._methods.length > 0;
    };
    Window_BattleLog.prototype.setWaitMode sets the wait mode of the battle log window:
    JavaScript:
    Window_BattleLog.prototype.setWaitMode = function(waitMode) {
        this._waitMode = waitMode;
    };
    The wait mode's used to indicate whether the battle log window needs to wait for the spriteset to finish its execution indicated by the wait mode, as shown in Window_BattleLog.prototype.updateWaitMode.
    In the case of the default RMMV battle system, there are only 2 wait modes, as shown by Window_BattleLog.prototype.waitForEffect and Window_BattleLog.prototype.waitForMovement:
    JavaScript:
    Window_BattleLog.prototype.waitForEffect = function() {
        this.setWaitMode('effect');
    };
    JavaScript:
    Window_BattleLog.prototype.waitForMovement = function() {
        this.setWaitMode('movement');
    };

    Reading Function Execution Sequence
    As an example, Window_BattleLog.prototype.startAction shows the starting message of the Currently Executing Action:
    JavaScript:
    Window_BattleLog.prototype.startAction = function(subject, action, targets) {
        var item = action.item();
        this.push('performActionStart', subject, action);
        this.push('waitForMovement');
        this.push('performAction', subject, action);
        this.push('showAnimation', subject, targets.clone(), item.animationId);
        this.displayAction(subject, item);
    };
    At the 1st glance, you might feel/think that the function execution sequence is the following:
    1. Window_BattleLog.prototype.performActionStart
    2. Window_BattleLog.prototype.waitForMovement
    3. Window_BattleLog.prototype.performAction
    4. Window_BattleLog.prototype.showAnimation
    5. Window_BattleLog.prototype.displayAction
    But the real sequence is this:
    1. Window_BattleLog.prototype.displayAction
    2. Window_BattleLog.prototype.performActionStart
    3. Window_BattleLog.prototype.waitForMovement
    4. Window_BattleLog.prototype.performAction
    5. Window_BattleLog.prototype.showAnimation
    It's because all functions in 1-4 are Asynchronous Callbacks.

    Note that rewriting Window_BattleLog.prototype.startAction into this can(and in this case, will) change its behaviors:
    JavaScript:
    Window_BattleLog.prototype.startAction = function(subject, action, targets) {
        var item = action.item();
        this.displayAction(subject, item);
        this.push('performActionStart', subject, action);
        this.push('waitForMovement');
        this.push('performAction', subject, action);
        this.push('showAnimation', subject, targets.clone(), item.animationId);
    };
    It's because it's possible(and in this case, true) that Window_BattleLog.prototype.displayAction will pushes some other callbacks into the Callback Queue.
    So the original function execution sequence is this:
    1. Window_BattleLog.prototype.displayAction
    2. Window_BattleLog.prototype.performActionStart
    3. Window_BattleLog.prototype.waitForMovement
    4. Window_BattleLog.prototype.performAction
    5. Window_BattleLog.prototype.showAnimation
    6. Callbacks added into the Callback Queue by Window_BattleLog.prototype.displayAction
    While the rewritten one is this:
    1. Window_BattleLog.prototype.displayAction
    2. Callbacks added into the Callback Queue by Window_BattleLog.prototype.displayAction
    3. Window_BattleLog.prototype.performActionStart
    4. Window_BattleLog.prototype.waitForMovement
    5. Window_BattleLog.prototype.performAction
    6. Window_BattleLog.prototype.showAnimation

    Let's check the contents of Window_BattleLog.prototype.displayAction to confirm this:
    JavaScript:
    Window_BattleLog.prototype.displayAction = function(subject, item) {
        var numMethods = this._methods.length;
        if (DataManager.isSkill(item)) {
            if (item.message1) {
                this.push('addText', subject.name() + item.message1.format(item.name));
            }
            if (item.message2) {
                this.push('addText', item.message2.format(item.name));
            }
        } else {
            this.push('addText', TextManager.useItem.format(subject.name(), item.name));
        }
        if (this._methods.length === numMethods) {
            this.push('wait');
        }
    };
    So the actual function execution sequence of Window_BattleLog.prototype.startAction is this:
    1. Window_BattleLog.prototype.displayAction
    2. Window_BattleLog.prototype.performActionStart
    3. Window_BattleLog.prototype.waitForMovement
    4. Window_BattleLog.prototype.performAction
    5. Window_BattleLog.prototype.showAnimation
    6. Window_BattleLog.prototype.addText(once or twice)
    7. Window_BattleLog.prototype.wait(none or once)
    Which is the actual sequence of the starting message display of the Currently Executing Action shown to the players.

    Spriteset Battle
    Spoiler
    The role of the spriteset in the default RMMV battle flow is to reserve the needed time for updating battler sprite poses, positions and damage popups.

    Timing coordination

    Spriteset_Battle.prototype.isBusy calls Spriteset_Battle.prototype.isAnimationPlaying and Spriteset_Battle.prototype.isAnyoneMoving:
    JavaScript:
    Spriteset_Battle.prototype.isBusy = function() {
        return this.isAnimationPlaying() || this.isAnyoneMoving();
    };
    Code:
    Spriteset_Battle.prototype.isAnimationPlaying = function() {
        return this.battlerSprites().some(function(sprite) {
            return sprite.isAnimationPlaying();
        });
    };
    Code:
    Spriteset_Battle.prototype.isAnyoneMoving = function() {
        return this.battlerSprites().some(function(sprite) {
            return sprite.isMoving();
        });
    };

    Where Sprite_Base.prototype.isAnimationPlaying and Sprite_Battler.prototype.isMoving are these:
    Code:
    Sprite_Base.prototype.isAnimationPlaying = function() {
        return this._animationSprites.length > 0;
    };
    Code:
    Sprite_Battler.prototype.isMoving = function() {
        return this._movementDuration > 0;
    };
    They suggest that Sprite_Base.prototype.updateAnimationSprites,
    Sprite_Base.prototype.startAnimation, Sprite_Battler.prototype.updateMove and Sprite_Battler.prototype.startMove should be briefly checked too:
    JavaScript:
    Sprite_Base.prototype.updateAnimationSprites = function() {
        if (this._animationSprites.length > 0) {
            var sprites = this._animationSprites.clone();
            this._animationSprites = [];
            for (var i = 0; i < sprites.length; i++) {
                var sprite = sprites[i];
                if (sprite.isPlaying()) {
                    this._animationSprites.push(sprite);
                } else {
                    sprite.remove();
                }
            }
        }
    };
    JavaScript:
    Sprite_Base.prototype.startAnimation = function(animation, mirror, delay) {
        var sprite = new Sprite_Animation();
        sprite.setup(this._effectTarget, animation, mirror, delay);
        this.parent.addChild(sprite);
        this._animationSprites.push(sprite);
    };
    Code:
    Sprite_Battler.prototype.updateMove = function() {
        if (this._movementDuration > 0) {
            var d = this._movementDuration;
            this._offsetX = (this._offsetX * (d - 1) + this._targetOffsetX) / d;
            this._offsetY = (this._offsetY * (d - 1) + this._targetOffsetY) / d;
            this._movementDuration--;
            if (this._movementDuration === 0) {
                this.onMoveEnd();
            }
        }
    };
    Code:
    Sprite_Battler.prototype.startMove = function(x, y, duration) {
        if (this._targetOffsetX !== x || this._targetOffsetY !== y) {
            this._targetOffsetX = x;
            this._targetOffsetY = y;
            this._movementDuration = duration;
            if (duration === 0) {
                this._offsetX = x;
                this._offsetY = y;
            }
        }
    };
    Note that Sprite_Battler.prototype.updateMove is called by Sprite_Battler.prototype.updateMain, which is called by Sprite_Battler.prototype.update, which is called per frame, and Sprite_Base.prototype.updateAnimationSprites is called by Sprite_Base.prototype.update which is called per frame.

    Relationship with the battle log window
    As an example, recall that Window_BattleLog.prototype.updateWaitMode calls Spriteset_Battle.prototype.isEffecting and Spriteset_Battle.prototype.isAnyoneMoving(the latter's covered already so only the former will be shown here):
    JavaScript:
    Spriteset_Battle.prototype.isEffecting = function() {
        return this.battlerSprites().some(function(sprite) {
            return sprite.isEffecting();
        });
    };
    Which leads to Sprite_Enemy.prototype.isEffecting:
    JavaScript:
    Sprite_Enemy.prototype.isEffecting = function() {
        return this._effectType !== null;
    };

    Another example is Window_BattleLog.prototype.showNormalAnimation, which is also related to the battle spriteset:
    JavaScript:
    Window_BattleLog.prototype.showNormalAnimation = function(targets, animationId, mirror) {
        var animation = $dataAnimations[animationId];
        if (animation) {
            var delay = this.animationBaseDelay();
            var nextDelay = this.animationNextDelay();
            targets.forEach(function(target) {
                target.startAnimation(animationId, mirror, delay);
                delay += nextDelay;
            });
        }
    };
    As it leads to Game_Battler.prototype.startAnimation:
    JavaScript:
    Game_Battler.prototype.startAnimation = function(animationId, mirror, delay) {
        var data = { animationId: animationId, mirror: mirror, delay: delay };
        this._animations.push(data);
    };
    Followed by Game_Battler.prototype.isAnimationRequested:
    JavaScript:
    Game_Battler.prototype.isAnimationRequested = function() {
        return this._animations.length > 0;
    };
    And eventually Sprite_Battler.prototype.setupAnimation:
    JavaScript:
    Sprite_Battler.prototype.setupAnimation = function() {
        while (this._battler.isAnimationRequested()) {
            var data = this._battler.shiftAnimation();
            var animation = $dataAnimations[data.animationId];
            var mirror = data.mirror;
            var delay = animation.position === 3 ? 0 : data.delay;
            this.startAnimation(animation, mirror, delay);
            for (var i = 0; i < this._animationSprites.length; i++) {
                var sprite = this._animationSprites;
                sprite.visible = this._battler.isSpriteVisible();
            }
        }
    };

    Detailed Flow Reasoning
    Spoiler
    Consider the below detailed Action Execution Phase flowchart(even though it still doesn't literally show all details):
    Default RMMV Battle Action Execution Phase.JPG
    While the very essence of the Action Execution Phase can be highly condensed into this:
    JavaScript:
    BattleManager.processActionExecutionPhase = function() {
        this.makeActionOrderQueue().forEach(function(actionExecutionSubject) { // BattleManager.updateTurn
            if (!actionExecutionSubject.isAlive()) { return; }
            actionExecutionSubject.actionExecutionQueue().forEach(function(currentlyExecutingAction) { // BattleManager.processTurn
                if (!currentlyExecutingAction.isValid()) { return; }
                // Phase action
                this.startCurrentlyExecutingAction(currentlyExecutingAction); // BattleManager.startAction
                currentlyExecutingAction.makeActionTargetQueue().forEach(function(currentTarget) { // BattleManager.updateAction
                    if (currentTarget) { this.invokeAction(currentlyExecutingAction, currentTarget); }
                }, this);
                //
                this.endCurrentlyExecutingAction(currentlyExecutingAction); // BattleManager.endAction
            }, this);
        }, this);
    } // BattleManager.processActionExecutionPhase
    There's actually a lot more details going under the hood.

    BattleManager.startTurn
    The Action Execution Phase always starts with BattleManager.startTurn, as it's the only timing transiting the battle phase into turn.
    As the default RMMV battle system's supposed to let the faster battlers act earlier than the slower ones, an Action Order Queue based on the battler's speed will need to be made now. That's why BattleManager.makeActionOrders has to be called here.
    Also, apart from cases where the battle's just started with preemptive or surprise(where enemies and autobattle/confused actors that aren't supposed to be able to act in the 1st turn can still make valid actions that can be executed), it's unnecessary for the battle to judge which battlers can act in this turn, as BattleManager.getNextSubject will check whether the most up front battler in the Action Order Queue's alive and BattleManager.processTurn will check whether the Action Execution Subject has valid actions to execute. Therefore the Action Order Queue will literally include all battlers in battle.

    BattleManager.updateTurn
    It's the outer loop of the Action Execution Phase, and is responsible for setting up the most up front battler in the Action Order Queue to be the Action Execution Subject and removes that battler from that queue.
    Once the Action Execution Subject's set, BattleManager.updateTurn will call BattleManager.processTurn; If there's no such Action Execution Subject, BattleManager.endTurn will be called instead.
    Note that BattleManager.getNextSubject will only be called here if there's no Action Execution Subject already. This has to be the case, otherwise the default RMMV battle flow would setup a new Action Execution Subject when the current one tries to execute an invalid actions followed by valid ones, since BattleManager.updateTurn is called per frame as long as the battle phase's still turn.

    BattleManager.processTurn
    It's the middle loop of the Action Execution Phase, and is responsible for setting up the most up front valid action in the Action Execution Queue to be the Currently Executing Action and removes that action from that queue.
    Note that if the Action Execution Subject has n action slots, BattleManager.processTurn will be called at least n + 1 times for that subject. While the ith call is to process the ith action slot for that subject, the (n + 1)th call is to process the end of processing all action slots for that subject followed by setting up a new Action Execution Subject. This has to be the case, as Window_BattleLog.prototype.endAction, which is called by BattleManager.endAction, calls Window_BattleLog.prototype.performActionEnd:
    JavaScript:
    Window_BattleLog.prototype.endAction = function(subject) {
        this.push('waitForNewLine');
        this.push('clear');
        this.push('performActionEnd', subject);
    };
    Code:
    Window_BattleLog.prototype.performActionEnd = function(subject) {
        subject.performActionEnd();
    };
    It means that Game_Battler.prototype.performActionEnd has to be called before calling Game_Battler.prototype.onAllActionsEnd(read Action Execution Sequence Timing Coordination to know why that's the actual function execution sequence).

    BattleManager.updateAction
    It's the inner loop of the Action Execution Phase, and is responsible for setting up the most up front target in the Action Target Queue to be the current target and removes that target from that queue.
    The action execution sequence is this:
    1. Action Start -
    a. The Action Execution Subject battler sprite performs the action start pose
    b. The Action Execution Subject battler sprite performs the action execution pose
    c. The action animation's shown
    d. The battle log window shows the action start message
    2. Action Invocation -
    a. (Normal action with substititued target only)The battle log window shows the substitiute message for the original and real current target
    a. (Counter attack only)The counter attack action's applied to the Action Execution Subject by the current target
    b. (Counter attack only)The curent target battler sprite performs the counter attack pose
    c. (Counter attack only)The battle log window shows the counter attack message
    a. (Magic reflection only)The Currently Executing Action's applied to the Action Execution Subject
    b. (Magic reflection only)The magic reflection se's played
    c. (Magic reflection only)The battle log window shows the magic reflection message
    a. (Normal action only)The Currently Executing Action's applied to the current target
    d. (Critical damage only)The battle log window shows the critical hit message
    e. (Normal action only)The damage popup sprite's shown on the current target battler sprite
    e. (Counter attack and magic reflection only)The damage popup sprite's shown on the Action Execution Subject battler sprite
    f. The damage popup sprite's shown on the Action Execution Subject battler sprite
    g. (Normal action only)The current target battler sprite performs the damage pose(miss, evasion, hp, mp, tp)
    g. (Counter attack and magic reflection only)The Action Execution Subject battler sprite performs the damage pose(miss, evasion, hp, mp, tp)
    h. (Normal action only)The battle log window shows the damage message(miss, evasion, hp, mp, tp) for the current target
    h. (Counter attack and magic reflection only)The battle log window shows the damage message(miss, evasion, hp, mp, tp) for the Action Execution Subject
    i. (Normal action causing death only)The current target battler sprite performs the collpase effect
    i. (Counter attack and magic reflection causing death only)The Action Execution Subject battler sprite performs the collpase effect
    j. (Normal action only)The battle log window shows the added states message for the target
    j. (Counter attack and magic reflection only)The battle log window shows the added states message for the Action Execution Subject
    k. (Normal action only)The battle log window shows the removed states message for the target
    k. (Counter attack and magic reflection only)The battle log window shows the removed states message for the Action Execution Subject
    l. (Normal action only)The battle log window shows the added buffs messagef or the target
    l. (Counter attack and magic reflection only)The battle log window shows the added buffs message for the Action Execution Subject
    m. (Normal action only)The battle log window shows the removed buffs message for the target
    m. (Counter attack and magic reflection only)The battle log window shows the removed buffs message for the Action Execution Subject
    n. (Failed normal action only)The battle log window shows the failed message for the current target
    n. (Failed counter attack and magic reflection only)The battle log window shows the failed message for the Action Execution Subject
    3. Action end -
    a. The Action Execution Subject battler sprite performs the action end pose

    Action Execution Sequence Timing Coordination
    Recall that BattleManager.update, which is called per frame during the Action Execution Phase, is this(check I. Battle Frame Update for details):
    JavaScript:
    BattleManager.update = function() {
        if (!this.isBusy() && !this.updateEvent()) {
            switch (this._phase) {
            case 'start':
                this.startInput();
                break;
            case 'turn':
                this.updateTurn();
                break;
            case 'action':
                this.updateAction();
                break;
            case 'turnEnd':
                this.updateTurnEnd();
                break;
            case 'battleEnd':
                this.updateBattleEnd();
                break;
            }
        }
    };
    At the 1st glance, you might feel/think that BattleManager.updateAction will be called per frame when the battle phase's action, even though it's 100% crystal clear and obvious to you that it's impossible to be the case, or the Currently Executing Action would be executed within a split second, which just isn't how the default RMMV battle flow works.
    All these are because of BattleManager.isBusy:
    JavaScript:
    BattleManager.isBusy = function() {
        return ($gameMessage.isBusy() || this._spriteset.isBusy() ||
                this._logWindow.isBusy());
    };
    It means that when at least 1 sprite in the spriteset's performing an animation or effect or is moving or displaying a damage popup, or the battle log window's displaying messages(you're highly encouraged and recommended to check all these details yourselves so I don't have to quote lots of codes that aren't the major factors of the default RMMV battle flow), the battle will be busy, causing the Battle Frame Update to be halted right here.

    While the sole purpose of BattleManager._spriteset in BattleManager is to check whether the spriteset's busy, BattleManager._logWindow is significantly more important in the BattleManager when it comes to coordinating the action execution sequence timing, as the below Window_BattleLog functions are called by BattleManager directly:
    Code:
    Window_BattleLog.prototype.startTurn = function() {
        this.push('wait');
    };
    Code:
    Window_BattleLog.prototype.displayAutoAffectedStatus = function(target) {
        if (target.result().isStatusAffected()) {
            this.displayAffectedStatus(target, null);
            this.push('clear');
        }
    };
    Code:
    Window_BattleLog.prototype.displayCurrentState = function(subject) {
        var stateText = subject.mostImportantStateText();
        if (stateText) {
            this.push('addText', subject.name() + stateText);
            this.push('wait');
            this.push('clear');
        }
    };
    Code:
    Window_BattleLog.prototype.displayRegeneration = function(subject) {
        this.push('popupDamage', subject);
    };
    Code:
    Window_BattleLog.prototype.startAction = function(subject, action, targets) {
        var item = action.item();
        this.push('performActionStart', subject, action);
        this.push('waitForMovement');
        this.push('performAction', subject, action);
        this.push('showAnimation', subject, targets.clone(), item.animationId);
        this.displayAction(subject, item);
    };
    Code:
    Window_BattleLog.prototype.endAction = function(subject) {
        this.push('waitForNewLine');
        this.push('clear');
        this.push('performActionEnd', subject);
    };
    Code:
    Window_BattleLog.prototype.displayActionResults = function(subject, target) {
        if (target.result().used) {
            this.push('pushBaseLine');
            this.displayCritical(target);
            this.push('popupDamage', target);
            this.push('popupDamage', subject);
            this.displayDamage(target);
            this.displayAffectedStatus(target);
            this.displayFailure(target);
            this.push('waitForNewLine');
            this.push('popBaseLine');
        }
    };
    Code:
    Window_BattleLog.prototype.displayCounter = function(target) {
        this.push('performCounter', target);
        this.push('addText', TextManager.counterAttack.format(target.name()));
    };
    Code:
    Window_BattleLog.prototype.displayReflection = function(target) {
        this.push('performReflection', target);
        this.push('addText', TextManager.magicReflection.format(target.name()));
    };
    Code:
    Window_BattleLog.prototype.displaySubstitute = function(substitute, target) {
        var substName = substitute.name();
        this.push('performSubstitute', substitute, target);
        this.push('addText', TextManager.substitute.format(substName, target.name()));
    };
    As BattleManager._spriteset should also play a role in coordinating the action execution sequence timing while there's no such call in BattleManager at all, while Window_BattleLog is related to Spriteset_Battle, these imply that BattleManager._logWindow is also responsible for using the battle spriteset to coordinate the action execution sequence timing.

    Summary
    Spoiler
    The Action Execution Phase consists of the below 3 parts:
    turn - as the Setting Up Action Execution Subjects part, which is reached via Turn Start, of the Action Execution Phase, it's responsible for making the Action Order Queue(queue being a FIFO data structure) and setting up new Action Execution Subject one by one from that queue, and will transit the battle phase to action if that subject has valid actions in the Action Execution Queue to execute one by one, or turn end if there are no more such subjects.
    action - as the Executing Actions part is the Action Execution Phase, it's responsible for making the Action Target Queue for the Currently Executing Action, and invoking that action to each target in that queue, or ends that action if there are no much such targets.
    turn end- as the transition from the Action Execution Phase to the Action Input Phase, it's to ensure the auto affected status and regenerations are completed displayed, and all battle events that should be triggered on turn end are indeed triggered before transiting the battle into the Action Input Phase.

    While the very essence of the Action Execution Phase can be highly condensed into this:
    JavaScript:
    BattleManager.processActionExecutionPhase = function() {
        this.makeActionOrderQueue().forEach(function(actionExecutionSubject) { // BattleManager.updateTurn
            if (!actionExecutionSubject.isAlive()) { return; }
            actionExecutionSubject.actionExecutionQueue().forEach(function(currentlyExecutingAction) { // BattleManager.processTurn
                if (!currentlyExecutingAction.isValid()) { return; }
                // Phase action
                this.startCurrentlyExecutingAction(currentlyExecutingAction); // BattleManager.startAction
                currentlyExecutingAction.makeActionTargetQueue().forEach(function(currentTarget) { // BattleManager.updateAction
                    if (currentTarget) { this.invokeAction(currentlyExecutingAction, currentTarget); }
                }, this);
                //
                this.endCurrentlyExecutingAction(currentlyExecutingAction); // BattleManager.endAction
            }, this);
        }, this);
    } // BattleManager.processActionExecutionPhase

    The action execution sequence timing's coordinated by the battle log window, which also uses Callback Queue(with Asynchronous Callbacks) and the battle spriteset to do the job. It's done by halting the Battle Frame Update while at least 1 sprite in the spriteset's performing an animation or effect or is moving or displaying a damage popup, or the battle log window's displaying messages.
    The action execution sequence is this:
    1. Action Start -
    a. The Action Execution Subject battler sprite performs the action start pose
    b. The Action Execution Subject battler sprite performs the action execution pose
    c. The action animation's shown
    d. The battle log window shows the action start message
    2. Action Invocation -
    a. (Normal action with substititued target only)The battle log window shows the substitiute message for the original and real current target
    a. (Counter attack only)The counter attack action's applied to the Action Execution Subject by the current target
    b. (Counter attack only)The curent target battler sprite performs the counter attack pose
    c. (Counter attack only)The battle log window shows the counter attack message
    a. (Magic reflection only)The Currently Executing Action's applied to the Action Execution Subject
    b. (Magic reflection only)The magic reflection se's played
    c. (Magic reflection only)The battle log window shows the magic reflection message
    a. (Normal action only)The Currently Executing Action's applied to the current target
    d. (Critical damage only)The battle log window shows the critical hit message
    e. (Normal action only)The damage popup sprite's shown on the current target battler sprite
    e. (Counter attack and magic reflection only)The damage popup sprite's shown on the Action Execution Subject battler sprite
    f. The damage popup sprite's shown on the Action Execution Subject battler sprite
    g. (Normal action only)The current target battler sprite performs the damage pose(miss, evasion, hp, mp, tp)
    g. (Counter attack and magic reflection only)The Action Execution Subject battler sprite performs the damage pose(miss, evasion, hp, mp, tp)
    h. (Normal action only)The battle log window shows the damage message(miss, evasion, hp, mp, tp) for the current target
    h. (Counter attack and magic reflection only)The battle log window shows the damage message(miss, evasion, hp, mp, tp) for the Action Execution Subject
    i. (Normal action causing death only)The current target battler sprite performs the collpase effect
    i. (Counter attack and magic reflection causing death only)The Action Execution Subject battler sprite performs the collpase effect
    j. (Normal action only)The battle log window shows the added states message for the target
    j. (Counter attack and magic reflection only)The battle log window shows the added states message for the Action Execution Subject
    k. (Normal action only)The battle log window shows the removed states message for the target
    k. (Counter attack and magic reflection only)The battle log window shows the removed states message for the Action Execution Subject
    l. (Normal action only)The battle log window shows the added buffs messagef or the target
    l. (Counter attack and magic reflection only)The battle log window shows the added buffs message for the Action Execution Subject
    m. (Normal action only)The battle log window shows the removed buffs message for the target
    m. (Counter attack and magic reflection only)The battle log window shows the removed buffs message for the Action Execution Subject
    n. (Failed normal action only)The battle log window shows the failed message for the current target
    n. (Failed counter attack and magic reflection only)The battle log window shows the failed message for the Action Execution Subject
    3. Action end -
    a. The Action Execution Subject battler sprite performs the action end pose
  11. Now let's talk about V. Battle End in detail.

    Aborting Phase
    Spoiler
    Recall that this phase is the phase where the battle's going to be aborted.

    Transitions

    BattleManager.abort changes the battle phase to aborting:
    JavaScript:
    BattleManager.abort = function() {
        this._phase = 'aborting';
    };
    And is called by Game_Timer.prototype.onExpire and Game_Interpreter.prototype.command340:
    JavaScript:
    Game_Timer.prototype.onExpire = function() {
        BattleManager.abort();
    };
    Code:
    Game_Interpreter.prototype.command340 = function() {
        BattleManager.abort();
        return true;
    };
    While the details of those 2 functions are separation of concerns, their names still somehow indicate that the aborting phase's used to indicate that the battle's aborted due to battle events(including the timer).

    On the other hand, BattleManager.checkAbort, which is called by BattleManager.updateEvent and BattleManager.checkBattleEnd(check I. Battle Frame Update for details), calls BattleManager.processAbort to transit the battle phase to battle end:
    JavaScript:
    BattleManager.checkAbort = function() {
        if ($gameParty.isEmpty() || this.isAborting()) {
            this.processAbort();
            return true;
        }
        return false;
    };
    Code:
    BattleManager.processAbort = function() {
        this.replayBgmAndBgs();
        this.endBattle(1);
    };
    It's because BattleManager.endBattle does change the battle phase to battle end:
    JavaScript:
    BattleManager.endBattle = function(result) {
        this._phase = 'battleEnd';
        if (this._eventCallback) {
            this._eventCallback(result);
        }
        if (result === 0) {
            $gameSystem.onBattleWin();
        } else if (this._escaped) {
            $gameSystem.onBattleEscape();
        }
    };

    Why this phase's needed
    Apart from increasing codebase qualities like readability, BattleManager.isAborting suggests reasons why this phase's needed:
    JavaScript:
    BattleManager.isAborting = function() {
        return this._phase === 'aborting';
    };
    As it's called by Scene_Battle.prototype.updateBattleProcess:
    JavaScript:
    Scene_Battle.prototype.updateBattleProcess = function() {
        if (!this.isAnyInputWindowActive() || BattleManager.isAborting() ||
                BattleManager.isBattleEnd()) {
            BattleManager.update();
            this.changeInputWindow();
        }
    };
    It's 100% crystal clear and obvious that the sole reason why the default RMMV battle flow needs this phase's to call the Battle Frame Update(check I. Battle Frame Update for details) and close all active input windows(check III. Action Input Phase for details) even when the battle's not already ending yet.

    Also, recall that BattleManager.update, which calls BattleManager.checkAbort and via BattleManager.updateEvent directly and BattleManager.checkBattleEnd, which is called by BattleManager.updateEvent via BattleManager.updateEventMain, is called per frame when the battle's in the Action Execution Phase(check I. Battle Frame Update for details):
    JavaScript:
    BattleManager.update = function() {
        if (!this.isBusy() && !this.updateEvent()) {
            switch (this._phase) {
            case 'start':
                this.startInput();
                break;
            case 'turn':
                this.updateTurn();
                break;
            case 'action':
                this.updateAction();
                break;
            case 'turnEnd':
                this.updateTurnEnd();
                break;
            case 'battleEnd':
                this.updateBattleEnd();
                break;
            }
        }
    };
    So calling BattleManager.isAborting in Scene_Battle.prototype.updateBattleProcess is meaningless and pointless when the battle's in the Action Execution Phase, meaning that it's used in the Action Input Phase.
    Moreover, recall that Game_Timer.prototype.onExpire and Game_Timer.prototype.onExpire are the only reasons to change the battle phase's to aborting, while no battle events can be run while the battle's in the Action Input Phase(check I. Battle Frame Update and III. Action Input Phase for details). They imply that the only reason why the default RMMV battle flow needs the aborting phase's to transit the battle phase from the input to battle end with all active input window's deactivated when the timer expires.

    Battle End Phase
    Spoiler
    Recall that this phase's the phase where the battle ends.

    Transitions

    BattleManager.endBattle transits the battle phase to battle end:
    JavaScript:
    BattleManager.endBattle = function(result) {
        this._phase = 'battleEnd';
        if (this._eventCallback) {
            this._eventCallback(result);
        }
        if (result === 0) {
            $gameSystem.onBattleWin();
        } else if (this._escaped) {
            $gameSystem.onBattleEscape();
        }
    };
    While BattleManager.updateBattleEnd transits the battle phase to null:
    JavaScript:
    BattleManager.updateBattleEnd = function() {
        if (this.isBattleTest()) {
            AudioManager.stopBgm();
            SceneManager.exit();
        } else if ($gameParty.isAllDead()) {
            if (this._canLose) {
                $gameParty.reviveBattleMembers();
                SceneManager.pop();
            } else {
                SceneManager.goto(Scene_Gameover);
            }
        } else {
            SceneManager.pop();
        }
        this._phase = null;
    };

    Why this phase's needed
    Apart from increasing codebase qualities like readability, BattleManager.isBattleEnd might suggest reasons why this phase's needed:
    JavaScript:
    BattleManager.isBattleEnd = function() {
        return this._phase === 'battleEnd';
    };
    While Scene_Battle.prototype.updateBattleProcess calls BattleManager.isBattleEnd, similar to the case of BattleManager.isAborting, the battle phase's impossible to become battle end while the battle's still in the Action Input Phase, calling BattleManager.isBattleEnd in Scene_Battle.prototype.updateBattleProcess is just to play safe.

    Another use of BattleManager.isBattleEnd is in Sprite_Actor.prototype.onMoveEnd:
    JavaScript:
    Sprite_Actor.prototype.onMoveEnd = function() {
        Sprite_Battler.prototype.onMoveEnd.call(this);
        if (!BattleManager.isBattleEnd()) {
            this.refreshMotion();
        }
    };
    But it's a complete separation of concern from the default RMMV battle flow, so it might seem that the battle end phase only contributes little to the default RMMV battle flow.

    Actually, the real use of this phase's in the default RMMV battle flow's shown by BattleManager.processVictory and BattleManager.processDefeat:
    JavaScript:
    BattleManager.processVictory = function() {
        $gameParty.removeBattleStates();
        $gameParty.performVictory();
        this.playVictoryMe();
        this.replayBgmAndBgs();
        this.makeRewards();
        this.displayVictoryMessage();
        this.displayRewards();
        this.gainRewards();
        this.endBattle(0);
    };
    Code:
    BattleManager.processDefeat = function() {
        this.displayDefeatMessage();
        this.playDefeatMe();
        if (this._canLose) {
            this.replayBgmAndBgs();
        } else {
            AudioManager.stopBgm();
        }
        this.endBattle(2);
    };
    The key lies in BattleManager.displayVictoryMessage, BattleManager.displayRewards(which calls BattleManager.displayExp, BattleManager.displayGold, BattleManager.displayDropItems) and BattleManager.displayDefeatMessage:
    Code:
    BattleManager.displayVictoryMessage = function() {
        $gameMessage.add(TextManager.victory.format($gameParty.name()));
    };
    Code:
    BattleManager.displayRewards = function() {
        this.displayExp();
        this.displayGold();
        this.displayDropItems();
    };
    Code:
    BattleManager.displayExp = function() {
        var exp = this._rewards.exp;
        if (exp > 0) {
            var text = TextManager.obtainExp.format(exp, TextManager.exp);
            $gameMessage.add('\\.' + text);
        }
    };
    Code:
    BattleManager.displayGold = function() {
        var gold = this._rewards.gold;
        if (gold > 0) {
            $gameMessage.add('\\.' + TextManager.obtainGold.format(gold));
        }
    };
    Code:
    BattleManager.displayDropItems = function() {
        var items = this._rewards.items;
        if (items.length > 0) {
            $gameMessage.newPage();
            items.forEach(function(item) {
                $gameMessage.add(TextManager.obtainItem.format(item.name));
            });
        }
    };
    Code:
    BattleManager.displayDefeatMessage = function() {
        $gameMessage.add(TextManager.defeat.format($gameParty.name()));
    };

    Similar to how Window_BattleLog works(check IV. Action Execution Phase for details), Game_Message, which stores the texts to be displayed(contents), and Window_Message, which determines how the texts are displayed(visuals), uses a Callback Queue consisting of Asynchronous Callbacks(callback and queue are so vital in the default RMMV battle flow that you're highly encouraged and recommended to having a solid understanding on both before moving on).
    So BattleManager.processVictory and BattleManager.processDefeat first registers the text display sequence to be shown in subsequent frames, then calls BattleManager.endBattle. On the subsequent frames, the Battle Frame Update will be halt by BattleManager.isBusy to display the registered text sequence instead of calling BattleManager.updateBattleEnd due to Game_Message.prototype.isBusy:
    JavaScript:
    BattleManager.isBusy = function() {
        return ($gameMessage.isBusy() || this._spriteset.isBusy() ||
                this._logWindow.isBusy());
    };

    Null Phase
    Spoiler
    Recall that this phase's the phase where the battle has completely ended.

    Transitions

    BattleManager.updateBattleEnd transits the battle phase's to null:
    JavaScript:
    BattleManager.updateBattleEnd = function() {
        if (this.isBattleTest()) {
            AudioManager.stopBgm();
            SceneManager.exit();
        } else if ($gameParty.isAllDead()) {
            if (this._canLose) {
                $gameParty.reviveBattleMembers();
                SceneManager.pop();
            } else {
                SceneManager.goto(Scene_Gameover);
            }
        } else {
            SceneManager.pop();
        }
        this._phase = null;
    };
    While it also transits the Scene from Scene_Battle to the last scene, or Scene_Gameover if all party members are dead and the battle can't lose, by calling SceneManager.pop and SceneManager.goto:
    JavaScript:
    SceneManager.pop = function() {
        if (this._stack.length > 0) {
            this.goto(this._stack.pop());
        } else {
            this.exit();
        }
    };
    Code:
    SceneManager.goto = function(sceneClass) {
        if (sceneClass) {
            this._nextScene = new sceneClass();
        }
        if (this._scene) {
            this._scene.stop();
        }
    };
    Note that goto here isn't acting as a javascript reserved word.

    Briefly touching SceneManager
    The point of touching SceneManager here's to show how the scene transits from the Scene_Battle to some other scenes.
    SceneManager.update, which is called per frame, calls SceneManager.updateMain:
    JavaScript:
    SceneManager.updateMain = function() {
        this.changeScene();
        this.updateScene();
        this.renderScene();
        this.requestUpdate();
    };
    SceneManager.changeScene changes the scene to the new one if the scene's to be changed:
    JavaScript:
    SceneManager.changeScene = function() {
        if (this.isSceneChanging() && !this.isCurrentSceneBusy()) {
            if (this._scene) {
                this._scene.terminate();
                this._previousClass = this._scene.constructor;
            }
            this._scene = this._nextScene;
            if (this._scene) {
                this._scene.create();
                this._nextScene = null;
                this._sceneStarted = false;
                this.onSceneCreate();
            }
            if (this._exiting) {
                this.terminate();
            }
        }
    };
    SceneManager.isSceneChanging checks if there's a next scene:
    JavaScript:
    SceneManager.isSceneChanging = function() {
        return this._exiting || !!this._nextScene;
    };

    Detailed Flow Reasoning
    Spoiler
    Consider the below detailed battle end flowchart(even though it still doesn't literally show all details):
    Default RMMV Battle End.JPG
    There are basically 3 reasons to end the battle - Abort, Defeat, Victory.

    Abort
    There are 3 reasons to abort a battle: Successful party escape attempt, abort battle event command and the timer expiration.
    The latters start from Game_Timer.prototype.onExpire and Game_Interpreter.prototype.command340, while the former starts from Scene_Battle.prototype.commandEscape:
    JavaScript:
    Scene_Battle.prototype.commandEscape = function() {
        BattleManager.processEscape();
        this.changeInputWindow();
    };
    Which calls BattleManager.processEscape;
    JavaScript:
    BattleManager.processEscape = function() {
        $gameParty.removeBattleStates();
        $gameParty.performEscape();
        SoundManager.playEscape();
        var success = this._preemptive ? true : (Math.random() < this._escapeRatio);
        if (success) {
            this.displayEscapeSuccessMessage();
            this._escaped = true;
            this.processAbort();
        } else {
            this.displayEscapeFailureMessage();
            this._escapeRatio += 0.1;
            $gameParty.clearActions();
            this.startTurn();
        }
        return success;
    };
    Which calls BattleManager.processAbort if the party escape attempt's succeeded:
    JavaScript:
    BattleManager.processAbort = function() {
        this.replayBgmAndBgs();
        this.endBattle(1);
    };
    Which calls BattleManager.endBattle with result 1:
    JavaScript:
    BattleManager.endBattle = function(result) {
        this._phase = 'battleEnd';
        if (this._eventCallback) {
            this._eventCallback(result);
        }
        if (result === 0) {
            $gameSystem.onBattleWin();
        } else if (this._escaped) {
            $gameSystem.onBattleEscape();
        }
    };

    Defeat
    BattleManager.updateEventMain, which is called per frame(check I. Battle Frame Update for details), calls BattleManager.checkBattleEnd when no battle events are running:
    JavaScript:
    BattleManager.checkBattleEnd = function() {
        if (this._phase) {
            if (this.checkAbort()) {
                return true;
            } else if ($gameParty.isAllDead()) {
                this.processDefeat();
                return true;
            } else if ($gameTroop.isAllDead()) {
                this.processVictory();
                return true;
            }
        }
        return false;
    };
    Which calls BattleManager.processDefeat when the battle's not to be aborted and all party members' dead:
    JavaScript:
    BattleManager.processDefeat = function() {
        this.displayDefeatMessage();
        this.playDefeatMe();
        if (this._canLose) {
            this.replayBgmAndBgs();
        } else {
            AudioManager.stopBgm();
        }
        this.endBattle(2);
    };
    Which calls BattleManager.endBattle with result 2:
    JavaScript:
    BattleManager.endBattle = function(result) {
        this._phase = 'battleEnd';
        if (this._eventCallback) {
            this._eventCallback(result);
        }
        if (result === 0) {
            $gameSystem.onBattleWin();
        } else if (this._escaped) {
            $gameSystem.onBattleEscape();
        }
    };

    Victory
    BattleManager.updateEventMain, which is called per frame(check I. Battle Frame Update for details), calls BattleManager.checkBattleEnd when no battle events are running:
    JavaScript:
    BattleManager.checkBattleEnd = function() {
        if (this._phase) {
            if (this.checkAbort()) {
                return true;
            } else if ($gameParty.isAllDead()) {
                this.processDefeat();
                return true;
            } else if ($gameTroop.isAllDead()) {
                this.processVictory();
                return true;
            }
        }
        return false;
    };
    Which calls BattleManager.processVictory when the battle's not to be aborted, not all party members' dead and all troop members' dead:
    JavaScript:
    BattleManager.processVictory = function() {
        $gameParty.removeBattleStates();
        $gameParty.performVictory();
        this.playVictoryMe();
        this.replayBgmAndBgs();
        this.makeRewards();
        this.displayVictoryMessage();
        this.displayRewards();
        this.gainRewards();
        this.endBattle(0);
    };
    Which calls BattleManager.endBattle with result 0:
    JavaScript:
    BattleManager.endBattle = function(result) {
        this._phase = 'battleEnd';
        if (this._eventCallback) {
            this._eventCallback(result);
        }
        if (result === 0) {
            $gameSystem.onBattleWin();
        } else if (this._escaped) {
            $gameSystem.onBattleEscape();
        }
    };

    Summary
    Spoiler
    The battle end consists of the below 3 phases:
    aborting - the battle's going to be aborted, which is used to end the battle when it's still in the Action Input Phase due to the timer being expired
    battle end - the battle ends, which is used to display the victory/defeat messages before completely ending the battle
    null - the battle's completely ended, which transits the scene from Scene_Battle to some other scenes
    Similar to how the battle log window works, the game message uses a Callback Queue(queue data structure) consisting of Asynchronous Callbacks to let the battle register a text sequence to be displayed while halting the Battle Frame Update to coordinate the timing between the game message and the Battle Frame Update.

    There are 3 reasons to end a battle:
    abort - when no battle events are running and the party escape attempt succeeded, the abort battle event command's executed or the timer expires
    defeat - when no battle events are running,the battle's not to be aborted and all party members' dead
    victory - when no battle events are running, the battle's not to be aborted, not all party members' dead and all troop members' dead
    But they all transits the battle phase to battle end before ultimately transiting it to null and the scene from Scene_Battle to some other scenes
  12. Due to Photobucket, I've moved the images used in this topic to here:
    https://github.com/Double-X/Image-List/blob/master/Default RMMV Battle Frame Update.JPG
    https://github.com/Double-X/Image-List/blob/master/Default RMMV Battle Start.JPG
    https://github.com/Double-X/Image-List/blob/master/Default RMMV Battle Action Execution Phase.JPG
    https://github.com/Double-X/Image-List/blob/master/Default RMMV Battle Action Input Phase.JPG
    https://github.com/Double-X/Image-List/blob/master/Default RMMV Battle End.JPG
  13. why isn't this a sticky yet?
  14. This is an action I want to understand. It's hard for me to learn through my own discoveries. Thank you for the good things that you do. Is now i want to make the event happen immediately without going through Press any button first
    Yes, I have been doing this for 1 hour and still have no success.
  15. palatkorn said:
    Is now i want to make the event happen immediately without going through Press any button first
    I'm curious on what exactly it's about, would you please elaborate?
  16. Do it, so it doesn't work. I use this to check every time when I enter a fight page, but it renders when in Scene_Map as well. It helps my activities run instantly. May be my way That just figured it out But I'm stuck, the only problem for this is for sure. Into how to battle or not
    This is one of my actions. But I should have asked more people how to write correctly.
    This code I found on google as well and I understand if it is a check if it entered the fight or not or I am wrong because in Scene_Map it still works.
    Code:
    Scene_Map.prototype.terminate = function() {
        Scene_MenuBase.prototype.terminate.call(this);
        if (!SceneManager.isNextScene(Scene_Battle)) {
            SceneManager.push(Scene_Battle);
        }
        };
  17. @palatkorn Your quoted code first terminates the map scene(although I don't know why it has anything to do with the menu scene in this case), then goes to the battle scene, assuming that the next scene doesn't exist already.

    If you want to run something before showing the battle start message, you can do something like this:
    JavaScript:
    var startBattle = BattleManager.startBattle;
    BattleManager.startBattle = function() {
        this.runEventsBeforeShowingStartBattleMessages();
        startBattle.call(this);
    };
    Then you just have to implement BattleManager.runEventsBeforeShowingStartBattleMessages yourself :)
  18. DoubleX said:
    @palatkorn Your quoted code first terminates the map scene(although I don't know why it has anything to do with the menu scene in this case), then goes to the battle scene, assuming that the next scene doesn't exist already.

    If you want to run something before showing the battle start message, you can do something like this:
    JavaScript:
    var startBattle = BattleManager.startBattle;
    BattleManager.startBattle = function() {
        this.runEventsBeforeShowingStartBattleMessages();
        startBattle.call(this);
    };
    Then you just have to implement BattleManager.runEventsBeforeShowingStartBattleMessages yourself :)

    I want it to work under the conditions
    if (code) {stuff} else {stuff}

    In the test run
    test5a72e5fb736c7a5a.gif

    Events, it cannot work immediately.
    I want to know What should I do to know that
    This is a scene that is not a fight scene.
    If this action button is not in Scene_Battle
    It will work incorrectly.
    I call it together like this in the picture.
    $ gameTemp.reserveCommonEvent (5);
    SceneManager.push (Scene_Battle);
    The result is that the event will run immediately and open.
    Or you have an easy way to make me call this event anywhere. Without affecting Can go to another place Please guide with respect I can't find it now on my google hahaha
  19. @palatkorn It seems to me that it's much, much more than just the default battle system, so you may want to find someone else who's awesome enough to take your project and fix the issues for you, as I'm rather busy with RMMZ, and I'll remain busy for quite a while :)
  20. DoubleX said:
    @palatkorn It seems to me that it's much, much more than just the default battle system, so you may want to find someone else who's awesome enough to take your project and fix the issues for you, as I'm rather busy with RMMZ, and I'll remain busy for quite a while :)
    I am probably too annoyed. You have helped a lot, for a number of responses, maybe I will revisit the exercise.