SEN:P-AI/Game Memory Layout/PES2017

From Rigged Wiki
Revision as of 23:57, 20 February 2018 by Two Scoops (talk | contribs) (→‎Player Stats Entry: Unknown 137)
Jump to navigation Jump to search

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 ?UNKNOWN 10 Strongly correlated with goal scored
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
41 0x05A4 36 Bytes uint32x9 ?UNKNOWN 41
42 0x05C8 36 Bytes uint32x9 ?UNKNOWN 42 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
55 0x079C 36 Bytes uint32x9 ?UNKNOWN 55
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
117 0x0FEB 1 Byte uint8 ?UNKNOWN 117
118 0x0FEC 1 Byte uint8 ?UNKNOWN 118
119 0x0FED 1 Byte uint8 ?UNKNOWN 119
120 0x0FEE 1 Byte uint8 ?UNKNOWN 120
121 0x0FEF 1 Byte uint8 ?UNKNOWN 121
122 0x0FE0 4 Bytes uint32 ?UNKNOWN 122
123 0x0FF4 4 Bytes uint32 Current Playing Position [0-12] with the same values as 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, 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).
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
130 0x126C 4 Bytes uint32? ?UNKNOWN 142 Boolean value: 1 if player injured, 0 otherwise. (verification needed)
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 ?UNKNOWN 145 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 ?UNKNOWN 147 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 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.

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.
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.

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