Mirror Dungeon 5 - BP Exp Farm

Mirror Dungeon 5 - BP Exp Farm

December 4, 2024

One thing that has been revamped from Mirror Dungeon 4 is the updated Battle Pass Exp you get. Before you get too excited, the maximum Battle Pass Exp you get is still the same, but quitting early yields more rewards than it used to.

This is obviously bad for module efficiency (i.e. the amount of Battle Pass Exp you get per module), but in terms of time efficiency (i.e. the amount of Battle Pass Exp you get per unit time), it could be an improvement. Almost everyone who have done the double lunacy refreshes have at some time seen their modules spiral up to 999 (the soft cap) when they don’t feel like grinding for a while. Thus, module efficiency is not as important.

Weekly Bonus Floor 1 Cleared Floor 2 Cleared Floor 3 Cleared Floor 4 Cleared Floor 5 Cleared
No 8 16 24 27 30
Yes 12 24 36 40 45

We’ll only focus on the normal mode of Mirror Dungeon as that is used for farming.

So what was the change? Well, clearing 3 out of 4 floors in the previous mirror dungeon also yielded 24 Battle Pass Exp. Here, we see that clearing 3 out of 5 floors retained that property. The strategy we will study today is to only clear the first three floors and quit for 24 Battle Pass Exp.

Let us look at this from a perspective of an average player, say for example, our director Kim Ji-hoon. This numbers are not truly representative of a grinder, as the Mirror Dungeon will/have received buffs since then, as well as avoiding fighting nodes will speed up the run a bit.

Runs Floor 3 Clear Time Floor 4 Clear Time Floor 5 Clear Time
Run 1 25 mins 41 mins 53 mins
Run 2 19 mins 28 mins 37 mins
Run 3 39 mins 54 mins 77 mins

Let us compute the efficiency if he quits then. For example, in Run 1, he took 25 mins to clear floor 3, his efficiency will be 24/25 = 0.96 (modules / min). The following table will have units of modules / min. Moreover, in the following table, the higher the number the better.

Runs Floor 3 Clear Floor 4 Clear Floor 5 Clear
Run 1 0.96 0.65 0.57
Run 2 1.26 0.96 0.81
Run 3 0.61 0.50 0.38

In all cases, we can see that quitting at Floor 3 would have yielded the highest Battle Pass Exp per minute. This data is of course, mostly for fun, and the best data would be your own. Do consider timing your own runs and then deciding whether or not quitting at Floor 3 is worth it for you.

Is there any situation where you wouldn’t want to this strategy? Even if you average 16 minutes per complete run, you require that your Floor 3 clears take at least 13 minutes to be more time efficient. That being said, with such fast runs, you may end up spending down your modules too quickly, thus may need to reconsider module efficiency.

As an aside, this strategy could have been done in the previous mirror dungeons as well, but with overall mirror dungeon being slightly longer as well as floors 1 to 3 reducing the number of nodes, the value of this strategy has been buffed. A better question is why didn’t we start doing this in the previous mirror dungeon? Perhaps we should have been doing it all along…

Appendix

The following code is used to generate the BP Exp Table

using JSON3

function getBPReward(floor, bonus)
    dataList = JSON3.read(open("data/Extracted/StaticData/static-data/mirrordungeon/mirrordungeon-05.json","r"))[:list][1]
    MetConditions = filter(x-> (x[:rewardId] ÷ 1000  floor) && ((x[:rewardId] % 100) ÷ 10 == bonus), 
        dataList[:rewardInfo][:exitRewardListByCondition])

    BPXP = 0
    for Condition in MetConditions
        Reward = Condition[:rewardElements]
        for Element in Reward
            (Element[:type] == "BATTLEPASS_POINT") && (BPXP += Element[:num])
        end
    end

    return BPXP
end

function printBPRewards()
    io = IOBuffer()
    addRow(title, data) = println(io, "| $title |" * join([ " $i " for i in data ], "|") * "|")

    addRow("Weekly Bonus", ["Floor $i Cleared" for i in 1:5])
    addRow("---", ["---" for i in 1:5])
    addRow("No", [getBPReward(i, 0) for i in 1:5])
    addRow("Yes", [getBPReward(i, 1) for i in 1:5])

    return String(take!(io))
end