• Welcome to Smashboards, the world's largest Super Smash Brothers community! Over 250,000 Smash Bros. fans from around the world have come to discuss these great games in over 19 million posts!

    You are currently viewing our boards as a visitor. Click here to sign up right now and start on your path in the Smash community!

Project - Community Hitbox Datamining

Joined
May 3, 2009
Messages
7,190
Hello everyone. So today is an exciting day. Earlier, @Thinkaman posted a thread listing nearly complete hitbox data for the entire cast. Through this I found out that @ Dantarion Dantarion had already dumped the various versions of Smash 4 for 3DS, up to v1.0.4. Thinkaman's pastebin gives us a ton of useful information, such as base damage, knockback values, and the like. However, it doesn't cover all hitboxes of a move, since it only covers the "single biggest hitbox".

So I thought it would be really cool if we all tried our hand at datamining complete information on hitboxes. This was already attempted for Brawl but it was never completed to my knowledge. Even though there are some things missing from the dumps, such as custom moves, and other things are difficult to decipher, such as article-based attacks, I feel it would still be a huge step forward to gather data on everything we can.

That being said, here are resources to get started.

Master Core: SSB4 Data Resource: Contains dumps for all characters' movesets from v1.0.0-v1.0.4.

Villager Hitbox Data: The Google Docs sheet I'm currently working on for Villager's data. So far I think this is a good rubric to use for the sheets, but as time passes we should all definitely work together to improve the overall presentation. This weekend I'll make a single document with multiple sheets to cover all the characters, with editing permissions on each sheet limited to the people who've volunteered to work on whichever character the sheet covers. The notation is simple enough; non-multihit moves with multiple hitboxes have each hitbox listed numerically. Multihit moves have hitboxes listed in a decimal system. For example, Villager's UTilt is a multihit move. Each hitbox of the first hit is listed as 1.n, each hitbox of the second hit is listed as 2.n, etc. For moves whose hitboxes do not end, but change, the "Frame Change" column is filled in. For example, NAir's hitboxes change. They come out F3, and their first iteration lasts 8F. F3 + 8F = F11. F11 is the frame that the hitboxes change. Duration for changing hitboxes is listed with the first iteration's duration first, then the rest, separated by commas. The total duration of the hitboxes is listed after a bar. Other values that change are similarly listed, except without the total value. If a value does not change, it is only entered once. Base angle, BKB, KBG, and WKB have to be converted from hexadecimal to decimal values.

0x50: "Jab1",
0x51: "Jab2",
0x52: "Jab3",
0x56: "Dash Attack",
0x57: "F-tilt (high)",
0x58: "F-tilt (normal)",
0x5b: "F-tilt (low)",
0x5c: "U-tilt",
0x5d: "D-tilt",
0x5e: "F-smash release (high)",
0x5f: "F-smash release (normal)",
0x61: "F-smash release (low)",
0x63: "U-smash release",
0x65: "D-smash release", #wrong?
0x68: "Nair",
0x69: "Fair",
0x6a: "Bair",
0x6b: "Uair",
0x6c: "Dair",
0x6d: "Nair Landing",
0x6e: "Fair Landing",
0x6f: "Bair Landing",
0x70: "Uair Landing",
0x71: "Dair Landing",
0x72: "Grab",
0x73: "Dash Grab",
0x74: "Pivot Grab",
0x76: "Pummel",
0x78: "F-throw",
0x79: "B-throw",
0x7a: "U-throw",
0x7b: "D-throw",
CTRL + F "game_" followed by whatever number comes after the 0x. So if you want to find the data for DTilt, you would CTRL + F "game_5D", without the quotation marks.

Right now I'm working on Villager, then once I'm done I'll get to work on Rosalina and Wii Fit Trainer. Ideally we should have maybe three people tops working on any one character. If you're unsure about something, cross-reference with all of your available resources and knowledge, or just ask someone for help!

Now, on to how to read the dump info

Okay so I'll use two different attacks as examples

For the first example, let's take a look at Villager's Jab 1
Code:
def game_50():
      AsynchronousTimer_0D0(Frame=3.000000, )
      Hitbox_026(Id=0x0, Bone?=0x0, unk?=0x10, Damage=3.000000, Angle=0x3C, BKB=0x50, WKB?=0x0, KBG=0xA, Size=3.000000, X=-1.200000, Y=0.000000, Z=0.000000, 0x0, 0x0, 1.000000, 1.000000, 0x1, 0x1, 0x0, 0x0, 0x1, 0x3, 0x1, 0x4, )
      Hitbox_026(Id=0x1, Bone?=0x0, unk?=0x10, Damage=3.000000, Angle=0x50, BKB=0x50, WKB?=0x0, KBG=0xA, Size=3.600000, X=4.200000, Y=0.000000, Z=0.000000, 0x0, 0x0, 1.000000, 1.000000, 0x1, 0x1, 0x0, 0x0, 0x1, 0x3, 0x1, 0x4, )
      SynchronousTimer_20B(Frame=2.000000, )
      RemoveAllHitboxes_014()
      AsynchronousTimer_0D0(Frame=7.000000, )
      unk_170(0xD, 0x2100, )
      AsynchronousTimer_0D0(Frame=11.000000, )
      unk_170(0xE, 0x2100, )
      End_196()
Most moves begin with an AsynchronousTimer. These are usually used to indicate when something happens. Asynch timers operate on a sort of timeline system. The frame values they are assigned are not "'x' amount of frames", but rather, "frame 'x'". So for jab 1, we see
Code:
AsynchronousTimer_0D0(Frame=3.000000, )
This means that on F3 of the entire move, whatever is below the asynchronous timer begins. In this case, that would be a group of hitboxes.

The dump provides hitbox information such as base damage, knockback values, and other things. To be honest, I'm not entirely sure what their respective names (like here, "Hitbox_26") mean, because multiple hitboxes in an attack can share the same name but have different values. Id is another way for the game to identify hitboxes. I think in Brawl the higher the Id, the farther the hitbox was from the character's TransN bone. Bones are basically, well, bones. They are used to animate the character, and have hitboxes and hurtboxes anchored to them. TransN is sort of the "base" bone the character revolves around. Until the hitbox viewer is completed though, I don't think we should bother too much with these.

According to TSON, unk_ are just flags or whatever that Dantarion's dumper isn't able to identify, so they had their names replaced with unk(nown). According to ANOTHER post, unk_170 and unk_16F are found on aerials (I have only seen them on aerials, now that I think about it), and the first indicates when an aerial no longer autocancels, while the second indicates when it does. Also, I think unk_170 is equivalent to Brawl's RA-bit [16], which was used for multijab flows. So in the code above, I'm thinking that pressing the button or holding the button by/on F7 until F10 allows Jab 1 to flow into Jab 2. Pressing the button on F11 and afterwards might just start another Jab 1.

Base damage is given in decimal values so there's not much to say about that. Angles, BKB, WKB, and KBG on the other hand are given in hexadecimal values. Anything in the form of 0x_ is a hex value. So we have to convert the characters after 0x to decimal. In this case, hitbox1 angle = 0x3C = 60. So that particular hitbox has a base angle of 60 degrees for its trajectory. I say base angle because of course this can be changed by DI and other such factors.

BKB is base knockback. Generally, higher BKB means a move will be launching far, even at low percents. KBG is knockback growth, which is how much or how quickly the move's knockback will scale with damage. So if move A has high BKB but low KBG, and move B has low BKB but high KBG, move B's final knockback will increase more with each percentage point of damage the opponent has accumulated than move A's. So at high enough percents, move B will actually outlaunch move A.

WKB is weight knockback, which is for moves that have weight-based set knockback. All moves have weight-based knockback in that they take the victim's weight into account when calculating final knockback. However, if a move has a WKB value, then it most likely won't have a KBG value, and vice-versa. This is because WBSKB moves ignore the victim's damage when calculating knockback, taking only into effect the move's base damage, BKB, and WKB value. So if move C is a WBSKB move, then it will apply 100 units of KB to a victim with a weight of 100 at 0%, 150%, and 300% (those values are just examples, I don't actually know what WKB, BKB, and weight value would give 100 KB).

Finally we have a SynchronousTimer. These normally tell us after how many frames something happens, as opposed to asynchronous timers, which tell us when in a timeline something happens. Looking at the code, we can see
Code:
SynchronousTimer_20B(Frame=2.000000, )
      RemoveAllHitboxes_014()
This means that after 2F, the hitboxes are removed. In effect this tells us the duration of the previous action. The hitboxes are out for 2F, and after that they are gone. So, if yellow is startup, green is hitbox active, and red is hitbox gone and everything else, it would look like this:

[F1][F2][F3][F4][F5][F6][F7][F8]

The hitboxes came out on F3. The time of generation counts towards duration since the hitboxes are active the same frame they come out. So they are active F3 and F4, then gone by F5.

So

Duration = SynchronousTimerValue
HitboxIn = AsynchronousTimerValue + SynchronousTimerValue

F3 + 2F = F5. The hitboxes are "in" on F5, meaning they are no longer active on F5, meaning the last frame they are active is F4.

Now let's look at Villager's UTilt
Code:
def game_5C():
      AsynchronousTimer_0D0(Frame=7.000000, )
      Hitbox_026(Id=0x0, Bone?=0x0, unk?=0x18, Damage=6.000000, Angle=0x69, BKB=0x64, WKB?=0x3C, KBG=0x0, Size=4.000000, X=0.000000, Y=-1.000000, Z=0.000000, 0x0, 0x0, 1.000000, 1.000000, 0x1, 0x1, 0x0, 0x0, 0x1, 0x1, 0x1, 0x9, )
      Hitbox_026(Id=0x1, Bone?=0x0, unk?=0x18, Damage=6.000000, Angle=0x69, BKB=0x64, WKB?=0x3C, KBG=0x0, Size=6.000000, X=0.000000, Y=5.000000, Z=0.000000, 0x0, 0x0, 1.000000, 1.000000, 0x1, 0x1, 0x0, 0x0, 0x1, 0x1, 0x1, 0x9, )
      Hitbox_026(Id=0x2, Bone?=0x0, unk?=0x18, Damage=6.000000, Angle=0x60, BKB=0x64, WKB?=0xC, KBG=0x0, Size=6.000000, X=0.000000, Y=5.000000, Z=0.000000, 0x0, 0x0, 1.000000, 1.000000, 0x1, 0x1, 0x0, 0x0, 0x1, 0x2, 0x1, 0x9, )
      SynchronousTimer_20B(Frame=14.000000, )
      RemoveAllHitboxes_014()
      AsynchronousTimer_0D0(Frame=24.000000, )
      Hitbox_026(Id=0x0, Bone?=0x0, unk?=0x18, Damage=5.000000, Angle=0x50, BKB=0xA0, WKB?=0x0, KBG=0x32, Size=6.000000, X=0.000000, Y=6.000000, Z=0.000000, 0x0, 0x0, 1.000000, 1.000000, 0x1, 0x1, 0x0, 0x1, 0x1, 0x3, 0x1, 0x9, )
      Hitbox_026(Id=0x1, Bone?=0x0, unk?=0x18, Damage=5.000000, Angle=0x50, BKB=0xA0, WKB?=0x0, KBG=0x32, Size=4.000000, X=0.000000, Y=1.000000, Z=0.000000, 0x0, 0x0, 1.000000, 1.000000, 0x1, 0x1, 0x0, 0x1, 0x1, 0x3, 0x1, 0x9, )
      AsynchronousTimer_0D0(Frame=28.000000, )
      RemoveAllHitboxes_014()
      End_196()
This one is a little different. This attack also begins with an asynchronous timer, so the first hitboxes come out on F7. We can also see that these hitboxes lack KBG values, but have WKB values, meaning that they are weight-based set knockback hitboxes. Then we see a synchronous timer saying that after 14F, the hitboxes are gone, meaning that they last 14F.

After that though, there's another asynchronous timer! This is because not all moves have a single hitgroup. UTilt actually hits twice as it has two hitgroups. A single hitgroup can have multiple hitboxes, but unless they come out on different frames, it is not necessarily a multihit move. Jab 1 had one hitgroup with two hitboxes, but since they both came out on the same frame, only one will hit.

So UTilt has two hitgroups, indicated by one group of hitboxes going away and another being generated before the attack ends. The asynchronous timer still does what we've seen it doing. It is still telling us that on F24 of the attack, the second set of hitboxes come out.

Code:
AsynchronousTimer_0D0(Frame=28.000000, )
      RemoveAllHitboxes_014()
However, instead of a synchronous timer indicating the expiration of the hitboxes, there's another asynchronous timer. Why some moves are coded like this, I don't know. I'm not sure if all multihit attacks are like that, I haven't checked. But anyway, the asynchronous timer still works the same way, its just its function that is different. If that had been a synchronous timer, then the second set of hitboxes would have had a duration of 28F and been gone on F52. But since it is an asynchronous timer, they are gone on F28 of the attack. So, in this case,

Duration = AsynchronousTimer2Value - AsynchronousTimer1Value

[F21][F22][F23][F24][F25][F26][F27][F28][F29][F30]

The hitboxes came out on F24, and since they went away on F28, their last frame was F27.

I think that's about it for now. More experienced people should correct me on where I'm wrong.

Let's get cracking guys!
 
Last edited:

Dantarion

Smash Champion
Joined
May 21, 2007
Messages
2,492
Location
Santa Barbara, CA
No offense but doing stuff by hand at all when the dumps you are basing them on are automated is kinda pointless.
Help me figure out all the commands/params/subactionnames and ill work with you guys to create tables for each move for each character automatically!
 
Joined
May 3, 2009
Messages
7,190
Wait, what other automated programs are there for getting data are there aside from Thinkaman's script? Cause if there are then that would definitely be a lot better.

Also, you mean we need to figure out the offsets for the rest of movesets, right? Like figuring out what part is an airdodge, what part is a Side B, etc?
 
Top Bottom