Difference between revisions of "SEN:P-AI/Game Memory Layout/PES2017"

From Rigged Wiki
Jump to navigation Jump to search
m (→‎Player Stats Entry: Some data for variables 116-122, full description for #118.)
 
(28 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{TOC limit|3}}
==Common Substructures==
===Valid Pair===
Size: 4 bytes
{| class="wikitable"
|-
! Offset || Length || Description ||
|-
| 0x0:0 || 2 bits || Valid Indicator || 0b01, 0x10, or 0xb11 for a valid Home, valid Away, or invalid entry, respectively (combined with the next field, that's 0xFD, 0xFE, or 0xFF for the low byte)
|-
| 0x0:2 || 12 bits || Unknown || It's a fucking mystery, the value is never anything but 0xFFF
|-
| 0x1:6 || 18 bits || Team ID || The ID of the team contained in this entry.<br>When used for a player, the bottom 2 bits get overwritten with 0b11 (making the 2nd byte 0xFF), which causes the value to no longer make any fucking sense. What the fuck Konami?
|}
This structure appears all over PES memory, in both the Player Stats Table and Team Data Table.<br>It is used to indicate whether the next or current entry is valid such as a filled player slot vs an empty player slot (the 4CC only uses 23 players, but there are 32 slots available).
==Player Stats Table==
==Player Stats Table==
The Stats Table is an internal memory structure in PES17 containing all player stats that can be seen in the post-match screens but also a considerable number of "hidden stats" not displayed anywhere in the game.<br>
The Stats Table is an internal memory structure in PES17 containing all player stats that can be seen in the post-match screens but also a considerable number of "hidden stats" not displayed anywhere in the game.<br>
Line 23: Line 40:
|  0|| 0x0000 ||  4 Bytes || uint32  || Player ID        || Fixed value, checking it is a good way to see if the table has been overwritten with garbage
|  0|| 0x0000 ||  4 Bytes || uint32  || Player ID        || Fixed value, checking it is a good way to see if the table has been overwritten with garbage
|-
|-
|  1|| 0x0004 || 36 Bytes || uint32x9|| Goals Scored || Couting also goals in penalty shootout   
|  1|| 0x0004 || 36 Bytes || uint32x9|| Goals Scored ||
|-                                       
|-                                       
|  2|| 0x0028 || 36 Bytes || uint32x9|| Own Goals Scored
|  2|| 0x0028 || 36 Bytes || uint32x9|| Own Goals Scored
|rowspan="4"| These next hundred or so "uint32x9" stats follow the same format:
|rowspan="4"| These next hundred or so '''"uint32x9" stats''' follow the same format:


The 36 bytes are broken into 9 "segments" of 32-bit integers. Each match corresponds to a 15 minutes of a match, segments 1-3 are the first half and segments 4-6 are the second half. Injury time is counted as part of the last segment of the half.
The 36 bytes are broken into 9 "segments" of 32-bit integers. Each segment corresponds to 15 minutes of a match. Segments 1-3 are the 1st half, segments 4-6 are the 2nd half, segments 7 and 8 are the 1st and 2nd halves of Extra Time, and segment 9 is the Penalty Shootout. Injury time is counted as part of the last segment of the half.
 
Extra time is either segments 7-9 with 10 minute segments but accounting for all 9 segments OR segments 7-8 keeping with the 15 minute length but leaving the segment 9 unused {{tt|(penalties?)| I probably should have figured this out by now but my run-random-matches of testing hasn't been good at producing ties.}}.


Stats are recorded separately for each segment, which means to get the actual value of the stat, you need to calculate the total of all 9 segments.
Stats are recorded separately for each segment, which means to get the actual value of the stat, you need to calculate the total of all 9 segments.
Line 40: Line 55:
|  5|| 0x0094 || 36 Bytes || uint32x9|| Assists           
|  5|| 0x0094 || 36 Bytes || uint32x9|| Assists           
|-                                       
|-                                       
|  6|| 0x00B8 || 36 Bytes || uint32x9|| Shots || Couting also shots (penalties) in penalty shootout           
|  6|| 0x00B8 || 36 Bytes || uint32x9|| Shots ||        
|-                                       
|-                                       
|  7|| 0x00DC || 36 Bytes || uint32x9|| ?UNKNOWN 7 || Pretty sure about these three <br> Headers     
|  7|| 0x00DC || 36 Bytes || uint32x9|| Headers ||  
|-                                       
|-                                       
|  8|| 0x0100 || 36 Bytes || uint32x9|| ?UNKNOWN 8 || Shots with favourite foot     
|  8|| 0x0100 || 36 Bytes || uint32x9|| Shots (Strong Foot) ||    
|-                                       
|-                                       
|  9|| 0x0124 || 36 Bytes || uint32x9|| ?UNKNOWN 9 || Shots with weak foot     
|  9|| 0x0124 || 36 Bytes || uint32x9|| Shots (Weak Foot) ||  
|-                                       
|-                                       
| 10|| 0x0148 || 36 Bytes || uint32x9|| ?UNKNOWN 10 || Strongly correlated with goal scored
| 10|| 0x0148 || 36 Bytes || uint32x9|| Goals Scored (Extended) || '''Needs a double check'''. This value counts all the goals scored by a player plus those shots who hit a post and then an opponent player resulting in an own goal.
|-                                       
|-                                       
| 11|| 0x016C || 36 Bytes || uint32x9|| Shots on Target  || Couting also shots (penalties) on target in penalty shootout           
| 11|| 0x016C || 36 Bytes || uint32x9|| Shots on Target  ||        
|-                                       
|-                                       
| 12|| 0x0190 || 36 Bytes || uint32x9|| ?UNKNOWN 12     ||
| 12|| 0x0190 || 36 Bytes || uint32x9|| Free kicks shot     || Shots from free kicks in regular and extra time (default key: X. No matter from which half of the field is kicked, it is still considered a shot. Goal kicks are excluded since the game treats them as passes).
|-                                       
|-                                       
| 13|| 0x01B4 || 36 Bytes || uint32x9|| ?UNKNOWN 13      ||
| 13|| 0x01B4 || 36 Bytes || uint32x9|| Penalty kicks shot || Shots from {{tt|(mid-match) penalties|not benuldies}}.
|-                                       
|-                                       
| 14|| 0x01D8 || 36 Bytes || uint32x9|| Passes          || A_Passes + B_Passes + C_Passes + Crosses = (total) Passes <br> X_Passes + Y_Passes + Crosses == (total) Passes
| 14|| 0x01D8 || 36 Bytes || uint32x9|| Passes          || Low Passes + Through Balls + Lofted/High Passes + Crosses = (total) Passes <br> Ground Passes + Aerial Passes + Crosses == (total) Passes
|-                                       
|-                                       
| 15|| 0x01FC || 36 Bytes || uint32x9|| Passes Made      ||
| 15|| 0x01FC || 36 Bytes || uint32x9|| Passes Made      ||
|-                                       
|-                                       
| 16|| 0x0220 || 36 Bytes || uint32x9|| A_Passes       || Low passes (default key: A)
| 16|| 0x0220 || 36 Bytes || uint32x9|| Low Passes       || Low passes (default key: A)
|-                                       
|-                                       
| 17|| 0x0244 || 36 Bytes || uint32x9|| A_Passes Made  ||  
| 17|| 0x0244 || 36 Bytes || uint32x9|| Low Passes Made  ||  
|-                                       
|-                                       
| 18|| 0x0268 || 36 Bytes || uint32x9|| B_Passes       || Low Through Ball (default key: Y) + Chipped Through Ball (default key: LB + Y)
| 18|| 0x0268 || 36 Bytes || uint32x9|| Through Balls       || Low Through Ball (default key: Y) + Chipped Through Ball (default key: LB + Y)
|-                                       
|-                                       
| 19|| 0x028C || 36 Bytes || uint32x9|| B_Passes Made  ||  
| 19|| 0x028C || 36 Bytes || uint32x9|| Through Balls Made  ||  
|-                                       
|-                                       
| 20|| 0x02B0 || 36 Bytes || uint32x9|| C_Passes        || Lofted Pass (default key: B) + High Pass (default key: RT + B)
| 20|| 0x02B0 || 36 Bytes || uint32x9|| Lofted/High Passes || Lofted Pass (default key: B) + High Pass (default key: RT + B)
|-                                       
|-                                       
| 21|| 0x02D4 || 36 Bytes || uint32x9|| C_Passes Made  ||
| 21|| 0x02D4 || 36 Bytes || uint32x9|| Lofted/High Passes Made  ||
|-                                       
|-                                       
| 22|| 0x02F8 || 36 Bytes || uint32x9|| Crosses        ||
| 22|| 0x02F8 || 36 Bytes || uint32x9|| Crosses        ||
Line 76: Line 91:
| 23|| 0x031C || 36 Bytes || uint32x9|| Crosses Made    || Crosses where the sticker get the ball (the same way the game determinates when a pass in made or not).
| 23|| 0x031C || 36 Bytes || uint32x9|| Crosses Made    || Crosses where the sticker get the ball (the same way the game determinates when a pass in made or not).
|-                                       
|-                                       
| 24|| 0x0340 || 36 Bytes || uint32x9|| X_Passes        || A_Passes + Low Through Ball (low passes)
| 24|| 0x0340 || 36 Bytes || uint32x9|| Ground Passes || Low Passes + Low Through Ball (low passes)
|-                                       
|-                                       
| 25|| 0x0364 || 36 Bytes || uint32x9|| X_Passes Made  ||
| 25|| 0x0364 || 36 Bytes || uint32x9|| Ground Passes Made  ||
|-                                       
|-                                       
| 26|| 0x0388 || 36 Bytes || uint32x9|| Y_Passes       || C_Passes + BY_Passes (lofted passes)
| 26|| 0x0388 || 36 Bytes || uint32x9|| Aerial Passes       || Lofted/High Passes + Chipped Through Balls (lofted passes)
|-                                       
|-                                       
| 27|| 0x03AC || 36 Bytes || uint32x9|| Y_Passes Made  ||
| 27|| 0x03AC || 36 Bytes || uint32x9|| Aerial Passes Made  ||
|-                                       
|-                                       
| 28|| 0x03D0 || 36 Bytes || uint32x9|| BX_Passes       || Low Through Ball (default key: Y)
| 28|| 0x03D0 || 36 Bytes || uint32x9|| Low Through Balls       || Low Through Ball (default key: Y)
|-                                       
|-                                       
| 29|| 0x03F4 || 36 Bytes || uint32x9|| BX_Passes Made  ||
| 29|| 0x03F4 || 36 Bytes || uint32x9|| Low Through Balls Made  ||
|-                                       
|-                                       
| 30|| 0x0418 || 36 Bytes || uint32x9|| BY_Passes       || Chipped Through Ball (default key: LB + Y)
| 30|| 0x0418 || 36 Bytes || uint32x9|| Chipped Through Balls       || Chipped Through Ball (default key: LB + Y)
|-                                       
|-                                       
| 31|| 0x043C || 36 Bytes || uint32x9|| BY_Passes Made  ||
| 31|| 0x043C || 36 Bytes || uint32x9|| Chipped Through Balls Made  ||
|-                                       
|-                                       
| 32|| 0x0460 || 36 Bytes || uint32x9|| I_Passes        || (The part where I gave up trying to find correlations but still saw similar patterns to the above) <br> Not sure about these three, but maybe: forward passes
| 32|| 0x0460 || 36 Bytes || uint32x9|| ?Forward Passes || (The part where I gave up trying to find correlations but still saw similar patterns to the above) <br> Not sure about these three, but maybe: forward passes
|-                                       
|-                                       
| 33|| 0x0484 || 36 Bytes || uint32x9|| I_Passes Made   ||  
| 33|| 0x0484 || 36 Bytes || uint32x9|| ?Forward Passes Made ||  
|-                                       
|-                                       
| 34|| 0x04A8 || 36 Bytes || uint32x9|| J_Passes        || Passes between two players on (almost) the same line
| 34|| 0x04A8 || 36 Bytes || uint32x9|| ?Lateral Passes || Passes between two players on (almost) the same line
|-                                       
|-                                       
| 35|| 0x04CC || 36 Bytes || uint32x9|| J_Passes Made  ||
| 35|| 0x04CC || 36 Bytes || uint32x9|| ?Lateral Passes Made  ||
|-                                       
|-                                       
| 36|| 0x04F0 || 36 Bytes || uint32x9|| K_Passes        || Backward passes
| 36|| 0x04F0 || 36 Bytes || uint32x9|| ?Backward Passes || Backward passes
|-                                       
|-                                       
| 37|| 0x0514 || 36 Bytes || uint32x9|| K_Passes Made   ||
| 37|| 0x0514 || 36 Bytes || uint32x9|| ?Backward Passes Made ||
|-                                       
|-                                       
| 38|| 0x0538 || 36 Bytes || uint32x9|| Tackles          ||
| 38|| 0x0538 || 36 Bytes || uint32x9|| Tackles          ||
Line 108: Line 123:
| 39|| 0x055C || 36 Bytes || uint32x9|| Tackles Won      ||
| 39|| 0x055C || 36 Bytes || uint32x9|| Tackles Won      ||
|-                                       
|-                                       
| 40|| 0x0580 || 36 Bytes || uint32x9|| ?UNKNOWN 40      ||
| 40|| 0x0580 || 36 Bytes || uint32x9|| ?UNKNOWN 40      || Tackles Won without sliding???
|-                                       
|-                                       
| 41|| 0x05A4 || 36 Bytes || uint32x9|| ?UNKNOWN 41      ||
| 41|| 0x05A4 || 36 Bytes || uint32x9|| ?UNKNOWN 41      || Pretty rare, maybe is a tackle won while the opponent is trying to pass or shoot.
|-                                       
|-                                       
| 42|| 0x05C8 || 36 Bytes || uint32x9|| ?UNKNOWN 42      ||
| 42|| 0x05C8 || 36 Bytes || uint32x9|| ?UNKNOWN 42      || Tackles where the player hit only the opponent and not the ball??? (Correlated with Tackles and/or Tackles Won).
|-                                       
|-                                       
| 43|| 0x05EC || 36 Bytes || uint32x9|| Clearances      ||
| 43|| 0x05EC || 36 Bytes || uint32x9|| Clearances      ||
Line 137: Line 152:
| 53|| 0x0754 || 36 Bytes || uint32x9|| ?UNKNOWN 53      ||
| 53|| 0x0754 || 36 Bytes || uint32x9|| ?UNKNOWN 53      ||
|-                                       
|-                                       
| 54|| 0x0778 || 36 Bytes || uint32x9|| ?UNKNOWN 54      ||
| 54|| 0x0778 || 36 Bytes || uint32x9|| ?UNKNOWN 54      || '''Needs a double check'''. Passes and shots after two or more touches plus all the time a player lose possession, excluding interceptions (so it counts the tackles lost and when the player walks with the ball outside the pitch).
|-                                       
|-                                       
| 55|| 0x079C || 36 Bytes || uint32x9|| ?UNKNOWN 55      ||
| 55|| 0x079C || 36 Bytes || uint32x9|| ?UNKNOWN 55      || '''Needs a double check'''. Passes and shots after two or more touches.
|-                                       
|-                                       
| 56|| 0x07C0 || 36 Bytes || uint32x9|| Touches
| 56|| 0x07C0 || 36 Bytes || uint32x9|| Touches
Line 250: Line 265:
|109|| 0x0F34 || 36 Bytes || uint32x9|| ?UNKNOWN 109    ||
|109|| 0x0F34 || 36 Bytes || uint32x9|| ?UNKNOWN 109    ||
|-                                       
|-                                       
|110|| 0x0F58 || 36 Bytes || uint32x9|| Shots Faced      || Couting also shots (penalties) in penalty shootout
|110|| 0x0F58 || 36 Bytes || uint32x9|| Shots Faced      ||
|-                                       
|-                                       
|111|| 0x0F7C || 36 Bytes || uint32x9|| Shots Faced On Target || Couting also shots (penalties) on target in penalty shootout   
|111|| 0x0F7C || 36 Bytes || uint32x9|| Shots Faced On Target ||
|-                                       
|-                                       
|112|| 0x0FA0 || 36 Bytes || uint32x9|| Saves            || Couting also penalties saved in penalty shootout           
|112|| 0x0FA0 || 36 Bytes || uint32x9|| Saves            ||  
|-                                       
|-                                       
|113|| 0x0FC4 || 36 Bytes || uint32x9|| ?Saves On Target || (appears to be correlated to Saves in the same way other "(on target)" stats are, but I'm not entirely sure what it means, maybe that the shot saved was on target?) <br> Only shots in the area are count for this stat, even if they are not on target. Shots saved from outside the box do not add value to this stat. It looks like the word "target" means "area" here. <br> Saves in penalty shootout are not counted (see '''Saves''').
|113|| 0x0FC4 || 36 Bytes || uint32x9|| ?Saves On Target || (appears to be correlated to Saves in the same way other "(on target)" stats are, but I'm not entirely sure what it means, maybe that the shot saved was on target?) <br> Only shots in the area are count for this stat, even if they are not on target. Shots saved from outside the box do not add value to this stat. It looks like the word "target" means "area" here. <br> Saves in penalty shootout are not counted.
|-                                       
|-                                       
|114|| 0x0FE8 ||  1 Byte  || sint8  || First Minute on Pitch || when the player was first subbed on, 0 for starting players, -1 for benched players until they're subbed on
|114|| 0x0FE8 ||  1 Byte  || sint8  || First Minute on Pitch || when the player was first subbed on, 0 for starting players, -1 for benched players until they're subbed on
|-                                       
|-                                       
|115|| 0x0FE9 ||  1 Byte  || sint8  || Last Minute on Pitch || when the player was last on the pitch, -1 for benched players, for currently playing players this USUALLY matches the game clock but for recently subbed players, PES rounds it up to the next minute just to fuck with you.
|115|| 0x0FE9 ||  1 Byte  || sint8  || Last Minute on Pitch || when the player was last on the pitch, -1 for benched players, for currently playing players this USUALLY matches the game clock but for recently subbed players, PES rounds it up to the next minute just to fuck with you. Players in undergoing treatment are counted on the pitch.
|-                                       
|-                                       
|116|| 0x0FEA ||  1 Byte  || uint8  || ?UNKNOWN 116    ||
|116|| 0x0FEA ||  1 Byte  || uint8  || ?UNKNOWN 116    || Always 0.
|-                                       
|-                                       
|117|| 0x0FEB ||  1 Byte  || uint8  || ?UNKNOWN 117    ||
|117|| 0x0FEB ||  1 Byte  || uint8  || ?UNKNOWN 117    || Always 0.
|-                                       
|-                                       
|118|| 0x0FEC ||  1 Byte  || uint8  || ?UNKNOWN 118    ||
|118|| 0x0FEC ||  1 Byte  || uint8  || Substitution value || This variable has 5 or 6 possible values in the range [0,5] according the following situations:
* 0: Player is in the starting 11 or get subbed on during the first half (before the half time menu).
* 1: Player is subbed on during the second half (before the extra time menu).
* 2: Player is subbed on during the first extra time half (before the half time menu).
* 3: Player is subbed on during the second extra time.
* 4: Never seen this value, it might be a substitution between the end of the second extra time and benuldies (this is possible when you plan a substitution after the 105th minute but from that moment to the end of the half there's no pauses to do that).
* 5: Player did not play.
|-                                       
|-                                       
|119|| 0x0FED ||  1 Byte  || uint8  || ?UNKNOWN 119    ||
|119|| 0x0FED ||  1 Byte  || uint8  || ?UNKNOWN 119    || Always 0.
|-                                       
|-                                       
|120|| 0x0FEE ||  1 Byte  || uint8  || ?UNKNOWN 120    ||
|120|| 0x0FEE ||  1 Byte  || uint8  || ?UNKNOWN 120    || Always 0.
|-                                       
|-                                       
|121|| 0x0FEF ||  1 Byte  || uint8  || ?UNKNOWN 121    ||
|121|| 0x0FEF ||  1 Byte  || uint8  || ?UNKNOWN 121    || Always 0.
|-                                       
|-                                       
|122|| 0x0FE0 ||  4 Bytes || uint32  || ?UNKNOWN 122    ||
|122|| 0x0FE0 ||  4 Bytes || uint32  || ?UNKNOWN 122    || Always 0 except some super rare cases where it becomes 1 or 2 for GK only.
|-                                       
|-                                       
|123|| 0x0FF4 ||  4 Bytes || uint32  || Current Playing Position || [0-12] with the same values as the [[Pro_Evolution_Soccer_2017/Edit_file#Player_entry |Edit File]]
|123|| 0x0FF4 ||  4 Bytes || uint32  || Current Playing Position || [0-12] with the same values as the registered position in the [[Pro_Evolution_Soccer_2017/Edit_file#Player_entry |Edit File]]
|-                                       
|-                                       
|124|| 0x0FF8 || 52 Bytes || uint32  || Game Ticks Played || An array of 13 32-bit integers, each one corresponding to a playing position. Each element contains the number of "ticks" the player has spent playing in that position. The total sum of the array is the number of ticks the player, which is exact and the same for all unsubbed starting players. 1 real-time seconds is about 48 ticks, with what seems like no relation to framerate. 1 Game Minute is exactly 32*{Match Length Setting} ticks (320 for 10 minute matches).
|124|| 0x0FF8 || 52 Bytes || uint32  || Game Ticks Played || An array of 13 32-bit integers, each one corresponding to a playing position. Each element contains the number of "ticks" the player has spent playing in that position. The total sum of the array is the number of ticks the player has been on the pitch, which is exact and the same for all unsubbed starting players. 1 real-time second is about 48 ticks, with what seems like no relation to framerate. 1 Game Minute is exactly 32*{Match Length Setting} ticks (320 for 10 minute matches).
|-                                       
|-                                       
|125|| 0x102C ||  4 Bytes || uint32  || ?UNKNOWN 137    || (around 16840000 for Captians, 16770000 for other players, increases by some low number every so often)
|125|| 0x102C ||  4 Bytes || uint32  || ?UNKNOWN 137    || After further inspection this might actually be 4 single byte values. The 32-bit value is around 0x01010100 for captians and around 0x01000000 for other players and only the low byte changes every so often.<!-- I would have liked to expand this to 4 different stats but my dumb ass accidentally hard-coded the stat count into SEN:P-AI in a few places so I can't update it without breaking compatibility. Probably something I'll fix in the PES18 update -->
|-                                       
|-                                       
|126|| 0x1030 ||  4 Bytes || float32 || Player Rating    || A 32-bit floating point number. Matches the rating exactly, in increments of 0.5, no more exact. This leaves no (known) way to determine Man Of The Match if there's a tie for highest rating.
|126|| 0x1030 ||  4 Bytes || float32 || Player Rating    || A 32-bit floating point number. Matches the rating exactly, in increments of 0.5, no more exact. This leaves no (known) way to determine Man Of The Match if there's a tie for highest rating.
Line 288: Line 309:
|128|| 0x1264 ||  4 Bytes || uint32  || Realtime (sec) on Pitch || Roughly the number of real-time seconds a player has been playing. For some reason this drifts by multiple seconds for players who should have been playing the exact same amount of time.
|128|| 0x1264 ||  4 Bytes || uint32  || Realtime (sec) on Pitch || Roughly the number of real-time seconds a player has been playing. For some reason this drifts by multiple seconds for players who should have been playing the exact same amount of time.
|-                                       
|-                                       
|129|| 0x1268 ||  4 Bytes || uint32?|| ?UNKNOWN 141    || (very high value)
|129|| 0x1268 ||  4 Bytes || float32 || ?UNKNOWN 141    || Somehow correlated with stamina: almost constantly decreasing and it grows during the half time. It is lower for keepers (between 5 and 8), higher for all the other players (between 10 and 19). The update rate is around 6/7 times per second. After 0:01 seconds this value is over 900 for GK, over 200 for all other players, except the one who made the kick off with 10.
|-                                       
|-                                       
|130|| 0x126C ||  4 Bytes || uint32? || ?UNKNOWN 142    || (0)
|130|| 0x126C ||  4 Bytes || uint32? || ?UNKNOWN 142    || Boolean value: 1 if player injured, 0 otherwise.
|-                                       
|-                                       
|131|| 0x1270 ||  4 Bytes || uint32? || ?UNKNOWN 143    || (very high value, 0 for most/some players)
|131|| 0x1270 ||  4 Bytes || float32 || ?UNKNOWN 143    || (0 for most players, nonzero for only a few players)
|-                                       
|-                                       
|132|| 0x1274 ||  4 Bytes || uint32  || Stamina          || Starts at 100 and periodically decreases throughout the match. During halftime/fulltime/extra-halftime, players will recover stamina in the UI but this value is not updated to match until the next half actually starts.
|132|| 0x1274 ||  4 Bytes || uint32  || Stamina          || Starts at 100 and periodically decreases throughout the match. During halftime/fulltime/extra-halftime, players will recover stamina in the UI but this value is not updated to match until the next half actually starts.
|-                                       
|-                                       
|133|| 0x1278 ||  4 Bytes || uint32? || ?UNKNOWN 145     || (very high value)
|133|| 0x1278 ||  4 Bytes || float32 || Total Distance Covered     || Total distance covered (in meters) by a player during the match. (Formetly UNKNOWN 145). <br>
'''Old description''': Zero until the match starts. It constantly grows and it's related with player's movements across the pitch.
Apparently stamina, time on the pitch and many other stats do not affect this value. (may be related to calculating {{tt|Average Speed|listed on the Individual Match Records screen but not yet found within this table}})
|-                                       
|-                                       
|134|| 0x127C ||  4 Bytes || uint32? || ?UNKNOWN 146    || (very high value, 0 for a few players)
|134|| 0x127C ||  4 Bytes || float32 || Distance Dribbled || 32-bit floating point value tracking the distance dribbled in meters. Truncated to an integer on the match records screen. <br>Zero until the player makes a pass (no matter if completed or not), it grows every time the player passes the ball. Sometimes this rule is not followed and the value stays zero. (perhaps the game chooses to disregard individual distances if they're less than 1m)
|-                                       
|-                                       
|135|| 0x1280 ||  4 Bytes || uint32? || ?UNKNOWN 147     || (very high value)
|135|| 0x1280 ||  4 Bytes || float32 || Total Pass Distance     || This variable sums the length (in meters) of every pass made by a player even if intercepted. <br>
'''Old description''': Zero until the player completes a pass, it grows after every completed pass. (This may be related to overall possession)
|-                                       
|-                                       
|136|| 0x1284 ||  1 Byte  || uint8  || ?UNKNOWN 148 FLAG || (Have no idea what these are for, but only the low bit is ever active, leading me to believe they're all Boolean flags)
|136|| 0x1284 ||  1 Byte  || uint8  || ?UNKNOWN 148 FLAG || (Have no idea what these are for, but only the low bit is ever active, leading me to believe they're all Boolean flags)
Line 376: Line 400:
|172|| 0x12A8 ||  4 Bytes || uint32  || ?UNKNOWN 184      ||
|172|| 0x12A8 ||  4 Bytes || uint32  || ?UNKNOWN 184      ||
|-                                       
|-                                       
|173|| 0x12AC ||  4 Bytes ||validPair|| ?Next Player Valid || This structure is a set of two 16-bit values which I call a "team/player valid pair." The first value is 0xFFFD for a valid Home player, 0xFFFE for a valid Away player, or 0xFFFF for an invalid player.<br>
|173|| 0x12AC ||  4 Bytes || validPair || ?Next Player Valid || There's a validPair both before the first player entry and after the last one so I could have said this was at the beginning as "This Player Valid". I'm not sure why there's one on both ends of the table but I suspect the final one may be used as a [[wikipedia:Sentinel_value |sentinel]].
For an invalid player, the second value is 0, but for a valid player it's some arbitrary value that depends on the team but doesn't seem to have any obvious correlation to IDs or anything like that.<br>
There's one before the first entry in the table, but also one after the last entry of the table so I included it at the end of the entry instead of the beginning. This structure also appears in other parts of memory such as the Team Data Table.  
|}
|}
'''Unknown stats''' which have unidentified or uncertian purposes/meaning have "?" in front of the name. If you figure out what one of these is please feel free to edit this page. Unknown stats can be displayed in SEN:P-AI by checking the "show hidden stats" box in the columns menu and then checking the corresponding box next to the stat.
'''Unknown stats''' which have unidentified or uncertian purposes/meaning have "?" in front of the name. If you figure out what one of these is please feel free to edit this page. Unknown stats can be displayed in SEN:P-AI by checking the "show hidden stats" box in the columns menu and then checking the corresponding box next to the stat.
==Team Data Table==
The team data table is an internal data structure in PES that holds all kinds of data, including tactical, about the two currently selected teams.<br>
It is allocated (perhaps statically?) by PES as soon as the game launches (but is unpopulated and thus unable to be found until two teams are selected) and only deallocated when the game closes, staying in the same place for the entire duration of a particular PES17.exe instance.<br>
The most common location for the stats table is as specified:
* In a block of memory 0x60000 Bytes (96 4KiB Pages) in size, Committed, marked Private, with ReadWrite protection
* Beginning at offset 0x538B4 from the start of the block
It is unknown whether this pattern is static or just extremely common, since the allocation only ever happens once per PES17.exe instance (and at the very start of the program where memory allocations would follow a very consistent pattern).
===Overall Structure===
The substructures mentioned in the following table are described further below.<br>
Size: 18736 (0x4930) bytes
{| class="wikitable"
|-
! Offset || Length || Type || Description 
|-
| 0x0000 || 1312 bytes || Team Data || Home team data
|-
| 0x0520 || 1312 bytes || Team Data || Away team data
|-
| 0x0A40 || 632 bytes || Team Tactics || Home Team Tactics
|-
| 0x0CB8 || 632 bytes || Team Tactics || Away Team Tactics
|-
| 0x0F30 || 7424 bytes || (32x) Player Data || Home Team Players
|-
| 0x2C30 || 7424 bytes || (32x) Player Data || Away Team Players
|}
'''Note:''' The values for Unknowns in the following tables were determined with only limited testing. Further testing could potentially yield better results.
===Team Data===
Size: 1312 (0x520) bytes
{| class="wikitable"
|-
! Offset || Length || Type || Description ||
|-
| 0x000 ||  4 bytes || validPair || Team Valid ||
|-
| 0x004 || 70 bytes || cstring || Team Name || As written in EDIT0
|-
| 0x04A ||  4 bytes || cstring || Scoreboard Name || As written in EDIT0
|-
| 0x04E ||  2 bytes ||    ?    || Unknown A || 0xFFFF
|-
| 0x050 || 97 bytes ||    ?    || Unknown B || 0x00 x97
|-
| 0x0B1 || 16 bytes || cstring || Banner 1 Text || As written in EDIT0
|-
| 0x0C1 || 16 bytes || cstring || Banner 2 Text || As written in EDIT0
|-
| 0x0D1 || 16 bytes || cstring || Banner 3 Text || As written in EDIT0
|-
| 0x0E1 || 16 bytes || cstring || Banner 4 Text || As written in EDIT0
|-
| 0x0F1 ||  4 bytes || int8 x4 || Banner Edited Flags || See [[Pro_Evolution_Soccer_2017/Edit_file#Team_entry |Banner Edited Flags]]
|-
| 0x0F5 ||  3 bytes ||    ?    || Unknown C || Possibly padding
|-
! 0x0F8 ||colspan="2"| 256 bytes total || Player List || 32 entries
|-
| 0x0 || 4 bytes || validPair || Player Valid ||
|-
| 0x4 || 4 bytes || uint32 || Player ID ||
|-
!colspan="5"|
|-
| 0x1F8 ||  4 bytes || validPair? || Team Valid? || high bytes set to 0x0000
|-
| 0x1FC ||  4 bytes || uint32 || Team ID ||
|-
| 0x200 || 32 bytes || int8 x32 || Shirt Numbers ||
|-
| 0x220 ||colspan="2"| 16 bytes x15 (240 total) || Unknown D || 0xFFFF,0000,0000,0000,0000,0000,0000,0000 x15
|-
| 0x310 || 528 bytes ||colspan="3"| Got no fuckin clue
|}
===Team Tactics===
Size: 632 (0x278) bytes
{| class="wikitable"
|-
! Offset || Length || Type || Description ||
|-
| 0x00 || 32 bytes || ? || Unknown A || 0x00 x32
|-
| 0x20 ||  4 bytes || ? || Unknown B || 0x32 x4
|-
| 0x24 ||  8 bytes || ? || Unknown C || 0x02,02,00,02,00,02,00,00
|-
| 0x2C ||  4 bytes || validPair? || Team Valid? || high bytes set to 0x0000
|-
| 0x30 ||  4 bytes || uint32 || Manager ID || (I'm not actually sure since its the same as the Team ID)
|-
| 0x34 || 46 bytes || cstring || Manager Name || As written in EDIT0
|-
| 0x62 ||  6 bytes || ? || Unknown D || 0xD7,00,28,14,FF,FF
|-
| 0x68 || 528 bytes ||colspan="3"| Bytes [0x004, 0x213] of the team's [[Pro_Evolution_Soccer_2017/Edit_file#Team_Game_Plan |Game Plan]] from EDIT0
|}
'''Note:''' This structure contains the '''''currently set tactics''''' for the match.<br>
Changes made using the game plan menu are not written back to here until exiting the game plan menu.<br>
Changes made by {{tt|writing directly to memory|tested with Cheat Engine, not SEN:P-AI}} are NOT reflected by the UI. The game (reasonably) assumes that only the menu UI can be used to change anything and thus overwrites this memory with the UI's state whenever exiting said menu.
======Why do you know this?======
I wanted to see if timeout changes could be written directly to memory without pausing the game (and thus almost completely eliminating the stupid amounts of stream time spent on timeouts). Unfortunately the fact that doing so doesn't change the UI prevents the streamer from manually making changes themselves and prevents them and everyone else from seeing the actual state of the game plans (Rigcity, here we come). "The state of the UI" likely has multiple layers of indirection that would be impractical to reverse engineer, so I had to give up on the idea entirely.<br>It was the only use case for writing to game memory that would have convinced me that it would be worth it to switch SEN:P-AI from ReadOnly to ReadWrite mode, so it will stay ReadOnly until everyone can come up with and agree on a better idea.
===Player Data===
Size: 232 bytes
{| class="wikitable"
|-
! Offset || Length || Type || Description ||
|-
| 0x00 ||  1 byte  || uint8 || Height || (cm)
|-
| 0x01 ||  1 byte  || uint8 || Weight || (kg)
|-
| 0x02 || 28 bytes || ? || Unknown A || Bytes from the [[Pro_Evolution_Soccer_2017/Edit_file#Player_entry |Player Entry]] in EDIT0, potentially modified or partially out of order
|-
| 0x1E:0 || 5 bits || ? || Unknown B ||
|-
| 0x1E:5 || 3 bits || uint3 || Player Condition || 0 = Worst, 4 = Best, 5-7 appear to default back to neutral in the UI
|-
| 0x1F || 13 bytes || ? || Unknown C ||
|-
| 0x2C ||  4 bytes || validPair || Player Valid ||
|-
| 0x30 ||  4 bytes || uint32 || Player ID ||
|-
| 0x34 ||  4 bytes || uint32 || Player Commentary ID || (probably)
|-
| 0x38 || 46 bytes || cstring || Player Name || As written in EDIT0
|-
| 0x66 || 18 bytes || cstring || Shirt/Print Name || As written in EDIT0
|-
| 0x78 ||colspan="2"| 4 bytes x26 (104 total) || Unknown D || either 0x00000000, {{tt|0xFFFF0000|I don't know if I remembered endianess when I wrote this down}}, or 0xFFFFFFFF
|-
| 0xE0 || 4 bytes || int32? || Unknown E || 0x00000001
|-
| 0xE4 || 4 bytes || int32? || Unknown F || 0x00000015
|}
'''Note:''' Even though writing directly to the game plan wont change the UI, writing directly to player '''''conditions''''' DOES change the UI. This is because Conditions aren't controlled by the game plan menu, so the game has to check them and update the UI every time the menu opens. This suggests that the entire TDT is actually what the game reads from to make AI decisions rather than just being an extra copy, but I haven't done any more testing to confirm because I'm not interested in rigging the game.

Latest revision as of 08:55, 20 May 2020

Common Substructures

Valid Pair

Size: 4 bytes

Offset Length Description
0x0:0 2 bits Valid Indicator 0b01, 0x10, or 0xb11 for a valid Home, valid Away, or invalid entry, respectively (combined with the next field, that's 0xFD, 0xFE, or 0xFF for the low byte)
0x0:2 12 bits Unknown It's a fucking mystery, the value is never anything but 0xFFF
0x1:6 18 bits Team ID The ID of the team contained in this entry.
When used for a player, the bottom 2 bits get overwritten with 0b11 (making the 2nd byte 0xFF), which causes the value to no longer make any fucking sense. What the fuck Konami?

This structure appears all over PES memory, in both the Player Stats Table and Team Data Table.
It is used to indicate whether the next or current entry is valid such as a filled player slot vs an empty player slot (the 4CC only uses 23 players, but there are 32 slots available).

Player Stats Table

The Stats Table is an internal memory structure in PES17 containing all player stats that can be seen in the post-match screens but also a considerable number of "hidden stats" not displayed anywhere in the game.
It is dynamically allocated in memory by PES at the very beginning of the match, just before the first touch (not during the anthem cutscenes), updated in real-time for the duration of the match, and de-allocated from memory upon exiting the post-match results screen.
The most common location for the stats table is as specified:

  • In a block of memory 0x90000 Bytes (144 4KiB Pages) in size, Committed, marked Private, with ReadWrite protection
  • The Home team's stats table begins at offset 0x35010 from the start of the block
  • The Away team's stats table begins 0x28E30 bytes after the home offset, or 0x5DE40 from the start of the block

This memory block location was originally thought to be hardcoded, but it was later discovered that it was only the result of a memory allocation pattern that rendered this particular method of finding the tables 95-80% accurate, with the accuracy decreasing the longer the game was running. This search pattern is still used by default, but a brute force search can also be used.
There is additional data before and possibly after both of tables that is part of the same fixed-layout data structure but has yet to be deciphered.

Player Stats Entry

Entry Count: 32 per team, in the same order as the Team-Player Table (Edit File)
Entry Length: 4784 (0x12B0) Bytes

ID Offset Length Type Description Behavior
0 0x0000 4 Bytes uint32 Player ID Fixed value, checking it is a good way to see if the table has been overwritten with garbage
1 0x0004 36 Bytes uint32x9 Goals Scored
2 0x0028 36 Bytes uint32x9 Own Goals Scored These next hundred or so "uint32x9" stats follow the same format:

The 36 bytes are broken into 9 "segments" of 32-bit integers. Each segment corresponds to 15 minutes of a match. Segments 1-3 are the 1st half, segments 4-6 are the 2nd half, segments 7 and 8 are the 1st and 2nd halves of Extra Time, and segment 9 is the Penalty Shootout. Injury time is counted as part of the last segment of the half.

Stats are recorded separately for each segment, which means to get the actual value of the stat, you need to calculate the total of all 9 segments.

3 0x004C 36 Bytes uint32x9 Free kicks scored
4 0x0070 36 Bytes uint32x9 Penalties scored
5 0x0094 36 Bytes uint32x9 Assists
6 0x00B8 36 Bytes uint32x9 Shots
7 0x00DC 36 Bytes uint32x9 Headers
8 0x0100 36 Bytes uint32x9 Shots (Strong Foot)
9 0x0124 36 Bytes uint32x9 Shots (Weak Foot)
10 0x0148 36 Bytes uint32x9 Goals Scored (Extended) Needs a double check. This value counts all the goals scored by a player plus those shots who hit a post and then an opponent player resulting in an own goal.
11 0x016C 36 Bytes uint32x9 Shots on Target
12 0x0190 36 Bytes uint32x9 Free kicks shot Shots from free kicks in regular and extra time (default key: X. No matter from which half of the field is kicked, it is still considered a shot. Goal kicks are excluded since the game treats them as passes).
13 0x01B4 36 Bytes uint32x9 Penalty kicks shot Shots from (mid-match) penalties.
14 0x01D8 36 Bytes uint32x9 Passes Low Passes + Through Balls + Lofted/High Passes + Crosses = (total) Passes
Ground Passes + Aerial Passes + Crosses == (total) Passes
15 0x01FC 36 Bytes uint32x9 Passes Made
16 0x0220 36 Bytes uint32x9 Low Passes Low passes (default key: A)
17 0x0244 36 Bytes uint32x9 Low Passes Made
18 0x0268 36 Bytes uint32x9 Through Balls Low Through Ball (default key: Y) + Chipped Through Ball (default key: LB + Y)
19 0x028C 36 Bytes uint32x9 Through Balls Made
20 0x02B0 36 Bytes uint32x9 Lofted/High Passes Lofted Pass (default key: B) + High Pass (default key: RT + B)
21 0x02D4 36 Bytes uint32x9 Lofted/High Passes Made
22 0x02F8 36 Bytes uint32x9 Crosses
23 0x031C 36 Bytes uint32x9 Crosses Made Crosses where the sticker get the ball (the same way the game determinates when a pass in made or not).
24 0x0340 36 Bytes uint32x9 Ground Passes Low Passes + Low Through Ball (low passes)
25 0x0364 36 Bytes uint32x9 Ground Passes Made
26 0x0388 36 Bytes uint32x9 Aerial Passes Lofted/High Passes + Chipped Through Balls (lofted passes)
27 0x03AC 36 Bytes uint32x9 Aerial Passes Made
28 0x03D0 36 Bytes uint32x9 Low Through Balls Low Through Ball (default key: Y)
29 0x03F4 36 Bytes uint32x9 Low Through Balls Made
30 0x0418 36 Bytes uint32x9 Chipped Through Balls Chipped Through Ball (default key: LB + Y)
31 0x043C 36 Bytes uint32x9 Chipped Through Balls Made
32 0x0460 36 Bytes uint32x9 ?Forward Passes (The part where I gave up trying to find correlations but still saw similar patterns to the above)
Not sure about these three, but maybe: forward passes
33 0x0484 36 Bytes uint32x9 ?Forward Passes Made
34 0x04A8 36 Bytes uint32x9 ?Lateral Passes Passes between two players on (almost) the same line
35 0x04CC 36 Bytes uint32x9 ?Lateral Passes Made
36 0x04F0 36 Bytes uint32x9 ?Backward Passes Backward passes
37 0x0514 36 Bytes uint32x9 ?Backward Passes Made
38 0x0538 36 Bytes uint32x9 Tackles
39 0x055C 36 Bytes uint32x9 Tackles Won
40 0x0580 36 Bytes uint32x9 ?UNKNOWN 40 Tackles Won without sliding???
41 0x05A4 36 Bytes uint32x9 ?UNKNOWN 41 Pretty rare, maybe is a tackle won while the opponent is trying to pass or shoot.
42 0x05C8 36 Bytes uint32x9 ?UNKNOWN 42 Tackles where the player hit only the opponent and not the ball??? (Correlated with Tackles and/or Tackles Won).
43 0x05EC 36 Bytes uint32x9 Clearances
44 0x0610 36 Bytes uint32x9 Fouls
45 0x0634 36 Bytes uint32x9 Fouls Offside
46 0x0658 36 Bytes uint32x9 Yellow Cards For some reason, the exact moment these stats are updated depends on the particular card cutscene used
47 0x067C 36 Bytes uint32x9 Red Cards
48 0x06A0 36 Bytes uint32x9 ?UNKNOWN 48
49 0x06C4 36 Bytes uint32x9 ?UNKNOWN 49
50 0x06E8 36 Bytes uint32x9 Free Kicks
51 0x070C 36 Bytes uint32x9 ?UNKNOWN 51
52 0x0730 36 Bytes uint32x9 Corner Kicks
53 0x0754 36 Bytes uint32x9 ?UNKNOWN 53
54 0x0778 36 Bytes uint32x9 ?UNKNOWN 54 Needs a double check. Passes and shots after two or more touches plus all the time a player lose possession, excluding interceptions (so it counts the tackles lost and when the player walks with the ball outside the pitch).
55 0x079C 36 Bytes uint32x9 ?UNKNOWN 55 Needs a double check. Passes and shots after two or more touches.
56 0x07C0 36 Bytes uint32x9 Touches (These appeared to have some correlation to the total touches)
It looks like that type of Touches is not related to the kind of Passes and it may depends also on how the player stops the ball. Also A_Touches (and maybe B_Touches and C_Touches as well) can be greater than Touches.
57 0x07E4 36 Bytes uint32x9 ?A_Touches
58 0x0808 36 Bytes uint32x9 ?B_Touches
59 0x082C 36 Bytes uint32x9 ?C_Touches
60 0x0850 36 Bytes uint32x9 ?UNKNOWN 60
61 0x0874 36 Bytes uint32x9 ?UNKNOWN 61
62 0x0898 36 Bytes uint32x9 ?UNKNOWN 62
63 0x08BC 36 Bytes uint32x9 Interceptions
64 0x08E0 36 Bytes uint32x9 ?A_Interceptions (These appeared to have some correlation to the total interceptions)
65 0x0904 36 Bytes uint32x9 ?B_Interceptions
66 0x0928 36 Bytes uint32x9 ?C_Interceptions
67 0x094C 36 Bytes uint32x9 ?D_Interceptions
68 0x0970 36 Bytes uint32x9 ?UNKNOWN 68
69 0x0994 36 Bytes uint32x9 ?UNKNOWN 69
70 0x09B8 36 Bytes uint32x9 ?UNKNOWN 70
71 0x09DC 36 Bytes uint32x9 ?UNKNOWN 71
72 0x0A00 36 Bytes uint32x9 ?UNKNOWN 72
73 0x0A24 36 Bytes uint32x9 ?UNKNOWN 73
74 0x0A48 36 Bytes uint32x9 ?UNKNOWN 74
75 0x0A6C 36 Bytes uint32x9 ?UNKNOWN 75
76 0x0A90 36 Bytes uint32x9 ?UNKNOWN 76
77 0x0AB4 36 Bytes uint32x9 ?UNKNOWN 77
78 0x0AD8 36 Bytes uint32x9 ?UNKNOWN 78
79 0x0AFC 36 Bytes uint32x9 ?UNKNOWN 79
80 0x0B20 36 Bytes uint32x9 ?UNKNOWN 80
81 0x0B44 36 Bytes uint32x9 ?UNKNOWN 81
82 0x0B68 36 Bytes uint32x9 ?UNKNOWN 82
83 0x0B8C 36 Bytes uint32x9 ?UNKNOWN 83
84 0x0BB0 36 Bytes uint32x9 ?UNKNOWN 84
85 0x0BD4 36 Bytes uint32x9 ?UNKNOWN 85
86 0x0BF8 36 Bytes uint32x9 ?UNKNOWN 86
87 0x0C1C 36 Bytes uint32x9 ?UNKNOWN 87
88 0x0C40 36 Bytes uint32x9 ?UNKNOWN 88
89 0x0C64 36 Bytes uint32x9 ?UNKNOWN 89
90 0x0C88 36 Bytes uint32x9 ?UNKNOWN 90
91 0x0CAC 36 Bytes uint32x9 ?UNKNOWN 91
92 0x0CD0 36 Bytes uint32x9 ?UNKNOWN 92
93 0x0CF4 36 Bytes uint32x9 ?UNKNOWN 93
94 0x0D18 36 Bytes uint32x9 ?UNKNOWN 94
95 0x0D3C 36 Bytes uint32x9 ?UNKNOWN 95
96 0x0D60 36 Bytes uint32x9 ?UNKNOWN 96
97 0x0D84 36 Bytes uint32x9 ?UNKNOWN 97
98 0x0DA8 36 Bytes uint32x9 ?UNKNOWN 98
99 0x0DCC 36 Bytes uint32x9 ?UNKNOWN 99
100 0x0DF0 36 Bytes uint32x9 ?UNKNOWN 100
101 0x0E14 36 Bytes uint32x9 ?UNKNOWN 101
102 0x0E38 36 Bytes uint32x9 ?UNKNOWN 102
103 0x0E5C 36 Bytes uint32x9 ?UNKNOWN 103
104 0x0E80 36 Bytes uint32x9 ?UNKNOWN 104
105 0x0EA4 36 Bytes uint32x9 ?UNKNOWN 105
106 0x0EC8 36 Bytes uint32x9 ?UNKNOWN 106
107 0x0EEC 36 Bytes uint32x9 ?UNKNOWN 107
108 0x0F10 36 Bytes uint32x9 ?UNKNOWN 108
109 0x0F34 36 Bytes uint32x9 ?UNKNOWN 109
110 0x0F58 36 Bytes uint32x9 Shots Faced
111 0x0F7C 36 Bytes uint32x9 Shots Faced On Target
112 0x0FA0 36 Bytes uint32x9 Saves
113 0x0FC4 36 Bytes uint32x9 ?Saves On Target (appears to be correlated to Saves in the same way other "(on target)" stats are, but I'm not entirely sure what it means, maybe that the shot saved was on target?)
Only shots in the area are count for this stat, even if they are not on target. Shots saved from outside the box do not add value to this stat. It looks like the word "target" means "area" here.
Saves in penalty shootout are not counted.
114 0x0FE8 1 Byte sint8 First Minute on Pitch when the player was first subbed on, 0 for starting players, -1 for benched players until they're subbed on
115 0x0FE9 1 Byte sint8 Last Minute on Pitch when the player was last on the pitch, -1 for benched players, for currently playing players this USUALLY matches the game clock but for recently subbed players, PES rounds it up to the next minute just to fuck with you. Players in undergoing treatment are counted on the pitch.
116 0x0FEA 1 Byte uint8 ?UNKNOWN 116 Always 0.
117 0x0FEB 1 Byte uint8 ?UNKNOWN 117 Always 0.
118 0x0FEC 1 Byte uint8 Substitution value This variable has 5 or 6 possible values in the range [0,5] according the following situations:
  • 0: Player is in the starting 11 or get subbed on during the first half (before the half time menu).
  • 1: Player is subbed on during the second half (before the extra time menu).
  • 2: Player is subbed on during the first extra time half (before the half time menu).
  • 3: Player is subbed on during the second extra time.
  • 4: Never seen this value, it might be a substitution between the end of the second extra time and benuldies (this is possible when you plan a substitution after the 105th minute but from that moment to the end of the half there's no pauses to do that).
  • 5: Player did not play.
119 0x0FED 1 Byte uint8 ?UNKNOWN 119 Always 0.
120 0x0FEE 1 Byte uint8 ?UNKNOWN 120 Always 0.
121 0x0FEF 1 Byte uint8 ?UNKNOWN 121 Always 0.
122 0x0FE0 4 Bytes uint32 ?UNKNOWN 122 Always 0 except some super rare cases where it becomes 1 or 2 for GK only.
123 0x0FF4 4 Bytes uint32 Current Playing Position [0-12] with the same values as the registered position in the Edit File
124 0x0FF8 52 Bytes uint32 Game Ticks Played An array of 13 32-bit integers, each one corresponding to a playing position. Each element contains the number of "ticks" the player has spent playing in that position. The total sum of the array is the number of ticks the player has been on the pitch, which is exact and the same for all unsubbed starting players. 1 real-time second is about 48 ticks, with what seems like no relation to framerate. 1 Game Minute is exactly 32*{Match Length Setting} ticks (320 for 10 minute matches).
125 0x102C 4 Bytes uint32 ?UNKNOWN 137 After further inspection this might actually be 4 single byte values. The 32-bit value is around 0x01010100 for captians and around 0x01000000 for other players and only the low byte changes every so often.
126 0x1030 4 Bytes float32 Player Rating A 32-bit floating point number. Matches the rating exactly, in increments of 0.5, no more exact. This leaves no (known) way to determine Man Of The Match if there's a tie for highest rating.
127 0x1034 560 Bytes uint32 Play Area Grid This is an array of 140 32-bit integers representing a 10x14 grid of squares. About every real-time second, PES checks where each player is in this grid and increments the corresponding value. This is used to generate the pitch heat-map seen on the individual match records screen, however the highest intensity color it will show there corresponds to 12 seconds while most players will have one or more squares in the ballpark of 90 for a typical match.
128 0x1264 4 Bytes uint32 Realtime (sec) on Pitch Roughly the number of real-time seconds a player has been playing. For some reason this drifts by multiple seconds for players who should have been playing the exact same amount of time.
129 0x1268 4 Bytes float32 ?UNKNOWN 141 Somehow correlated with stamina: almost constantly decreasing and it grows during the half time. It is lower for keepers (between 5 and 8), higher for all the other players (between 10 and 19). The update rate is around 6/7 times per second. After 0:01 seconds this value is over 900 for GK, over 200 for all other players, except the one who made the kick off with 10.
130 0x126C 4 Bytes uint32? ?UNKNOWN 142 Boolean value: 1 if player injured, 0 otherwise.
131 0x1270 4 Bytes float32 ?UNKNOWN 143 (0 for most players, nonzero for only a few players)
132 0x1274 4 Bytes uint32 Stamina Starts at 100 and periodically decreases throughout the match. During halftime/fulltime/extra-halftime, players will recover stamina in the UI but this value is not updated to match until the next half actually starts.
133 0x1278 4 Bytes float32 Total Distance Covered Total distance covered (in meters) by a player during the match. (Formetly UNKNOWN 145).

Old description: Zero until the match starts. It constantly grows and it's related with player's movements across the pitch. Apparently stamina, time on the pitch and many other stats do not affect this value. (may be related to calculating Average Speed)

134 0x127C 4 Bytes float32 Distance Dribbled 32-bit floating point value tracking the distance dribbled in meters. Truncated to an integer on the match records screen.
Zero until the player makes a pass (no matter if completed or not), it grows every time the player passes the ball. Sometimes this rule is not followed and the value stays zero. (perhaps the game chooses to disregard individual distances if they're less than 1m)
135 0x1280 4 Bytes float32 Total Pass Distance This variable sums the length (in meters) of every pass made by a player even if intercepted.

Old description: Zero until the player completes a pass, it grows after every completed pass. (This may be related to overall possession)

136 0x1284 1 Byte uint8 ?UNKNOWN 148 FLAG (Have no idea what these are for, but only the low bit is ever active, leading me to believe they're all Boolean flags)
137 0x1285 1 Byte uint8 ?UNKNOWN 149 FLAG
138 0x1286 1 Byte uint8 ?UNKNOWN 150 FLAG
139 0x1287 1 Byte uint8 ?UNKNOWN 151 FLAG
140 0x1288 1 Byte uint8 ?UNKNOWN 152 FLAG
141 0x1289 1 Byte uint8 ?UNKNOWN 153 FLAG
142 0x128A 1 Byte uint8 ?UNKNOWN 154 FLAG
143 0x128B 1 Byte uint8 ?UNKNOWN 155 FLAG
144 0x128C 1 Byte uint8 ?UNKNOWN 156 FLAG
145 0x128D 1 Byte uint8 ?UNKNOWN 157 FLAG
146 0x128E 1 Byte uint8 ?UNKNOWN 158 FLAG
147 0x128F 1 Byte uint8 ?UNKNOWN 159 FLAG
148 0x1290 1 Byte uint8 ?UNKNOWN 160 FLAG
149 0x1291 1 Byte uint8 ?UNKNOWN 161 FLAG
150 0x1292 1 Byte uint8 ?UNKNOWN 162 FLAG
151 0x1293 1 Byte uint8 ?UNKNOWN 163 FLAG
152 0x1294 1 Byte uint8 ?UNKNOWN 164 FLAG
153 0x1295 1 Byte uint8 ?UNKNOWN 165 FLAG
154 0x1296 1 Byte uint8 ?UNKNOWN 166 FLAG
155 0x1297 1 Byte uint8 ?UNKNOWN 167 FLAG
156 0x1298 1 Byte uint8 ?UNKNOWN 168 FLAG
157 0x1299 1 Byte uint8 ?UNKNOWN 169 FLAG
158 0x129A 1 Byte uint8 ?UNKNOWN 170 FLAG
159 0x129B 1 Byte uint8 ?UNKNOWN 171 FLAG
160 0x129C 1 Byte uint8 ?UNKNOWN 172 FLAG
161 0x129D 1 Byte uint8 ?UNKNOWN 173 FLAG
162 0x129E 1 Byte uint8 ?UNKNOWN 174 FLAG
163 0x129F 1 Byte uint8 ?UNKNOWN 175 FLAG
164 0x12A0 1 Byte uint8 ?UNKNOWN 176 FLAG
165 0x12A1 1 Byte uint8 ?UNKNOWN 177 FLAG
166 0x12A2 1 Byte uint8 ?UNKNOWN 178 FLAG
167 0x12A3 1 Byte uint8 ?UNKNOWN 179 FLAG
168 0x12A4 1 Byte uint8 ?UNKNOWN 180 FLAG
169 0x12A5 1 Byte uint8 ?UNKNOWN 181 FLAG
170 0x12A6 1 Byte uint8 ?UNKNOWN 182 FLAG
171 0x12A7 1 Byte uint8 ?UNKNOWN 183 FLAG
172 0x12A8 4 Bytes uint32 ?UNKNOWN 184
173 0x12AC 4 Bytes validPair ?Next Player Valid There's a validPair both before the first player entry and after the last one so I could have said this was at the beginning as "This Player Valid". I'm not sure why there's one on both ends of the table but I suspect the final one may be used as a sentinel.

Unknown stats which have unidentified or uncertian purposes/meaning have "?" in front of the name. If you figure out what one of these is please feel free to edit this page. Unknown stats can be displayed in SEN:P-AI by checking the "show hidden stats" box in the columns menu and then checking the corresponding box next to the stat.

Team Data Table

The team data table is an internal data structure in PES that holds all kinds of data, including tactical, about the two currently selected teams.
It is allocated (perhaps statically?) by PES as soon as the game launches (but is unpopulated and thus unable to be found until two teams are selected) and only deallocated when the game closes, staying in the same place for the entire duration of a particular PES17.exe instance.
The most common location for the stats table is as specified:

  • In a block of memory 0x60000 Bytes (96 4KiB Pages) in size, Committed, marked Private, with ReadWrite protection
  • Beginning at offset 0x538B4 from the start of the block

It is unknown whether this pattern is static or just extremely common, since the allocation only ever happens once per PES17.exe instance (and at the very start of the program where memory allocations would follow a very consistent pattern).

Overall Structure

The substructures mentioned in the following table are described further below.
Size: 18736 (0x4930) bytes

Offset Length Type Description
0x0000 1312 bytes Team Data Home team data
0x0520 1312 bytes Team Data Away team data
0x0A40 632 bytes Team Tactics Home Team Tactics
0x0CB8 632 bytes Team Tactics Away Team Tactics
0x0F30 7424 bytes (32x) Player Data Home Team Players
0x2C30 7424 bytes (32x) Player Data Away Team Players

Note: The values for Unknowns in the following tables were determined with only limited testing. Further testing could potentially yield better results.

Team Data

Size: 1312 (0x520) bytes

Offset Length Type Description
0x000 4 bytes validPair Team Valid
0x004 70 bytes cstring Team Name As written in EDIT0
0x04A 4 bytes cstring Scoreboard Name As written in EDIT0
0x04E 2 bytes ? Unknown A 0xFFFF
0x050 97 bytes ? Unknown B 0x00 x97
0x0B1 16 bytes cstring Banner 1 Text As written in EDIT0
0x0C1 16 bytes cstring Banner 2 Text As written in EDIT0
0x0D1 16 bytes cstring Banner 3 Text As written in EDIT0
0x0E1 16 bytes cstring Banner 4 Text As written in EDIT0
0x0F1 4 bytes int8 x4 Banner Edited Flags See Banner Edited Flags
0x0F5 3 bytes ? Unknown C Possibly padding
0x0F8 256 bytes total Player List 32 entries
0x0 4 bytes validPair Player Valid
0x4 4 bytes uint32 Player ID
0x1F8 4 bytes validPair? Team Valid? high bytes set to 0x0000
0x1FC 4 bytes uint32 Team ID
0x200 32 bytes int8 x32 Shirt Numbers
0x220 16 bytes x15 (240 total) Unknown D 0xFFFF,0000,0000,0000,0000,0000,0000,0000 x15
0x310 528 bytes Got no fuckin clue

Team Tactics

Size: 632 (0x278) bytes

Offset Length Type Description
0x00 32 bytes ? Unknown A 0x00 x32
0x20 4 bytes ? Unknown B 0x32 x4
0x24 8 bytes ? Unknown C 0x02,02,00,02,00,02,00,00
0x2C 4 bytes validPair? Team Valid? high bytes set to 0x0000
0x30 4 bytes uint32 Manager ID (I'm not actually sure since its the same as the Team ID)
0x34 46 bytes cstring Manager Name As written in EDIT0
0x62 6 bytes ? Unknown D 0xD7,00,28,14,FF,FF
0x68 528 bytes Bytes [0x004, 0x213] of the team's Game Plan from EDIT0

Note: This structure contains the currently set tactics for the match.
Changes made using the game plan menu are not written back to here until exiting the game plan menu.
Changes made by writing directly to memory are NOT reflected by the UI. The game (reasonably) assumes that only the menu UI can be used to change anything and thus overwrites this memory with the UI's state whenever exiting said menu.

Why do you know this?

I wanted to see if timeout changes could be written directly to memory without pausing the game (and thus almost completely eliminating the stupid amounts of stream time spent on timeouts). Unfortunately the fact that doing so doesn't change the UI prevents the streamer from manually making changes themselves and prevents them and everyone else from seeing the actual state of the game plans (Rigcity, here we come). "The state of the UI" likely has multiple layers of indirection that would be impractical to reverse engineer, so I had to give up on the idea entirely.
It was the only use case for writing to game memory that would have convinced me that it would be worth it to switch SEN:P-AI from ReadOnly to ReadWrite mode, so it will stay ReadOnly until everyone can come up with and agree on a better idea.

Player Data

Size: 232 bytes

Offset Length Type Description
0x00 1 byte uint8 Height (cm)
0x01 1 byte uint8 Weight (kg)
0x02 28 bytes ? Unknown A Bytes from the Player Entry in EDIT0, potentially modified or partially out of order
0x1E:0 5 bits ? Unknown B
0x1E:5 3 bits uint3 Player Condition 0 = Worst, 4 = Best, 5-7 appear to default back to neutral in the UI
0x1F 13 bytes ? Unknown C
0x2C 4 bytes validPair Player Valid
0x30 4 bytes uint32 Player ID
0x34 4 bytes uint32 Player Commentary ID (probably)
0x38 46 bytes cstring Player Name As written in EDIT0
0x66 18 bytes cstring Shirt/Print Name As written in EDIT0
0x78 4 bytes x26 (104 total) Unknown D either 0x00000000, 0xFFFF0000, or 0xFFFFFFFF
0xE0 4 bytes int32? Unknown E 0x00000001
0xE4 4 bytes int32? Unknown F 0x00000015

Note: Even though writing directly to the game plan wont change the UI, writing directly to player conditions DOES change the UI. This is because Conditions aren't controlled by the game plan menu, so the game has to check them and update the UI every time the menu opens. This suggests that the entire TDT is actually what the game reads from to make AI decisions rather than just being an extra copy, but I haven't done any more testing to confirm because I'm not interested in rigging the game.