Bid And Ask Price Thresholds As Technical Indicators

The original MS word file can be downloaded here.

Note that the following technical indicators only works with Direct Market Access.

Summary

The word “amount” in this summary refers to the number of shares for convenience.

MBA and MAA

The maximum number of shares for a bid to be instantly matched in full amount for sure in theory regardless of the bid price is the total number of shares for all unmatched asks, which is also the Maximum Bid Amount(MBA).

The maximum number of shares for an ask to be instantly matched in full amount for sure in theory regardless of the ask price is the total number of shares for all unmatched bids, which is also the Maximum Ask Amount(MAA).

MBA and MAA can also have their respective K-charts and Moving Averages, which can help investors to decide a suitable number of shares to open/close long/short positions.

BPT and APT

For a bid with number of shares not exceeding MBA, Bid Price Threshold(BPT) is the lowest price for that bid to be instantly matched in full amount for sure in theory, but larger shares won’t have BPT since they can’t be matched in full no matter how high the bid price is.

For an ask with number of shares not exceeding MAA, Ask Price Threshold(APT) is the highest price for that ask to be instantly matched in full amount for sure in theory, but larger shares won’t have APT since they can’t be matched in full no matter how low the ask price is.

BPT and APT can also have their respective K-charts and Moving Averages, with the catch that invalid BPT and APT values should be skipped respectively.

These indicators can help investors with a predetermined number of shares for opening/closing long/short positions to fine-tune the precise bid/ask price and the timing.

BPT and APT ordering

The BAPT Ordering Theorem states that, in Direct Market Access, BPT is always greater than APT for any same or different number of shares of the corresponding bids and asks at the exact same moment, so there are 5 possibilities regarding the ordering among BPT, APT and the current price:

price < APT < BPT – Probably meaning that most bidders and askers expect the price to rise or keep rising significantly for quite some time, so it can point to a solid trend based on strong fundamental improvements or a baseless surge caused by good news coming out of thin air

price = APT < BPT – Probably meaning that most bidders expect the price to rise or keep rising significant for quite some time but most askers expect this trend to diminish or end soon, so it’s better to wait and look for signs of reversal unless it’s still obviously undervalued

APT < price < BPT – Probably meaning that the market have drastically different expectations on the upcoming price trend, so it can be due to the price still under corrections or many important but uncertain signs of reversal being surfaced

APT < price = BPT – Basically the polar opposite of the “price = APT < BPT” case

APT < BPT < price – Basically the polar opposite of the “price < APT < BPT” case

BPT Table and APT Table

Because a bid with a different number of shares usually have different BPTs, a BPT Table can be used to show all BPTs with their corresponding number of shares.

Because an ask with a different number of shares usually have different APTs, a APT Table can be used to show all APTs with their corresponding number of shares.

Real-time BPT Table and APT Table can help investors to weight against different combinations of number of shares with the bid/ask price as well as the pros/cons of different timing to open/close long/short positions.

Some Ways To Apply Some Programming Wisdom In Real Lives – Exceptions

Disclaimer: While exceptions and negative emotions are essentially similar, they’re still not 100% the same, so there will be minor discrepancies here and there when this article tries to apply wisdom on handling exceptions into handling negative emotions, but I still hope that this article can make its points across to as many of you as I can 🙂

As programmers, we probably at least have a basic knowledge on what exceptions do in general, so it’s unlikely that I’ve to explain much about that here. However, did we think about applying some wisdom from exceptions in real lives? Since I’ve had some thought about that, I’m going to share about them in this article, but the gist is this – Exceptions in software are a lot like negative emotions in human, so negative emotions should be addressed responsibly, just like exceptions being supposed to be handled properly.

The following 3 approaches show the similarities among exceptions and negative emotions:

Letting Exceptions Crash The Software – Letting Negative Emotions Take Over Control

Let’s use an unrealistically silly example about exceptions first.

Let’s say that a program has to send some GET requests to get data from some remote servers, and it’s totally normal for the requests to fail, possibly because of unstable network connections, overloaded servers, or some other similar reasons, so it’s just the norm to throw exceptions in such cases. However, an unbelievably sloppy programmer may just let the exceptions abruptly crash the whole program badly without even telling the users what’s going on, when he/she could’ve just tell them why those requests failed and ask whether they’d like to retry or abort those requests. Needless to say, if a so-called experienced professional frequently handle exceptions in such immature ways without even thinking about them, he/she probably won’t last long in the software engineering industries, because he/she’d likely just create disasters after disasters otherwise.

Of course, there are really cases where there’s indeed nothing for a software engineer to do when some methods throw some nasty exceptions, like StackOverflowException in C#, even though such exceptions shouldn’t be that easy to leak out to production to begin with. But the point remains that, letting an exception crash the entire system should at least be a careful and conscious decision(and preferably as the last resort only), rather than out of laziness nor misconceptions.

Now let’s go on to another childish example, but this time about negative emotions.

Let’s say a rookie investor just watched an online video about a seemingly legitimate(while actually unqualified) stock market expert “explaining”(when it’s actually nothing but nonsense) about how certain stocks will skyrocket to record highs after several days, and that rookie investor trusted this kind of insanity by investing more than 80% of his/her total wealth into that stock. Unfortunately, after several days, those stocks dropped to such lows that the underlying companies may as well be considered bankrupt, so that rookie investor feel extremely angry and unjust about his/her tragic loss, and leave many insulting and vulgar comments on that video, without even thinking about how that fraud really caused him/her to lose so much money in such a short time.

What’s worse, even that isn’t enough for that rookie investor to vent all his/her anger, so he/she feels exceptionally furious whenever he/she perceives anything he/she doesn’t like in his/her family, and disproportionally blames his/her sons and daughters for even trivial mistakes that he/she wouldn’t normally even notice nor care. Needless to say, if he/she continues to behave this way without thinking about his/her part of the responsibility of this mess(just automatically listening to any apparent authority without critical thinking), his/her family, as well as him/herself, will just suffer deeper and deeper, while he/she’ll increasing feel that it’s all the others’ fault for his/her disarray in his/her life.

Of course, there will be times where some adversities will cause even some of the most self-aware and serene people to be completely outraged, like when a guy realizes that his girlfriend had been concealing the fact that she’s pregnant for weeks because of another guy, even though there are actually people who can behave friendly(but not being weak) towards their girlfriends and even those guys responsible for such pregnant, all without repressing any negative emotions(like by nonjudgmental and nonviolent expressions of the feelings of hurt and sadness). But the point remains that, letting negative emotions to take over control should be rare and the last resort only(even though it’s okay to fail on this sometimes as long as the damages from uncontrolled emotional outbursts are at least partially compensated), rather than out of complete lack of self-awareness nor emotional intelligence.

Silently Swallowing Exceptions – Repressing Negative Emotions

Those used to handling exceptions should know that exception swallowing is generally a very bad practice and should only be used when there are very solid reasons behind it, otherwise the original exceptions that could be properly handled can easily become something much worse much later – severe errors that seem to come out of thin air, so it’d be very hard to find the root causes behind all this, let alone fixing it.

For instance, I still vaguely remember that, when I had a full-time programming job, I’ve taken over a codebase from someone else, and soon realized that that codebase will occasionally be out of memory without obvious causes. While it’s reasonable to suspect that there are memory leaks unknown to me(and it’s extremely hard to eradicate every possible memory leak anyway), I’d to spend quite some time to find out that, some of those memory leaks come from silently swallowing(an empty catch that’s not even logging anything) a certain exception when using an API of a library as a dependency of that codebase(I unconfidently recall something like only closing connections/streams in the try block but the exception’s thrown before reaching that line of code). If that exception were properly handled, I might have noticed those suspected improper use of resources much earlier, thus saving me tons of time when debugging the application.

In a very similar sense, those used to exercise self-awareness practices should know that repressing negative emotions(even though strictly speaking there’s no such thing as “negative” emotions as every emotion reflects unique messages about one’s dominant internal states) is generally a very bad practice and should only be used when there are very solid reasons behind it(like under prolonged critical emergencies constantly requiring difficult yet immediate actions with no room of errors), otherwise the originally manageable negative emotions can easily become something much worse after several years or at most decades – total mental breakdown triggered by seemingly trivial setbacks as the last straw, and sometimes even seasoned professional therapists may fail to understand the accumulated suffering of such patients, regardless of years of attempted consultations and treatments.

For instance, while I don’t claim to remember every last details, someone I know very well had almost committed suicide more than a decade ago, with the last straw being having no hope to finish his bachelor degree in university(and he really didn’t finish it at the end). While I don’t think I’ve thoroughly comprehended the essence behind his depressions at that time(fortunately nowadays he’s at most lightly depressed once in a while for a short time), I do know that he almost never asked for help unless absolutely necessary, and he nearly always refused to talk about his hardship to anyone else(now he’ll at least try to talk a little bit about that when someone else ask him about that directly).

With the fact that he rarely expressed even his positive emotions to the others at that time(but now he can genuinely smile easily), it’s reasonable to think that his self-awareness and emotional intelligence were both very low at that time, so repressing negative emotions in front of the others and even himself was all he could do back then. If he didn’t try to escape from external challenges as well as not ignoring his internal unhappiness, I don’t think he’d have tried to prepare to commit suicide(although I’d still doubt if he could’ve finished his bachelor degree even with external helps), even though it’s lucky that he never did it, and it was all that mattered.

Properly Handling Exceptions Thoughtfully – Observing Negative Emotions Nonjudgmentally

In short, exceptions that can be handled should be properly handled with thought, because different kinds of exceptions need different kinds of care, and sometimes even the same kind of exceptions can have totally different meanings under different contexts, so it’s usually better to think about how to handle a specific exception under a specific context with a case-by-case basis, even though it doesn’t mean there’s no need to establish exception handling facilities and policies for each software.

Mixing Different Exceptions – Lacking Emotional Granularity

If you’re a Java developer, it’d be a fortune for you to have not worked with a high-level try-catch block that has just a single catch catching Throwable for no reason(ideally such codes should never exist to begin with), without caring whether it’s an IOException(which can still be too broad sometimes), NullPointerException(which might be effectively meaningless under some contexts), OutOfMemoryError, StackOverflowError, or some other kinds of errors and exceptions. Because, strictly speaking, it’s also a kind of exception swallowing, not by negating the existence of exceptions altogether, but by erasing their specific details necessary to handle them properly. Obviously, it helps avoiding to face the problems head-on, but it won’t solve them either, and in fact, it often makes them much worse, sometimes even to the point of being impossible to fix within feasible costs anymore.

Similarly, if you only know that you feel bad when you’re facing negative emotions, without knowing what kind of the bad feeling it’s(like anger, anxiety, guilt, sadness or shame), you can end up with swallowing the details of your unmet internal needs by covering them using the generic word “bad” and nothing more(although it’s still better than negating negative emotions altogether), thus pretending to be working hard on improving mindfulness while giving you excuses to evade all those limiting beliefs and psychological pains that have to be faced, in order to have meaningful spiritual advancement and mental growth required to function effectively and efficiently as a healthy being. While increasing emotional granularity demands some courage and knowledge, it’s the only way to stop those stagnant negative emotions from eventually evolving into nastier and nastier mental disorders, even though one won’t descend into such hell that easily nor quickly in normal cases.

Analyzing Exception Stack Trace – Identifying Negative Emotion Roots

When investigating the root causes of an exception, it’s often helpful to study its stack trace, at least until to the level where some meaningful fix can be done, instead of just covering its symptoms. Of course, sometimes, including rare instances where I’ve experienced personally, covering the symptoms reflected by an exception is indeed better than trying to fix its root causes, and this can be due to varying special reasons, like the prohibiting cost and technical barrier needed to fix it, with the reasonably assumed lack of serious consequences of just covering its symptoms, or maybe the exception is due to some native bugs of the frameworks or platform used, when it’d be infeasible to find replacement just because of those relatively minor annoyances. The key of this, again, is to really know what you’re truly doing, rather than just mechanically sweeping ugly messes under the carpet without long-term thinking, and being at least this responsible and thoughtful will be one of the advantages helping us go a long way as seasoned professional software engineers.

Similarly, after giving ourselves some time to just feel those negative emotions without criticism, it’s often helpful to ask what triggers those negative emotions, and I might have to use an example to illustrate this. Let’s say you and colleagues A and B have the same position in the same company, while they’ve higher salaries than yours. While you dislike A a lot because of that, you respect B despite of that however. After some brief self-observation, you realize that you dislike A more and more whenever he/she creates even more mess(and you’ve to clean it up) without contributing much to anybody or anything(and the higher-ups never punished A for anything ever), and you respect B more and more whenever he/she performs even better than he/she already did without making troubles to anyone else, so having the same position with different salaries isn’t the full story of your disdain towards A but not B.

Instead, it makes sense to have a hypothesis that(which needs to be further verified), you’ve an implicit golden rule that the rewards received by someone should be proportional to the values that someone brought to the others, and your hatred towards A stems from him/her violating your golden rule without any negative consequences, thus threatening some parts of your subjective value systems that are imbued deep within your brain and heart. With this new insight about yourself, you can choose to either accept that it’s okay for your golden rule to slightly fail sometimes, or continue to be angry with A but with the crystal clear awareness of him/her violating your golden rule without having to pay for it, or try to reveal your past pains causing your adoption of this golden rule by digging even deeper about where it came from(which is insanely hard without professional supports), but what’s the most important is that, no matter what you choose, it’d be better to admit that it’s your conscious choice, and be responsible for it, as well as every consequences on your part.

Do note that, in practice, exception stack traces are handled by our minds, meaning that it’s a thinking and objective process, while negative emotion roots are handled by our hearts, meaning that it’s a feeling and subjective process, so just blindly applying the methodologies of handling exception stack traces into handling negative emotion roots will only make things even worse, and emphasizing the similarities between exception stack traces and negative emotion roots is to use another way to reveal some parts of the essence behind negative emotions, especially for us programmers and former programmers 😀

Throwing So Many Exceptions – Being Triggered So Easily

While it’s totally fine for a method to throw a couple of exceptions, if a method can throw dozens of them, then it’s most likely a code smell, because that method probably does too much and/or rethrows too many exceptions coming from even lower level methods, when at least some of those exceptions should be handled by the original method instead. Either way, since exceptions are special kinds of union types(and checked exceptions are special kinds of tagged unions), methods throwing so many exceptions have the same problems of union types having so many different types included, which at least indicate the possibility of low cohesion and/or tight coupling.

Similarly, while it’s totally fine for us to have a couple of negative emotions once in a while, if we frequently have so many negative emotions simultaneously, then it’s most likely a sign for some needs on more personal growth, because we’re probably under too much stress and/or have so many past yet unhealed mental sufferings triggered by the current adversities, when it’d be ideal for us to let go of at least some of those stale psychological pains. Either way, since emotions, including negative ones, are the communication media between our conscious and unconscious mind, when we frequently feel so many negative emotions simultaneously, it’s natural to suspect that our conscious minds have been ignoring or twisting too many messages from our unconscious minds for far too long, and such self-defeating pattern can indicate the tendency of feeling a false need to strictly control the others rather than ourselves at all times, and being far from always solely responsible for our external behaviors(barring extreme cases like being forcibly drugged by the others).

Chaining Exceptions – Stepping Back

It seems to me, and possibly seems to you as well, that exception chaining is a best practice when it comes to handling exceptions, but whenever we’ve to chain exceptions, it means those exceptions can’t be handled by places they’re thrown, and have to be escalated to a higher level method, by wrapping those original exceptions irrelevant to that higher level method with exceptions meaningful to it, to hope that it can handle those wrapped exceptions, with the original exceptions as their causes. If it still can’t handle those wrapped exceptions, the same exception chaining process will be repeated to further escalate those exceptions into an even higher level method, so the whole process will repeat until a high enough level method can handle those exceptions, or the program has to escalate them into the highest level and inform the end users about what really happened, then either ask for user inputs and continue the program safely or ask for user apologies and crash the program nicely.

Without wrapping lower level exceptions with higher level exceptions, the higher level methods won’t even understand what’s going on, let alone doing anything meaningful to it; Without preserving the original lower level exceptions, the higher level methods won’t know what causes the exceptions they understand, and sometimes different actions are needed for different causes.

The same wisdom can be applied when we’re facing some serious negative emotions that can’t be just looked away from, but can’t be directly dealt with on the level directly triggering those negative emotions either, and this can be illustrated with the following example. When my annual contract of my previous job nearly ended, I feel anxious about both renewing and not renewing the annual contract. On one hand, I liked the workplace, and I’d slightly miss it as well as my colleagues for a while if I just choose not to renew the contract; On the other hand, as I foresee a high probability for the workplace to change from being very nice to being very nasty within months, I’d probably have to change from contributing as much to the workplace as I sustainably can to protecting myself from the workplace as much as my track records won’t become too broken, so I’d likely suffer significantly for quite a while if I choose to renew the contract.

Because I already had some experience on self-awareness and mindfulness at that time, I realize that this apparent psychological conflict is more than just about the contract itself, so I took a step back and escalated this issue to a higher level. After some inner work, I revealed something noticeably deeper – I don’t want to escape from difficult challenges and leave my colleagues behind(I was perceived by most of them as the most helpful colleague there), as I’d feel that doing so is a little bit like betraying at least some of them(now I still think I’m just an unforgivable deserter that deserves to be hated even though no one seems to despise me for that), but I don’t want to go back to be someone defending my self interests at the cost of the greater good either, as I’d feel that doing so is going massively backwards when it comes to personal growth(and this will eventually harm my self interests even more even though this backward approach is just temporary). Since I already know that my core principle is to avoid hurting anyone else as much as I can sustainably do so(I suspect that my whole value system’s built for this), while choosing either side is going to somehow violate what I care the most, I decided to choose the side that most likely hurt my colleague less – Not renewing the annual contract, in the hopes that the one replacing me will perform much better and help those colleagues much more than I did, thus causing them to at least suffer less.

Of course, that doesn’t mean my decision is perfect, because maybe I could’ve taken another step back, and try to have some insights on my past psychological pains causing me to avoiding hurting anyone else even at the cost of harming myself(provided that those harms are totally reversible), or maybe I could’ve found ways to raise my map of conscious level to joy(540) before starting the renewed contract, so I’d feel incredibly blessed and eternally ecstatic when I know I’m going to face the toughest challenge for me ever, while still sustainably contributing even more to my colleagues and fostering my personal growth. But without taking a step back and escalate the original conflict of whether to renew the contract into a higher level, I might not have understood that the nature of the conflict is actually failing to find any way to withstand my core principle no matter what I do, so I feel hurt and sad about having no means to maintain the integrity of my identity towards myself and possibly some of the others. Therefore, if I just kept struggling on the surface issue alone, no matter what I choose, I’d just be even more guilty and remorseful about what I’ve done and I’ll have to do, all without fathoming why I’d be this ashamed of myself.

Summary

As seasoned professional programmers, we’re good on our thinking sides, otherwise we wouldn’t have lasted that long in the software engineering industries, so we’d usually have little problems on aspects primarily using our minds. But as authentic human being rather than objectified machines(although a little bit of systematic dehumanization is still a necessary evil to support the civilization of the mankind) solely for keeping the societies running(when societies are supposed to serve their members rather than the other way around), we’d want to be good on our feeling sides as well, otherwise we’d be more and more alienated and foreign with who we really are and what we really want, so our hearts would bleed and die more and more inside everyday we try to escape from and eliminate our negative emotions. Therefore, by spotting the similarities between exceptions and negative emotions, this article tried to apply some wisdom on handling the former into handling the latter, with the goal of helping me, and perhaps at least some of you, to be good on both our thinking and feeling sides(although most of you are already this good without needing this article at all), and to have little problems on using either our minds and hearts(rather than treating them as polar opposites), thus our lives can become more complete and fulfilling to us and preferably to the others.

Even though this article is by no means exhaustive on applying wisdom on handling exceptions to handling negative emotions, at the very least, if we realize that choosing between letting our negative emotions take over control and repressing them is such a false dilemma that will only cause us to be more and more miserable, we’re already on a good way to be more self-aware and mindful, just like how understanding exceptions will help us to be better and better programmers. As our emotional intelligence keep increasing, it’d be more natural for us to handle negative emotions wisely, until it’d so intuitive to us that it’d become our second nature, even though it doesn’t mean that this will become a piece of cake nor we’ll always do it well, just as sometimes we’ll make an ugly mess out of exceptions no matter how seasoned and professional we’re, and no matter how much we take exceptions seriously, hence it’s still okay for us to become a little bit childish once in a while, and it’s a part of being human rather than machines 😛

DoubleX_RMMZ_Formulae_Edit

Purpose

Lets you directly edit various built-in global formulae

Video

Games using this plugin

None so far

Prerequisites

Plugins:

  1. DoubleX RMMZ Enhanced Codebase

Abilities:

  1. Nothing special

Terms Of Use

  1. Commercial use’s always allowed and crediting me’s always optional.
  2. You shall keep this plugin’s Plugin Info part’s contents intact.
  3. You shalln’t claim that this plugin’s written by anyone other than DoubleX or my aliases. I always reserve the right to deny you from using any of my plugins anymore if you’ve violated this.
  4. If you repost this plugin directly(rather than just linking back), you shall inform me of these direct repostings. I always reserve the right to request you to edit those direct repostings.
  5. CC BY 4.0, except those conflicting with any of the above, applies to this plugin, unless you’ve my permissions not needing follow so.
  6. I always reserve the right to deny you from using this plugin anymore if you’ve violated any of the above.

Contributors

Authors:

  1. DoubleX

Plugin Development Collaborators:

– None So Far

Bug Reporters:

– None So Far

Compatibility Issue Raisers:

– None So Far

Feature Requesters:

– None So Far

Changelog

{ codebase: “1.5.0”, plugin: “v1.00a” }(2022 Oct 27 GMT 1000):

  1. 1st version of this plugin finished

Download Link

Demo Link

DoubleX_RMMV_RMMZ_Event_Text_Extractor

Note

This plugin works for both RMMV and RMMZ

Purpose

Lets you extract texts in events/common events/battle events to txt file

Video

Games using this plugin

None so far

Parameters

* @param fileName
* @type string
* @desc Sets the name of the txt file having those extracted texts
* @default Extracted Event Texts
*
* @param filePath
* @type string
* @desc Sets the path of the txt file having those extracted texts
* Leaving it empty means placing the file at project root directory
* @default

Prerequisites

Abilities:

1. Nothing special

Terms Of Use

* 1. Commercial use’s always allowed and crediting me’s always optional.
* 2. You shall keep this plugin’s Plugin Info part’s contents intact.
* 3. You shalln’t claim that this plugin’s written by anyone other than
* DoubleX or my aliases. I always reserve the right to deny you from
* using any of my plugins anymore if you’ve violated this.
* 4. If you repost this plugin directly(rather than just linking back),
* you shall inform me of these direct repostings. I always reserve
* the right to request you to edit those direct repostings.
* 5. CC BY 4.0, except those conflicting with any of the above, applies
* to this plugin, unless you’ve my permissions not needing follow so.
* 6. I always reserve the right to deny you from using this plugin
* anymore if you’ve violated any of the above.

Contributors

* Authors:
* 1. DoubleX
* Plugin Development Collaborators:
* – None So Far
* Bug Reporters:
* – None So Far
* Compatibility Issue Raisers:
* – None So Far
* Feature Requesters:
* – None So Far

Changelog

* { codebase: “1.4.4”, plugin: “v1.00a” }(2022 Apr 15 GMT 1300):
* 1. 1st version of this plugin finished

Download Link

Demo Link

Basic knowledge to the default RMMZ TPBS battle flow implementations

This topic aims to share the basic knowledge on what the default RMMZ TPBS battle flow implementations do in general, but you’re still assumed to have at least:
1. Some plugin development proficiency(having written several easy, simple and small battle-related plugins up to 1k LoC scale)
2. Basic knowledge on what the default RMMZ turn based battle flow implementations do in general
3. Basic knowledge on what the default RMMZ TPBS battle flow does in general on the user level(At least you need to know what’s going on on the surface when playing it as a player)

Simplified Flowchart

Please note that this flowchart only includes the most important elements of the battle flow, to avoid making it too complicated and convoluted for the intended targeting audience 😉

Battle Start
It’s almost exactly the same as that in the turn based counterpart, so the phase will change to “start” after finished starting the battle.

Input Action Slots
It’s actually quite similar to that in the turn based counterpart, except that:
1. As nothing other than inputting action slots can happen during the “input” phase in the turn based counterpart, the exact input sequence is always fixed there, whereas in the TPBS some party members can become inputable or uninputable at anytime, especially when it comes to active TPBS.
2. At any given frame in TPBS, players are still supposed to start from inputting the 1st action slot of the 1st inputable party member to inputting the last action slot of the last party member.
3. If players are inputting the action slots of a party member, and then they cancel inputting all those action slots of of that party member, among all the other inputable party members, those whose party member indices are greater rather than less than the previously inputting one will be selected first, and the party command window will be setup in case no other inputable party member exists.
This is because BattleManager.selectPreviousCommand will call BattleManager.selectPreviousActor, which will still call BattleManager.changeCurrentActor with argument forward as true, which is the same as what BattleManager.selectNextActor, which is called by BattleManager.selectNextCommand, does:

BattleManager.selectPreviousCommand = function() {
    if (this._currentActor) {
        if (this._currentActor.selectPreviousCommand()) {
            return;
        }
        this.cancelActorInput();
    }
    this.selectPreviousActor();
};

4. Also, unlike the turn based counterpart, if another inputable party member is selected for inputting actions due to cancelling inputs of another inputable party member, the newly selected one will still input his/her/its 1st action slot first, then proceed the same sequence until the last action slot is inputted.
5. As a corollary, once an inputable party member has inputted all his/her/its action slots, there’s no way to cancel those input because he/she/it’ll proceed to casting and then executing those actions, and this is unlike the turn based counterpart, where players can cancel party members who’ve inputted all their action slots, as long as the phase is still “input”.
6. In the turn based counterpart, the only way to activate or deactivate any input window is by the ok and cancel commands issued by players, whereas in TPBS this can also be affected by whether the currently inputting party member becomes not inputable, due to Scene_Battle.prototype.changeInputWindow, which will only be called if some input windows need to be activated/deactivated:

Scene_Battle.prototype.changeInputWindow = function() {
    this.hideSubInputWindows();
    if (BattleManager.isInputting()) {
        if (BattleManager.actor()) {
            this.startActorCommandSelection();
        } else {
            this.startPartyCommandSelection();
        }
    } else {
        this.endCommandSelection();
    }
};

In short, other than hiding the skill, item, actor and enemy windows:
– If there are inputable party members and 1 of them becomes selected to input action slots, the actor command window will be setup with the status window selecting that actor
– If there are inputable party members and all of them become not selected to input action slots, the party command window will be setup with the status window deselected
– If there are no more inputable party members, all the input windows will be closed and the status window will be deselected
Bear in mind that how the above points work in details are too advanced to be covered here.

Thinking In Frames
Unlike the default turn based battle system, thinking in frames are vital even in just trying to have a basic knowledge on what the default RMMZ TPBS battle flow implementations do in general, especially when it comes to active TPBS, so the flowchart is drawn quite differently from the turn based counterpart.
To be able to think in frames, one first need to know the starting point of a frame and all the possible ending points of that frame, then one can sequentially grasp the summary of each path, until a vague impression of a frame can be formed.
To make the task even easier, simpler and smaller, one can first try to briefly read the codes without thinking about active TPBS, which is more complicated and convoluted, especially when it comes to edge cases that are hard but still possible to reach.
When one becomes familiar with thinking in frames, he/she should be able to at least partially simulate what a frame does in general in his/her mind, and eventually roughly visualize the TPBS battle flow implementations mentally.

Frame Start
A frame starts from Scene_Battle.prototype.update, which is a vital part of the scene life cycle(too advanced to be covered here):

Scene_Battle.prototype.update = function() {
    const active = this.isActive();
    $gameTimer.update(active);
    $gameScreen.update();
    this.updateVisibility();
    if (active && !this.isBusy()) {
        this.updateBattleProcess();
    }
    Scene_Message.prototype.update.call(this);
};

Then Scene_Battle.prototype.updateBattleProcess will be called to use the result of Scene_Battle.prototype.isTimeActive as the argument of BattleManager.update, which is being called immediately afterwards:

Scene_Battle.prototype.updateBattleProcess = function() {
    BattleManager.update(this.isTimeActive());
};
Scene_Battle.prototype.isTimeActive = function() {
    if (BattleManager.isActiveTpb()) {
        return !this._skillWindow.active && !this._itemWindow.active;
    } else {
        return !this.isAnyInputWindowActive();
    }
};
BattleManager.update = function(timeActive) {
    if (!this.isBusy() && !this.updateEvent()) {
        this.updatePhase(timeActive);
    }
    if (this.isTpb()) {
        this.updateTpbInput();
    }
};

Because of Scene_Battle.prototype.isTimeActive, the active TPBS will keep the TPB running unless the skill or item window’s active, while the non-active TPBS will only keep the TPB running when there are no active input windows(party or actor command, or skill, item, actor or enemy window), meaning that there are no inputable party members.
(On a side note: Strictly speaking, the way the TPBS battle flow’s implemented won’t let plugin developers change the active TPBS to keep the TPB running even when battlers are executing actions, unless those plugin developers rewrite the whole TPBS from scratch, but these details are way, way too advanced and complex to be elaborated here)
BattleManager.isBusy and BattleManager.updateEvent will be called to only call BattleManager.updatePhase when the TPB can technically keep running(the details of these underlying technical limitations are way, way too advanced and complex to be elaborated here):

BattleManager.isBusy = function() {
    return (
        $gameMessage.isBusy() ||
        this._spriteset.isBusy() ||
        this._logWindow.isBusy()
    );
};
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();
};
BattleManager.updatePhase = function(timeActive) {
    switch (this._phase) {
        case "start":
            this.updateStart();
            break;
        case "turn":
            this.updateTurn(timeActive);
            break;
        case "action":
            this.updateAction();
            break;
        case "turnEnd":
            this.updateTurnEnd();
            break;
        case "battleEnd":
            this.updateBattleEnd();
            break;
    }
};

While Game_Message.prototype.isBusy and Spriteset_Battle.prototype.isBusy are self-explanatory enough, Window_BattleLog.prototype.isBusy is a lot more complicated and convoluted(too advanced to be covered here), but it’s still about whether the TPB needs to stop to let the visual coordination running, like the battle log, animations, battler sprites, etc.
The main function of interest inside BattleManager.updateEvent is BattleManager.updateEventMain(too advanced to be covered here), and what makes it interesting here is that it’ll check whether the battle needs to end by checking whether it’s aborted, victorious or defeated, and will change the phase to “battleEnd” if any of those conditions are met.
As for BattleManager.updatePhase, it’s mainly about picking the function to call according to the current phase of the battle, while the argument timeActive is the result of Scene_Battle.prototype.isTimeActive.

Start Phase
There’s not much in this phase, as all BattleManager.updateStart does in TPBS is to change to phase to “turn”:

BattleManager.updateStart = function() {
    if (this.isTpb()) {
        this._phase = "turn";
    } else {
        this.startInput();
    }
};

Turn Phase
The “turn” phase is the majority of the difference between the TPBS battle flow and the turn based counterpart.
First, BattleManager.updateTurn will be called to use the argument timeActive as the result of Scene_Battle.prototype.isTimeActive to determine if BattleManager.updateTpb should be called as well:

BattleManager.updateTurn = function(timeActive) {
    $gameParty.requestMotionRefresh();
    if (this.isTpb() && timeActive) {
        this.updateTpb();
    }
    if (!this._subject) {
        this._subject = this.getNextSubject();
    }
    if (this._subject) {
        this.processTurn();
    } else if (!this.isTpb()) {
        this.endTurn();
    }
};
BattleManager.updateTpb = function() {
    $gameParty.updateTpb();
    $gameTroop.updateTpb();
    this.updateAllTpbBattlers();
    this.checkTpbTurnEnd();
};

Assuming that timeActive is true –
Now, Game_Unit.prototype.updateTpb will be called to call Game_Battler.prototype.updateTpb for all battlers:

Game_Battler.prototype.updateTpb = function() {
    if (this.canMove()) {
        this.updateTpbChargeTime();
        this.updateTpbCastTime();
        this.updateTpbAutoBattle();
    }
    if (this.isAlive()) {
        this.updateTpbIdleTime();
    }
};

So, if a battler can move, he/she/it’ll update the TPB and action casting bars, as well as start casting all the autobattle actions that are just made in case he/she/it’s in Auto Battle.
If he/she/it’s alive, he/she/it’ll update the idle TPB bar as well.
If his/her/its TPB becomes fully charged, he/she/it’ll become available for inputting action slots.
If his/her/its action casting bar becomes full, he/she/it’ll become available for executing valid actions.
BattleManager.updateAllTpbBattlers will call BattleManager.updateTpbBattler for all battle members:

BattleManager.updateTpbBattler = function(battler) {
    if (battler.isTpbTurnEnd()) {
        battler.onTurnEnd();
        battler.startTpbTurn();
        this.displayBattlerStatus(battler, false);
    } else if (battler.isTpbReady()) {
        battler.startTpbAction();
        this._actionBattlers.push(battler);
    } else if (battler.isTpbTimeout()) {
        battler.onTpbTimeout();
        this.displayBattlerStatus(battler, true);
    }
};

First, if the turn of the battler involved becomes ended, the old turn will be ended and the new one will be started here, with the latest battler status displayed on the battle log window.
Second, if the battler involved becomes available for executing actions, that battler will be pushed into the back of the action execution subject queue, so later BattleManager.updateTurn can call BattleManager.getNextSubject to pickup that battler to be the action execution subject.
Third, if the battler involved has become idled for so long that a turn has passed, that battler will be in the new battler turn, with the latest battler status displayed on the battle log window.
BattleManager.checkTpbTurnEnd will be covered in “Turn End Phase”.
Regardless of whether BattleManager.updateTpb is called, the rest of BattleManager.updateTurn is exactly the same as the turn based counterpart.

Action Phase
It’s almost the same as the turn based counterpart, as least when only the battle flow is concerned.

Turn End Phase
It’s quite similar to the “turn” phase in TPBS, except that, after calling BattleManager.checkTpbTurnEnd, if Game_Troop.prototype.isTpbTurnEnd returns true, BattleManager.endTurn will be called to change the phase to “turnEnd” as well:

BattleManager.checkTpbTurnEnd = function() {
    if ($gameTroop.isTpbTurnEnd()) {
        this.endTurn();
    }
};
Game_Troop.prototype.isTpbTurnEnd = function() {
    const members = this.members();
    const turnMax = Math.max(...members.map(member => member.turnCount()));
    return turnMax > this._turnCount;
};
BattleManager.endTurn = function() {
    this._phase = "turnEnd";
    this._preemptive = false;
    this._surprise = false;
};

Note that this doesn’t always mean that the phase at the next frame will be “turnEnd”, because as shown in the flowchart, it’s still possible that BattleManager.startAction will be called to change the phase to “action” before proceeding to the next frame(the proof of this possibility is too advanced to be covered here), meaning that the battle turn count can trigger later than expected, and thus potentially surprising effects on the subsequent action executions before all the queued action execution subjects have executed all their valid actions.

Battle End Phase
It’s exactly the same as the turn based counterpart as well, since BattleManager.updateBattleEnd is the absolute last stop of both of the battle flows:

BattleManager.updateBattleEnd = function() {
    if (this.isBattleTest()) {
        AudioManager.stopBgm();
        SceneManager.exit();
    } else if (!this._escaped && $gameParty.isAllDead()) {
        if (this._canLose) {
            $gameParty.reviveBattleMembers();
            SceneManager.pop();
        } else {
            SceneManager.goto(Scene_Gameover);
        }
    } else {
        SceneManager.pop();
    }
    this._phase = "";
};

Note that SceneManager here is to change the scene from Scene_Battle to something else:
1. Exits the game in the case of battle test
2. Goes to the last scene(the one before this battle) if it’s not a game over
3. Goes to the game over scene(Scene_GameOver)

Update TPB Input
It’s always run at the end of a frame in TPBS, regardless of what the current phase of the battle is.
Basically, if there’s at least 1 inputable party members, BattleManager.updateTpbInput will call BattleManager.checkTpbInputClose, otherwise it’ll call BattleManager.checkTpbInputOpen:

BattleManager.updateTpbInput = function() {
    if (this._inputting) {
        this.checkTpbInputClose();
    } else {
        this.checkTpbInputOpen();
    }
};
BattleManager.checkTpbInputClose = function() {
    if (!this.isPartyTpbInputtable() || this.needsActorInputCancel()) {
        this.cancelActorInput();
        this._currentActor = null;
        this._inputting = false;
    }
};
BattleManager.checkTpbInputOpen = function() {
    if (this.isPartyTpbInputtable()) {
        if (this._tpbNeedsPartyCommand) {
            this._inputting = true;
            this._tpbNeedsPartyCommand = false;
        } else {
            this.selectNextCommand();
        }
    }
};

In the case of running BattleManager.checkTpbInputClose, it’s to void the currently inputting party member(the one whose action slots are being inputted by players) and the party inputability flag if the currently inputting party member becomes not inputable(BattleManager.isPartyTpbInputtable is mainly for handling edge cases here).
In the case of BattleManager.checkTpbInputOpen, the gist is that(the details are too advanced to be covered here), when at least 1 of the party members become inputable, the party inputability flag will be raised if it’s the 1st time the party becomes inputable(to show the party command window instead of the actor command window), otherwise BattleManager.selectNextCommand will be called:

BattleManager.selectNextCommand = function() {
    if (this._currentActor) {
        if (this._currentActor.selectNextCommand()) {
            return;
        }
        this.finishActorInput();
    }
    this.selectNextActor();
};

While the exact mechanism of raising the inputability flag and setting up the actor command window are too advanced to be covered here, the point is that BattleManager.selectNextActor will call BattleManager.changeCurrentActor, which will call BattleManager.startActorInput, and thus raise the inputability flag if the players are already inputting the action slots of an inputable party member.

Summary
First, the battle will start, and the phase will change to “start” upon fully starting the battle, with the catch that this phase will only trigger once, which is at the start of the battle.
Then, the phase will quickly change to “turn”.
After that, all battlers will charge their TPB, and will become inputable when theirs become full.
In the case of actors, the party command window will be setup for the 1st time such event triggers in this battle, otherwise the actor command window corresponding to the inputable party member with the smallest party index at that frame will be setup.
Whenever a battler becomes restricted, his/her/its TPB and cast bars will be cleared.
Players will input from the 1st action slot of the 1st inputable party member to the last action slot of the last inputable party member at any given frame.
Whenever the party becomes to have at least 1 inputable party member, the actor command window will be setup if an actor’s selected for inputting action slots, otherwise the party command window will be setup.
Whenever the party becomes to have no inputable party members, all the input windows will be closed.
When battlers finish inputting all their action slots, they’ll start casting those actions, until they’re fully cast, and this will cause those battlers to be pushed at the back of the action execution subject queue.
As long as no actions are already executing, the most up front battler in that queue will be picked up as the action execution subject to execute will be cast valid actions, and the phase will be changed to “action”.
When that action execution subject has executed all those cast valid actions, that battler will have the TPB and cast bars emptied, and the above process of picking up new action execution subject will be repeated, until there are no more battlers available as action execution subjects, in which the phase will be changed to “turn”.
If a battle turn’s supposed to be ended, the phase will be changed to “turnEnd”, but it’ll be immediately changed to “action” at the same frame if there are still action execution subjects to execute actions.
If a battle’s supposed to be ended, the phase will be changed to “battleEnd”, and the scene will be changed from the battle scene to something else, followed by changing the phase to empty.

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

Basic knowledge to the default RMMZ turn based battle flow implementations

This topic aims to share the basic knowledge on what the default RMMZ turn based battle flow implementations do in general, but you’re still assumed to have at least:
1. Little javascript coding proficiency(barely okay with writing rudimentary Javascript codes up to 300 LoC scale)
2. Basic knowledge on what the default RMMZ turn based battle flow does on the user level(At least you need to know what’s going on on the surface when playing it as a player)

Simplified Flowchart

Please note that this flowchart only includes the most important elements of the battle flow, to avoid making it too complicated and convoluted for the intended targeting audience :)

Start Battle
This is the phase handling the start of the battle(with the empty phase only being run once), until BattleManager.startInput will be called to change the phase to “input”.
To keep things simple here, only the parts that are common to all the 3 different ways(battle tests, normal encounters and event encounters) of starting battles will be covered.
The common parts start from BattleManager.setup, which initializes the battle phase as empty in BattleManager.initMembers:

BattleManager.initMembers = function() {
    this._phase = "";
    this._inputting = false;
    this._canEscape = false;
    this._canLose = false;
    this._battleTest = false;
    this._eventCallback = null;
    this._preemptive = false;
    this._surprise = false;
    this._currentActor = null;
    this._actionForcedBattler = null;
    this._mapBgm = null;
    this._mapBgs = null;
    this._actionBattlers = [];
    this._subject = null;
    this._action = null;
    this._targets = [];
    this._logWindow = null;
    this._spriteset = null;
    this._escapeRatio = 0;
    this._escaped = false;
    this._rewards = {};
    this._tpbNeedsPartyCommand = true;
};

Then, regardless of how the battles are started, either of the following will be called to start the battle scene:

SceneManager.goto(Scene_Battle);
SceneManager.push(Scene_Battle);

At the beginning of the scene life cycle(too advanced to be covered here), Scene_Battle.prototype.create will be called to call Scene_Battle.prototype.createDisplayObjects as well, which calls Scene_Battle.prototype.createAllWindows:

Scene_Battle.prototype.createAllWindows = function() {
    this.createLogWindow();
    this.createStatusWindow();
    this.createPartyCommandWindow();
    this.createActorCommandWindow();
    this.createHelpWindow();
    this.createSkillWindow();
    this.createItemWindow();
    this.createActorWindow();
    this.createEnemyWindow();
    Scene_Message.prototype.createAllWindows.call(this);
};

Here, Scene_Battle.prototype.createPartyCommandWindow and Scene_Battle.prototype.createActorCommandWindow are methods creating the party and actor command windows respectively, and these 2 are the windows that are parts of the battle flow.
As the scene life cycle reaches Scene_Battle.prototype.start, BattleManager.startBattle will be called to change the phase to “start”:

BattleManager.startBattle = function() {
    this._phase = "start";
    $gameSystem.onBattleStart();
    $gameParty.onBattleStart(this._preemptive);
    $gameTroop.onBattleStart(this._surprise);
    this.displayStartMessages();
};

When the events that are supposed to be run upon battle start are finished(how this is exactly done is too advanced to be covered here), Scene_Battle.prototype.update will call Scene_Battle.prototype.updateBattleProcess, which will call BattleManager.update, causing BattleManager.updatePhase to be called as well(frame updates in battle flow are too advanced to be covered here), and so BattleManager.updateStart will be called to call BattleManager.startInput, in order to change the phase to “input”, meaning that the battle is finally fully started:

BattleManager.startInput = function() {
    this._phase = "input";
    this._inputting = true;
    $gameParty.makeActions();
    $gameTroop.makeActions();
    this._currentActor = null;
    if (this._surprise || !$gameParty.canInput()) {
        this.startTurn();
    }
};

Input Actions
This phase starts from BattleManager.startInput and ends with BattleManager.startTurn, and it’s the phase where players can either try to escape the battle, or input all actions for all inputable party members, until BattleManager.startTurn is called to change the phase to “turn”, or BattleManager.processAbort is called to abort the battle.
First, Game_Unit.prototype.makeActions will be called, causing Game_Battler.prototype.makeActions to be called to make all battlers have their respective number of action slots determined by their respective Action Times+ at that moment:

Game_Battler.prototype.makeActions = function() {
    this.clearActions();
    if (this.canMove()) {
        const actionTimes = this.makeActionTimes();
        this._actions = [];
        for (let i = 0; i < actionTimes; i++) {
            this._actions.push(new Game_Action(this));
        }
    }
};

Note that Auto Battle and/or confused actors will automatically input all their action slots without player inputs because of Game_Actor.prototype.makeActions:

Game_Actor.prototype.makeActions = function() {
    Game_Battler.prototype.makeActions.call(this);
    if (this.numActions() > 0) {
        this.setActionState("undecided");
    } else {
        this.setActionState("waiting");
    }
    if (this.isAutoBattle()) {
        this.makeAutoBattleActions();
    } else if (this.isConfused()) {
        this.makeConfusionActions();
    }
};

Whereas all enemies will always automatically input all their action slots:

Game_Enemy.prototype.makeActions = function() {
    Game_Battler.prototype.makeActions.call(this);
    if (this.numActions() > 0) {
        const actionList = this.enemy().actions.filter(a =>
            this.isActionValid(a)
        );
        if (actionList.length > 0) {
            this.selectAllActions(actionList);
        }
    }
    this.setActionState("waiting");
};

As for inputability, an actor’s inputable if he/she/it’s alive, in battle and has no Restrictions enforced by states and no special flag Auto Battle.
As long as the party can input actions in the current turn(determined by whether it’s the 1st turn with a surprise battle start and whether any party member can input actions), this phase will proceed as follows:
1. Scene_Battle.prototype.changeInputWindow will call Scene_Battle.prototype.startPartyCommandSelection(its reasons are too advanced to be covered here), which setups the party command window:

Scene_Battle.prototype.changeInputWindow = function() {
    this.hideSubInputWindows();
    if (BattleManager.isInputting()) {
        if (BattleManager.actor()) {
            this.startActorCommandSelection();
        } else {
            this.startPartyCommandSelection();
        }
    } else {
        this.endCommandSelection();
    }
};
Scene_Battle.prototype.startPartyCommandSelection = function() {
    this._statusWindow.deselect();
    this._statusWindow.show();
    this._statusWindow.open();
    this._actorCommandWindow.setup(null);
    this._actorCommandWindow.close();
    this._partyCommandWindow.setup();
};

2a. If those players choose to escape, then Scene_Battle.prototype.commandEscape as the corresponding handler of the party command window(handlers are too advanced to be covered here) will be called to call BattleManager.processEscape.
The escape attempt will always succeed upon the 1st turn if the battle starts with preemptive, otherwise its probability of success is determined by the escape ratio at that moment, which is initially set as 0.5 * the average of agi of all party members in battle / the average of agi of all enemies in battle, and will increase by 0.1 per failed attempt.
2a(i). If the escape attempt succeeded, then BattleManager.onEscapeSucces will be called to call BattleManager.processAbort, which calls BattleManager.endBattle which the result argument as 1 to abort the battle(how battles are ended are too advanced to be covered here):

BattleManager.processAbort = function() {
    $gameParty.removeBattleStates();
    this._logWindow.clear();
    this.replayBgmAndBgs();
    this.endBattle(1);
};

2a(ii). If the escape attempt failed, then BattleManager.onEscapeFailure will be called to call BattleManager.startTurn, which starts the current turn and will be covered in the later parts of this post:

BattleManager.onEscapeFailure = function() {
    $gameParty.onEscapeFailure();
    this.displayEscapeFailureMessage();
    this._escapeRatio += 0.1;
    if (!this.isTpb()) {
        this.startTurn();
    }
};

Note that Game_Party.prototype.onEscapeFailure will call Game_Actor.prototype.onEscapeFailure for all party members, and so Game_Actor.prototype.clearActions will be called to void all action slots:

Game_Actor.prototype.onEscapeFailure = function() {
    if (BattleManager.isTpb()) {
        this.applyTpbPenalty();
    }
    this.clearActions();
    this.requestMotionRefresh();
};
Game_Actor.prototype.clearActions = function() {
    Game_Battler.prototype.clearActions.call(this);
    this._actionInputIndex = 0;
};

2b. If those players choose to fight, then Scene_Battle.prototype.commandFight use select next command(covered in the later parts of this post) to let those players input all actions of all inputable party members sequentially.
3. Those players will first input the 1st action slot of the 1st inputable party member, then the 2nd, 3rd, and finally the last action slot of that member, and those players will proceed with the same sequence for the 2nd inputable party member, finally those players will repeat this sequence until the last action slot of the last inputable party member is inputted, with the restriction that those players can never break nor escape this sequence without inputting all action slots of all inputable party members.
4. When inputting actions for inputable party members, players can use the ok command to proceed to the next action slot of the current member, or from the last action slot of that member to the 1st action slot of the next member(or start the current turn upon finish inputting the last action slot of the last member).
The ok command is handled by the actor command window(how it’s setup is too advanced to be covered here) using the handler Scene_Battle.prototype.selectNextCommand, which calls BattleManager.selectNextCommand to call Game_Actor.prototype.selectNextCommand:

Scene_Battle.prototype.selectNextCommand = function() {
    BattleManager.selectNextCommand();
    this.changeInputWindow();
};
BattleManager.selectNextCommand = function() {
    if (this._currentActor) {
        if (this._currentActor.selectNextCommand()) {
            return;
        }
        this.finishActorInput();
    }
    this.selectNextActor();
};
Game_Actor.prototype.selectNextCommand = function() {
    if (this._actionInputIndex < this.numActions() - 1) {
        this._actionInputIndex++;
        return true;
    } else {
        return false;
    }
};

5. Similarly, players can use the cancel command to proceed to the previous action slot of the current member, or from the 1st action slot of that member to the last action slot of the previous member(or setup the party command window upon cancelling the input of the 1st action slot of the 1st member).
The cancel command is handled by the actor command window using the handler Scene_Battle.prototype.selectPreviousCommand, which calls BattleManager.selectPreviousCommand to call Game_Actor.prototype.selectPreviousCommand:

Scene_Battle.prototype.selectPreviousCommand = function() {
    BattleManager.selectPreviousCommand();
    this.changeInputWindow();
};
BattleManager.selectPreviousCommand = function() {
    if (this._currentActor) {
        if (this._currentActor.selectPreviousCommand()) {
            return;
        }
        this.cancelActorInput();
    }
    this.selectPreviousActor();
};
Game_Actor.prototype.selectPreviousCommand = function() {
    if (this._actionInputIndex > 0) {
        this._actionInputIndex--;
        return true;
    } else {
        return false;
    }
};

6. While the exact traversals of this doubly linked list are too advanced to be covered here, the party command window(head sentinel node) and the turn start(tail sentinel node) are the start and end of this sequence respectively, while the ok and cancel commands are single steps for moving forward(next pointer) and backward(previous pointer) respectively.

Process Turns
To be precise, there are 2 phases in this part, which are “turn” and “turnEnd”.
The “turn” phase starts from having BattleManager.startTurn called upon inputting the last action slot of the last inputable party member, and ends with calling BattleManager.startAction to change the phase to “action”, or BattleManager.endTurn to change the phase to “turnEnd”:

BattleManager.startTurn = function() {
    this._phase = "turn";
    $gameTroop.increaseTurn();
    $gameParty.requestMotionRefresh();
    if (!this.isTpb()) {
        this.makeActionOrders();
        this._logWindow.startTurn();
        this._inputting = false;
    }
};

This changes the phase to “turn” and increases the battle turn count by 1.
Then, by calling BattleManager.makeActionOrders, the action order queue descendingly sorted by the speed of all battlers(the faster the battlers are the more up front they’re on this queue) at this moment will have all the inputted actions of all those battlers, with the ordering of all actions among the same battler unchanged from his/her/its action slot input sequence:

BattleManager.makeActionOrders = function() {
    const battlers = [];
    if (!this._surprise) {
        battlers.push(...$gameParty.battleMembers());
    }
    if (!this._preemptive) {
        battlers.push(...$gameTroop.members());
    }
    for (const battler of battlers) {
        battler.makeSpeed();
    }
    battlers.sort((a, b) => b.speed() - a.speed());
    this._actionBattlers = battlers;
};

Note that the speed of a battler is determined by the fastest action slot inputted by that battler(the skill/item with the lowest Speed).
After that, all battle events which should be run upon turn start will be run(how this is exactly done is too advanced to be covered here), and then BattleManager.updatePhase will call BattleManager.updateTurn:

BattleManager.updateTurn = function(timeActive) {
    $gameParty.requestMotionRefresh();
    if (this.isTpb() && timeActive) {
        this.updateTpb();
    }
    if (!this._subject) {
        this._subject = this.getNextSubject();
    }
    if (this._subject) {
        this.processTurn();
    } else if (!this.isTpb()) {
        this.endTurn();
    }
};

If there’s no action execution subject, BattleManager.getNextSubject will be used as a try to find the most up front alive battler in the action order queue at that moment, with all the dead ones removed from the queue before an alive one is found, and having found such a battler means that battler will be removed from the queue as well:

BattleManager.getNextSubject = function() {
    for (;;) {
        const battler = this._actionBattlers.shift();
        if (!battler) {
            return null;
        }
        if (battler.isBattleMember() && battler.isAlive()) {
            return battler;
        }
    }
};

If no such battler’s found, then the phase will change to “turnEnd” by calling BattleManager.endTurn(which will be covered in the later parts of this post).
If such a battler’s found, he/she/it’ll be the new action subject, and BattleManager.processTurn will be called to try to execute inputted actions of that battler:

BattleManager.processTurn = function() {
    const subject = this._subject;
    const action = subject.currentAction();
    if (action) {
        action.prepare();
        if (action.isValid()) {
            this.startAction();
        }
        subject.removeCurrentAction();
    } else {
        this.endAction();
        this._subject = null;
    }
};

An action is said to be valid upon execution if it’s forced or its user meets all the conditions of the corresponding skill/item upon execution.
If the action execution subject has no valid actions to execute, then BattleManager.endAction will be called(this will be covered in the later parts of this post), which will cause BattleManager.updateTurn to be called again later, meaning that another action execution subject has to be found, or the turn will just end.
If the action execution subject has valid actions to execute, then all the invalid ones will be discarded and the valid ones will be executed sequentially, by calling BattleManager.startAction, which makes the target queue of the current action to be executed and changes the phase to “action”:

BattleManager.startAction = function() {
    const subject = this._subject;
    const action = subject.currentAction();
    const targets = action.makeTargets();
    this._phase = "action";
    this._action = action;
    this._targets = targets;
    subject.cancelMotionRefresh();
    subject.useItem(action.item());
    this._action.applyGlobal();
    this._logWindow.startAction(subject, action, targets);
};

The “turnEnd” phase starts from having BattleManager.endTurn called upon having no more action execution subject to be found nor execute valid actions not yet executed, and ends with later calling BattleManager.updatePhase, which calls BattleManager.updateTurnEnd to change the phase to “start”:

BattleManager.endTurn = function() {
    this._phase = "turnEnd";
    this._preemptive = false;
    this._surprise = false;
};
BattleManager.updateTurnEnd = function() {
    if (this.isTpb()) {
        this.startTurn();
    } else {
        this.endAllBattlersTurn();
        this._phase = "start";
    }
};

Execute Actions
It basically starts from BattleManager.startAction and ends with BattleManager.endAction to change the phase to “turn”.
It’s the phase where the current action execution subject will, after discarding all the invalid actions, execute all the valid ones sequentially, which the ordering unchanged from the action slot input sequence of that subject.
As far as only the current action execution subject is concerned, this phase will proceed as follows:
1. The 1st valid action that aren’t executed yet will be executed after showing its start using the battle log window(how Window_BattleLog works is too advanced to be covered here).
2. Upon the start of the execution, BattleManager.updatePhase will call BattleManager.updateAction, which tries to find the 1st target in the target queue of the action to be executed:

BattleManager.updateAction = function() {
    const target = this._targets.shift();
    if (target) {
        this.invokeAction(this._subject, target);
    } else {
        this.endAction();
    }
};

If such target’s found, that target will be removed from the queue and BattleManager.invokeAction will be called:

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");
};

For now, you just need to know that Window_BattleLog is way more than just a battle log window, as it actually coordinates all the visual display sequences in the battle flow(also too advanced to be covered here).
If no such target’s found, then BattleManager.endAction will be called to change the phase to “turn”:

BattleManager.endAction = function() {
    this._logWindow.endAction(this._subject);
    this._phase = "turn";
    if (this._subject.numActions() === 0) {
        this.endBattlerActions(this._subject);
        this._subject = null;
    }
};

Summary
The battle first starts with the empty phase.
The empty phase will always change to “start” after finished preparing to start the battle.
The “start” phase will always change to “input” after finished starting the battle to try to let players input actions for all inputable party members.
All battlers will use their respective Action Times+ at that moment to determine their respectively number of action slots they can have in the current turn.
If there’s no such member or the battle starts with surprise, the battle phase will immediately change to “turn”.
Otherwise players will either try to escape the battle, or sequentially input from the 1st action slot of the 1st inputable party member to the last one of the last such member.
A sucess escape attempt will abort the battle while a failed one will change the phase to “turn” without inputting any action slot of any inputable party member.
The battle phase will change to “turn” when all actions slots of all inputable party members are inputted.
The “turn” phase will try to sequentially execute actions from the 1st inputted valid ones of the fastest alive battler at that moment to the last inputted valid ones of the slowest alive battler at that moment.
Whenever the 1st inputted valid action not executed yet by the current action execution subject is to be executed now, the phase will change to “action”.
When there are no more alive battlers left to execute valid actions that aren’t executed yet, the phase will change to “turnEnd”, which will soon change to “start”.
The “action” phase will try to sequentially invoke the currently valid action to be executed into each of its targets and remove that target from the action target queue.
When that action target queue has no more targets, the phase will change to “turn”.

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

From Trust To Hypothetical Thinking

We all know that trust is one of the most important aspects in our lives, yet it doesn’t mean everyone can handle it well, and sometimes some people are so bad on it that many problems in their lives are due to that. As far as I know, the maturity of thinking about trust can at least be categorized into following levels – from the most dysfunctional to the most effective and efficient, even though it’s clearly oversimplified and it’s entirely possible that there are even lower and higher levels than those listed below:

Level 1

Some people either always completely trust everything or always completely distrust everything without even assessing what that thing is, and we know that’s it’s so unrealistic and overgeneralized that only very immature people won’t see past that. Fortunately, such naive people are extremely rare, and they won’t remain that uneducated for long.

For instance, some people do deeply believe that they can only trust themselves and everyone else is always completely untrustworthy while they know next to nothing about any of the others. Needless to say, their lives will be in deep struggles when everyone is so connected to each other and the demands of a person becomes so complex in the modern world that it’s incredibly hard to be totally self-sufficient forever.

For those who choose to always completely trust everything, they’ll soon fathom the truth that something really can’t be trusted at all, and either they’ll ascend to Level 2, or go to the other extreme – always completely distrust everything, which will cause their lives to be even more miserable. Anyway, they’ll soon see past the false dilemma between trusting everything and distrusting everything, thus it’s very improbable that they won’t ever ascend to Level 2 in their lives.

Level 2

Some people are better in that, they know that not everything can be trusted but there are still something trustworthy. However, they still either completely trust something or completely distrust something, and they’ll quickly judge whether something is trustworthy or not, so it’s still a rather black and white thinking that doesn’t work well in reality, and this inflexibility, albeit not uncommon at all, will soon hit such people so hard that they’ll have to relearn what trust really is sooner or later.

For instance, those deeply suffering from confirmation bias without even knowing will likely just use the first impression from someone to decide whether that person can be completely trusted or is completely untrustworthy, and will never reevaluate the decision until the reality teaches those people a tough lesson. Of course, judging someone using the first impression alone is judgmental to the extreme, and the negative consequences are so obvious that it’s even hard for those people themselves to look the other way.

For the things they completely trust, quite some of them will turn out to be untrustworthy, so those people will turn from completely trusting them to completely distrusting them, and if there are more and more such things, those people will distrust more and more things in their lives, therefore the whole trend will induce them to descend to Level 1 – always completely distrusting everything. On the bright side, because it’s even harder to remain on Level 1 than ascending from Level 2 to Level 3, when those people ascend back to Level 2 after descending to Level 1, they’ll be forced to let go of the false dilemma between complete trust and complete mistrust towards something, and hence ascend to Level 3.

Level 3

Some people realize that trust isnt either all or nothing, but rather a continuous spectrum, so instead of just thinking whether something is trustworthy or not, they’ll also think about how much it can be trusted, so itll take them some time to be familiar with something before evaluating how much it can be trusted. Still, it’s a static thinking that misses the key that how much something can be trusted can change over time under certain conditions(unless such signs are so obvious that it’s impossible for such people to miss them), so they’ll be eventually caught completely off guard, even when there were already so many warning signs that they completely missed(because they never have the habit to actively seek for such signs to begin with), and they’d have long decreased the amount of trust if they noticed those signs.

For instance, let’s say an employee has worked in a company for a year, and the track record of that employee suggests that, while that employee isn’t trustworthy enough to take the most crucial and difficult tasks, that employee is trustworthy enough to take some other important tasks that are still somewhat challenging but nowhere as difficult. However, because that employee mentally suffers deeply from suddenly becoming single without knowing what’s going on, that employee can no longer function as effectively and efficiently as before, so some of the latest important tasks, which is very similar than those done well by that employee, suddenly failed badly, even though that employee didn’t even try to hide the personal suffering in the company.

As the boss decided that that employee is that trustworthy solely based on the performance of that employee over the last year, without even trying to periodically check for any abnormalities from that employee, that boss missed many obvious signs from that personal suffering and assigned those tasks to that employee anyway, hence causing the totally unexpected failure from that employee. While it’s clear that that employee is also at fault and responsible for not actively informing the boss about the personal suffering and its impact of future performance, the point remains that assuming that the trustworthiness of something is a constant to be found can be very dangerous, so unless those people at this level still didn’t grasp the utter horror of even lower levels, they should figure out the problem of not dynamically adjusting the amount of trust of something over time, and thus ascend to Level 4.

Level 4

At this point, some people finally understand that trust is actually dynamic rather than static, so dynamic thinking is needed when thinking about trust, meaning that instead of just using past experience and track record to judge how trustworthy something is right now, theyll also consistently look for both positive and negative signs at the present moment, therefore they can take these present factors of changes of trustworthiness into account as well. Although its already pragmatic enough to think about trust this way and not many has already reached this level, the problem is that it’s just reactive rather than proactive, so while they can quickly adjust the amount of trust towards something after those factors of changes have already manifested, they’re still just passively reacting to these signs instead of actively trying to figure out the essence behind those factors.

Let’s say there’s another employee who was prolific and reliable at the start slowly became less and less effective and efficient, and eventually dysfunctional altogether due to prolonged covert workplace bullying hidden from the boss. So the boss, noticing this trend without knowing the root cause behind this issue, could only try to ask that employee about the lengthened performance drop, while gradually assigning less and less challenging and important tasks to that employee, with the benefits given to that employee being smaller and smaller, and had to unwillingly fire that employee at the end, because the boss failed to know the truth that way.

Although it’s hard to blame the boss for not knowing what’s really going on with that employee when that employee didn’t even try to report anything, it still shows the issues of just passively reacting to the changes of the amount of trustworthiness, as it could’ve been become more rather than less trustworthy if the underlying conditions of changes were revealed. If the boss tried to proactively investigate what makes the employee appear to be less and less trustworthy besides just asking that employee personally, the boss might have discovered the workplace bullying in secret and kept an originally competent and loyal employee, rather than having to reluctantly fire that employee and possibly repeating the history in the future unknowingly.

Level 5

This is where proactive thinking comes in, but people of this level are hard to find as it’s hard to keep being on this level, and the paradox is that they don’t consciously emphasize trust anymore, because to them hypothetical thinking is much more flexible and responsive when it comes to constantly reassess the essence of the ever changing conditions behind the factors that increases and decreases the amount of trustworthiness towards something. So instead of thinking about how much something can be trusted at any moment, they think about on what probability that how something will behave under what conditions, and the essence behind the when and why of such correlations and causation hold, so once those underlying conditions change, those people can immediately adjust and correct their hypotheses while reconsidering whether and which previously established contingencies need to be executed(or swiftly come up with a backup plan that didn’t exist beforehand), and when they’ll be executed to what extents.

For example, an employee formerly working for a rival company has demonstrated extraordinary competence and willingness to take the most challenging and important tasks in the current company without asking anything extra in return, and that employee can get them done all exceptionally well, so the current boss happily give that employee more and more privilege and recognition within the company, and thus that employee can ascend incredibly quickly there, regardless of the fact that that employee was frequently badmouthing the previous employer, which is the rival company.

But as what that employee has shown is far too good to be true and the badmouthing of the rival company from that employee doesn’t match what the boss knows about that company, the boss can’t stop to suspect that that employee, which worked for a rival company, is just acting and up to something even bigger, so on one hand the boss appeared to have complete trust over that employee by giving that employee sole discretion over a new and large project that demands access to valuable company secrets to lower the guard of that employee, but on the other hand privately asked a trustworthy security expert in the current company to silently monitor the activities in that project from that employee behind the scenes. It turns out that that employee being suspected is actually an industrial espionage still working for that rival company, and is assigned to elusively install an undetectable backdoor deep inside the new project using internal software systems that can access the most confidential and sensitive algorithms and data of the current company, so the rival company can later invisibly hack into that backdoor to steal those crucial information while keeping a low profile, and the frequent badmouthing from that employee about that rival company is just a cover-up.

Hypothetical Thinking

While it’s clear that it’d be overkill and exhausting to use hypothetical thinking over trivial matters as well, when it comes to the key moments of determining the trustworthiness of something vital, hypothetical thinking can still come into handy. Also, do note that thinking about trust and hypothetical thinking don’t have to be mutually exclusive, and in fact they can work well together, even though such unison will never be easy nor cheap.

Although there are many factors affecting the trustworthiness of someone, usually the most subjective and unclear one is motivation, which can be broken into at least these following 5 basic building blocks:

  1. What does that someone need to get right now?
  2. What does that someone need to avoid right now?
  3. What does that someone want to get right now?
  4. What does that someone want to avoid right now?
  5. What is the emotional statuses of that someone right now?

Other factors, like whether that someone has the experience, knowledge, information, resources and technique to get something done, while still absolutely necessary to determine the trustworthiness of that someone over that something, are usually much more tangible and visible to the others, so if one can reliably comprehend the basic building blocks constituting the motivation of someone, the other factors should also be of little challenge. As long as one can keep in touch with the factors constituting the trustworthiness of someone, that someone will unlikely to suddenly change from very trustworthy to very untrustworthy without being noticed beforehand, so it’s generally hard to back-stab those with hypothetical thinking as their second nature, at least not with them unprepared.

When using hypothetical thinking, one doesn’t just come up with a single hypothesis and call it a day, but should instead explore at least several ones that are reasonably likely to warrant further verification, and act on the currently most probable one, with contingencies designated to handle cases when that hypothesis is proven to be wrong, until its proven to be wrong and act on another hypothesis. Do note that besides having to actively and consistently look for signs both supporting and negating the hypotheses, while a hypothesis can be the most probable one right now, after some time with some changes, another hypothesis can become the most probable one later, and sometimes one even needs to generate new hypotheses on the fly, so the whole hypothetical thinking is a constantly dynamic process, and there should be as few unsupported assumptions as possible at any moment.

Of course, it’s impossible to be even near perfect, so no matter how experienced, knowledgeable and skillful in practicing hypothetical thinking in real lives, there will always be times where one will be caught completely off guard, so hypothetical thinking isn’t about trying to eliminate uncertainty and the concept of trust altogether, but rather minimize the amount of uncertainty and reliance of trust while accepting that uncertainty is a nature of lives and trust that one can deal with most of the remaining uncertainty most of the time. Because of that, those practicing hypothetical thinking should also be ready to be completely caught off guard, and that means theyll have to be able to be very flexible, spontaneous and versatile at any time, even though one will have to take very complicated and convoluted paths to get there.

Combining everything, those with hypothetical thinking in mind first observe and test someone for a while, then act on a hypothesis based on the initial track record of that someone collected during that period, and those people will continue to look for signs that indicate both the increase and decrease the trustworthiness of that someone. If the hypothesis suggests that some such positive or negative signs will manifest and they mostly do, then the hypothesis is somehow verified and should be kept, otherwise its shown to be less and less accurate and should be tweaked somehow, and when there are enough such significant mismatches, the hypothesis will be proven to be dead wrong so those people will have to act on a new hypothesis, and the whole cycle will repeat again and again.

Why Outsourcing Core Business Functions Can Be Dangerous

Outsourcing business functions is nothing new in the business world, and is actually a very common and well-established practice, although whether it’s a wise decision depends on the concrete circumstances.

On the other hand, outsourcing core business functions is generally quite dangerous, because you can end up falling into a rather disadvantageous scenario, as demonstrated in the following example.

Situation

A company has its headquarter in a very well-developed city(so its various expenditures will be much higher), and 3 branches in 3 different other much, much less developed cities(so their various expenditures will be much lower) all being very far away from the headquarter, where each branch runs a core business function outsourced by the headquarter:

Branch A runs most of the back end for the core business of the whole company

Branch B runs the 24 hour call center and most of the customer support services for the whole company

Branch C runs most of the software testing and sales activities for the whole company

Of course, each branch is also responsible for expanding the markets in their respective cities, and they’re allowed to take a large portion of the profits from those markets by running their own business, in order to motivate and reward them for more effective and efficient market expansion(they’ll also take a small portion of the profits from the core business of the headquarter so the branch will still have the incentive to keep the core business running).

Back to the headquarter, it runs most of the front end for the core business of the whole company(and takes a large portion of profits from the core business), and is responsible for finding new customers and maintaining existing ones, even though the headquarter will also take a small portion of the profits from the business owned by its branches.

This seems to be a decent setup that can significantly lower long-term expenditures and raise overall profits, but actually there’s a big problem: The headquarter will likely have less and less control over its branches, which will be more and more powerful due to its own businesses growing over time.

Problem

So, if you were the head of a branch, and you can frequently pretend to obey the headquarter while actually ignoring its orders, will you focus primarily on the core business of the headquarter, or the business owned by the branch?

Needless to say, you’ll choose to work on the latter most of the time, and will only work on the former when it delays too much, because you can take a large portion of the profits from the latter but only a small portion of those from the former, and not working on the latter will mainly hurt your branch while not working on the former will mainly hurt the headquarter.

As time passes, the branches will become more and more independent from the headquarter, because they’ll rely on more and more on their own business and less and less on the core business of the headquarter, whereas the headquarter will become harder and harder to control the branches, because its situation will become more and more dire while those of those branches will become better and better.

By the time the business owned by those branches become mature enough for those branches to totally ignore the core business of the headquarter, it’s when the headquarter will be forced to submit into those branches, because the headquarter still needs those branches to keep its core business running, and now it’s already too late to try to take back control from those branches or migrate those outsourced core business functions from those branches to somewhere else(or just taking them back and let the headquarter run all those functions itself).

Normally, the headquarter should be the one controlling its branches but not the other way around, however the control can indeed be reversed if the headquarter does outsource its core business function into its branches, so how to prevent that from happening in the first place?

Solution

The simplest solution is, of course, never outsourcing core business functions to begin with, but sometimes it has to be done to keep the expenditures low enough by utilizing resources in less developed cities, therefore some other ways have to be found to somehow even out the odds.

In the short term, when a branch’s just established, the headquarter should find the most trustworthy ones to run its branches in the first place, and they have to be almost absolutely trustworthy for a long time(whether it’s because they’ve such high integrity or the headquarter has their key weaknesses on its hands), to ensure that they won’t betray the headquarter so easily even when their self-interests will be more and more inclined to do so.

In the medium term, when a branch becomes able to take care of itself, a system should be implemented to mitigate the potential conflicts of interests among the headquarters and its branches, like when a branch starts to ignore the core business function outsourced from the headquarter, the branch should take a larger and larger portion of the profits from the core business of the headquarter and smaller and smaller portion of those from the business owned by that branch, and when it’s more important to expand the market assigned by that branch, the opposite adjustment should be made accordingly, so the branch will be more rewarded for focusing on what it should focus on at any moment.

In the long term, when a branch starts to intend to become independent, the core business function outsourced to it should also be outsourced to a new branch that is far from being able to stand on its own feet, so the headquarter won’t have to totally rely on the former branch(albeit the whole mitigation process can take years), probably even at the hefty cost of having to open a new branch, which would be also responsible for opening yet another market.

Of course, even these measures won’t last forever, because eventually the headquarter can have so many branches(even when some of them will be sub-branches of other branches) that it won’t be able to control anymore, but at least the risk of outsourcing core business function won’t be as unmanageable as before, and nearly no company can last forever anyway.

Evaluation

So far it’s all about outsourcing core business functions from the headquarter to its branches, but how about outsourcing them to foreign and popular companies(with excellent reputation) specialized in such functions? It really depends on the functions and the companies planning to have them outsourced, like outsourcing a crucial database to companies running database centers is already quite different from outsourcing a 24 hour call center to respective companies, because different functions have different risks associated to them, and their respective companies can have different reasons to go against your best interests.

For instance, while outsourcing a crucial database to a normally good company is usually wise, that company can also be interested by powerful and resourceful hackers(due to its high popularity and excellent reputation), so that company can be more prone to be targeted by sophisticated attacks, therefore although that company should also have quite a good defense against such attacks, once an attack succeeded, the database being outsourced can become totally compromised.

Whereas outsourcing a core business function to an unknown company in a foreign country can have some other risks, like asking one such company to write the cross-platform front-end of a mobile app for you, and you can end up being effectively blackmailed by that company, perhaps the app will be stable at the beginning of production but have more and more bugs later on(so you’ll have to pay more and more money to ask it to fix the bugs), and perhaps you can even end up having to give it a hefty sum so you can take back the codebase of that front-end and fix all those artificially created bugs yourself(of course you’ll also have to hire some new employees to do that).

On the other hand, just because outsourcing a core business function can be dangerous, it doesn’t mean one should never do so, because sometimes the resource and technical requirements for running that function can be much higher than what a company possesses in the foreseeable future, and this restriction alone shouldn’t always mean a company shouldn’t even have a try on such function, it’s just that outsourcing a core business function, no matter how big and strong a company is, should be a very serious(and perhaps irreversible) decision that can never be taken lightly.

How DVCS Can Be Used Outside Of Software Engineering

Most seasoned professional software engineering teams probably understand the immense value of DVCS in their jobs, but it seems to me that the concepts of DVCS isn’t used much outside of software engineering, even when DVCS has existed for way more than a decade already, which is quite a pity for me.

So how DVCS can be used outside of software engineering? Let’s show it using the following example:

  1. You’ve a front-line customer service job(sitting on a booth with the customer on the other side while you’re using a computer to do the work) which demands you to strictly follow a SOP covering hundreds of cases(each of your cases will be checked by a different supervisor but no one knows who that supervisor will be beforehand), and the most severe SOP breach can cause you to end up going to jail(because of unintentionally violating serious legal regulations)
  2. You’ve to know what cases should be handled by yourselves and what have to be escalated to your supervisors(but no one knows which supervisor will handle your escalation beforehand), because escalating too many cases that could’ve been handled by yourselves will be treated as incompetent and get yourselves fired, while handling cases yourselves that should’ve been escalated is like asking to be fired immediately
  3. As the SOP is constantly revised by the upper management, it’ll change quite a bit every several weeks on average, so the daily verbal briefing at the start of the working day is always exercised, to ensure all of you will have the updated SOP, as well as reminding what mistakes are made recently(but not mentioning who of course)
  4. Clearly, a SOP of this scale with this frequency and amount of changes won’t be fully written in a black and white manner(it’d cost hundreds of A4 papers per copy), otherwise the company would’ve to hire staffs that are dedicated to keep the SOP up to date, in which the company will of course treat this as ineffective and inefficient(and wasting tons of papers), so the company expects EVERYONE(including the supervisors themselves) to ALWAYS have ABSOLUTELY accurate memory when working according to the SOP
  5. As newcomer joins, they’ve about 2 months to master the SOP, and senior staff of the same ranks will accompany these newcomers during this period, meaning that the seniors will verbally teach the newcomers the SOP, using the memory of the former and assuming that the latter will remember correctly

Needless to say, the whole workflow is just asking for trouble, because:

  1. Obviously, no one can have absolutely accurate memory, especially when it’s a SOP covering hundreds of cases, so it’s just incredibly insane to assume that EVERYONE ALWAYS have ABSOLUTELY accurate memory on that, but that’s what the whole workflow’s based on
  2. As time passes, one’s memory will start to become more and more inaccurate gradually(since human’s memory isn’t lossless), so eventually someone will make a mistake, and the briefing on the upcoming several days will try to correct that, meaning that the whole briefing thing is just an ad-hoc, rather than systematic, way to correct the staff’s memories
  3. Similarly, as newcomers are taught by the seniors using the latter’s memory, and human communications aren’t lossless either, it’s actually unreasonable to expect the newcomers to completely capture the SOP this way(because of the memory loss of the seniors, the information loss in the communication, and the memory loss of the newcomers, which is essentially the phenomenon revealed by Chinese whipsers), even when they’ve about 2 months to do so
  4. As each of your cases will be checked by a different supervisor and no one knows who that supervisor will be beforehand, and supervisors will also have memory losses(even though they’ll usually deny that), eventually you’ll have to face memory conflicts among supervisors, without those supervisors themselves even realizing that such conflicts among them do exist(the same problem will eventually manifest when you escalate cases to them, and this includes whether the cases should actually be escalated)
  5. Therefore, overtime, the memories on the SOP among the staff will become more and more different from each other gradually, eventually to the point that you won’t know what to do as the memory conflicts among the supervisors become mutually exclusive at some parts of the SOP, meaning that you’ll effectively have to gamble on which supervisor will handle your escalation and/or check your case, because there’s no way you can know which supervisor will be beforehand

Traditionally, the solution would be either enforcing the ridiculously wrong assumption that EVERYONE must ALWAYS have ABSOLUTELY accurate memory on a SOP worth hundreds of A4 papers even harder and more ruthlessly, or hiring staff dedicated to keep the written version of the SOP up to date, but even the written version will still have problems(albeit much smaller ones), because:

  1. As mentioned, while it does eliminate the issue of gradually increasing memory conflicts among staff overtime, having a written version per staff member would be far too ineffective and inefficient(not to mention that it’s a serious waste of resources)
  2. When a written version of the SOP has hundreds of A4 papers and just a small parts of the SOP change, those staff dedicated to keep the SOP up to date will have to reprint the involved pages per copy and rearrange those copies before giving them back to the other staff, and possibly highlight the changed parts(and when they’re changed) so the others won’t have to reread the whole abomination again, and this will constantly put a very heavy burden on the former
  3. Because now the staff will rely on their own copies of the written version of the SOP, if there are difference among those written versions, the conflicts among the SOP implementations will still occur, even though now it’d be obvious that those staff dedicated to keep the SOP up to date will take the blame instead(but that’d mean they’ll ALWAYS have to keep every copy up to date IMMEDIATELY, which is indeed an extremely harsh requirement for them)
  4. As it’d only be natural and beneficial for the staff to add their own notes onto their own copies of the written version of the SOP, when those written versions get updated, some of their notes there can be gone because those involved pages will be replaced, so now those staff might have to rewrite those notes, regardless of whether they’ve taken photos on those pages with their notes beforehand(but taking such photos would risk leaking the SOP), which still adds excessive burden on those staff
  5. As you’re supposed to face customers at the other side of the booth while you’re using a computer to do the work, it’d be detrimental on the customer service quality(and sometimes this can lead to the customer filing formal complaints, which are very major troubles) if you’ve to take out the written version of the SOP in front of the customer when you’re not sure what to do in this case, even though it’s still way, way better than screwing up the cases

Combining all the above, that’s where DVCS for the SOP can come into play:

  1. Because now the written version of the SOP is a soft copy instead(although it still works for soft copies without DVCS), this can be placed inside the system and the staff can just view it on the computer without much trouble, since the computer screen isn’t facing the customer(and this largely mitigates the risk of having the staff leak out the written version of the SOP)
  2. Because the written version of the SOP‘s now in a DVCS, each staff will have its own branch or fork of the SOP, which can be used to drop their own private notes there as file changes(this assumes that the SOP is broken down into several or even dozens of files but this should be a given), and their notes can be easily added back to the updated versions of the files having those notes previously added, by simply viewing the diff of those files(or better yet, those notes can also be completely separate files, although it’d mean the staff have to know which note files corresponds to which SOP files, which can be solved by carefully naming all those files and/or using well-named folders)
  3. Because the written version of the SOP‘s now centralized in the system(the master branch), every staff should’ve the same latest version, thus virtually eliminating the problems caused by conflicts among different written versions from different staff members, and the need of the dedicated manual work to ensure they’ll remain consistent
  4. Clearly, the extra cost induced from this DVCS application is its initial system setup and the introduction to newcomers of using DVCS at work, which are all one time costs instead of long-term ones, and compared to the troubles caused by other workflows, these one time costs are really trivial
  5. Leveraging the issues and pull requests features(but using blames as well might be just too much) in any decent DVCS, any staff can raise concerns on the SOP, and they’ll either be solved, or at least the problems will become clear for everyone involved, so this should be more effective and efficient than just verbal reflections towards any particular colleagues and/or supervisors on difficulties faced(if called for, anonymous issues and pull requests can even be used, although it’d seem to be gone overboard)

So the detailed implementation of the new workflow can be something like this:

  1. The briefing before starting the work of the day should still take place, as it can be used to emphasize the most important SOP changes and/or the recent mistakes made by colleagues(as blames not pointing to anyone specific) in the DVCS, so the staff don’t have to check all the recent diffs themselves
  2. Whenever you’re free, you can make use of the time to check the parts in the SOP of your concern from the computer in your booth, including parts being unclear to you, recent changes, and even submit an anonymous issue for difficulties you faced on trying to follow those parts of the SOP(or you can try to answer some issues in the DVCS made by the others as a means of helping them without having to leave your booth or explicitly voice out to avoid disturbing the others)
  3. When you’re facing a customer right in front of you and you’re unsure what to do next, you can simply ask the customer to wait for a while and check the involved parts of the SOP without the customer even noticing(you can even use issues to ask for help and hope there are colleagues that are free and will help you quickly), thus minimizing the damages caused to the customer service quality
  4. To prevent the DVCS from being abused by some staff members as a poor man’s chat room at work, the supervisors can periodically check a small portions of the issues, blames and pull requests there as samples to see if they’re just essentially conversations unrelated to work, and the feature of anonymity can be suspended for a while if those abusers abuse this as well(if they don’t use anonymity when making those conversations, then the supervisors can apply disciplinary actions towards them directly), but don’t always check all of them or those supervisors would be exhausted to death due to the potentially sheer number of such things
  5. Of course, you still have to try to master the SOP yourselves, as the presence of this DVCS, which is just meant to be an AUXILIARY of your memory, doesn’t mean you don’t have to remember anything, otherwise you’d end up constantly asking the customer to have unnecessary waits(to check the SOP) and asking colleagues redundant questions(even with minimal disruptions), causing you to become so ineffective and inefficient all the time that you’ll still end up being fired in no time

Of course, it’s easier said than be done in the real world, because while setting up a DVCS and training new comers to use it are both easy, simple and small tasks, the real key that makes things complicated and convoluted is the willingness for the majority to adopt this totally new way of doing things, because it’s such a grand paradigm shift that’s wholeheartedly alien to most of those not being software engineers(when even quite some software engineers still reject DVCS in situations clearly needing it, just think about the resistance imposed by the outsiders).

Also, there are places where DVCS just isn’t suitable at all, like emergency units having to strictly follow SOPs, because the situations would be too urgent for them to check the SOP in DVCS even if they could use their mobile phones under such circumstances, and these are some cases where they do have to ALWAYS have ABSOLUTELY ACCURATE memories, as it’s already the least evil we’ve known so far(bear in mind that they’d already have received extensive rigorous training for months or even years before being put into actions)

Nevertheless, I still believe that, if some big companies having nothing to do with software engineering are brave enough to use some short-term projects as pilot schemes on using DVCS to manage their SOPs of their staffs, eventually more and more companies will realize the true value of this new ways of doing things, thus causing more and more companies to follow, eventually to the point that this becomes the norm across multiple industries, just like a clerk using MS Office in their daily works.

To conclude, I think that DVCS can at least be applied to manage some SOPs of some businesses outside of software engineering, and maybe it can be used for many other aspects of those industries as well, it’s just that SOP management is the one that I’ve personally felt the enormous pain of lacking DVCS when it’s obviously needed the most.

Control variables in reproducible fair tests might not be as simple as you think

Let’s say that there’s a reproducible fair test with the following specifications:

  1. The variable to be tested is A
  2. All the other variables as a set B is controlled to be K
  3. When A is set as X, the test result is P
  4. When A is set as Y, the test result is Q

Then can you always safely claim that, X and Y must universally lead to P and Q respectively, and A is solely responsible for the difference between P and Q universally?

If you think it’s a definite yes, then you’re probably oversimplifying control variables, because the real answer is this: When the control variables are set as K, then X and Y must lead to P and Q respectively.

Let’s show you an example using software engineering(Test 1):

  1. Let’s say that there’s a reproducible fair test about the difference of impacts between procedural, object oriented and functional programming paradigms on the performance of the software engineering teams, with the other variables, like project requirements, available budgets, software engineer competence and experience, software engineering team synergy, etc, controlled to be the same specified constants, and the performance measured as the amount and the importance of the conditions and constraints fulfilled in the project requirements, the budget spent(mainly time), the amount and the severity of unfixed bugs, etc.
  2. The result is that, procedural programming always performs the best in all the project requirement fulfillment, budget consumption, with the least amount of bugs, all being the least severe, and the result is reproducible, and this result seems to be scientific right?
  3. So can we safely claim that procedural programming always universally performs the best in all those regards? Of course it’s absurd to the extreme, but those experiments are indeed reproducible fair tests, so what’s really going on?
  4. The answer is simple – The project requirements are always(knowingly or unknowingly) controlled to be those inherently suited for procedural programming, like writing the front end of an easy, simple and small website just for the clients to conveniently fill in some basic forms online(like back when way before things like Google form became a real thing), and the project has to be finished within a very tight time scope.
  5. In this case, it’s obvious that both object oriented and functional programming would be overkill, because the complexity is tiny enough to be handled by procedural programming directly, and the benefits of both of the former need time to materialize, whereas the tight time scope of the project means that such up front investments are probably not worth it.

If the project’s changed to write a 3A game, or a complicated and convoluted full stack cashier and inventory management software for supermarkets, then I’m quite sure that procedural programming won’t perform the best, because procedural programming just isn’t suitable for writing such software(actually, in reality, the vast majority of practical projects should be solved using the optimal mix of different paradigms, but that’s beyond the scope of this example).

This example aims to show that, even a reproducible fair test isn’t always accurate when it comes to drawing universal conclusions, because the contexts of that test, which are the control variables, also influence the end results, so the contexts should always be clearly stated when drawing the conclusions, to ensure that those conclusions won’t be applied to situations where those conclusions no longer hold.

Another example can be a reproducible fair test examining whether proper up front architectural designs(but that doesn’t mean it must be waterfall) are more productive than counterproductive, or visa versa(Test 2):

  1. If the test results are that it’s more productive than counterproductive, then it still doesn’t mean that it’s universally applicable, because those project requirements as parts of the control variables can be well-established and being well-known problems with well-known solutions, and there has never been abrupt nor absurd changes to the specifications.
  2. Similarly, if the test results are that it’s more counterproductive than productive, then it still doesn’t mean that it’s universally applicable, because those project requirements as parts of the control variables can be highly experimental, incomplete and unclear in nature, meaning that the software engineering team must first quickly explore some possible directions towards the final solution, and perhaps each direction demands a PoC or even a MVP to be properly evaluated, so proper architectural designs can only be gradually emerged and refined in such cases, especially when the project requirements are constantly adjusted drastically.

If an universally applicable conclusion has to be reached, then one way to solve this is to make even more fair tests, but with the control variables set to be different constants, and/or with different variables to be tested, to avoid conclusions that actually just apply to some unstated contexts.

For instance, in Test 2, the project nature as the major part of the control variables can be changed, then one can check if the following new reproducible fair tests testing the productivity of proper up front architectural designs will have changed results; Or in Test 1, the programming paradigm to be used can become a part of the control variables, whereas the project nature can become the variable to be tested in the following new reproducible fair tests.

Of course, that’d mean a hell lot of reproducible fair tests to be done(and all those results must be properly integrated, which is itself a very complicated and convoluted matter), and the difficulties and costs involved likely make the whole thing too infeasible to be done within a realistic budget in the foreseeable future, but it’s still better than making some incomplete tests and falsely draw universal conclusions from them, when those conclusions can only be applied to some contexts(and those contexts should be clearly stated).

Therefore, to be practical while still respectful to the truth, until the software engineering industry can finally perform complete tests that can reliably draw actually universal conclusions, it’s better for the practitioners to accept that many of the conclusions there are still just contextual, and it’s vital for us to carefully and thoroughly examine our circumstances before applying those situational test results.

For example, JavaScript(and sometimes even TypeScript), is said to suck very hard, partly because there are simply too many insane quirks, and writing JavaScript is like driving without any traffic rules at all, so it’s only natural that we should avoid JavaScript as much as we can right?

However, to a highly devoted, diligent and disciplined JavaScript programmer, JavaScript is one of the few languages that provide the amount of control and freedom that are simply unthinkable in many other programming languages, and such programmers can use them extremely effectively and efficiently, all without causing too much technical debts that can’t be repaid on time(of course, it’s only possible when such programmers are very experienced in JavaScript and care a great deal about code qualities and architectural designs).

The difference here is again the underlying context, because those blaming JavaScript might be usually working on large projects(like those way beyond the 10M LoC scale) with large teams(like way beyond 50 members), and it’d be rather hard to have a team with all members being highly devoted, diligent and disciplined, so the amount of control and freedom offered by JavaScript will most likely lead to chaos; Whereas those praising JavaScript might be usually working alone or with a small team(like way less than 10 members) on small projects(like those way less than the 100k LoC scale), and the strict rules imposed by many statically strong typed languages(especially Java with checked exceptions) may just be getting in their way, because those restrictions lead to up front investments, which need time and project scale to manifest their returns, and such time and project scale are usually lacking in small projects worked by small teams, where short-term effectiveness and efficiency is generally more important.

Do note that these opinions, when combined, can also be regarded as reproducible fair tests, because the amount of coherent and consistent opinions on each side is huge, and many of them won’t have the same complaint or compliment when only the languages are changed.

Therefore, it’s normally pointless to totally agree or disagree on a so-called universal conclusion about some aspects on software engineering, and what’s truly meaningful instead is to try to figure out the contexts behind those conclusions, assuming that they’re not already stated clearly, so we can better know when to apply those conclusions and when to apply some others.

Actually, similar phenomenons exist outside of software engineering.

For instance, let’s say there’s a test on the relations between the number of observers of a knowingly immoral wrongdoing, and the percentage of them going to help the victims and stop the culprits, with the entire scenes under the watch of surveillance cameras, so those recordings are sampled in large amounts to form reproducible fair tests.

Now, some researchers claim that the results from those samplings are that, the more the observers are out there, the higher the percentage of them going to help the victims and stop the culprits, so can we safely conclude that the bystander effect is actually wrong? It at least depends on whether those bystanders knew that those surveillance cameras did exist, because if they did know, then it’s possible that those results are affected by hawthorne effect, meaning that the percentage of them going to help the victims and stop the culprits could be much, much lower if there were no surveillance cameras, or they didn’t know those surveillance cameras did exist(but that still doesn’t mean the bystander effect is right, because the truth could be that the percentage of bystanders going to help the victims has little to do with the number of bystanders).

In this case, the existence of those surveillance cameras is actually a major part of the control variables in those reproducible fair tests, and this can be regarded as an example of the observer’s paradox(whether this can justify the more and more numbers of surveillance cameras everywhere are beyond the scope of this article).

Of course, this can be rectified, like trying to conceal those surveillance cameras, or finding some highly trained researchers to regularly record places that are likely to have culprits openly hurting victims with a varying number of observers, without those observers knowing the existence of those researchers, but needless to say, these alternatives are just so unpragmatic that no one will really do it, and they’ll also pose even greater problems, like serious privacy issues, even if they could be actually implemented.

Another example is that, when I was still a child, I volunteered into a research of the sleep quality of children in my city, and I was asked to sleep in a research center, meaning that my sleeping behaviors will be monitored.

I can still vaguely recall that I ended up sleeping quite poorly at that night, despite the fact that both the facilities(especially the bed and the room) and the personnel there are really nice, while I sleep well most of the time back when I was a child, so such a seemingly strange result was probably because I failed to quickly adapt to a vastly different sleeping environment, regardless of how good that bed in that research center was.

While I can vaguely recall that the full results of the entire study of all children volunteered was far from ideal, the changes of the sleeping environment still played as a main part of the control variables in those reproducible fair tests, so I still wonder whether the sleep qualities the children in my city back then were really that subpar.

To mitigate this, those children could have been slept in the research center of many, instead of just 1, nights, in order to eliminate the factor of having to adapt to a new sleeping environment, but of course the cost of such researches to both the researchers and the volunteers(as well as their families) would be prohibitive, and the sleep quality results still might not hold when those child go back to their original sleeping environment.

Another way might be to let parents buy some instruments, with some training, to monitor the sleep qualities of their children in their original sleeping environment, but again, the feasibility of such researches and the willingness of the parents to carry them out would be really great issues.

The last example is the famous Milgram experiment, does it really mean most people are so submissive to their perceived authorities when it comes to immoral wrongdoings? There are some problems to be asked, at least including the following:

  1. Did they really think the researchers would just let those victims die or have irreversible injuries due to electric shocks? After all, such experiments would likely be highly illegal, or at least highly prone to severe civil claims, meaning that it’s only natural for those being researched to doubt the true nature of the experiment.
  2. Did those fake electric shocks and fake victims act convincing enough to make the experiment look real? If those being researched figured out that those are just fakes, then the meaning of the whole experiment would be completed changed.
  3. Did those being researched(the “teachers”) really don’t know they’re actually the ones being researched? Because if those “students” were really the ones being researched, why would the researchers need extra participants to carry out the experiments(meaning that the participants would wonder the necessity of some of them being “teachers”, and why not just make them all “students” instead)?
  4. Assuming that the whole “teachers” and “students” things, as well as the electric shocks are real, did those “students” sign some kind of private but legally valid consents proving that they knew they were going to receive real electric shocks when giving wrong answers, and they were willing to face them for the research? If those “teachers” had reasons to believe that this were the case, their behaviors would be really different from those in their real lives.

In this case, the majority of the control variables in those reproducible fair tests are the test setups themselves, because such experiments would be immoral to the extreme if those being researched truly did immoral wrongdoings, meaning that it’d be inherently hard to properly establish a concrete and strong causation between immoral wrongdoings and some other fixed factors, like the submissions to the authorities.

Some may say that those being researched did believe that they were performing immoral wrongdoings because of their reactions during the test and the interview afterwards, and those reactions will also manifest when someone does do some knowingly immoral wrongdoings, so the Milgram experiment, which is already reproduced, still largely holds.

But let’s consider this thought experiment – You’re asked to play an extremely gore, sadistic and violent VR game with the state of the art audios, immersions and visuals, with some authorities ordering you to kill the most innocent characters with the most brutal means possible in that game, and I’m quite certain that many of you would have many of the reactions manifested by those being researched in the Milgram experiment, but that doesn’t mean many of you will knowingly perform immoral wrongdoings when being submissive to the authority, because no matter how realistic those actions seem to be, it’s still just a game after all.

The same might hold for Milgram experiment as well, where those being researched did know that the whole thing’s just a great fake on one hand, but still manifested reactions that are the same as someone knowingly doing some immoral wrongdoings on the other, because the fake felt so real that their brains got cheated and showed some real emotions to some extent despite them knowing that it’s still just a fake after all, just like real immense emotions being evoked when watching some immensely emotional movies.

It doesn’t mean the Milgram experiment is pointless though, because it at least proves that being submissive to the perceived or real authorities will make many people do many actions that the latter wouldn’t normally do otherwise, but whether such actions include knowingly immoral wrongdoings might remain inconclusive from the results of that experiment(even if authorities do cause someone to do immoral wrongdoings that won’t be done otherwise, it could still be because that someone really doesn’t know that they’re immoral wrongdoings due to the key information being obscured by the authorities, rather than being submissive to those authorities even though that someone knows that they’re immoral wrongdoings).

Therefore, to properly establish a concrete and strong causation between knowingly immoral wrongdoings and submissions to the perceived or real authorities, we might have to investigate actual immoral wrongdoings in real life, and what parts of the perceived or real authorities were playing in those incidents.

To conclude, those making reproducible fair tests should clearly state their underlying control variables when drawing conclusions when feasible, and those trying to apply those conclusions should be clear on their circumstances to determine whether those conclusions do apply under those situations they’re facing, as long as the time needed for such assessments are still practical enough in those cases.