Release Hitbox viewer + file swapper + more

charaed1

New Member
This mod was made for DOA6 v1.22a#8 (Steam); with size of DOA6.exe being 44,261,008 bytes and its sha256 being 7922bba920bf471730baad946b2641553f6957f510a5eaca39ea6ce9634b1efc . If that matches and your version doesn't include d3d11.dll already then it'll probably work.

Hi, thanks for the very quick response. I do have it working with the 'vanilla' Steam version perfectly fine; I have to say, I'm rather blown away by this mod! The codex patch modifies the executable though, so both the file size and sha256 will be different. Is there a way to get it working for this as well?
 

AlexXsWx

Active Member
Hi, thanks for the very quick response. I do have it working with the 'vanilla' Steam version perfectly fine; I have to say, I'm rather blown away by this mod! The codex patch modifies the executable though, so both the file size and sha256 will be different. Is there a way to get it working for this as well?
In that cases addresses for the mod to patch are probably different. I am not really interested in looking for them. But if you're willing to find them, adapt the code and recompile it, I can give some hints what to look for.
 

WAZAAAAA

Well-Known Member
Hi, thanks for the very quick response. I do have it working with the 'vanilla' Steam version perfectly fine; I have to say, I'm rather blown away by this mod! The codex patch modifies the executable though, so both the file size and sha256 will be different. Is there a way to get it working for this as well?
dude the game's officially FREE and easy to unlock DLC's on, why tf do you need compatibility with a (possibly outdated) shady version?
 

charaed1

New Member
In that cases addresses for the mod to patch are probably different. I am not really interested in looking for them. But if you're willing to find them, adapt the code and recompile it, I can give some hints what to look for.
I guess that's fair enough. I mean, I'd be willing to take a look at it, but I don't think I'd get very far. I've got a tiny bit of experience with coding software up more generally, but I wouldn't know where to begin with something like this.

dude the game's officially FREE and easy to unlock DLC's on, why tf do you need compatibility with a (possibly outdated) shady version?
That's a fair point, but it is completely up to date. I was just trying to get everything together (as well as the add-ons), self-contained and working independently of Steam.

Thanks, both of you, for replying, anyway.
 

AlexXsWx

Active Member
I'd be willing to take a look at it, but I don't think I'd get very far.
In case you will, I think it might work if you just update addresses in source/consts/consts.cpp (and mod version in dllmain.cpp :) ). They are prefixed with comment /* DOA6.exe + */, and followed by bytes of asm code that is expected to be found at that location. You can check that addresses in Cheat Engine in vanilla version to get more bytes around for less results when you search for them in your version.

The only other place that doesn't use consts.cpp is projection matrix, but it seems to be hardcoded as a global variable so I don't think the codex patch affects it.
 

charaed1

New Member
In case you will, I think it might work if you just update addresses in source/consts/consts.cpp (and mod version in dllmain.cpp :) ). They are prefixed with comment /* DOA6.exe + */, and followed by bytes of asm code that is expected to be found at that location. You can check that addresses in Cheat Engine in vanilla version to get more bytes around for less results when you search for them in your version.

The only other place that doesn't use consts.cpp is projection matrix, but it seems to be hardcoded as a global variable so I don't think the codex patch affects it.

OK, thanks for the advice.
 

AlexXsWx

Active Member
Added abilities in new version:
* Save and restore reset positions - so labbing out non-initial positions gets a TON more easier;
* Record, save and restore "hitboxes history" channels to "scroll" through previously occured hitboxes - helpful e.g. to see how close a whiffed strike was to hitting, or to compare hurtboxes between characters by switching channels;
* Display player's exact positions and their back-turned regions;
* Save and restore COM recordings - they're available as text files so you can edit them for frame-perfect inputs and share them;
* Display player's health number;
* Auto-restart COM recording playback on training mode reset;

For the full change log please see the first post.

Added content in new version:
* Decent selection of custom starting positions of various stages (credit goes to revan)
* Bunch of example recordings, showcasing different bugs / hidden moves / not very well-known game mechanics / etc
* Example mod of Helena's moveset bin to replace her 33p with the one she had in DOA5LR (Moruma's idea)

Note: there are some changes to the existing configuration names in the .ini file

New link (v2.04a): https://www.mediafire.com/file/u23d...d_bin_swapper_18may22-v2.04a-9b08d7c.zip/file

Short video showcasing some of the new features: https://gfycat.com/wideeyedunlawfulfairybluebird

Huge thanks to WAZAAAAA for getting the related addresses of code and pointers of data, and the other help!
Also huge thanks to revan for lots of testing, providing feedback and content, and the other help!
And thanks to Matt Ponton for reviewing the documentation!
 
Last edited:

AlexXsWx

Active Member
Ladies and gentlemen, I present you realtime hurtboxes and (what very much looks like) pushboxes!
As well as some other additions and changes - for the full change log please see the first post.

Note: there are LOTS of changes to the .ini file

New link (v2.05a): https://www.mediafire.com/file/kl0q...d_bin_swapper_05jun22-v2.05a-2465b41.zip/file

Short video showcase: https://gfycat.com/defiantalertanura-dead-or-alive-6-dead-or-alive-hitboxes-doa6-doa

Huge thanks to revan for testing, feedback and help with the documentation!
 
Last edited:

AlexXsWx

Active Member
Few more gifs:

Short sample of pushboxes, how they generally look like and how they grow when colliding: https://gfycat.com/magnificentvibrantkudu.gif
Pushboxes during jump, using history feature and featuring alternate visual style: https://gfycat.com/snappyvictoriouskusimanse.gif
Weird pushboxes behavior, seemingly without even collision?.. https://gfycat.com/hopefulhollowarabianwildcat.gif
Code:
# DOA6++v2.04a REC

; Stage: Chamber of Potential
; P1: Rig (player)
; P2: Rig (bot)
;
; Description:
;   Rig goes off-axis while mid air and while pushboxes don't seem to even collide

X 034E9F44000000009747E44385900000761E9544000000001372F543AD0F0100
            16
  u         3
      H     29
            55
  u f       2
  u f   K   7
        K   1
            30
      H K   6
            1
    f       6
    f   K   4
        K   4
            137
 

Whyte69

New Member
Yo, is there a way where i can change damage values of moves for offline play?
So for example i can change Izuna drop to 10 damage or can change it to 300 damage?
Would be amazing, great work you guys!
 

AlexXsWx

Active Member
Yo, is there a way where i can change damage values of moves for offline play?
So for example i can change Izuna drop to 10 damage or can change it to 300 damage?
Would be amazing, great work you guys!
Yes, although it's far from being user friendly. See https://www.freestepdodge.com/threads/doa6-moveset-bin-format-partial-how-to-mod-them.8918/ for more details. Additionally I plan to release another version of this mod with added display of move IDs, which makes the modding process somewhat easier.
 

AlexXsWx

Active Member
Note for Linux / Steam Deck / Proton users - if you have issues launching the game with the mod, try installing d3dcompiler_47 through protontricks.
Thanks to @Isaiahmag for this fix!
 

Deathwalksalone

New Member
Hello,

This is really neat! I was wondering, can I modify ai behavior? I play against the computer on 5 and 6 respectively everyday and I know very much the patterns they possess.
I want to do the following modifications specifically for verses mode level 8 computer;
1. Modify certain move frequencies to practice against more realistic playstyles. Lower S moves to a quarter of current use, specific move usages that are underutilized or not at all with the new movelists, as well as increase frequency against things I find difficult or a necessity to practice against. I was hoping to test a character at a time and figure out what would be viable.
2. Correct combo routes, to make it far more devastating when you fight. There are several inconsistencies that exist with current combo routes already, especially with characters like leifang.
3. If possible, make certain costumes possibly play completely different playstyles. I am very good at identifying prominent playstyles and the many hundreds of doa players i wanted to try to emulate some of the better ones to create some different interesting matchups. This is more of a pipedream but I am curious if it is possible.

I play mostly offline so having a tool to change how the computer would practice would be very valuable, I appreciate any input on if this is possible.

Respectfully,

Deathwalksalone
 

AlexXsWx

Active Member
I was wondering, can I modify ai behavior? I play against the computer on 5 and 6 respectively everyday and I know very much the patterns they possess.
I want to do the following modifications specifically for verses mode level 8 computer;
1. Modify certain move frequencies to practice against more realistic playstyles. Lower S moves to a quarter of current use, specific move usages that are underutilized or not at all with the new movelists, as well as increase frequency against things I find difficult or a necessity to practice against. I was hoping to test a character at a time and figure out what would be viable.
2. Correct combo routes, to make it far more devastating when you fight. There are several inconsistencies that exist with current combo routes already, especially with characters like leifang.
3. If possible, make certain costumes possibly play completely different playstyles. I am very good at identifying prominent playstyles and the many hundreds of doa players i wanted to try to emulate some of the better ones to create some different interesting matchups. This is more of a pipedream but I am curious if it is possible.
1. is doable, although finding the bytes you need to change is quite complicated. It'll be more reasonable once I get myself to publish the next version of the tools, but still not easy.
2. With the next version of the tools it'll be partially doable, the AI combos seem to be split into situational categories (think "neutral game", "juggle", "ground game" etc - but it's very roughly). You could try to shove a full combo-launcher-finisher into "neutral game" category but it'll behave accordingly. But here is another issue - understanding the AI combos format (hex bytes and their meaning) - I only did a brief analysis on it. Also it seems that in DOA6 the ai is worse and is not as configurable as in DOA5 (e.g. I couldn't replicate the 100% defensive/crushing Momiji as I showed in the clip in my doa5 tools thread).
3. Not with the moveset mods

Generally speaking the AI modding hasn't been a focus for this tools so it's not very well reverse engineered, and needs more research - e.g. understanding what the situational categories actually are, meaning of most ai combos hex bytes and more.

If you're up for the task, ready to do some coding and analysing, read documentation and tried to do some modding with it already, PM me and I'll send you the next version for testing.
 

Deathwalksalone

New Member
1. is doable, although finding the bytes you need to change is quite complicated. It'll be more reasonable once I get myself to publish the next version of the tools, but still not easy.
2. With the next version of the tools it'll be partially doable, the AI combos seem to be split into situational categories (think "neutral game", "juggle", "ground game" etc - but it's very roughly). You could try to shove a full combo-launcher-finisher into "neutral game" category but it'll behave accordingly. But here is another issue - understanding the AI combos format (hex bytes and their meaning) - I only did a brief analysis on it. Also it seems that in DOA6 the ai is worse and is not as configurable as in DOA5 (e.g. I couldn't replicate the 100% defensive/crushing Momiji as I showed in the clip in my doa5 tools thread).
3. Not with the moveset mods

Generally speaking the AI modding hasn't been a focus for this tools so it's not very well reverse engineered, and needs more research - e.g. understanding what the situational categories actually are, meaning of most ai combos hex bytes and more.

If you're up for the task, ready to do some coding and analysing, read documentation and tried to do some modding with it already, PM me and I'll send you the next version for testing.
Im willing to read through to understand more of what to do as far as any articles or documentation are concerned.I have never coded at all so is there a place that would give me a basic understanding?
Research isn’t a problem I like that stuff but I wouldn’t want to waste your time or mine if it is ridiculously out of my wheelhouse. I am just a competitor wanting an edge since offline handheld computers are my main source of playing.
 

AlexXsWx

Active Member
I wouldn’t want to waste your time or mine if it is ridiculously out of my wheelhouse.
It all depends on your resolve to achieve this. I'll once again mention that it's not an easy, and modding in general is a very time consuming process, and reverse engineering is even more so. So if time is of concern to you, it's probably not a good idea.
I have never coded at all so is there a place that would give me a basic understanding?
The tools use primarily JavaScript (and TypeScript, but you won't need to write in TypeScript, only read it - and it's very similar to JavaScript in a way), however you won't be using it in its "traditional" way - e.g. you won't need to know HTML/CSS, asynchronous stuff and classes/inheritance; so finding an efficient tutorial is tricky.
I personally like this intro to JavaScript (~4.5 hours) https://cs50.harvard.edu/mobile/2018/weeks/0/ (first two chapters - "Overview, JavaScript" and "JavaScript, ES6") but if you have never coded before it might be going too fast and too technical.
Here's another harvard course you can watch beforehands, about computer science in general: https://cs50.harvard.edu/x/2021/weeks/0/ (first 5-6 chapters/"weeks", the JavaScript part is actually almost completely irrelevant there). It's much longer but hopefully will also help with understanding coding better, as well as understanding binary/hex which will be usefull during reverse engineering/research part.
Or just google some other JavaScript course. Preferably pure JavaScript, without HTML and frameworks.

Here's the kind of code you'll be working with:

JavaScript:
function createVisitor() {
    const arr = [];
    return {
        visited: (obj) => {
            if (arr.includes(obj)) return true;
            arr.push(obj);
            return false;
        },
    };
}

// file: momiji - 01 - mess with AI.js

(function(){

// WIP code messing around with AI, trying to understand it

logged(rebuildBin(reparsedBins.momiji, {

    // // get some free space by removing gaps
    // removeGapsFromTimelines:     true,
    // removeGapsFromInputCommands: true,
    // removeGapsFromAiCombos:      true,

    transformAiBehaviors: (pAiBehaviorsMap) => {
        const unique = pAiBehaviorsMap.filterUnique();
        unique.forEach(behavior => {
            // behavior.someFloats = [ 1.75, 2.25, 6.5, 1.45, 1.25 ];
            // behavior.someFloats = [ 6.4, 6.5, 6.6, 6.5, 6.4 ];
            // behavior.someFloats = [ 0.4, 0.5, 0.6, 0.5, 0.4 ];

            // behavior.someFloats = [ 1.5, 2.2, 6.2, 1.4, 1.2 ];
            behavior.someFloats = [ 0.3, 0.4, 6.2, 0.4, 0.3 ];
            behavior.weights1 = [ 0, 0, 0, 100 ];
            behavior.weights2 = [ 100, 0, 0, 0 ];

            // behavior.someFloats = [ 1.5, 2.2, 6.2, 1.4, 1.2 ];
            // // ai runs in until 1.8m
            // // ai circles around until <= {firstFloat=0.8m}  and then does i2=0 type=09 unknown4=05 unknown2=<whatever>
            // // ai circles around until <= {secondFloat=0.9m} and then does i2=1 type=09 unknown4=05 unknown2=<whatever>
            // // ai circles around until <= {thirdFloat=1.3m}  and then does i2=2 type=09 unknown4=05 unknown2=<whatever>
            // behavior.someFloats = [ 0.8, 0.9, 1.3, 1.1, 1.0 ];
            // behavior.weights1 = [ 25, 25, 25, 25 ];
            // behavior.weights2 = [ 25, 25, 25, 25 ];
        });
        return pAiBehaviorsMap;
    },

    transformAiWeightedCombos: (
        {
            pAiWeightedCombosLists1Map,
            pAiWeightedCombosLists2Map,
        },
        addCombo,
    ) => {
        // debugger;

        // example 1: remove everything except 1st entry
        [
            ...pAiWeightedCombosLists1Map,
            ...pAiWeightedCombosLists2Map,
        ].filterUnique().flatMap(e => e).filterUnique().forEach((e, i, a) => {
            // remove everything except 1st entry
            // e.splice(1, e.length - 1);
            // remove everything
            e.splice(0, e.length);
        });

        // example 2: parse type and modify one of the categories
        const visitor = createVisitor();
        [
            pAiWeightedCombosLists1Map,
            pAiWeightedCombosLists2Map,
        ].forEach((pAiWeightedCombosListsIMap, i0) => {
            pAiWeightedCombosListsIMap.forEach((e, i1) => {
                if (visitor.visited(e)) return;
                e.forEach((e, i2, a) => {
                    if (visitor.visited(e)) return;
                    if (i0 === 0 && [28, 29].includes(i2)) {
                        // type "28and29" - ground attacks
                    } else
                    if (i0 === 0 && [30, 31].includes(i2)) {
                        // type "30and31" - combo throws and holds
                    } else {
                        // type "09"
                        // i2 === 0 = neutral / range < someFloats[0]
                        // i2 === 1 = neutral / range < someFloats[1]
                        // i2 === 2 = neutral / range < someFloats[2]
                        // defense against 2p with 7p: i0=0&i2=15,16,17; i0=1&i2=13
                        // modify the third "category"
                        if (i2 === 2) {
                            // remove everything
                            e.splice(0, e.length);
                            // add new weighted combo
                            e.push({
                                unknown1: 100, // weight
                                unknown2: 3,   // idk // 00, FF, 01, 02 or 03
                                [magicLinks["unknown3->pAiCombosMap->pAiCombos"]]: [
                                    "00 00 00 00", "78 1F 00 00", // start with 24p
                                    "94 00 00 00", addCombo([ // if got 100% meter, go to this combo instead
                                        "02 00 00 00", "79 1F 00 00", // cancel recovery into followup p+k
                                        "28 00 00 00", "00 00 00 00", // done
                                    ]).asAob4Str,
                                    "02 00 00 00", "F9 1F 00 00", // cancel recovery into followup p
                                    "28 00 00 00", "00 00 00 00", // done
                                ],
                                unknown4: "05",
                                // unknown5: bitmaskFromComLevels([ 6, 7, 8 ]),
                                unknown5: bitmaskFromComLevels([ 7 ]),
                            });
                        }
                    }
                });
            });
        });
    },
}));

}());

// file: rig - 01 - mess with AI.js

(function(){

// WIP code messing around with AI, trying to understand it

logged(rebuildBin(reparsedBins.rig, {

    // get some free space by removing gaps
    removeGapsFromTimelines:     true,
    removeGapsFromInputCommands: true,
    removeGapsFromAiCombos:      true,

    transformAiBehaviors: (pAiBehaviorsMap) => {
        return new Array(8).fill({
            someFloats: [ 1.2, 2.25, 6.0, 2.25, 1.2 ],
            weights1: [ 0, 0, 100, 0 ], // [ 25, 25, 25, 25 ],
            weights2: [ 100, 0, 0, 0 ], // [ 25, 25, 25, 25 ],
        });
    },

    transformAiWeightedCombos: (
        {
            pAiWeightedCombosLists1Map,
            pAiWeightedCombosLists2Map,
        },
        addCombo,
    ) => {

        // helper function to create a simple front-facing striking combo
        function createCombo(...moveIdGroups) {
            return addCombo([
                ...moveIdGroups.flatMap(moveIds => [
                    "00 00 00 00", moveIds[0].dehexUint.asAob4Str, // start with given move id
                    ...moveIds.slice(1).flatMap(moveId => [
                        "02 00 00 00", moveId.dehexUint.asAob4Str, // cancel recovery into move id
                    ]),
                ]),
                "28 00 00 00", "00 00 00 00",                      // done
            ]).asAob2Str;
        }

        // helper function to create a simple bt striking combo
        function createBtCombo(...moveIdGroups) {
            return addCombo([
                ...moveIdGroups.flatMap(moveIds => [
                    "01 00 00 00", moveIds[0].dehexUint.asAob4Str, // start from bt with given move id
                    ...moveIds.slice(1).flatMap(moveId => [
                        "02 00 00 00", moveId.dehexUint.asAob4Str, // cancel recovery into move id
                    ]),
                ]),
                "28 00 00 00", "00 00 00 00",                      // done
            ]).asAob2Str;
        }

        return {
            // Fill all 8 slots with same data
            pAiWeightedCombosLists1Map: new Array(8).fill(Object.entries({
                // define data for all 48 sections
                // Note: this example only adds 1 combo per section, but you could add more
                 0: [ `FF 00 00 00 ${  createCombo(["B1 00"])} 00 00 05 FF 00 00` ], // 3p        // + weights1[0] neutral offense / close range
                 1: [ `FF 00 00 00 ${  createCombo(["53 1F"])} 00 00 05 FF 00 00` ], // 4p        // + weights1[0] neutral offense / medium range
                 2: [ `FF 00 00 00 ${  createCombo(["59 1F"])} 00 00 05 FF 00 00` ], // 66p       // neutral offense / long range      weights1[0&1]
                 3: [ `FF 00 00 00 ${  createCombo(["B5 00"])} 00 00 05 FF 00 00` ], // 2k        // high crushes / close range?..     weights1[1] / stun extender (close range)
                 4: [ `FF 00 00 00 ${  createCombo(["58 1F"])} 00 00 05 FF 00 00` ], // 1p        // high crushes / medium range?..    weights1[1] / stun extender (medium range)
                 5: [ `FF 00 00 00 ${  createCombo(["D2 00"])} 00 00 05 FF 00 00` ], // wuk 2k    // high crushes / long range?...     weights1[1]

                 6: [ `FF 00 00 00 ${               "B9 00"  } 00 00 01 FF 00 00` ], // bt k      // + weights1[2] throw-like? offense against standing/block
                //  6: [ `FF 00 00 00 ${  createCombo(["98 00"])} 00 00 05 FF 00 00` ], // 7h        // + weights1[2] throw-like? offense against standing/block
                 7: [ `FF 00 00 00 ${  createCombo(["9C 00"])} 00 00 05 FF 00 00` ], // 1h        // + weights1[2] throw-like? offense against crouching/block

                 8: [ `FF 00 00 00 ${  createCombo(["BF 00"])} 00 00 05 FF 00 00` ], // 8K        // against high holds or throws? (launcher and throws)
                 9: [ `FF 00 00 00 ${  createCombo(["76 1F"])} 00 00 05 FF 00 00` ], // 33K       // against low holds or throws? (launcher and low throws)
                10: [ `FF 00 00 00 ${  createCombo(["9A 00"])} 00 00 05 FF 00 00` ], // 4h        // + weights1[3] OH-like? offense against standing/block
                11: [ `FF 00 00 00 ${  createCombo(["9B 00"])} 00 00 05 FF 00 00` ], // 6h        // + weights1[3] OH-like? offense against crouching/block
                12: [ `FF 00 00 00 ${  createCombo(["82 20"])} 00 00 05 FF 00 00` ], // S         // weights2[0] general purpose defense?.. weights1[0&1] long range offense?.. neutral / against direct high punch/kick?
                13: [ `FF 00 00 00 ${  createCombo(["65 1F"])} 00 00 05 FF 00 00` ], // 6k        // neutral / against direct mid k?
                14: [ `FF 00 00 00 ${  createCombo(["50 1F"])} 00 00 05 FF 00 00` ], // 6p        // neutral / against direct mid p?
                15: [ `FF 00 00 00 ${  createCombo(["8A 1F"])} 00 00 05 FF 00 00` ], // 2h+k      // ??? neutral / against direct low?...
                16: [ `FF 00 00 00 ${  createCombo(["8B 1F"])} 00 00 05 FF 00 00` ], // 1h+k      // ??? neutral / against direct low?...
                17: [ `FF 00 00 00 ${  createCombo(["80 1F"])} 00 00 05 FF 00 00` ], // bnd 8k    // +- weights2[0] defense against low strikes; weights2[1] general purpose defense
                18: [ `FF 00 00 00 ${  createCombo(["B2 00"])} 00 00 05 FF 00 00` ], // 2p        // + defense against standing throw  / weights2[2] defense against all strikes
                19: [ `FF 00 00 00 ${  createCombo(["ED 1F"])} 00 00 05 FF 00 00` ], // 6Ap       // + defense against crouching throw / weights2[2] defense against low strikes
                20: [ `FF 00 00 00 ${  createCombo(["85 1F"])} 00 00 05 FF 00 00` ], // tlc k     // + weights2[0] defense against high OHs (high throws) / weights2[3] defense against all strikes
                21: [ `FF 00 00 00 ${  createCombo(["89 1F"])} 00 00 05 FF 00 00` ], // tlc kk4k  // + weights2[0] defense against low OHs (low throws)   / weights2[3] defense against low strikes
                22: [ `FF 00 00 00 ${  createCombo(["F8 1F"])} 00 00 05 FF 00 00` ], // tlc 6k    // ??? high throws?..
                23: [ `FF 00 00 00 ${  createCombo(["BC 00"])} 00 00 05 FF 00 00` ], // 9p        // juggles / mid range?
                24: [ `FF 00 00 00 ${  createCombo(["A0 1F"])} 00 00 05 FF 00 00` ], // bnd 4h+k  // +- juggle 1
                25: [ `FF 00 00 00 ${  createCombo(["40 20"])} 00 00 05 FF 00 00` ], // bnd 6h+kk // +- juggle 2 (bound / low / far?..)
                26: [], // `FF 00 00 00 ${createBtCombo(["B6 00"])} 00 00 05 FF 00 00` ], // bt p      // +- bt close range?
                27: [], // `FF 00 00 00 ${createBtCombo(["B7 00"])} 00 00 05 FF 00 00` ], // bt 4p     // +- bt medium range?
                28: [                                                             ],              // + 2p/2k-like ground attacks
                29: [                                                             ],              // + 8p+k-like ground attacks (ones available from bt?..)
                30: [                                                             ],              // + combo throws
                31: [                                                             ],              // + combo holds
                32: [ `FF 00 00 00 ${  createCombo(["94 20"])} 00 00 05 FF 00 00` ], // tlc 8p    // + disadvantage/stun against high punches
                33: [ `FF 00 00 00 ${  createCombo(["FF 1F"])} 00 00 05 FF 00 00` ], // tlc h+k   // + disadvantage/stun against high kicks
                34: [ `FF 00 00 00 ${  createCombo(["98 1F"])} 00 00 05 FF 00 00` ], // bnd p+k   // + disadvantage/stun against mid punch
                35: [ `FF 00 00 00 ${  createCombo(["36 20"])} 00 00 05 FF 00 00` ], // bnd 3k    // + disadvantage/stun against mid kick
                36: [ `FF 00 00 00 ${  createCombo(["41 1F"])} 00 00 05 FF 00 00` ], // ppp       // + disadvantage/stun against low punch
                37: [ `FF 00 00 00 ${  createCombo(["7F 1F"])} 00 00 05 FF 00 00` ], // h+k2k     // + disadvantage/stun against low kick
                38: [ `FF 00 00 00 ${  createCombo(["B8 00"])} 00 00 05 FF 00 00` ], // bt 2p     // ??? (low block)
                39: [ `FF 00 00 00 ${  createCombo(["D1 00"])} 00 00 05 FF 00 00` ], // wuk       // ???
                40: [ `FF 00 00 00 ${  createCombo(["D0 00"])} 00 00 05 FF 00 00` ], // high wuk  // + hard punish against mid/high holds/throws
                41: [ `FF 00 00 00 ${  createCombo(["91 20"])} 00 00 05 FF 00 00` ], // h+k6k     // + hard punish against low holds/throws
                42: [ `FF 00 00 00 ${  createCombo(["C1 00"])} 00 00 05 FF 00 00` ], // 7k        // + main ground game
                43: [ `FF 00 00 00 ${  createCombo(["BE 00"])} 00 00 05 FF 00 00` ], // 8p        // ???
                44: [ `FF 00 00 00 ${  createCombo(["B2 1F"])} 00 00 05 FF 00 00` ], // 426t      // empty for all chars
                45: [ `FF 00 00 00 ${  createCombo(["63 20"])} 00 00 05 FF 00 00` ], // 24k       // ground game?..
                46: [ `FF 00 00 00 ${  createCombo(["EC 1F"])} 00 00 05 FF 00 00` ], // Ap        // ???
                47: [ `FF 00 00 00 ${  createCombo(["71 20"])} 00 00 05 FF 00 00` ], // 4S        // ???
            }).sortAscending(e => Number(e[0])).map(e => {
                return e[1].map(e => {
                    const aob = e.dehexUintAob;
                    return {
                        unknown1: aob[0],
                        unknown2: aob[1],
                        unknown3: aob.slice(4, 4 + 2).asAobStr,
                        unknown4: aob[8],
                        unknown5: aob[9],
                    };
                });
            })),
            // Fill all 8 slots with same data
            pAiWeightedCombosLists2Map: new Array(8).fill(Object.entries({
                // ...
            }).sortAscending(e => Number(e[0])).map(e => e[1])),
        };

        // Changes mai quest #132 rig's spam of 4P+K P to 6Ap
        // const replacement = {
        //     unknown1: 0xFF, // weight
        //     unknown2: 0,
        //     [magicLinks["unknown3->pAiCombosMap->pAiCombos"]]: [
        //         "00 00 00 00", "ED 1F 00 00", // start with 6Ap
        //         "28 00 00 00", "00 00 00 00", // done
        //     ],
        //     unknown4: "05",
        //     unknown5: 0x80, // difficulty 1
        // };
        // pAiWeightedCombosLists1Map[7][0][0] = replacement;
        // pAiWeightedCombosLists1Map[7][1][0] = replacement;
        // pAiWeightedCombosLists1Map[7][2][0] = replacement;

    },
}));

}());
 

AlexXsWx

Active Member
Thanks to revan messing around and finding out that the file swapper picks up combo challenge files, it all snowballed into a new release that is now able to mod/swap files like main menu (e.g. adding hidden stages and chars), localization strings and more. However this is a brand new territory so there's a risk of getting yout save data corrupted - please meake sure to back up your save data before attempting the main config swap. There might also be a risk of corrupting someone else's save data, so please don't use this online unless the other person uses the same mod and swaps. We did a quick test and it appears to work online without issues.

Another new thing in the release is command line arguments which you can use to organize your mods better.

I've also added some more code to help with debugging the game (e.g. to extract files that the swapper has access to or to get a nice breakpoint when the game reads a particular file).

New link (v2.07a): https://www.mediafire.com/file/3jv4...d_bin_swapper_26jun23-v2.07a-ca09650.zip/file

See release notes (e.g. in main post) and the updated README for more info.

Also, example swaps now include a swap that adds the Douglas Memorial stage (the one that is exclusive to story mode) and hidden characters (Raidou Boss, Raidou Prototype and "MPP" - some clone of Phase 4, e.g. she has string pppkk from kasumi).
The Douglas Memorial stage reuses some assets from Colloseum in the main menu, so don't let that confuse you.
Also the hidden characters should not be considered proper characters, e.g. you can expect the game to crash when you try to access Boss's command list.

As always, thanks to revan for all the help :)
 
Last edited:

Rev_an

Active Member
editing combo challenge is pretty straightforward, i'd love to see people make and share those but maybe we need a gui or webapp to make that more accessible.
 
ALL DOA6 DOA5 DOA4 DOA3 DOA2U DOAD
Top