DCFFVII Research Thread

Drum cans in Dirge of Cerberus are usually very simple. They have an address containing its explosive power, typically a value like 400 or 600, and enemies in the vicinity of its explosion will take that exact amount of damage. Difficulty-mode modifiers do not play into the final damage here.

It's also worth mentioning that the difficulty-mode variables that adjust enemy defense is only called at the moment when the player initiates an attack. Since the address is not called at the moment of impact on an enemy, but instead when the bullet prepares to leave the barrel, it would technically be more accurate to name the address as "Base Player Attack" modifier. ......This question of what names I should give to variables shouldn't cause this much conflict in me. XP

The exception to this simplicity are the drum cans in the Ch4-4 Azul boss fight. They will randomly generate an explosion power value in the range of 695 - 710. A total of 16 possible values. How fascinating to find random damage output in ANY part of Dirge! The only other randomness people will encounter is the bullet-scatter that determines whether or not a bullet actually lands on an enemy. But once the bullet lands the damage is fixed: No random damage variation like you'd typically see in a Final Fantasy J-RPG battle system.

Azul only has 4150 HP and the randomness in damage output from explosions is not enough to change how many drum cans you need to destroy.
Worst case
695 * 5 = 3475
695 * 6 = 4170. KO!

Best case
710 * 5 = 3550
710 * 6 = 4260. KO!

ch4-4_azul.png

Truly, the only real benefit is that Vincent might get spared from lethal damage if he is lucky when caught in an explosion. The battle also becomes less boring/plain for me as a researcher since it gave me a mystery to solve. :monster:


To start with, each group of drum cans reference TWO "Explosion Power" addresses instead of just the one.

Explosion Power addresses for the 8 drum cans on the ground:
[20FE4E00] = 0x2B7 (695)
[20FE4E08] = 0x2C6 (710)


Explosion Power addresses for the 6 drum cans that can be shot down from platforms:
[20FFC4B8] = 0x2B7 (695)
[20FFC4C0] = 0x2C6 (710)


When you successfully destroy any of these, the higher explosion power will be subtracted with the lower explosion power and then +1 is added.
(710 - 695) + 1 = 16

The value 16 will then be multiplied with a random value between 0 and 1. The random value can only approach 1 but never actually reach it.
For example: 16 * 0.67 = 10.72
The result is rounded down to the closest integer which in this case is 10.

The lower explosion power value, 695, is then added together with the result of the previous calculation.
695 + 10 = 705
And that is the damage Azul will experience.


The story of how the random value between 0 and 1 was generated is too lengthy for this post so I shall reserve it for later. Suffice to say that while I do not know ALL the steps of randomness calculation in Dirge, I have come across some powerful knowledge via this dive into the Azul Ch4 boss fight.
 

ForceStealer

Double Growth
The implication is that the Cerberus(/Hydra/Griffon) fire three bullets simultaneously, and you can see that if you shoot a wall in the distance, iirc. But that doesn't actually play into any part of the damage calculation, correct?

Sorry if you've covered this already :P
 
Last edited:
Indeed. Each bullet, and the potential power they contain, is calculated individually. Same with how big the scatter-trajectory of each bullet becomes. The three bullets fired from a single Cerberus shot are NOT treated as a single object. If that had been the case that sure would have helped the game in terms of how fast it can process damage calculations. :wacky:

This was one of the reasons I opted for a one-bullet-per-shot gun like the rifle in my speedrun of Widow Missileer. The most powerful rifles actually have a stronger base power than even the Ultima Weapon handgun. In most situations the Ultima Weapon will still come out on top though thanks to it firing three bullets in one go and having a very fast firing rate. Though in order to "one-shot" the Black Widows in that mission with the Ultima Weapon, at least 2 out of 3 bullets had to strike critical hits. Additional bullets mean more time the game spends calculating the bullet impact- and damage. You are almost guaranteed to lose 1 frame to this extra processing time.

For a mission as short as Widow Missileer, saving that extra 0.033 or 0.066 seconds can mean the difference for a world record. I did extensive testing to confirm that my strategy was legit.

EDIT: The fact that rifle bullets travel at 600 m/s, compared to the handgun bullet speed of 400 m/s, also helps me save an additional frame. :awesomonster:
 
Last edited:
The Event-Randomness Counter (ERC)

In address 204FC9C0 there is a 4-byte variable that is continuously incremented as you play the game. So far, all signs point to this value being incremented whenever an event is taking place that involves randomness. Ergo I've named it the "Event-Randomness Counter" (ERC).

Examples of events/actions that increment the ERC:
- Player- and enemies shooting.
- Enemy AI deciding what to do next.
- Using a Red Potion or Red Ether. These heal a random amount of HP and MP respectively.
- Cutscene events (presumably handling stuff like particle effects and when characters blink).

Examples of events/actions that DON'T increment the ERC:
- Player running, jumping and dashing.
- Navigating menus.
- Changing equipment.

When you fire a shot with a single-barrel gun the ERC is incremented with +5. That's because a total of 5 randomness events take place. At least one of those concern the scatter-trajectory of a bullet (I have not confirmed yet if each distance, short/medium/long, is its own event). If you use a three-barrel handgun then the ERC sees a +15 increase because you are firing three bullets, 3*5=15. Slow down the game enough and you will see the ERC is only ever incremented with a value of +1 at a time.

Booting up the game always start the ERC at value 0. When the counter reaches a value of 623 it is reset back to 0. Thus, under normal circumstances, the ERC will only adopt a total of 624 unique values.

This number is not a arbitrary: The ERC number references a table that consists of 624 unique 4-byte variables. When a randomness calculation is about to take place the game uses the ERC value to pick a 4-byte variable from the table and perform operations with that value.


The Randomly Generated Table (RGT)

The table with 624 unique 4-byte variables is located in the address region of 204FC000 - 204FC9BF. Just add +1 to the final address and we are right back at 204FC9C0, the location of the Event-Randomness Counter. Fittingly then the ERC is immediately adjacent to the Randomly Generated Table (RGT).

The RGT is generated when the game boots up, right as the Square Enix logo fades out. Its values are different each time and probably use the console's clock to decide its values, though I have not been able to confirm this. From the get-go then we have no way to manipulate randomness in Dirge even though we know the ERC always start at value 0. The result of randomness calculations depend on the values in the RGT, so with current knowledge it will not help speedrunners even if they know the exact ERC value.

The RGT values are further obscured by the fact that each randomness-event will cause the RGT values to change. Let us say that an event with a random element takes place when ERC = 0. The game will retrieve the value from the 4-byte variable at 204FC000 (the "0th block" in the RGT, as it were) for the randomness calculation but it will then immediately afterwards go through a lengthy series of operations that entirely change the value of this first 4-byte variable. This algorithm is complex and will also grab other values from the table for the RGT-update calculation.

If you observe the RGT in a memory viewer you will be able to see its values updating as the ERC increments. Use a Red Potion? That's a +1 increment to the ERC, which means the corresponding 4-byte variable is updated. Fire a rifle shot? That's a +5 increase in total, so the five corresponding blocks in the RGT are updated with new values.


Let's imagine for a moment though that we are back in Ch4-4, fighting Azul. We have just destroyed a drum can that is about to cause damage on Azul. We know the exact ERC value and we know the exact values of the corresponding block in the RGT. What calculations will be performed?

The ERC value is 0xA6 (166). This value is shifted-left twice, which is the equivalent of multiplying it with 4. This shows the game which block address in the RGT to pick. All hexadecimal values from here on out unless otherwise stated.

A6 << 2 = 298
204FC000 + 298 = 204FC298


Looking up the value of the 4-byte variable in address 204FC298, before it has any time to change to a new value, we find the hex value 3FB108CC. A series of XOR, AND, OR and shift operations are then performed on this value.

Shifted right B times (11 times in decimal)
3FB108CC >> B = 0007F621

The old value is XOR'd with the new value.
3FB108CC ^ 0007F621 = 3FB6FEED

Shifted left 7 times.
3FB6FEED << 7 = DB7F7680

A constant, 9D2C5680, is collected from instruction space and used for an AND operation.
DB7F7680 & 9D2C5680 = 992C5680

One of the previous calc results is XOR'd with the new value.
3FB6FEED ^ 992C5680 = A69AA86D

Shifted left F times (15 times in decimal).
A69AA86D << F = 54368000

Once more a constant is collected from instruction space. This time it's EFC60000.
54368000 & EFC60000 = 44060000

One of the previous calc results is XOR'd with the new value.
A69AA86D ^ 44060000 = E29CA86D

Shifted right 12 times (18 times in decimal).
E29CA86D >> 12 = 000038A7

One of the previous calc results is XOR'd with the new value.
E29CA86D ^ 000038A7 = E29C90CA

Shifted left 9 times.
E29C90CA << 9 = 39219400

Shifted right 9 times.
39219400 >> 9 = 001C90CA

And finally, the result is OR'd with the constant 3F800000 from instruction space.
001C90CA | 3F800000 = 3F9C90CA

This constant of 3F800000 is not a coincidence. If you enter these values into the hexadecimal representation in this floating point converter you will find that 3F800000 represents a floating point value of exactly 1.0. By performing an OR operation with this legitimate float value, we are guaranteed to come out of this journey with a valid floating point number.

Indeed, our result of 3F9C90CA stores the following value: 1.2231686115264892578125
A consequence of the two operations "shift left 9 times" and "shift right 9 times" is also


The game subtracts exactly 1 from this new floating point number.
1.2231686115264892578125 - 1 = 0.2231686115264892578125

And that is how we get a value between 0 and 1 to be multiplied with the value 16 (which will be familiar from my earlier post).

(710 - 695 + 1) * 0.2231686115264892578125 ≈ 3,57
The result is rounded down to the closest whole integer which in this case is 3.
695 + 3 = 698
Thusly, Azul will take 698 damage in this example where 166th block in the RGT was the hexadecimal value 3FB108CC.


Different types of game events have different algorithms for calculating the final random value. Simply knowing of the ERC and the RGT open dozens of door for reverse-engineering Dirge. I feel it is reasonable to assume that I can use this knowledge to figure out how the Crystal Feelers in Ch12-2 work. I don't expect that knowing the algorithm will help speedrunners. For that we'd need methods of breaking the RNG calculations. But learning how the game chooses which Crystal Feeler to open, and how long it stays open, will be satisfying when that day comes.
 
Last edited:
The boss fight against Rosso in Ch8-2-3 has two phases: "Rosso the Crimson" and "Bloodburst Rosso".

She has a total of 17000 HP and will enter her second phase, via a cutscene, when 4080 HP or more has been depleted. While individual handgun bullets are capped at a maximum 9999 damage, you can technically cause more damage via the combination of two- or three bullets from a single Cerberus shot. In other words the highest damage number you can see displayed above Rosso is 9999*3=29997.

The boss fight is programmed with the intent that you can't simply one-shot Rosso with a powerful handgun shot. If you cause enough damage while in her first phase, Rosso's HP will be partially restored when she enters her second phase. I have not (yet) looked up the exact values and calculations, but the end result is that Rosso will have at least 40% of her max HP when her Bloodburst Rosso phase initiates.

Thankfully I just found a glitch that reliably works around this.


By using a Limit Breaker immediately after the moment that you fire a lethal shot, but before the shot actually lands and digits are displayed, the game will register Rosso as defeated. You'll still have to skip a cutscene, see Rosso's name change to "Bloodburst Rosso" and her HP bar will claim that some HP is left, but she will in fact be defeated.

A bonus with this bug is that even if your shot isn't lethal, using a Limit Breaker prevents Rosso from healing herself for her second phase. So if the digits say that you land 16000 HP worth of damage, and you have used a Limit Breaker at the right moment, then this is the value that will apply.

Having confirmed this behavior in both Japanese versions I am assuming this method works in all releases.

rosso-already-defeated.png

It would have looked quite cool (and confusing) to use this strategy in my All S Rankings run. :monster: Though I still appreciate the boss battle that I did record over 4 1/2 years ago.


Currently there is no reasonable way to employ this glitch in a speedrun. If you are using Automatic aiming then you are limited to "normal" levels of damage which would require way too high killchains. With the right equipment and a perfect headshot you *can* get the job done with a somewhat reasonable killchain. The risk-reward ratio is higher though because you may end up using a Limit Breaker after missing your shot. Galian Beast form is not effective against Rosso and needless time spent transforming is most undesirable in a speedrun. Such a mistake could easily ruin your entire run.
 
Happy birthday to Dark Byte, the creator of Cheat Engine!

Without their software 95% of this thread would not even exist. It is the magic box of awesome power that enables me to continuously learn more about Dirge of Cerberus which in turn motivates me to do programming.


Currently I'm mapping the boss-enemy hitboxes and in the process learning more about their stats and AI. Here is a sample of some of the stat-related knowledge gained.

- Only the Ch1 and Ch2 bosses have their maximum HP change along with the difficulty mode.

Dragonfly (Ch1-3)​
Normal: HP 1600
Hard/Ex Hard: HP 2800
Dragonfly GL (Ch1-6)​
Normal: HP 7000
Hard/Ex Hard: HP 12000
Crimson Hound (Ch2-4)​
Normal: HP 1500
Hard/Ex Hard: HP 2500
Pegasus Riders (Ch2-5) *5 targets*​
Normal: HP 300 each (5*300 = 1500)
Hard/Ex Hard: HP 1200 each (5*1200 = 6000)

I am amused that only these bosses have their HP scaled up with difficulty but even then the maximum HP remains the same between Hard and Ex Hard modes. Really feels like the developers went "Augh eff it". :wacky:


- Like I mentioned in the previous page, enemies have the four stats STR, DEF, DEX and INT in memory. I have now found boss target examples where these stats are not all set to 0.

Dragonfly (Ch1-3) has a DEF stat of 31. It shares this trait with with Dragonfly PT (Ch11-3) but interestingly the Dragonfly GL at the end of Ch1 has a DEF stat of 0. The enemy DEF stat does not affect the damage output of your magic attacks.​
The Heavy Armored Soldier at the end of Ch3 has a STR stat of 50 but it ONLY boosts the attack power of their sword slashes. Bazooka and common gunfire are unaffected by the STR stat here.​
Weiss the Immaculate (Ch11-5), in this unwinnable battle, has a DEF stat of 80. When you transition to the winnable battle against Weiss Empowered (Ch11-6) then this new Weiss has a DEF stat of 0.​
Omega Cocoon's DEF stat is 128. I have not yet confirmed all the stats in the Omega Weiss battle.​


- The damage output from your bullets are checked twice for the damage cap of 9999 per bullet. After the bullet hits and the game has calculated the damage output based on things like the enemy's DEF, the damage gets capped for the first time at 9999. Second time when the hitbox-specific defense values are applied and the calculated result is compared with the damage cap of 9999.

The consequence of this, apart from even a massive critical hit never breaking the damage cap, is that a hitbox defense value of lower than 1 means the maximum damage output gets lowered even further. For example Rosso's arms have a defense modifier of 0.7 (14*0.05) which leads to a maximum possible damage value of 6999. Much of Dragonfly GL (Ch1-6) has a defense modifier of 0.1 (2*0.05) and thus you can't cause more than 999 damage per bullet via those hitboxes.
 
Last edited:
More boss- and damage calculation facts. Keep in mind I have primarily investigated bullets and elemental magic. Content regarding melee attacks and Galian Beast's fire projectiles have not been fully confirmed and uncovered.

- Found the memory region with the float values responsible for things like making Arch Azul impervious to bullets and making the post-JORG version of Azul the Cerulean (Ch4, WRO HQ) impervious to magic. By neat coincidence with the FF7R Yuffie DLC, the string "InterMission" is found in here.

dmg-limiters-region.png

The only way to reach Omega Cocoon with a melee strike is by jumping from platform to platform until you get high enough that you can land a few hits. Normally the damage is 0 but even if you change address 204A04B4 to value 1 then the melee damage is tiny.

cocoon-melee-cheat.png

Arch Azul has 37 hitboxes reserved for calculating bullet damage and their overall defense against bullets is pretty average if you change 204A04B4 to value 1.

Magic attacks are unaffected by an enemy's DEF stat. In essence the "damage limiters" in the presented memory region above become the only real "Magic Defense" adjuster for enemies.

Whenever Magic Defense is adjusted this way it lowers the damage cap for Thunder magic. Usually the damage cap is 9999.
[204A04B8] = 0.25 → 2500 is now the damage cap for Thunder
[204A04BC] = 0.50 → 5000 is now the damage cap for Thunder

My gut tells me that this behavior is an oversight. The damage cap for Fire and Blizzard is never lowered to below 9999. Ultimately it's impossible to tell if the programmer was aware of this behavior and if they even cared.

The player will always have a killchain of 0 when they battle Weiss (Ch11). Even with Vincent on Lv50 and with Manasoul equipped you can't inflict Thunder damage higher than 468, so without cheats you will never notice the damage cap of 2500.

In the case of bullets, these damage limiters are applied *after* the enemy's DEF stat has been taken into account but *before* the bullet-specific hitboxes are accessed. Usually the float value of 1 from address 204A04B0 is accessed and the formula looks like this:
(Calculated Potential Damage * 1.0) + 0.50 = New Calculated Potential Damage
Result is rounded down to the closest integer and in the end this part of the calculation has no effect on the final damage.

This confused me for a long time because I could not backtrack to where the 1.0 value came from. In the same way I could not backtrack where the float value of 0 came from that made Azul (Ch4) impervious to magic and Arch Azul (Ch9) impervious to bullets. Thanks to the more unique float value used by Dragonfly PT, where all damage types (bullets/magic/melee) are halved, I could at long last find the memory region responsible for all these cases.


- When Black Widows have fallen from the ceiling (Ch5 & Ch9) they are impervious to Fire and Thunder magic until they have gotten back up on their feet. Blizzard shots can cause damage though you need to look behind and below the Black Widow to see the damage digits actually displayed. This weird immunity to Fire and Thunder is unrelated to the damage limiters in the aforementioned memory region. I have no idea why only Blizzard can inflict damage here. My assumption is that the hitbox(es) for when the Black Widow's belly is exposed are simply poorly programmed.


- While a Pegasus Rider foe consists of two models (e029 = hoverbike, e031 = rider) only the hitboxes of the hoverbike is used for damage calculation from bullets. Its weak spot is the nose and the undercarriage.

This reveals a lie in the official guide, as it will claim that the head of the rider is a weak spot. It is NOT a weak spot in any version of Dirge. Not only is the rider (e031) not having its own hitboxes used for damage calculation, but the "rider" hitbox of the hoverbike actually has a pretty high defense.

DC_Complete_198_pegasus-rider.jpg

- For some reason, Shelke's feet will only register bullets if you are in third-person view. While in first-person, be it in sniper-scope mode or otherwise, it's like the hitboxes for her feet just cease to be.

- The weakest point of a Shrike is their jetpack and it will take 4 times more damage than a "normal" shot. However it is not defined as a "critical" hit, and so the damage digits will still be displayed in white and not in red. The "critical hit" weak point of a Shrike is their head, but it only takes 3 times more damage compared to normal.

The Shrike is especially prone to displaying the wrong damage digits. If you cause a lethal shot on their jetpack, even if it's only from one bullet, then the actual damage will be multiplied with 4 but the damage digits displayed will be as though you struck a normal-level blow.
 
Last edited:
After a lot of dedication and ugly spaghetti code, it is finally here. A basic damage calculator for Dirge. See download link at the bottom of this post.

picture-preview.png

By going the path of bullet damage (handgun, machine gun, or rifle) you also get to select any of the bosses to apply damage on. The definition of "boss" in this case is any target that has a visible HP bar on screen.

shelke-example.png


Going the magic route you don't select bosses, but you do get to choose whether the magic damage is applied on a foe with normal magic defense, double defense or quadruple defense.

magic-example.png

The program might still have some rounding errors, with values being +1 higher than they would be in-game, but for the vast majority of cases this program will output the correct damage values.

The main intent is for Dirge speedrunners to use this tool when they need to double-check how high of a killchain they need to instakill a given boss. The tool may also help any speedrunner trying to conjure up new strategies, as they try to figure out what setups might be reasonable and allow (or not allow) for one-shotting bosses.
 

Attachments

  • dcff7-damage_calculator_ver1.0.zip
    423.8 KB · Views: 2
The "Undead Epiolnis" glitch turned out to be a dead-end in the search for extra cardkey farming.

The glitch only ever happens in the original Japanese release and it's triggered by using a Thunder spell on the Epiolnis in Ch6-2 right as they notice you. The Epiolnis on the far right, who is programmed to run towards the player, will enter a glitched paralyzed state if they still have some HP left after the Thunder spell has been applied. The glitch is really easy to trigger and is mostly down to timing and the Thunder spell causing less than 600 damage (the max HP of the Epiolnis foe). No items are dropped here by the Epiolnis since the game never thinks of them as being defeated. No item duping potential here. =/

It's still an interesting glitch though. When you first try to push around the Epiolnis they will be super-heavy and hard to move. But if you use one melee strike on them, their body suddenly becomes super light. It's as though some invisible velocity vector pushing the Epiolnis down is reset to 0. If you use a blowback-strike, causing the Epiolnis to be launched into the air, the "Paralyzed Epiolnis" glitch is undone and they act as normal. The fact this glitch was patched out post-JORG shows once again just how much was fixed after the initial release.


The hunt for glitches with exploit potential continues and to be truthful you can't be sure what useless glitches may turn out to actually be useful in the future. Even the disappointing "Paralyzed Epiolnis" example. One such glitch I found now is the "L1+R1 combo" bug. What does it do? It makes it so that if you keep holding down R1 the game locks you away from browsing shortcut items, using shortcut items, entering first-person view, melee-ing and using magic.

I found two ways to trigger this. The easiest is to fire a normal shot with R1, immediately aim-cancel, then raising your aim again by pressing L1+R1 or R1+L1 (the order doesn't matter) in quick succession. The other method was to restore MP, aim up, aim-cancel and do the L1+R1/R1+L1. This latter method is especially confusing and was less consistent than simply firing bullets. There's also the absurdity that changing your MP allows for this glitch at all but restoring HP does not set up for the L1+R1 combo glitch.

I tried out a ton of different actions while in this state. You can still dash, jump, climb ladders, use items via the main Item menu etc and the glitch will remain. Letting go of R1 cancels the bug. Try as I might, there are so far no signs of any game exploits being unlocked by accidentally freezing Vincent from using multiple basic actions. I was unable to trigger the glitch when Vincent is in Chaos form.

For a game with so many odd behaviors its programming remains frustratingly solid and impossible to profoundly break.
 
A neat example of what speedrunners have to consider and what the consequences can sometimes be from the handgun firing three bullets at a time: The goldilocks killchains against Crimson Hound in Chapter 2.

Speedrunners of Normal mode have known for a while that if you have a killchain higher than 18, when you first shoot the Crimson Hound standing on the rock pillar, you will not be dealing the maximum possible damage. I recently confirmed the reason: When the Crimson Hound has lost 70% or more of its HP, they enter an invincible state and begin the animation to descend to the ground.

Damage table derived from the damage calculator and confirmed in-game:

crimson-hound_first-shot-table.png

Crimson Hound has 1500 HP in Normal mode (2500 HP in Hard and Ex Hard). While the Crimson Hound is standing on a pillar their HP will not go below 10% of their max, so in Normal mode their HP will not go below 150 and in Hard/Ex-Hard their HP will not go below 250. Ergo in the most common speedrunning category, Any% Normal mode, the maximum damage you can deal is 1350 on the Crimson Hound while they are still standing on a pillar.

Recall though that the enemy AI is such that when 70% of the total HP has been depleted they become invincible. So when 1050 damage or more (1750 damage in Hard/Ex-Hard) has been dealt, you can't deplete more HP until the Crimson Hound has finished their descent to the ground.

That's why having a killchain of 19-22 becomes especially troublesome. You cause so much damage with the first bullet that the second- and third bullet become essentially rejected. Damage is no longer maximized.

Having a 9-10 chain is decent backup scenario if you for some reason failed in acquiring a bigger killchain. This requires though that all 3 bullets land on the target. Often runners will find only 2 bullets, or just 1 bullet, hitting the Crimson Hound.

The goldilocks zone of 13-18 chain is preferable because it only requires 2 bullets and it's not a difficult chain to acquire.

A 23-chain or higher is the way to go if you desperately want to require only a single bullet to land on the Crimson Hound. The segment when you ride on the Shadowfox vehicle has a total of 24 Guard Hounds so a 23-chain is the maximum you can gain from that. Not easy but not impossible. The only way to have a higher killchain is to retain one from the gun turret section, but that means taking a lot of damage in the latter section since you won't be allowed to attack- and expend your chain.


If the 3-bullet shot from a Cerberus gun was handled as a single target then none of this complexity with "goldilocks chain zones" would manifest with the Crimson Hound. Each bullet is their own object though and the enemy AI is quick to react, ergo why it's important to know how the damage ranges change depending on both the chain and the number of bullets that land.
 
Last edited:
Notes about Galian Beast's Flame Bullet

This homing fire projectile is called 火炎弾 [Flame Bullet] in the official Japanese guide though I often simply call it "the fireball". In all versions you can launch a flame bullet with the press of R1 but the post-original releases grant the ability to launch fireballs in midair with melee strikes.

The fireball is a magic-type attack with the ability to cause blowback on most enemies. Being a magic attack, it grows in strength as Vincent's INT stat grows and it ignores the enemy's DEF stat. The flame bullet will however NOT be affected by items that boost magic power (Manamind and Manasoul). This is true for all versions of the game, including the original Japanese release which doesn't grant a 'Mana Booster' item to the player.

The flame bullet is notoriously weak in the original JP version, having merely a base power of 37. Below are the result of calculations where it is assumed that the enemy has normal magic defense (multiplier with value 1). I do not know if there exists an enemy with lower magic defense than normal.

Japanese Original
Damage outputs on Easy mode
0-chain, INT 1 (Vincent Lv1) : 75
99-chain, INT 1 (Vincent Lv1) : 3675
0-chain, INT 100 (Vincent Lv50) : 85
99-chain, INT 100 (Vincent Lv50) : 3685

Damage outputs on Normal/Hard mode
0-chain, INT 1 (Vincent Lv1) : 38
99-chain, INT 1 (Vincent Lv1) : 3638
0-chain, INT 100 (Vincent Lv50) : 47
99-chain, INT 100 (Vincent Lv50) : 3647

As is usually the case with the four stats STR, DEF, DEX and INT, the boost they grant is really tiny. The main advantage of levelling up Vincent is the increase in max HP.

Thankfully the fireball had an increase in power for later releases. The base power was changed from 37 to 100.

Post-Original
Damage outputs on Normal/Hard mode
0-chain, INT 1 (Vincent Lv1) : 102
99-chain, INT 1 (Vincent Lv1) : 9750
0-chain, INT 100 (Vincent Lv50) : 128
99-chain, INT 100 (Vincent Lv50) : 9776

Damage outputs on Ex Hard mode
0-chain, INT 1 (Vincent Lv1) : 52
99-chain, INT 1 (Vincent Lv1) : 9700
0-chain, INT 100 (Vincent Lv50) : 78
99-chain, INT 100 (Vincent Lv50) : 9726

Falling just short of reaching the damage cap of 9999. Unless there is an enemy with low magic defense, the maximum damage you can cause with a single Galian Beast flame bullet is 9776.


The original JP version had a glitch with the flame bullet that would cause it to display critical-hit damage instead of normal damage. If an enemy was last struck with a critical hit, then all Galian Beast flame bullet strikes on that specific foe will count as a critical hit. This would not actually increase the damage output but simply change the damage text from white to red and increase your total count of critical hits in that stage. The glitch could be reset by shooting the enemy with a normal bullet and causing non-critical damage.

To their credit, the beast's flame bullet attack does not suffer from faulty killchain storage the way that Fire- and Blizzard does in the original release. I'm honestly surprised that the Galian Beast's fireball does not have this bug in any version. Well, it kinda-sorta-but-not-really exists in the post-original versions. In those editions you can throw a fireball in midair by pressing the melee button. But if you are carrying an old killchain (created more than 5 seconds ago), then launching a flame bullet this way means that the killchain will be EXPENDED on the melee strike and no killchain will be left to apply on the midair "melee" fireball. I wouldn't call this a bug, but it is an example of deceptive killchain storage. In those cases it is better to launch a fireball with a press of R1. That way the old killchain is utilized for the damage boost instead of being consumed by the melee strike.



The +100 Damage Glitch
The flame bullet acquired a new bug with the post-original releases of Dirge. Semi-randomly, an extra 100 damage will be added to the fireball after it lands on an enemy. Depending on the enemy this +100 damage behavior may occur 50% - 95% of the time. The mechanics that decide whether or not the +100 is applied are still unknown.

This extra damage counts as its own damage strike, so essentially the single fireball attack becomes TWO attacks in one. The context when I first realized the presence of the +100 was when I used cheats to reach the damage cap with the flame bullet only to find the final displayed damage to be 10099 (so long as I ensured enemy's HP was above 9999).

max-damage-plus-one-hundred.png

It looks like you are breaking the damage cap with a single attack, when in fact it is two attacks that are added:
9999 (flame bullet) + 100 (flame bullet bug) = 10099

This damage boost will ignore most possible variables: Physical attack variables, magic attack variables, killchain, base stats (STR/DEF/INT), difficulty mode modifiers, base fireball strength etc.

What it does not ignore are the "damage limiters" (those that decide if a damage type deals normal damage, double damage, half damage, one-quarter damage, zero damage). So if the enemy is using a variable to halve all the incoming damage, the +100 will be reduced to a +50. Since Azul in Ch4 is immune to magic, including Galian Beast's flame bullets, even the +100 is reduced to 0.
The +100 will also respect if the enemy has entered an invincible status and thus deal no damage in these cases.


One possible hint into the origin of the +100 glitch is how fireballs interact with the shields of the DG Elite. In the original version, fireballs did no damage on the DG Elite when their shields were raised and would not even knock the enemy back. This was changed in later releases so that when you strike the shield with a flame bullet you ALWAYS deal the 100 damage and ONLY that damage, plus the DG Elite now gets knocked back. The default power of the fireball is NEVER applied when you hit the bullet-deflecting shield of this enemy. If however the enemy has been knocked back and is laying on the ground, a fireball will deal the normal/main flame bullet damage plus (usually) the extra 100.

Ergo why I speculate that the +100 glitch *might* have originated from giving the player this additional method of penetrating the DG Elite's shield. Even when the day comes and these aspects of the code get fully decompiled it will be difficult, as always, to discern the programmer's true intent. Whether or not the general +100 damage was an accident, the programmer might have been aware of this phenomenon happening on all enemies and decided that it was "a feature and not a bug". I will however keep referring to this behavior as a glitch/bug because of its sheer strangeness.
 
Last edited:

Makoeyes987

Listen closely, there is meaning in my words.
AKA
Smooth Criminal
I noticed immediately when playing Dirge that Gallian Beast's Flame Bullets (they really should've left it's name as Beast Flare :P) was hella broke. I can't believe it had such a low attack power in the Japanese version, that's so lame. Glad the developers went out of their way to buff this. It makes such quick work of Azul, I love it. :monster:
 
Beast Flare
It would have been nice if you gained the ability to charge up your standard Flame Bullet/Shot into a full-blown Beast Flare. A magic attack covering a wider area.

I noticed immediately when playing Dirge that Gallian Beast's Flame Bullets ... was hella broke.
The combination of strong melee and the fireballs launched simultaneously is indeed why speedrunners will usually opt to midair-melee Arch Azul into submission. It is fast and efficient.

Galian Beast's melee is also something that was buffed between releases which contributes even more to how relatively overpowered the beast became in certain situations.

Japanese Original
Melee - Base Power
1st strike: 85
2nd strike: 90
3rd strike: 155
4th strike (ground-pound) : 200


Post-Original
Melee - Base Power
1st strike: 160
2nd strike: 160
3rd strike: 160
4th strike (ground-pound) : 500


Only the midair version of the melee combo launches fireballs and it does so in the first three strikes, one flame shot per melee strike. In the original release you could not melee in midair.

Fun fact is that the post-original Dirge editions still load the old melee power data in memory but it just sits there, unused. The old base power of the fireball is not in memory though and has been completely replaced by the new data.


Post-JORG Flame Bullet data:

galian-beast_fireballs_post-jorg.png


The base power of both the R1-Fireball (uppermost red) and Melee-Fireball (uppermost green) are their own 2-byte variables.
The addresses responsible for the +100 damage are in the same region and are 2-byte variables (lower red and lower green). These corresponding variables are present even in the original Japanese release, where the +100 glitch does not manifest, and it's possible that they influence the height of the enemy's arc when they get blown back by the projectile. There are still many unknowns and confusing aspects of the game's blowback mechanics though, so I can't be 100% confident yet.

It is definitely a possibility though that what's happening here is that a variable normally responsible for blowback-height ends up acting as the "base power" for the +100 damage glitch.

The strings visible in the memory viewer above, bsj_131 and bsj_132, correspond to the sound effects when the Flame Bullet is fired and when it hits a surface, respectively. Often one will find the base power/strength of an attack near a string that corresponds to its sound effect.
 
Last edited:
City Hall has been working really hard at trying to get world record in the Any% Normal Mode speedrunning category. He just had a heartbreaking run that was super awesome up until Ch10 and Ch11 when everything just went wrong until there was no saving it. Would have been WR if not for those mistakes.

That session marks the first time I've seen Limit Flexing perfectly performed in a live run though. Epic instakill where all three bullets struck critical and caused a total of 19248 damage on Rosso. Usually random bullet-scatter will cause only one- or two bullets to hit, so getting this perfect headshot requires both skill and luck.

Calculation replicating the damage done during this Limit Flex:

rosso-instakill-calc-example.png


but the idea that he was originally just completely nailed to the ground...what were they thinking?
I think two aspects were at play.

1) A general design philosophy of wanting the Single Player to be a sort-of tutorial for Multiplayer, so they may have wanted to limit the number of differences between the two modes. This was a bad idea.​
2) Prioritizing fixing- and updating the online gameplay before release rather than the offline components. As demonstrated by the fact that online players could fire in midair during the 2006 era AND limit breaks were no longer activated by consuming MP. Meanwhile Vincent stayed grounded and still had the MP-dependent limit break mechanic.​
 
The player's inventory has a total of 60 item slots, though the inventory max will usually be assigned as 50. This is because slots 51-60 are reserved for special items. "Key items", in a sense. When picked up, these items will be added to the 51-60 region and will increase the displayed inventory maximum with +1. The special items are...
- Cardkey​
- Omega Report​
- G Report​
- Death Penalty (gun)​
- Death Penalty Bullets​

item-inventory-max-51.png

^Example of inventory max having changed to 51. When the cardkey is used up your displayed inventory maximum is reduced to 50 again. The consequence is that even with a maxed out inventory you will still be able to pick up a cardkey (or other special item).

If you were to force other items, like a Potion, into any of the item slots in the 51-60 region this would NOT increase the displayed maximum. This will only happen for Cardkey, Omega Report, G Report, Death Penalty and Death Penalty Bullets.

In other words if you could freely access the 51-60 region, you could go over the "displayed" inventory maximum. Max out your inventory, use cheats to add a "normal" item to the 51-60 region, and your item total will be displayed as 51/50.

Fun fact: In the Beta Version disc the bgd file only shows 50 item slots for the player in memory. In all retail editions this has been expanded to the aforementioned 60 item slots.


The Item Slot #54 Occurrence/Anomaly

When looking in the game's memory you will usually find that special items are added to the lowest available item slot in the 51-60 region. If slot #51 is free and you pick up a cardkey, that's where it gets placed. If an Omega Report occupies slot #51 and you pick up a cardkey, that cardkey is added to slot #52.

With this knowledge you can actually affect which item slot that the G Report will settle in. Omega Report in slot 51 is mandatory in most cases because it's added via a story event. But it's possible to pick up the first G Report with- or without a cardkey currently also in your inventory.
Cardkey first, G Report second:
Slot #52 - Cardkey
Slot #53 - G Report

G Report first, Cardkey second:
Slot #52 - G Report
Slot #53 - Cardkey

The order in which you pick these items up has ZERO impact on how- and where the items are displayed in your inventory. No glitches will occur from either pick-up order. The way that item slots in region 51-60 are picked is entirely invisible to the player unless they are using a memory viewer.

During my investigations the game was initially very strict about adding a special item to the lowest available slot...and then all of a sudden I found that my Ex Hard save file had the Omega Report in slot #54! Under normal rules this should not be possible.

The cause: When playing Extra Missions or when loading up a fresh Ex Hard playthrough, slot #54 is treated as the lowest available item slot in the 51-60 region. Extra Missions stay strict about this behavior but in the Ex Hard story mode session the game will start acknowleding slots 51-53 again if at any point you leave your current playthrough.

This is why my final list of items in my Ex Hard playthrough looked like this:
Slot #51 - G Report
Slot #52 - Death Penalty
Slot #53 - Death Penalty Bullets
Slot #54 - Omega Report

I began my Ex Hard playthrough and unbeknownst to me every cardkey was being added into slot 54. The session continued up until at least Ch5-4, where the Omega Report had settled in slot 54 (you will never have a cardkey in your inventory when the first Omega Report is granted). Exited the game, resumed playing and from then on the game prioritized slots in the 51-60 region as intended. G Report got added to slot 51 and the Chaos Vincent items were added in slots 52 & 53 for the game's final chapter.



*EDITED TO CORRECT* If I had completed the game in one sitting, without selecting Restart or creating a Tempsave or otherwise leaving the story mode playthrough, the final lineup in memory would have been this:
Slot #51 - Death Penalty Bullets
Slot #52 - Death Penalty
Slot #53 - G Report
Slot #54 - Omega Report
Yes, you are reading that correctly. New special items are added DOWNWARDS in the list when this weird anomaly is active. First an item in slot 54, then in slot 53, 52 and 51. If we were to add one more special item in addition to the above, it would land on slot #55.

Why the game prioritizes slot #54 when playing Extra Missions and when starting a new Ex Hard playthrough, I do not know. Just the same I have no idea why special items are occupying slots downwards in the list when in this state.


I have also been unable to trigger any glitches with use of the Slot #54 Anomaly. The game still keeps a good track of where items should end up and nothing is deleted or duplicated. It's interesting though to explore how the game updates itself to remember where items are and where they should be added.

In one test (when the 'Slot #54 Anomaly' was not active) I used cheats to move G Report from slot 52 and over to slot 53 while fighting Azul at the end of Ch9. This meant that slot 52 was free. But upon starting Ch10, the upcoming cardkeys were still added to slot 53: They overwrote and deleted the G Report! The game still considered slot 53 to be the lowest available slot in the 51-60 region.

Playing from the end of Ch8-2 with the same cheats though caused the first cardkey in Ch10 to land in slot 52. Nothing was overwritten/deleted because the game had updated itself to know which slots were free and which were not. This shows that the game only updates its awareness of the 51-60 region during certain chapter transitions but not during others.

Zero glitch exploit potential thus far? Yes. Still fascinating and potentially important to know the game's item inventory mechanics? Also yes.
 
Last edited:
Speedrunners learned long ago that it saves time to pick up the tutorial-initiating Potion (or the tutorial-initiating Handgun Bullets) right at the start of a new playthrough (Ch1-1). How does it save time? By making the duration of this load wall, at the bottom of the stairs transitioning you from Ch1-1 to Ch1-2, way shorter.

load-wall.png

If you skip both of the tutorials that pop up on screen when you pick up either of the first two items, on console the game will spend roughly 5.7 to 6.2 seconds loading the cutscene that shows Vincent running down the stairs and then saying "Now where am I supposed to meet Reeve?"

If you triggered either tutorial pop-up, which will consistently last only 2.0 to 2.1 seconds if you exit the message right away, then the load wall at the bottom of the stairs will only last for 1.1 to 1.5 seconds. The net result being that you're spending 3.1 to 3.6 seconds with the "initiate tutorial" strategy which is significantly faster than letting the load wall slow your game to roughly 6 seconds of waiting. In the best scenario, picking up the first Potion or the first Handgun Bullets will save the runner 3 seconds!

Now, if ever you subject yourself to watching a DoC speedrun, you will no longer be perplexed by the runner choosing to trigger a lengthy tutorial message.


The console measurements above are from a small sample size but the behavior is consistent with more extensive measurements on emulator as well. See average results from emulator measurements below.

Duration of tutorial pop-up: 1.93 seconds
Load wall duration if tutorial was not triggered: 4.16 seconds
Load wall duration if tutorial was triggered: 0.9 seconds

On emulator you would thus save a bit over 1 second from employing the optimal strategy. It's fascinating to see how the time save becomes so much greater on console due to loading time differentials. Because of the fast load times on emulator these are banned from the Dirge speedrunning leaderboards.


The Ex Hard difficulty does not trigger any tutorial pop-ups. The consequence of this becomes that you are pretty much forced to endure the 6-second load wall at the bottom of the stairs (4 seconds on emulator).

My knowledge contribution here is noticing that creating a Tempsave in Ch1-1, and then loading that Tempsave, leads to the load wall duration being even shorter than via the tutorial pop-up optimization. On emulator the average loading time was 0.82 seconds. I have not measured this loading time on console but the game behavior has nevertheless been proven: Tempsaves are slightly better than any other method to optimize the transition from Ch1-1 to Ch1-2.

The time it takes to create a Tempsave naturally destroys any potential to use it for speedrunning. The fact that the game acts this way at all is way fascinating. Selecting Restart or even getting a Game Over does not optimize this load wall's duration. Only tutorial pop-ups and Tempsaves accomplish that.

I hope that one day we will know enough about the inner workings of Dirge to understand what is going on here under the hood.
 
6 months ago, on January 23rd, Gocu landed the Any% Normal Mode World Record with a time of 1h33m23s.

Today, runner City Hall broke the record by two seconds (yet to be officially counted), achieving a 1h33m21s. City Hall has been hard at work climbing the ranks on the leaderboard. Just over two months ago he achieved 2nd place and he was only moved down to 3rd place for less than a day, on June 1st, before using the drive of competition to promptly take his spot back.

The video, erroneously titled August 30th (today is July 30th), has the successful run begin at 41:46. The run is the result of months of hard work and after all these sessions it is neat to see a new runner on 1st place. City Hall became really good at the Rosso instakill known as "Limit Flex" and it's a shame that the technique was not achieved this time around (the reference to my damage calculator is appreciated though). That, along with other mistakes in the run that CH usually do not make, reveals that he definitely has what it takes to get a time below 1 hour 33 minutes.

Gocu is a competitive runner who at any time may return from the shadows, so it would not surprise me if we see him reclaiming 1st place shortly. Time will tell. The Year of Dirge is not yet over.
 
Last edited:
Level Cap and Stat Progression: Part 1

The final game has Vincent's level cap at 50. EXP to next level, the max HP, STR, DEF, DEX and INT all progress in a fixed fashion. There is no randomness involved.

The official JP Dirge of Cerberus guide and the Bradygames guide will include spreadsheets that look something like this (minus the "EXP to next level" category written out).

level-chart_final-game.png

The game does not internally store each individual value seen above. Rather, a set of key values are retrieved when the player levels up and then a formula is applied to calculate what the new stat should be. These key values are located in the bgd file (which I like to assume stands for 'basic game(play) data'). Studying the bgd file reveals not only four unused stats but also that the level cap used to be higher than 50.

guide_stat-growth_retail_BGD.png

It is anyone's guess what the four additional stats were planned for and how many of the stats, used or unused, were ever involved in the programming of the online mode player character(s).

The stat-calculation formula depends on which level interval/phase/stage you are in when the level-up has occurred.

Interval 0 : Lv1 - Lv9
Interval 1 : Lv10 - Lv19
Interval 2 : Lv20 - Lv29
Interval 3 : Lv30 - Lv39
Interval 4 : Lv40 - Lv49
Interval 5 : Lv50 - Lv59
Interval 6 : Lv60 - Lv69
Interval 7 : Lv70

The game learns the interval by taking the level value (after the level-up has happened) and dividing it by 10. Because these are integer variables, and thus have no fractions, the result from these calcs are very straightforward. Examples:
8 / 10 = 0
22 / 10 = 2
27 / 10 = 2
45 / 10 = 4


The interval decides which of the "key values" in bgd is the ceiling and which one is the floor. In regards to HP, if we are at Lv1-Lv9, 780 max HP is the floor and 1500 max HP is the ceiling. But if we are at Lv10-Lv19, 1500 max HP is the floor and 2000 max HP is the ceiling. Knowing the floor and the ceiling is important for the stat calculation formula.


Rough summary of the formula while the player is at interval 0

The float value 0.111111111939 (0x3DE38E39) is moved in from instruction space.
A value of 1 is subtracted from the new level value. For example let's say we are now at Lv3, which means 3 - 1 occurs.
The result is then multiplied with the float value 0.111111111939.
2 * 0.111111111939 = 0.222222223878
This has given us a value that will be multiplied with the ceiling stat value.
1 - 0.222222223878 = 0.777777776122
And now we have a value that will be multiplied with the floor stat value.

Max HP: (0.777777776122 * 780) + (1500 * 0.222222223878) + 0,50 ≈ 940,5 940
Thus we have acquired the max HP value for when Vincent has reached Lv3.
We will see values matching up with the charts when we apply the formula for the other stats as well. Continuing with the Lv3 example.

EXP to next level: (0.777777776122 * 20) + (560 * 0.222222223878) + 0.50 ≈ 140.5 140
STR: (0.777777776122 * 2) + (20 * 0.222222223878) + 0.50 ≈ 6.5 6
DEF: (0.777777776122 * 4) + (40 * 0.222222223878) + 0.50 ≈ 12.5 12
DEX: (0.777777776122 * 2) + (30 * 0.222222223878) + 0.50 ≈ 8.72 8
INT: (0.777777776122 * 1) + (10 * 0.222222223878) + 0.50 ≈ 3.5 3


The floor- and ceiling values are essentially like scales and the more our level increases in the interval, the more weight the ceiling value will have over the floor value. For example when we reach Lv8 the scales will have been reversed compared to Lv3.

Max HP: (0.222222223878 * 780) + (1500 * 0.777777776122) + 0.50 ≈ 1340.5 1340
EXP to next level: (0.222222223878 * 20) + (560 * 0.777777776122) + 0.50 ≈ 440.5 440
STR: (0.222222223878 * 2) + (20 * 0.777777776122) + 0.50 ≈ 16.5 16
DEF: (0.222222223878 * 4) + (40 * 0.777777776122) + 0.50 ≈ 32.5 32
DEX: (0.222222223878 * 2) + (30 * 0.777777776122) + 0.50 ≈ 24.28 24
INT: (0.222222223878 * 1) + (10 * 0.777777776122) + 0.50 ≈ 8.5 8



Rough summary of the formula while the player is at intervals 1 through 7

The same principle at the end is applied with floor- and ceiling values getting fractions to be multiplied with. The only difference is how we acquire these fractions for multiplication. The float value 0.111111111939 is NOT retrieved from instruction space. Instead we have...
(Current Level - (10 * Current Interval)) / 10 = Ceiling Multiplicator
1 - Ceiling Multiplicator = Floor Multiplicator




When experimenting with levelling up beyond the normal level cap of 50, I changed two values in instruction space.
First, obviously, changing the level cap from 50 (0x32) to 70 (0x46).

level-cap_check.png

This however was not enough. Stat values in bgd for intervals 6 and 7 would not be collected, so Vincent's max stats from Lv50 stayed the same even when going through Lv60-Lv70. An "interval check" cap had to be changed from value 6 to value 8.

interval-cap_check.png

Once this was done, the key values in the bgd were properly accessed and Vincent's stats were changed to their originally planned Lv70 values. These are lower than the final game's Lv50 values but it's still a neat thing to see.

vincent-lv70.png

One "glitch" from reaching Lv70 (interval 7) is that the new "ceiling" become's the next stat's bottom value. So when the max HP of Lv70 (value 2600) is accessed and becomes the floor, the DEX stat Lv1 value of 2 becomes the new ceiling. Fortunately this new ceiling will always be multiplied with a value of 0, so the final stat progression still works out fine.

I do not know if the game's code has an intended, better way to deal with reaching Lv70 and if so what values I need to change in instruction space.
 
Last edited:
Level Cap and Stat Progression: Part 2

Now that we know a bit more, here is the spreadsheet for Vincent's stats from Lv1 and up to Lv70.

retail-stat-progression_up-to-70.png
From Lv50 and up to Lv60 your stats remain the same. This is because of how the "floor vs ceiling" formula is set up. The values balance each other out perfectly and so no change occurs.


The game always calculates and stores internally how much EXP you need to reach the next level, even if you've reached the level cap at 50 or 70. That's why the spreadsheet shows how much EXP you need to reach Lv71 even though Lv71 doesn't exist. In-game menus never show this EXP-to-next-level number to the player once you've reached the maximum level.

There is no value in the game (that I've been able to find so far) that explicitly states the max level used to be 70. I think it is a reasonable assumption based on the data we've seen so far, but I just want to put that caveat out there. Perhaps we might one day unlock a piece of code in the Beta Version where the level cap is by default set to 70 instead of 50.

Barring that, we can still study the bgd file in the Beta Version and compare it with the retail edition. This provides some interesting context.

bgd_stat-progression_retail-vs-beta.png

We see here that the Lv70 values in the final game are a leftover from when those indeed represented the peak of a constant, gradual climb in the player's stats.

Assuming that the stats DEX, DEF, STR and INT were already decided on in beta, we can see these stats used to have the same growth curves that the unknown stats have/had. Hopefully one day we'll be able to unlock actual gameplay in the Beta Version and thus have an easier means to study the code but for now we are limited to the start menus and data mining.

Perhaps most pleasingly of all to find though is that Vincent's Lv1 HP is set to 1000 in the beta bgd. This matches early pre-release screenshots and the build we have a cam-recording of from September 2005.

33.jpg

Later screenshots would show Vincent with a starting HP of 760, but no remnants of this setting exist in the game files we have.

dc_gameplay07.jpg

I long wondered if 760 represented Vincent at Level 0. But even if you make Vincent start out at Level 0, or have him level up from a negative value and up to 0, his HP and other stats will not change. The game is remarkably good at dealing with negative level values and level zero, in the sense that almost nothing happens if your level is lower than 1.

Ergo, I'm assuming for now that the 760 HP value would only be found in an intermediate bgd file that we don't have. As an aside, these are the identifying strings that each unique bgd file begins with.
Beta Version: bgd016:2005/ 7/ 7:10:54: 7
JP Original: bgd019:2005/11/25:22:44:31
Post-Original: bgd020:2006/ 5/31:20:38:32

The stat growth values are the same in all retail releases, though many other basic gameplay values were changed.


Continuing on with the assumptions and speculations, what if we apply the final game's stat progression formula to the values found on the beta disc? What will the level-up chart look like?

beta-stat-progression.png

Levelling up required far less EXP in this earlier build.
Total EXP, Lv50, Beta: 6085
Total EXP, Lv50, Retail: 52670
Total EXP, Lv70, Beta: 25585
Total EXP, Lv70, Retail: 98170

By the time you reach Lv70 in the beta, you're only halfway to Lv50 in the final game.
 
Last edited:
A rare beast appears! One week ago, French YouTuber "Zelant" livestreamed a showcase of hidden areas in Dirge of Cerberus.

The narration is entirely in French but the video quality is high. Anyone here who knows French and can fully take in the video's commentary? :monster: @Eerie is the only TLS member I know of who can speak French.

Zelant is able to emulate and record Dirge of Cerberus while still maintaining a high framerate. Until I acquire a more powerful computer, I am limited to 480p recordings if I want to retain a consistent, reasonable framerate. It's very much appreciated to see 1080p recordings of some of these areas online. Followers of this thread may particularly enjoy seeing the maps City and Temple.

While I do not speak French it is obvious that Zelant goes over a ton of both common- and obscure Dirge of Cerberus facts throughout the video. My name is mentioned three times (and Lifestream.Net is mentioned once at 6:30) and my research is definitely the basis for this showcase. Impressively Zelant did all the cheats and explorations without my direct aid.


1:14 - 5:22
Exploration of normal areas in the Shera but controlling Cait Sith's model instead. Zelant also had fun changing the names of the items in the shop, seen at 2:56.
Potion de Nyx​
Ether de Cernan​
Elixir de Tenerus​
Remede de Josianne​
Plume de Kerzian​
Tente de Haricotie​
Boisson de Corsicasse​
Hyper de Rico​
Ainsi que...​
... tous les autres !​
Evidemment :D !​

TRANSLATION:
Potion of Nyx​
Ether of Cernan​
Elixir of Tenerus​
Josianne's Remedy​
Kerzian's Feather​
Tent of Haricotie​
Corsicasse's Drink​
Hyper of Rico​
And...​
... all the others !​
Of course :D !​
These names seem to reference people who watch Zelant's videos.

5:22 - 7:09
Showing off the Shera room that is only ever limited to cutscenes in the final game.

7:26 - 16:18
Exploring the Deepground Lobby. All Multiplayer maps from here on out until we return to the Shera at the end of the video.

16:35 - 19:57
With the help of Tempsave Teleportation, the Deepground Lobby is further explored again but this time with the map's terminals (Ranking, Battle Entry, Shop and Unit Management) partially activated. A common consequence of using Tempsave Teleportation is that your player character is invisible and that is indeed the mode in which most zones are explored in Zelant's video.

20:14 - 22:28
Weiss's Throne room, Multiplayer version.

22:57 - 27:38
City. Exclusive to the NA and PAL discs of Dirge of Cerberus. I announced the discovery of this- and other unique maps back in March but I never made videos covering them. Many thanks to Zelant for sharing a high-quality recording of this area.

28:00 - 30:39
Interior of Kalm Church. This one is available in the Extra Missions but the EM barriers loaded here are from Multiplayer-based mission data.

30:57 - 38:10
Valley. The way Zelant loaded this area he actually made the following Multiplayer models visible: Destructible Bases, Flag Base and Flag(s). When I loaded and explored Valley, only the collision of these models were present but not their actual graphics. Depending on the game version and from where you setup Tempsave Teleportation, maps may be loaded differently this way (or not load at all!). The livestream chat end up talking about the FF7-FF10 connection, which shows that I am not the only one whose imagination springs to both Cetrans and Spirans when roaming the Valley zone.

38:29 - 41:41
Temple. Exclusive to the NA and PAL discs of Dirge of Cerberus. The textures pop out wonderfully in this 1080p recording.

41:55 - 46:26
Battlefield map, familiar from the Extra Missions. Wish I had known beforehand about Zelant's planned video so I could have pointed him to the Multiplayer-exclusive memory capsule that can be found when loading Battlefield by using Tempsave Teleportation!

46:40 - 49:59
Back to the Shera. Zelant talks about the unique textures and easter eggs found on the airship.

50:29 - 60:21
Chillin' in the sickbay of the Shera, stream winds down and the conversation focuses on The First Soldier and Ever Crisis.
 
Last edited:
Feels good when patience is rewarded and you finally learn what a series of assembly instructions actually mean.

Holy heck though. This sure was a long-winded way for even assembly code to perform "sine(radian)". :wacky:

Code:
3021177A - F3 0F59 CF            - mulss xmm1,xmm7
3021177E - F3 0F11 0D D08E6201   - movss [pcsx2.exe+5F8ED0],xmm1 { [0.01] }
30211786 - F3 0F11 3D A08E6201   - movss [pcsx2.exe+5F8EA0],xmm7 { [1.00] }
3021178E - 31 C0                 - xor eax,eax
30211790 - A3 149B6301           - mov [pcsx2.exe+609B14],eax { [00000000] }
30211795 - A3 F49C6301           - mov [pcsx2.exe+609CF4],eax { [00000000] }
3021179A - C7 05 109B6301 36FA8E3C - mov [pcsx2.exe+609B10],3C8EFA36 { [1.00] }
302117A4 - C7 05 F09C6301 08A22500 - mov [pcsx2.exe+609CF0],0025A208 { [0025A208] }
302117AE - C7 05 A89D6301 A09F2500 - mov [pcsx2.exe+609DA8],00259FA0 { [0025A000] }
302117B8 - A1 C09E6301           - mov eax,[pcsx2.exe+609EC0] { [A1DA6C44] }
302117BD - 83 C0 29              - add eax,29 { 41 }
302117C0 - A3 C09E6301           - mov [pcsx2.exe+609EC0],eax { [A1DA6C44] }
302117C5 - 2B 05 848E6201        - sub eax,[pcsx2.exe+5F8E84] { [A1DA741E] }
302117CB - 0F88 05000000         - js 302117D6
302117D1 - E9 2A28E6D2           - jmp pcsx2.exe+2044000
302117D6 - 83 05 D09C6301 C0     - add dword ptr [pcsx2.exe+609CD0],-40 { [01FFF5B0] }
302117DD - 9F                    - lahf
302117DE - 66 C1 F8 0F           - sar ax,0F { 15 }
302117E2 - 98                    - cwde
302117E3 - A3 D49C6301           - mov [pcsx2.exe+609CD4],eax { [00000000] }
302117E8 - 8B 15 F08E6201        - mov edx,[pcsx2.exe+5F8EF0] { [-0.50] }
302117EE - 8B 0D D09C6301        - mov ecx,[pcsx2.exe+609CD0] { [01FFF5B0] }
302117F4 - 83 C1 30              - add ecx,30 { 48 }
302117F7 - 89 C8                 - mov eax,ecx
302117F9 - C1 E8 0C              - shr eax,0C { 12 }
302117FC - 8B 04 85 30D0EA0C     - mov eax,[eax*4+0CEAD030]
30211803 - BB 12182130           - mov ebx,30211812 { [186] }
30211808 - 01 C1                 - add ecx,eax
3021180A - 0F88 30EADDD2         - js pcsx2.exe+1FC0240
30211810 - 89 11                 - mov [ecx],edx
30211812 - BA 009C6301           - mov edx,pcsx2.exe+609C00 { [01FFF6B0] }
30211817 - 8B 0D D09C6301        - mov ecx,[pcsx2.exe+609CD0] { [01FFF5B0] }
3021181D - 83 C1 20              - add ecx,20 { 32 }
30211820 - 83 E1 F0              - and ecx,-10 { 240 }
30211823 - 89 C8                 - mov eax,ecx
30211825 - C1 E8 0C              - shr eax,0C { 12 }
30211828 - 8B 04 85 30D0EA0C     - mov eax,[eax*4+0CEAD030]
3021182F - BB 42182130           - mov ebx,30211842 { [243] }
30211834 - 01 C1                 - add ecx,eax
30211836 - 0F88 84EADDD2         - js pcsx2.exe+1FC02C0
3021183C - 0F28 02               - movaps xmm0,[edx]
3021183F - 0F29 01               - movaps [ecx],xmm0
30211842 - F3 0F10 0D D08E6201   - movss xmm1,[pcsx2.exe+5F8ED0] { [0.01] }
3021184A - F3 0F10 D1            - movss xmm2,xmm1
3021184E - BA 109C6301           - mov edx,pcsx2.exe+609C10 { [01FFF5F0] }
30211853 - 8B 0D D09C6301        - mov ecx,[pcsx2.exe+609CD0] { [01FFF5B0] }
30211859 - 83 C1 10              - add ecx,10 { 16 }
3021185C - 83 E1 F0              - and ecx,-10 { 240 }
3021185F - F3 0F11 15 F08E6201   - movss [pcsx2.exe+5F8EF0],xmm2 { [-0.50] }
30211867 - 89 C8                 - mov eax,ecx
30211869 - C1 E8 0C              - shr eax,0C { 12 }
3021186C - 8B 04 85 30D0EA0C     - mov eax,[eax*4+0CEAD030]
30211873 - BB 86182130           - mov ebx,30211886 { [161] }
30211878 - 01 C1                 - add ecx,eax
3021187A - 0F88 40EADDD2         - js pcsx2.exe+1FC02C0
30211880 - 0F28 1A               - movaps xmm3,[edx]
30211883 - 0F29 19               - movaps [ecx],xmm3
30211886 - A1 509B6301           - mov eax,[pcsx2.exe+609B50] { [00000000] }
3021188B - 8B 15 549B6301        - mov edx,[pcsx2.exe+609B54] { [00000000] }
30211891 - A3 009C6301           - mov [pcsx2.exe+609C00],eax { [01FFF6B0] }
30211896 - 89 15 049C6301        - mov [pcsx2.exe+609C04],edx { [00000000] }
3021189C - A1 409B6301           - mov eax,[pcsx2.exe+609B40] { [0.06] }
302118A1 - 8B 15 449B6301        - mov edx,[pcsx2.exe+609B44] { [00000000] }
302118A7 - A3 109C6301           - mov [pcsx2.exe+609C10],eax { [01FFF5F0] }
302118AC - 89 15 149C6301        - mov [pcsx2.exe+609C14],edx { [00000000] }
302118B2 - BA F09C6301           - mov edx,pcsx2.exe+609CF0 { [0025A208] }
302118B7 - 8B 0D D09C6301        - mov ecx,[pcsx2.exe+609CD0] { [01FFF5B0] }
302118BD - 89 C8                 - mov eax,ecx
302118BF - C1 E8 0C              - shr eax,0C { 12 }
302118C2 - 8B 04 85 30D0EA0C     - mov eax,[eax*4+0CEAD030]
302118C9 - BB DC182130           - mov ebx,302118DC { [8EF4158B] }
302118CE - 01 C1                 - add ecx,eax
302118D0 - 0F88 AAE9DDD2         - js pcsx2.exe+1FC0280
302118D6 - 0F12 22               - movlps xmm4,[edx]
302118D9 - 0F13 21               - movlps [ecx],xmm4
302118DC - 8B 15 F48E6201        - mov edx,[pcsx2.exe+5F8EF4] { [6.60] }
302118E2 - 8B 0D D09C6301        - mov ecx,[pcsx2.exe+609CD0] { [01FFF5B0] }
302118E8 - 83 C1 38              - add ecx,38 { 56 }
302118EB - 89 C8                 - mov eax,ecx
302118ED - C1 E8 0C              - shr eax,0C { 12 }
302118F0 - 8B 04 85 30D0EA0C     - mov eax,[eax*4+0CEAD030]
302118F7 - BB 06192130           - mov ebx,30211906 { [49] }
302118FC - 01 C1                 - add ecx,eax
302118FE - 0F88 3CE9DDD2         - js pcsx2.exe+1FC0240
30211904 - 89 11                 - mov [ecx],edx
30211906 - 31 C0                 - xor eax,eax
30211908 - A3 F49C6301           - mov [pcsx2.exe+609CF4],eax { [00000000] }
3021190D - C7 05 F09C6301 C89F2500 - mov [pcsx2.exe+609CF0],00259FC8 { [0025A208] }
30211917 - C7 05 A89D6301 30B74500 - mov [pcsx2.exe+609DA8],0045B730 { [0025A000] }
30211921 - A1 C09E6301           - mov eax,[pcsx2.exe+609EC0] { [A1DA6C44] }
30211926 - 83 C0 0E              - add eax,0E { 14 }
30211929 - A3 C09E6301           - mov [pcsx2.exe+609EC0],eax { [A1DA6C44] }
3021192E - 2B 05 848E6201        - sub eax,[pcsx2.exe+5F8E84] { [A1DA741E] }
30211934 - 0F88 7019E8FF         - js 300932AA

...

300932AA - A1 D08E6201           - mov eax,[pcsx2.exe+5F8ED0] { [0.01] }
300932AF - 99                    - cdq
300932B0 - A3 209B6301           - mov [pcsx2.exe+609B20],eax { [00000000] }
300932B5 - 89 15 249B6301        - mov [pcsx2.exe+609B24],edx { [00000000] }
300932BB - 83 05 D09C6301 E0     - add dword ptr [pcsx2.exe+609CD0],-20 { [01FFF5B0] }
300932C2 - 9F                    - lahf
300932C3 - 66 C1 F8 0F           - sar ax,0F { 15 }
300932C7 - 98                    - cwde
300932C8 - A3 D49C6301           - mov [pcsx2.exe+609CD4],eax { [00000000] }
300932CD - A1 209B6301           - mov eax,[pcsx2.exe+609B20] { [00000000] }
300932D2 - 8B 15 249B6301        - mov edx,[pcsx2.exe+609B24] { [00000000] }
300932D8 - A3 409B6301           - mov [pcsx2.exe+609B40],eax { [0.06] }
300932DD - 89 15 449B6301        - mov [pcsx2.exe+609B44],edx { [00000000] }
300932E3 - 81 25 409B6301 FFFFFF7F - and [pcsx2.exe+609B40],7FFFFFFF { [0.06] }
300932ED - C7 05 449B6301 00000000 - mov [pcsx2.exe+609B44],00000000 { [00000000] }
300932F7 - B8 01000000           - mov eax,00000001 { 1 }
300932FC - 83 3D 449B6301 00     - cmp dword ptr [pcsx2.exe+609B44],00 { [00000000] }
30093303 - 7F 10                 - jg 30093315
30093305 - 7C 0C                 - jl 30093313
30093307 - 81 3D 409B6301 D80F493F - cmp [pcsx2.exe+609B40],3F490FD8 { [0.06] }
30093311 - 77 02                 - ja 30093315
30093313 - 31 C0                 - xor eax,eax
30093315 - A3 209B6301           - mov [pcsx2.exe+609B20],eax { [00000000] }
3009331A - C7 05 249B6301 00000000 - mov [pcsx2.exe+609B24],00000000 { [00000000] }
30093324 - C7 05 309B6301 FFFFFF7F - mov [pcsx2.exe+609B30],7FFFFFFF { [7FFFFFFF] }
3009332E - C7 05 349B6301 00000000 - mov [pcsx2.exe+609B34],00000000 { [0.00] }
30093338 - 83 3D 209B6301 00     - cmp dword ptr [pcsx2.exe+609B20],00 { [00000000] }
3009333F - 75 0D                 - jne 3009334E
30093341 - 83 3D 249B6301 00     - cmp dword ptr [pcsx2.exe+609B24],00 { [00000000] }
30093348 - 0F84 55000000         - je 300933A3
3009334E - BA F09C6301           - mov edx,pcsx2.exe+609CF0 { [0025A208] }
30093353 - 8B 0D D09C6301        - mov ecx,[pcsx2.exe+609CD0] { [01FFF5B0] }
30093359 - 83 C1 10              - add ecx,10 { 16 }
3009335C - 89 C8                 - mov eax,ecx
3009335E - C1 E8 0C              - shr eax,0C { 12 }
30093361 - 8B 04 85 30D0EA0C     - mov eax,[eax*4+0CEAD030]
30093368 - BB 7B330930           - mov ebx,3009337B { [199] }
3009336D - 01 C1                 - add ecx,eax
3009336F - 0F88 0BCFF5D2         - js pcsx2.exe+1FC0280
30093375 - 0F12 02               - movlps xmm0,[edx]
30093378 - 0F13 01               - movlps [ecx],xmm0
3009337B - C7 05 A89D6301 70B74500 - mov [pcsx2.exe+609DA8],0045B770 { [0025A000] }
30093385 - A1 C09E6301           - mov eax,[pcsx2.exe+609EC0] { [A1DA6C44] }
3009338A - 83 C0 0D              - add eax,0D { 13 }
3009338D - A3 C09E6301           - mov [pcsx2.exe+609EC0],eax { [A1DA6C44] }
30093392 - 2B 05 848E6201        - sub eax,[pcsx2.exe+5F8E84] { [A1DA741E] }
30093398 - 0F88 F3260000         - js 30095A91
3009339E - E9 5D0CFED2           - jmp pcsx2.exe+2044000
300933A3 - BA F09C6301           - mov edx,pcsx2.exe+609CF0 { [0025A208] }
300933A8 - 8B 0D D09C6301        - mov ecx,[pcsx2.exe+609CD0] { [01FFF5B0] }
300933AE - 83 C1 10              - add ecx,10 { 16 }
300933B1 - 89 C8                 - mov eax,ecx
300933B3 - C1 E8 0C              - shr eax,0C { 12 }
300933B6 - 8B 04 85 30D0EA0C     - mov eax,[eax*4+0CEAD030]
300933BD - BB D0330930           - mov ebx,300933D0 { [9DA805C7] }
300933C2 - 01 C1                 - add ecx,eax
300933C4 - 0F88 B6CEF5D2         - js pcsx2.exe+1FC0280
300933CA - 0F12 0A               - movlps xmm1,[edx]
300933CD - 0F13 09               - movlps [ecx],xmm1
300933D0 - C7 05 A89D6301 5CB74500 - mov [pcsx2.exe+609DA8],0045B75C { [0025A000] }
300933DA - A1 C09E6301           - mov eax,[pcsx2.exe+609EC0] { [A1DA6C44] }
300933DF - 83 C0 0D              - add eax,0D { 13 }
300933E2 - A3 C09E6301           - mov [pcsx2.exe+609EC0],eax { [A1DA6C44] }
300933E7 - 2B 05 848E6201        - sub eax,[pcsx2.exe+5F8E84] { [A1DA741E] }
300933ED - 0F88 05000000         - js 300933F8
300933F3 - E9 080CFED2           - jmp pcsx2.exe+2044000
300933F8 - C7 05 D48E6201 00000000 - mov [pcsx2.exe+5F8ED4],00000000 { [00000000] }
30093402 - 31 C0                 - xor eax,eax
30093404 - A3 409B6301           - mov [pcsx2.exe+609B40],eax { [0.06] }
30093409 - A3 449B6301           - mov [pcsx2.exe+609B44],eax { [00000000] }
3009340E - A3 F49C6301           - mov [pcsx2.exe+609CF4],eax { [00000000] }
30093413 - C7 05 F09C6301 68B74500 - mov [pcsx2.exe+609CF0],0045B768 { [0025A208] }
3009341D - C7 05 A89D6301 E0EB4500 - mov [pcsx2.exe+609DA8],0045EBE0 { [0025A000] }
30093427 - A1 C09E6301           - mov eax,[pcsx2.exe+609EC0] { [A1DA6C44] }
3009342C - 83 C0 03              - add eax,03 { 3 }
3009342F - A3 C09E6301           - mov [pcsx2.exe+609EC0],eax { [A1DA6C44] }
30093434 - 2B 05 848E6201        - sub eax,[pcsx2.exe+5F8E84] { [A1DA741E] }
3009343A - 0F88 05000000         - js 30093445
30093440 - E9 BB0BFED2           - jmp pcsx2.exe+2044000
30093445 - A1 409B6301           - mov eax,[pcsx2.exe+609B40] { [0.06] }
3009344A - 8B 15 449B6301        - mov edx,[pcsx2.exe+609B44] { [00000000] }
30093450 - A3 509B6301           - mov [pcsx2.exe+609B50],eax { [00000000] }
30093455 - 89 15 549B6301        - mov [pcsx2.exe+609B54],edx { [00000000] }
3009345B - A1 D08E6201           - mov eax,[pcsx2.exe+5F8ED0] { [0.01] }
30093460 - 99                    - cdq
30093461 - A3 209B6301           - mov [pcsx2.exe+609B20],eax { [00000000] }
30093466 - 89 15 249B6301        - mov [pcsx2.exe+609B24],edx { [00000000] }
3009346C - A1 209B6301           - mov eax,[pcsx2.exe+609B20] { [00000000] }
30093471 - 8B 15 249B6301        - mov edx,[pcsx2.exe+609B24] { [00000000] }
30093477 - A3 409B6301           - mov [pcsx2.exe+609B40],eax { [0.06] }
3009347C - 89 15 449B6301        - mov [pcsx2.exe+609B44],edx { [00000000] }
30093482 - 81 25 409B6301 FFFFFF7F - and [pcsx2.exe+609B40],7FFFFFFF { [0.06] }
3009348C - C7 05 449B6301 00000000 - mov [pcsx2.exe+609B44],00000000 { [00000000] }
30093496 - B8 01000000           - mov eax,00000001 { 1 }
3009349B - 83 3D 449B6301 00     - cmp dword ptr [pcsx2.exe+609B44],00 { [00000000] }
300934A2 - 7F 10                 - jg 300934B4
300934A4 - 7C 0C                 - jl 300934B2
300934A6 - 81 3D 409B6301 FFFFFF31 - cmp [pcsx2.exe+609B40],31FFFFFF { [0.06] }
300934B0 - 77 02                 - ja 300934B4
300934B2 - 31 C0                 - xor eax,eax
300934B4 - A3 209B6301           - mov [pcsx2.exe+609B20],eax { [00000000] }
300934B9 - C7 05 249B6301 00000000 - mov [pcsx2.exe+609B24],00000000 { [00000000] }
300934C3 - C7 05 309B6301 FFFFFF7F - mov [pcsx2.exe+609B30],7FFFFFFF { [7FFFFFFF] }
300934CD - C7 05 349B6301 00000000 - mov [pcsx2.exe+609B34],00000000 { [0.00] }
300934D7 - 83 3D 209B6301 00     - cmp dword ptr [pcsx2.exe+609B20],00 { [00000000] }
300934DE - 0F85 35000000         - jne 30093519
300934E4 - 83 3D 249B6301 00     - cmp dword ptr [pcsx2.exe+609B24],00 { [00000000] }
300934EB - 0F85 28000000         - jne 30093519
300934F1 - C7 05 A89D6301 0CEC4500 - mov [pcsx2.exe+609DA8],0045EC0C { [0025A000] }
300934FB - A1 C09E6301           - mov eax,[pcsx2.exe+609EC0] { [A1DA6C44] }
30093500 - 83 C0 0B              - add eax,0B { 11 }
30093503 - A3 C09E6301           - mov [pcsx2.exe+609EC0],eax { [A1DA6C44] }
30093508 - 2B 05 848E6201        - sub eax,[pcsx2.exe+5F8E84] { [A1DA741E] }
3009350E - 0F88 2A190000         - js 30094E3E
30093514 - E9 E70AFED2           - jmp pcsx2.exe+2044000
30093519 - F3 0F10 05 D08E6201   - movss xmm0,[pcsx2.exe+5F8ED0] { [0.01] }
30093521 - F3 0F10 C8            - movss xmm1,xmm0
30093525 - F3 0F59 C8            - mulss xmm1,xmm0
30093529 - F3 0F11 0D B48E6201   - movss [pcsx2.exe+5F8EB4],xmm1 { [0.00] }
30093531 - C7 05 A89D6301 28EC4500 - mov [pcsx2.exe+609DA8],0045EC28 { [0025A000] }
3009353B - A1 C09E6301           - mov eax,[pcsx2.exe+609EC0] { [A1DA6C44] }
30093540 - 83 C0 0F              - add eax,0F { 15 }
30093543 - A3 C09E6301           - mov [pcsx2.exe+609EC0],eax { [A1DA6C44] }
30093548 - 2B 05 848E6201        - sub eax,[pcsx2.exe+5F8E84] { [A1DA741E] }
3009354E - 0F88 05000000         - js 30093559
30093554 - E9 A70AFED2           - jmp pcsx2.exe+2044000
30093559 - C7 05 A08E6201 D3C92E2F - mov [pcsx2.exe+5F8EA0],2F2EC9D3 { [1.00] }
30093563 - C7 05 A48E6201 342FD7B2 - mov [pcsx2.exe+5F8EA4],B2D72F34 { [1.00] }
3009356D - C7 05 A88E6201 1BEF3836 - mov [pcsx2.exe+5F8EA8],3638EF1B { [0.05] }
30093577 - F3 0F10 05 A08E6201   - movss xmm0,[pcsx2.exe+5F8EA0] { [1.00] }
3009357F - F3 0F10 0D B48E6201   - movss xmm1,[pcsx2.exe+5F8EB4] { [0.00] }
30093587 - F3 0F59 C1            - mulss xmm0,xmm1
3009358B - C7 05 AC8E6201 010D50B9 - mov [pcsx2.exe+5F8EAC],B9500D01 { [00000000] }
30093595 - C7 05 B08E6201 8988083C - mov [pcsx2.exe+5F8EB0],3C088889 { [-0.01] }
3009359F - F3 0F10 1D D08E6201   - movss xmm3,[pcsx2.exe+5F8ED0] { [0.01] }
300935A7 - F3 0F10 E1            - movss xmm4,xmm1
300935AB - F3 0F59 E3            - mulss xmm4,xmm3
300935AF - F3 0F10 35 A48E6201   - movss xmm6,[pcsx2.exe+5F8EA4] { [1.00] }
300935B7 - 66 0F7E C1            - movd ecx,xmm0
300935BB - 66 0F7E F2            - movd edx,xmm6
300935BF - C1 E9 17              - shr ecx,17 { 23 }
300935C2 - C1 EA 17              - shr edx,17 { 23 }
300935C5 - 81 E1 FF000000        - and ecx,000000FF { 255 }
300935CB - 81 E2 FF000000        - and edx,000000FF { 255 }
300935D1 - 29 D1                 - sub ecx,edx
300935D3 - 83 F9 19              - cmp ecx,19 { 25 }
300935D6 - 7D 23                 - jnl 300935FB
300935D8 - 83 F9 00              - cmp ecx,00 { 0 }
300935DB - 7F 2E                 - jg 3009360B
300935DD - 74 4E                 - je 3009362D
300935DF - 83 F9 E7              - cmp ecx,-19 { 231 }
300935E2 - 7E 3C                 - jle 30093620
300935E4 - F7 D9                 - neg ecx
300935E6 - 49                    - dec ecx
300935E7 - BA FFFFFFFF           - mov edx,FFFFFFFF { -1 }
300935EC - D3 E2                 - shl edx,cl
300935EE - 66 0F6E D2            - movd xmm2,edx
300935F2 - 0F54 C2               - andps xmm0,xmm2
300935F5 - F3 0F58 C6            - addss xmm0,xmm6
300935F9 - EB 36                 - jmp 30093631
300935FB - 0F28 D6               - movaps xmm2,xmm6
300935FE - 0F54 15 00004C01      - andps xmm2,[pcsx2.exe+490000] { [80000000] }
30093605 - F3 0F58 C2            - addss xmm0,xmm2
30093609 - EB 26                 - jmp 30093631
3009360B - 49                    - dec ecx
3009360C - BA FFFFFFFF           - mov edx,FFFFFFFF { -1 }
30093611 - D3 E2                 - shl edx,cl
30093613 - 66 0F6E D2            - movd xmm2,edx
30093617 - 0F54 D6               - andps xmm2,xmm6
3009361A - F3 0F58 C2            - addss xmm0,xmm2
3009361E - EB 11                 - jmp 30093631
30093620 - 0F54 05 00004C01      - andps xmm0,[pcsx2.exe+490000] { [80000000] }
30093627 - F3 0F58 C6            - addss xmm0,xmm6
3009362B - EB 04                 - jmp 30093631
3009362D - F3 0F58 C6            - addss xmm0,xmm6
30093631 - F3 0F59 C1            - mulss xmm0,xmm1
30093635 - F3 0F10 3D A88E6201   - movss xmm7,[pcsx2.exe+5F8EA8] { [0.05] }
3009363D - 66 0F7E C1            - movd ecx,xmm0
30093641 - 66 0F7E FB            - movd ebx,xmm7
30093645 - C1 E9 17              - shr ecx,17 { 23 }
30093648 - C1 EB 17              - shr ebx,17 { 23 }
3009364B - 81 E1 FF000000        - and ecx,000000FF { 255 }
30093651 - 81 E3 FF000000        - and ebx,000000FF { 255 }
30093657 - 29 D9                 - sub ecx,ebx
30093659 - 83 F9 19              - cmp ecx,19 { 25 }
3009365C - 7D 23                 - jnl 30093681
3009365E - 83 F9 00              - cmp ecx,00 { 0 }
30093661 - 7F 2E                 - jg 30093691
30093663 - 74 4E                 - je 300936B3
30093665 - 83 F9 E7              - cmp ecx,-19 { 231 }
30093668 - 7E 3C                 - jle 300936A6
3009366A - F7 D9                 - neg ecx
3009366C - 49                    - dec ecx
3009366D - BB FFFFFFFF           - mov ebx,FFFFFFFF { -1 }
30093672 - D3 E3                 - shl ebx,cl
30093674 - 66 0F6E EB            - movd xmm5,ebx
30093678 - 0F54 C5               - andps xmm0,xmm5
3009367B - F3 0F58 C7            - addss xmm0,xmm7
3009367F - EB 36                 - jmp 300936B7
30093681 - 0F28 EF               - movaps xmm5,xmm7
30093684 - 0F54 2D 00004C01      - andps xmm5,[pcsx2.exe+490000] { [80000000] }
3009368B - F3 0F58 C5            - addss xmm0,xmm5
3009368F - EB 26                 - jmp 300936B7
30093691 - 49                    - dec ecx
30093692 - BB FFFFFFFF           - mov ebx,FFFFFFFF { -1 }
30093697 - D3 E3                 - shl ebx,cl
30093699 - 66 0F6E EB            - movd xmm5,ebx
3009369D - 0F54 EF               - andps xmm5,xmm7
300936A0 - F3 0F58 C5            - addss xmm0,xmm5
300936A4 - EB 11                 - jmp 300936B7
300936A6 - 0F54 05 00004C01      - andps xmm0,[pcsx2.exe+490000] { [80000000] }
300936AD - F3 0F58 C7            - addss xmm0,xmm7
300936B1 - EB 04                 - jmp 300936B7
300936B3 - F3 0F58 C7            - addss xmm0,xmm7
300936B7 - F3 0F59 C1            - mulss xmm0,xmm1
300936BB - F3 0F10 2D AC8E6201   - movss xmm5,[pcsx2.exe+5F8EAC] { [0.00] }
300936C3 - 66 0F7E C1            - movd ecx,xmm0
300936C7 - 66 0F7E EE            - movd esi,xmm5
300936CB - C1 E9 17              - shr ecx,17 { 23 }
300936CE - C1 EE 17              - shr esi,17 { 23 }
300936D1 - 81 E1 FF000000        - and ecx,000000FF { 255 }
300936D7 - 81 E6 FF000000        - and esi,000000FF { 255 }
300936DD - 29 F1                 - sub ecx,esi
300936DF - 83 F9 19              - cmp ecx,19 { 25 }
300936E2 - 7D 23                 - jnl 30093707
300936E4 - 83 F9 00              - cmp ecx,00 { 0 }
300936E7 - 7F 2E                 - jg 30093717
300936E9 - 74 4E                 - je 30093739
300936EB - 83 F9 E7              - cmp ecx,-19 { 231 }
300936EE - 7E 3C                 - jle 3009372C
300936F0 - F7 D9                 - neg ecx
300936F2 - 49                    - dec ecx
300936F3 - BE FFFFFFFF           - mov esi,FFFFFFFF { -1 }
300936F8 - D3 E6                 - shl esi,cl
300936FA - 66 0F6E CE            - movd xmm1,esi
300936FE - 0F54 C1               - andps xmm0,xmm1
30093701 - F3 0F58 C5            - addss xmm0,xmm5
30093705 - EB 36                 - jmp 3009373D
30093707 - 0F28 CD               - movaps xmm1,xmm5
3009370A - 0F54 0D 00004C01      - andps xmm1,[pcsx2.exe+490000] { [80000000] }
30093711 - F3 0F58 C1            - addss xmm0,xmm1
30093715 - EB 26                 - jmp 3009373D
30093717 - 49                    - dec ecx
30093718 - BE FFFFFFFF           - mov esi,FFFFFFFF { -1 }
3009371D - D3 E6                 - shl esi,cl
3009371F - 66 0F6E CE            - movd xmm1,esi
30093723 - 0F54 CD               - andps xmm1,xmm5
30093726 - F3 0F58 C1            - addss xmm0,xmm1
3009372A - EB 11                 - jmp 3009373D
3009372C - 0F54 05 00004C01      - andps xmm0,[pcsx2.exe+490000] { [80000000] }
30093733 - F3 0F58 C5            - addss xmm0,xmm5
30093737 - EB 04                 - jmp 3009373D
30093739 - F3 0F58 C5            - addss xmm0,xmm5
3009373D - F3 0F10 0D B48E6201   - movss xmm1,[pcsx2.exe+5F8EB4] { [0.00] }
30093745 - F3 0F59 C1            - mulss xmm0,xmm1
30093749 - C7 05 109B6301 8988083C - mov [pcsx2.exe+609B10],3C088889 { [1.00] }
30093753 - C7 05 149B6301 00000000 - mov [pcsx2.exe+609B14],00000000 { [00000000] }
3009375D - F3 0F11 05 A08E6201   - movss [pcsx2.exe+5F8EA0],xmm0 { [1.00] }
30093765 - F3 0F11 25 B88E6201   - movss [pcsx2.exe+5F8EB8],xmm4 { [0.00] }
3009376D - 83 3D 509B6301 00     - cmp dword ptr [pcsx2.exe+609B50],00 { [00000000] }
30093774 - 75 0D                 - jne 30093783
30093776 - 83 3D 549B6301 00     - cmp dword ptr [pcsx2.exe+609B54],00 { [00000000] }
3009377D - 0F84 BE000000         - je 30093841
30093783 - F3 0F10 1D B08E6201   - movss xmm3,[pcsx2.exe+5F8EB0] { [-0.01] }
3009378B - F3 0F10 25 A08E6201   - movss xmm4,[pcsx2.exe+5F8EA0] { [1.00] }
30093793 - F3 0F10 EC            - movss xmm5,xmm4
30093797 - 66 0F7E E9            - movd ecx,xmm5
3009379B - 66 0F7E DF            - movd edi,xmm3
3009379F - C1 E9 17              - shr ecx,17 { 23 }
300937A2 - C1 EF 17              - shr edi,17 { 23 }
300937A5 - 81 E1 FF000000        - and ecx,000000FF { 255 }
300937AB - 81 E7 FF000000        - and edi,000000FF { 255 }
300937B1 - 29 F9                 - sub ecx,edi
300937B3 - 83 F9 19              - cmp ecx,19 { 25 }
300937B6 - 7D 23                 - jnl 300937DB
300937B8 - 83 F9 00              - cmp ecx,00 { 0 }
300937BB - 7F 2E                 - jg 300937EB
300937BD - 74 4E                 - je 3009380D
300937BF - 83 F9 E7              - cmp ecx,-19 { 231 }
300937C2 - 7E 3C                 - jle 30093800
300937C4 - F7 D9                 - neg ecx
300937C6 - 49                    - dec ecx
300937C7 - BF FFFFFFFF           - mov edi,FFFFFFFF { -1 }
300937CC - D3 E7                 - shl edi,cl
300937CE - 66 0F6E FF            - movd xmm7,edi
300937D2 - 0F54 EF               - andps xmm5,xmm7
300937D5 - F3 0F58 EB            - addss xmm5,xmm3
300937D9 - EB 36                 - jmp 30093811
300937DB - 0F28 FB               - movaps xmm7,xmm3
300937DE - 0F54 3D 00004C01      - andps xmm7,[pcsx2.exe+490000] { [80000000] }
300937E5 - F3 0F58 EF            - addss xmm5,xmm7
300937E9 - EB 26                 - jmp 30093811
300937EB - 49                    - dec ecx
300937EC - BF FFFFFFFF           - mov edi,FFFFFFFF { -1 }
300937F1 - D3 E7                 - shl edi,cl
300937F3 - 66 0F6E FF            - movd xmm7,edi
300937F7 - 0F54 FB               - andps xmm7,xmm3
300937FA - F3 0F58 EF            - addss xmm5,xmm7
300937FE - EB 11                 - jmp 30093811
30093800 - 0F54 2D 00004C01      - andps xmm5,[pcsx2.exe+490000] { [80000000] }
30093807 - F3 0F58 EB            - addss xmm5,xmm3
3009380B - EB 04                 - jmp 30093811
3009380D - F3 0F58 EB            - addss xmm5,xmm3
30093811 - F3 0F11 2D A48E6201   - movss [pcsx2.exe+5F8EA4],xmm5 { [1.00] }
30093819 - C7 05 A89D6301 ACEC4500 - mov [pcsx2.exe+609DA8],0045ECAC { [0025A000] }
30093823 - A1 C09E6301           - mov eax,[pcsx2.exe+609EC0] { [A1DA6C44] }
30093828 - 83 C0 28              - add eax,28 { 40 }
3009382B - A3 C09E6301           - mov [pcsx2.exe+609EC0],eax { [A1DA6C44] }
30093830 - 2B 05 848E6201        - sub eax,[pcsx2.exe+5F8E84] { [A1DA741E] }
30093836 - 0F88 D0320000         - js 30096B0C
3009383C - E9 BF07FED2           - jmp pcsx2.exe+2044000
30093841 - F3 0F10 05 B08E6201   - movss xmm0,[pcsx2.exe+5F8EB0] { [-0.01] }
30093849 - F3 0F10 0D A08E6201   - movss xmm1,[pcsx2.exe+5F8EA0] { [1.00] }
30093851 - F3 0F10 D1            - movss xmm2,xmm1
30093855 - 66 0F7E D1            - movd ecx,xmm2
30093859 - 66 0F7E C2            - movd edx,xmm0
3009385D - C1 E9 17              - shr ecx,17 { 23 }
30093860 - C1 EA 17              - shr edx,17 { 23 }
30093863 - 81 E1 FF000000        - and ecx,000000FF { 255 }
30093869 - 81 E2 FF000000        - and edx,000000FF { 255 }
3009386F - 29 D1                 - sub ecx,edx
30093871 - 83 F9 19              - cmp ecx,19 { 25 }
30093874 - 7D 23                 - jnl 30093899
30093876 - 83 F9 00              - cmp ecx,00 { 0 }
30093879 - 7F 2E                 - jg 300938A9
3009387B - 74 4E                 - je 300938CB
3009387D - 83 F9 E7              - cmp ecx,-19 { 231 }
30093880 - 7E 3C                 - jle 300938BE
30093882 - F7 D9                 - neg ecx
30093884 - 49                    - dec ecx
30093885 - BA FFFFFFFF           - mov edx,FFFFFFFF { -1 }
3009388A - D3 E2                 - shl edx,cl
3009388C - 66 0F6E E2            - movd xmm4,edx
30093890 - 0F54 D4               - andps xmm2,xmm4
30093893 - F3 0F58 D0            - addss xmm2,xmm0
30093897 - EB 36                 - jmp 300938CF
30093899 - 0F28 E0               - movaps xmm4,xmm0
3009389C - 0F54 25 00004C01      - andps xmm4,[pcsx2.exe+490000] { [80000000] }
300938A3 - F3 0F58 D4            - addss xmm2,xmm4
300938A7 - EB 26                 - jmp 300938CF
300938A9 - 49                    - dec ecx
300938AA - BA FFFFFFFF           - mov edx,FFFFFFFF { -1 }
300938AF - D3 E2                 - shl edx,cl
300938B1 - 66 0F6E E2            - movd xmm4,edx
300938B5 - 0F54 E0               - andps xmm4,xmm0
300938B8 - F3 0F58 D4            - addss xmm2,xmm4
300938BC - EB 11                 - jmp 300938CF
300938BE - 0F54 15 00004C01      - andps xmm2,[pcsx2.exe+490000] { [80000000] }
300938C5 - F3 0F58 D0            - addss xmm2,xmm0
300938C9 - EB 04                 - jmp 300938CF
300938CB - F3 0F58 D0            - addss xmm2,xmm0
300938CF - F3 0F11 15 A48E6201   - movss [pcsx2.exe+5F8EA4],xmm2 { [1.00] }
300938D7 - C7 05 A89D6301 8CEC4500 - mov [pcsx2.exe+609DA8],0045EC8C { [0025A000] }
300938E1 - A1 C09E6301           - mov eax,[pcsx2.exe+609EC0] { [A1DA6C44] }
300938E6 - 83 C0 28              - add eax,28 { 40 }
300938E9 - A3 C09E6301           - mov [pcsx2.exe+609EC0],eax { [A1DA6C44] }
300938EE - 2B 05 848E6201        - sub eax,[pcsx2.exe+5F8E84] { [A1DA741E] }
300938F4 - 0F88 05000000         - js 300938FF
300938FA - E9 0107FED2           - jmp pcsx2.exe+2044000
300938FF - F3 0F10 05 A48E6201   - movss xmm0,[pcsx2.exe+5F8EA4] { [1.00] }
30093907 - F3 0F10 0D B48E6201   - movss xmm1,[pcsx2.exe+5F8EB4] { [0.00] }
3009390F - F3 0F10 D1            - movss xmm2,xmm1
30093913 - F3 0F59 D0            - mulss xmm2,xmm0
30093917 - C7 05 A48E6201 ABAA2ABE - mov [pcsx2.exe+5F8EA4],BE2AAAAB { [1.00] }
30093921 - F3 0F10 25 A48E6201   - movss xmm4,[pcsx2.exe+5F8EA4] { [1.00] }
30093929 - 66 0F7E D1            - movd ecx,xmm2
3009392D - 66 0F7E E2            - movd edx,xmm4
30093931 - C1 E9 17              - shr ecx,17 { 23 }
30093934 - C1 EA 17              - shr edx,17 { 23 }
30093937 - 81 E1 FF000000        - and ecx,000000FF { 255 }
3009393D - 81 E2 FF000000        - and edx,000000FF { 255 }
30093943 - 29 D1                 - sub ecx,edx
30093945 - 83 F9 19              - cmp ecx,19 { 25 }
30093948 - 7D 23                 - jnl 3009396D
3009394A - 83 F9 00              - cmp ecx,00 { 0 }
3009394D - 7F 2E                 - jg 3009397D
3009394F - 74 4E                 - je 3009399F
30093951 - 83 F9 E7              - cmp ecx,-19 { 231 }
30093954 - 7E 3C                 - jle 30093992
30093956 - F7 D9                 - neg ecx
30093958 - 49                    - dec ecx
30093959 - BA FFFFFFFF           - mov edx,FFFFFFFF { -1 }
3009395E - D3 E2                 - shl edx,cl
30093960 - 66 0F6E F2            - movd xmm6,edx
30093964 - 0F54 D6               - andps xmm2,xmm6
30093967 - F3 0F58 D4            - addss xmm2,xmm4
3009396B - EB 36                 - jmp 300939A3
3009396D - 0F28 F4               - movaps xmm6,xmm4
30093970 - 0F54 35 00004C01      - andps xmm6,[pcsx2.exe+490000] { [80000000] }
30093977 - F3 0F58 D6            - addss xmm2,xmm6
3009397B - EB 26                 - jmp 300939A3
3009397D - 49                    - dec ecx
3009397E - BA FFFFFFFF           - mov edx,FFFFFFFF { -1 }
30093983 - D3 E2                 - shl edx,cl
30093985 - 66 0F6E F2            - movd xmm6,edx
30093989 - 0F54 F4               - andps xmm6,xmm4
3009398C - F3 0F58 D6            - addss xmm2,xmm6
30093990 - EB 11                 - jmp 300939A3
30093992 - 0F54 15 00004C01      - andps xmm2,[pcsx2.exe+490000] { [80000000] }
30093999 - F3 0F58 D4            - addss xmm2,xmm4
3009399D - EB 04                 - jmp 300939A3
3009399F - F3 0F58 D4            - addss xmm2,xmm4
300939A3 - F3 0F10 3D B88E6201   - movss xmm7,[pcsx2.exe+5F8EB8] { [0.00] }
300939AB - F3 0F59 D7            - mulss xmm2,xmm7
300939AF - 8B 35 F09C6301        - mov esi,[pcsx2.exe+609CF0] { [0025A208] }
300939B5 - F3 0F10 1D D08E6201   - movss xmm3,[pcsx2.exe+5F8ED0] { [0.01] }
300939BD - 66 0F7E D1            - movd ecx,xmm2
300939C1 - 66 0F7E DB            - movd ebx,xmm3
300939C5 - C1 E9 17              - shr ecx,17 { 23 }
300939C8 - C1 EB 17              - shr ebx,17 { 23 }
300939CB - 81 E1 FF000000        - and ecx,000000FF { 255 }
300939D1 - 81 E3 FF000000        - and ebx,000000FF { 255 }
300939D7 - 29 D9                 - sub ecx,ebx
300939D9 - 83 F9 19              - cmp ecx,19 { 25 }
300939DC - 7D 23                 - jnl 30093A01
300939DE - 83 F9 00              - cmp ecx,00 { 0 }
300939E1 - 7F 2E                 - jg 30093A11
300939E3 - 74 4E                 - je 30093A33
300939E5 - 83 F9 E7              - cmp ecx,-19 { 231 }
300939E8 - 7E 3C                 - jle 30093A26
300939EA - F7 D9                 - neg ecx
300939EC - 49                    - dec ecx
300939ED - BB FFFFFFFF           - mov ebx,FFFFFFFF { -1 }
300939F2 - D3 E3                 - shl ebx,cl
300939F4 - 66 0F6E F3            - movd xmm6,ebx
300939F8 - 0F54 D6               - andps xmm2,xmm6
300939FB - F3 0F58 D3            - addss xmm2,xmm3

And I still got ways to go in figuring out the calculation formula for bullet trajectories.
 
Last edited:
Speedrun of Extra Mission #07: Gatling in the Wastes

RTA: 02:11.966
IGT: 02:12




The goal in this mission is to accumulate 500 points before the timer runs out. Five enemies spawn in this stage and grant the following amount of points when defeated:
Guard Hound.....1
Crimson Hound...3
Epiolnis........5
Cactuar.........20
Dual Horn.......30

Enemies and their respective HP amounts:
Guard Hound.....1000
Crimson Hound...1000
Epiolnis........2000
Cactuar.........1000
Dual Horn.......15000


The intended method, as the mission name implies, is to use any of the gun turrets present throughout the stage. These are located in the west- and central regions. Because enemies only spawn in the east you'll end up waiting a lot if you camp out on any of the gatling guns. Gun turrets only provide manual aim, no auto-lock, so the requirement for precision gatling will also lose you time. With the intended method it is not reasonable to achieve a time below even 03:30.

Thankfully the mission starts out with some normal ammo in our inventory. Moving to the east and battling monsters right in the thick of it, combining magic and normal bullets, is thus a functional (and faster) approach so long as you are able to maintain a high killchain. There are no additional ammo drops so you have to make do with the initial supply.
180 Handgun Bullets (60 shots)
300 Machine Gun Bullets
60 Rifle Bullets

To finish the mission quickly you need good RNG with lots of Cactuars and Dual Horns spawning. "Gatling in the Wastes" gives the impression of being *almost* all RNG in regards to which enemy spawns where. The only discernible pattern is that it takes a while from mission start before Cactuars and Dual Horns start showing up (I do not know if this is related to your points and/or kill count in any way). This stands in contrast to a mission like "Vincent the Mage" where there are clear pre-determined patterns for enemy spawns, with some branching paths, and so memorization is rewarded in that mission.

Handgun Bullets are reserved for the initial build-up of the killchain and then later for the Dual Horns due to their immense HP pool. I got a bit greedy/wasteful with my handgun bullets in my 02:12 and so I lost roughly two seconds at the end by not reacting fast enough to having depleted that ammo type.


Sight Support: Semi-Automatic​
W1: Ultima Weapon + Nova L Barrel + Materia Floater + Manasoul + Thunder Materia (Thunder Lv2)​
W2: Starry Griffon + Nova L Barrel + Materia Floater Gamma + Manasoul + Thunder Materia (Thunder Lv3)​
W3: Velvet Hydra + Nova L Barrel + Materia Floater + Manasoul + Thunder Materia (Thunder Lv2)​

One constant risk in the mission is that you'll lose the damage-boosting killchain due to new enemies not showing up fast enough or you not reacting quickly enough to their presence. Thunder Lv3 can often be a detriment because it clears too many enemies in one go, increasing the risk that more than five seconds will pass before the next enemy shows up to save your killchain. Thunder Lv2 is thus favored both because of the lower MP consumption and because of the lowered risk that you'll defeat enemies faster than they can spawn.

I tell ya, those moments when you are desperately looking for the next enemy to continue the chain really gets your heart pumping. :wacky: Continuously rotating and moving around is also important since you can never tell by sound alone if an enemy is right behind you, ready to damage you and cancel your killchain.

Gun frames were chosen as a balance between power, speed and magazine size. Velvet Hydra is one of the weaker rifles but the large magazine, 42 bullets per magazine, is essential for lowering the risk that a reload will cost you your killchain. One machine gun I usually favor is the Sonic Griffon thanks to its immense firing rate and large 99-magazine. Starry Griffon has the same magazine size but fires slower and is more powerful. The lower firing rate actually helps, as the risk decreases of me accidentally unloading more bullets than intended. Nova L Barrel helps ensure that even the machine gun can strike targets very far away.

A lot of bullets do end up wasted though and in many cases it would have been beneficial to change Sight Support to fully Automatic. I stand by my choice though because Automatic aim means you have to fight against the game itself more frequently. The game will auto-lock on undesired foes and chaotically shift between targets, to the point that accuracy can be lowered and your run may fail.



I ended up quite loving this mission. The lack of dash-jumping makes it among the more appealing speedruns for outside viewers and the high-octane action gets my heart pumping. I don't even mind the RNG aspect because it's just so exciting when you are able to keep the killchain and absolutely shred your surroundings. As is often the case with intense DoC gameplay, the main reason I'm not grinding this mission further is because my heart can only take so much before the stress takes a toll on me.

Beforehand I actually dreaded EM07 because I was expecting it to be a boring gun turret affair. Thankfully, the game shows once again that it's rewarding to skip out on the gatling gun.
 
Last edited:
Top Bottom