|
hi TL nerds,
a lot of people have been asking over the years if we could figure out a way to get Spending Quotient and other interesting stats about our matches. there is an interesting file that i believe contains all the stats that are shown in the Summary Screen after a game completes.
it's the s2gs file. You can trigger arbitrary *.s2gs files to be downloaded to your machine by viewing game summaries in the SC2 client. In SC2, go to your Match History, then click on one of the magnifying glasses. That will trigger a new s2gs file to be downloaded to your machine.
On my Mac, they're in paths like this:
/Users/Shared/Blizzard/Battle.net/Cache/69/61/6961b3a6c6c294dbff91a786d60fddea962e70b01a040a5c7a096987896a2e0e.s2gs
On PCs I'm told they are here:
C:\ProgramData\Blizzard Entertainment\Battle.net\Cache
The easiest way to find a s2gs file is to look at some match summary screen in the game client, then go to the directory and sort by date modified.
If we all put our heads together, I bet we can figure out the format.
A fellow SC2 nerd, Nick, was able to get this far:
#!/usr/bin/env python
import zlib
data = open("test.s2gs","rb").read()
print zlib.decompress(data[16:])
Some of you may wonder about what Blizzard's reaction to this project will be. I hope that Blizzard will have the same reaction that they've had to the community's study of the structure of the MPQ and the replay format -- essentially none. Of course, if Blizzard prefers that this project not move forward, I for one will cease immediately.
I'm not sure what's the best way to structure our findings -- I guess people can post what they discover in this thread, and once that becomes unwieldy, someone can set up a wiki or public Google docs page to hold the findings. Or a github project.
You might be asking, what's the point of being able to parse s2gs files? Basically every tool that does anything useful with replays could parse s2gs as well, and all the info that is visible in the end-of-game summary screen could be merged with the replay info. For example, computing Spending Quotient would be trivial. There are about 30 other cool things would be immediately quite doable.
|
I am not sure what to say... so I will say good luck decrypting the encrypted file.
|
This would be all kinds of amazing seeing this kind of information more power to you sir.
|
Sounds interesting but I don't even understand what you are saying to be honest, hope it works out for you.
|
On April 21 2012 06:04 Kralic wrote: I am not sure what to say... so I will say good luck decrypting the encrypted file.
I dont think its encrypted, just compressed. This seams like a cool project, but I cant think of anything you can get from the summery that you couldnt get from the replay file. Just easier parsing perhaps?
|
spancho, the summary has a lot of things you can't get from the replay, for example: * average unspent resources * resource collection rate * number of workers created * first 64 things built by each player
each of these can be estimated from the replay, but in many cases the estimation will be off, sometimes by a lot.
the replay file contains build commands that fail due to lack of resources, and there's no way to tell which these are without recreating the whole game engine. unspent resources also cannot be calculated without essentially rebuilding the game engine.
also the replay file doesnt tell you when workers are killed. when my workers die it can change my resource collection rate a lot
|
On April 21 2012 06:15 spancho wrote:Show nested quote +On April 21 2012 06:04 Kralic wrote: I am not sure what to say... so I will say good luck decrypting the encrypted file. I dont think its encrypted, just compressed. This seams like a cool project, but I cant think of anything you can get from the summery that you couldnt get from the replay file. Just easier parsing perhaps?
It would be a way to get spending quotient without relying on a sketchy text recognition script.
|
Would you care to upload a decompressed version of an s2gs file?
I keep getting an "input string does not conform to zlib format" when trying to do this myself...
Edit: nvm, got it working now.
|
This is really interesting. I've found some things and will continue trying to understand it. I will "publish" my findings here: User:Prillan/s2gs
|
I'm not sure this file has complete data, I'm only seeing reference points (game speed, difficulty, players) and no game data such as resources/workers.
It would be nice to chat with some others who are working with this data. I'm in #teamliquid on IRC.
Edit(s): zlib 1.2.5 being used instead of 1.2.6.
|
After some further discussion, I believe this might be a red herring. A file containing reference points needed to parse the relevant packets coming from Battle.net, which are consumed by the replay scoreboard to populate variables.
|
I added some things to your liquipedia page (including the 2 lines required in PHP to read and decompress the file)
|
I believe the s2gs file is actually the concatenation of a few different logical files.
|
Ok I'm 100% sure there is all the data that we want :D
Values as stored as the double !
0x28 => 40 => 20 0x50 => 80 => 40 0xF001 => 240+0 =>120 0x9802 => 152+1*128 => 280 0xc002 => 192+1*128 => 320 0x9003 => 144+2*128 => 400 0xe003 => 224+2*128 => 480 General rule : YY1 YY2 gives (YY1 + (YY2 - 1) * 128) / 2
Graph data is like this : 02 04 00 04 09 [XX] 05 06 00 09 [YY1 YY2 YY3 ...] XX is X coordinates 00,02,04, ...,3C YY is Y coordinate as stated above.
average unspent resource is preceded by 05040009ce0f02090802001e00 Ressource collection rate is preceded by 05040009ce0f02090a02001e00
05040009ce0f02090a02001e00 ==> ressource collection rate 0205060009 f018 02040004099a1300 => player 1's = f018 0205060009 ba1e 02040004099a1300 => player2's = ba1e 0000 3's 0000 4's 0000 5's 0000 6's 0000 7's 0000 8's 0000 9's 0000 10's 0000 11's 0000 12's 0000 13's 0000 14's 00 end
|
Ok I just wrote a PHP script that reads all the score values, which leaves build order and graph data to do ! Here is an output example :
+ Show Spoiler + Array ( [Player0] => Array ( [Resources] => 28425 [Units] => 32725 [Structures] => 6100 [Overview] => 69300 [Average Unspent Resources] => 797 [Resource Collection Rate] => 1592 [Workers Created] => 70 [Units Trained] => 132 [Killed Unit Count] => 87 [Structures Built] => 63 [Structures Razed Count] => 0 [Spending Quotient] => 82.506486242342 ) [Player1] => Array ( [Resources] => 31012 [Units] => 56625 [Structures] => 7000 [Overview] => 98487 [Average Unspent Resources] => 1495 [Resource Collection Rate] => 1949 [Workers Created] => 112 [Units Trained] => 252 [Killed Unit Count] => 85 [Structures Built] => 32 [Structures Razed Count] => 11 [Spending Quotient] => 77.608697996132 ) )
And here is the PHP script : + Show Spoiler + <?php $c = bin2hex(gzuncompress(file_get_contents($_GET['file'].'.s2gs', false, null, 16))); $desc = array('Resources','Units','Structures','Overview','Average Unspent Resources','Resource Collection Rate','Workers Created','Units Trained','Killed Unit Count','Structures Built','Structures Razed Count'); for ($i = 0; $i < sizeof($desc); $i++) { $bleh = str_pad(base_convert($i * 2, 10, 16), 2, '0', STR_PAD_LEFT); $search = '09ce0f0209'.$bleh.'02001e00'; $pos = strpos($c, $search) + strlen($search); $found = 0; for ($p = 0; $p <= 14; $pos += 2) { $hex = substr($c, $pos, 2); if ($hex == '02') { $found = 1; $after = strpos($c, '020400', $pos); $value = substr($c, $pos + 10, $after - $pos - 10); $v = 0; for ($x = 0; $x*2 < strlen($value); $x++) { $dec = base_convert(substr($value, $x*2, 2),16,10); if ($x == 0) $inc = $dec; if ($x == 1) $inc = ($dec-1)*128; if ($x == 2) $inc = ($dec-1)*16384; $v += $inc; } $v = $v / 2; $players['Player'.$p][$desc[$i]] = $v; $pos = $after; } if ($hex == '00') { if ($found == 1) $found = 0; else $p++; } } } foreach($players as $k => $v) { $i = $players[$k]['Resource Collection Rate']; $u = $players[$k]['Average Unspent Resources']; $players[$k]['Spending Quotient'] = 35*(0.00137*$i-log($u))+240; } echo '<pre>'; print_r($players); echo '</pre>'; ?>
|
|
Great job everyone
|
Now do it with all the files in SC2, find me more goodies!
P.S. Can and admin rename the SC2 forum "The Goodie Room" for few hours or so? lol
|
I just added the spending quotient to my script, edited on my previous post.
|
This is awesome. I wonder if this can somehow be integrated into sc2gears to add additional information for replay analyses.
|
|
|
|