Sometimes I feel like the way framedata works is just as abstract and random as this video about plumbuses. Anyways, lets start from the beginning.
Note: This article was sponsored by my Patrons: To help support the creation of more content like this, please consider becoming a Patron here
What is Framedata Anyways?
When people talk about framedata, they are generally talking about a specific set of properties associated with a attack in a fighting game. Knowledge of these properties can be used to understand how fast a move is, what combos after said move, and how safe the attacker is when the move is blocked. This data is essentially what dictates the flow of the game.
Startup – How many frames does the attack take to become active
Active – How many frames does the attack remain active
Recovery – How many frames until the character can move or block after the move is over.
Hitstun – How many frames is the opponent stunned when the attack hits
Blockstun – How many frames is the opponent stunned when the attack is blocked.
To give an example of a situation where framedata is effective, lets say you are playing SF5, and its a mirror match; Ryu vs Ryu, the classic matchup. You opponent keeps doing st.MP followed by st.MP, hadouken on block. You keep feeling like you have to just sit back and watch it happen, as pushing any button just ends up with you being counterhit by the second st.MP.
Ryu’s st.MP is +1 on block. It has a 5 frame startup. This means that you have a 4 frame gap to do a move before the second st.MP hits. Using a list of framedata allows you to come to this conclusion, and then look for 4 frame or less moves to counter your opponents simple blockstring.
Where does Framedata Come from?
Framedata comes from the game. To be more specific, you can derive framedata from the game itself. There are multiple methods of doing this, and ill talk about each of them and the pros and cons below.
First, lets talk about the original method. Recording Video.
Video Method: The Ancient Path
Originally, if you wanted to get framedata, the best method was to record footage of the game, then manually review it and count frames by hand. In most situations, this would involve doing the move in training mode 3 separate times: Once for whiff, once for hit, and once for block. After the move hits or is blocked, up is held on both controllers, and a note is made as to which character is able to jump first, and how many frames they jump before their opponent.
This method was the only method for a long time, but its clear to see why I call it “The Ancient Path”. This method is old. And slow. And it requires a lot of manual labor. This makes it prone to tons of errors. Human error, dropped frames from recording, dropped frames from the game itself, frameskip, etc, can cause data to be incorrect. After a game is patched, the entire process has to be repeated to look for changes if there aren’t good patch notes.
It also makes a lot of assumptions about how the game works. For example, what if a move has different framedata on crouching characters? What if it has non-standard framedata on counter-hit? What if the game features hitstun scaling depending on the length of the combo? What if theres a distance where the move hits later/earlier than normal?
This method is very straight forward, but it requires video recording equipment and tons of time, and is prone to error.
@toolassisted method: The Automated Input Path
So, one of the biggest issues with the above is that it requires you to do things by hand. But what if you could simply automate doing all the moves, and automate the counting of frames as well? Whats what @toolassisted does! Inputs are sent to the game, the result is recorded through hooks, and a database of framedata is created!
One of the nice things about this is that, implemented correctly, the data that is recorded is always correct. Since its being done automatically, theres no room for human error, and any mistakes in the code can be corrected and then have the entire database regenerated with little human interaction.
However, it still manages to bring over all of the other shortcomings of the previous method. You still have to test each move multiple times in realtime to get the data you need, and you still have to make assumptions about what the game engine allows in order to get the data players may want.
For 99% of situations, this method is fine. However, I aimed to do things a different way.
@dantarion method: Simulate the game offline based on the game’s data files
Ill admit, this wasn’t what I aimed to do, but this is what I ended up doing for SF5. I have basically written code that takes the actual files the game uses that contain the moveset information, and simulates what happens on a frame by frame basis. This allows me to process data as fast as my machine allows, much faster than the 16ms/frame speed that the above methods are generally restricted to (I think @toolassisted may use something to speed the game up for his method actually)
This means that I can process all moves for all characters in batch in under 30 minutes for SF5. It also means that I can do processing offline, without the game running, in a script, or even in the browser. This is how boxdox works. Its not using recorded data, its is actively simulating a dumbed down version of the game engine.
The big con of this is that the accuracy depends wildly on how correct my pseudo engine is when compared to the real thing. If I don’t implement physics and movement properly, then all the data becomes slightly off. The pseudo engine was developed by a mix of reverse engineering the data formats, the executable of the game itself, and recording the real engine results and comparing them to the pseudo engines results.
For most attacks, my pseudo engine is 100% accurate. However, projectiles, push-box simulation, hit/block pushback simulation, juggle points, etc, are all unimplemented, so situations that rely on those all fail miserably.
This article is all about SF! What about Blazblue!
Blazblue is pretty much impossible for my pseudo engine method.
Ill explain why and compare the engines of SF vs Blazblue/Xrd in my next blog post.