Request: Ranking by GCL
- 
					
					
					
					
 As a new player, maybe 2 weeks in and GCL 3, I find the overall rankings underwhelming. I am roughly 350 right now, with very few people above me who are also GCL 3. I don't really care that people with higher GCL gather more than me. I think it would be really interesting to compare myself to players at or below my GCL. If someone at my level is outperforming me, that is far more interesting a comparison than someone to whom the game artificially gives access to more resources just because they've been playing longer. The overall ranking is OK, but I think you would have a nice tool for new players to see how they're really doing if you let them compare themselves to other new players as well. This should be a new filter option to the ranking system basically, is my request. UPDATE: Based on this thread I modified some code that was suggested and copied some other code and ended up with a basic utility that will do this which is posed here: https://gist.github.com/gamrxist/ae1c945fccdda5b32496d0939a0994b3 
 
- 
					
					
					
					
 Hello Xist, I did some quick script for that last day, you can tweak the parameters to get what you want. It outputs a csv so you can just order by columns in xlsx to check your stats. Change "min_gcl" / "max_gcl" to filter the players on gcl. And "offset" to filter on ranks. var https = require('https');
 var _ = require('lodash');
 function getUser(user, interval) {
 var query = '/api/user/stats?id=' + user._id + '&interval=' + interval;
 var options = {
 hostname: 'screeps.com',
 port: 443,
 path: query,
 method: 'GET',
 headers: {
 'Content-Type': 'application/json; charset=utf-8',
 },
 };
 var data = '';
 https.request(options, function(response) {
 response.on('data', function (chunk) {
 data += chunk;
 });
 response.on('end', function() {
 var stats = JSON.parse(data).stats;
 console.log([
 user.username,
 user.gcl,
 stats.energyHarvested,
 stats.energyControl,
 stats.energyCreeps,
 stats.energyConstruction,
 stats.energyHarvested ? stats.energyControl / stats.energyHarvested : 0,
 stats.energyHarvested ? stats.energyCreeps / stats.energyHarvested : 0,
 ].join(','));
 })
 }).end();
 }
 function getBoard(offset, min_gcl, max_gcl, interval) {
 var query = '/api/leaderboard/list?limit=10&mode=world&offset=' + offset + '&season=2016-12';
 var options = {
 hostname: 'screeps.com',
 port: 443,
 path: query,
 method: 'GET',
 headers: {
 'Content-Type': 'application/json; charset=utf-8',
 },
 };
 var data = '';
 https.request(options, function(response) {
 response.on('data', function (chunk) {
 data += chunk;
 });
 response.on('end', function() {
 var users = JSON.parse(data).users;
 _.forOwn(users, function(user) {
 if(min_gcl < user.gcl && user.gcl < max_gcl) {
 getUser(user, interval);
 }
 })
 })
 }).end();
 }
 var min_gcl = 0;
 var max_gcl = 100000000;
 var interval = 180; // 8 => 1hour, 180 => 24hour, 1440 => 7days
 for(var offset = 0; offset < 200; offset += 10) {
 getBoard(offset, min_gcl, max_gcl, interval);
 }
 
- 
					
					
					
					
 This is the result for those params: vestad,78831357,8627362,3507638,3318045,1201680,0.40657132504698423,0.3845955461240643 
 FuddyDuddy,74811697,7631822,3396823,3304830,724606,0.445086769581366,0.4330328983039699
 GOREACRAFT,60886322,6739880,1803062,3450317,538992,0.2675213802026149,0.5119255832448055
 PervyPenguin,49275720,5754190,2900487,2139450,444059,0.5040652116110174,0.3718073264873075
 demawi,49228057,9468916,2723543,5045150,970520,0.28762986174975047,0.5328117812007204
 Asku,81177003,7039288,2138142,4123400,392245,0.3037440718436296,0.5857694698668388
 forkmantis,86496854,4547962,1067537,2444830,407125,0.23472865428515013,0.5375660570602833
 Admiral,96591576,3619516,1885117,1172850,375153,0.5208201870084288,0.32403503672866757
 cyberlink916,90873198,3346460,1594087,1031920,226085,0.47635023278329935,0.30836167173670087
 0mni,81693912,3865576,1694845,1372380,347913,0.4384456546708692,0.35502600388661354
 zolox,58725822,2779086,1050970,1351800,279936,0.37817109654037334,0.4864189161472513
 Xephael,74953823,2762910,1532499,677800,184552,0.5546684473978523,0.24532105642239524
 Sparadraph,34601412,3791556,2234191,1103840,52615,0.5892543852708493,0.2911311345526744
 C00k1e_93,76266514,5123720,1477880,3235890,225824,0.28843886863450774,0.6315509044210066
 rudykocur,34559374,6427024,2475420,2616900,496029,0.3851580451543358,0.4071713439999602
 WASP103,73600072,5839594,1452356,2909943,499462,0.2487083862337005,0.4983125539207007
 Davaned,82728171,5278194,1376287,3303370,442899,0.2607496048837917,0.6258523275196024
 Dewey,46871738,4509950,2141878,1856750,236717,0.4749227818490227,0.4117007949090345
 king_lispi,82021914,2764058,878785,1359050,613990,0.31793290878845526,0.4916864986190594
 ICED_COFFEE,92953680,5907534,1075887,3130910,901480,0.18212116934070968,0.5299859467588337
 rbryson74,73512649,2729886,1568288,965770,110483,0.5744884584924059,0.353776677853947
 Kaldosh,43203801,2334918,1709571,395650,72810,0.7321760335909012,0.16944920549672407
 Sanados,78104370,2994444,1474302,1258740,143016,0.4923458244669127,0.4203585039493141
 ramoja,32290850,5862748,1506372,2560130,789549,0.256939578504824,0.4366774761596439
 Atanner,36785208,4552596,1971677,1860590,250038,0.4330885059864745,0.40868770257672765
 Ryleep,27475131,3249214,2170814,903410,164998,0.6681043476976278,0.2780395504882104
 PNoob,45955510,6108146,1357731,2468950,981989,0.22228201486997856,0.40420612080981694
 Aeries,80506581,3671886,1200157,1400850,1403391,0.3268502889250919,0.3815069422089902
 Xanathos,91915467,3068510,1326834,1025170,723557,0.4324033488566112,0.33409374582452067
 Disconnect,98081105,2805268,1112589,1242850,167336,0.3966070264944383,0.4430414491592247
 Eijolend,97952011,3929974,774360,2533780,269172,0.197039471507954,0.6447320007715064
 Zoiah,47857571,1225214,145299,692590,126007,0.11859071150019507,0.5652808407347615
 Noxeth,72809855,2221470,947578,1004500,166440,0.4265544886944231,0.45217806227407975
 vrs,28398452,4941660,1579932,2305503,527466,0.3197168562790641,0.466544238170979
 TiffanyTrump,29835306,5372020,1564128,2199170,340089,0.2911619837602987,0.4093748720220699
 rwampler,26292012,5177064,1910204,2342480,594480,0.36897438393653237,0.45247267563236615
 ScooterV,24413751,462334,337755,124950,35740,0.7305432868878343,0.2702591632888777
 stuy486,26296562,3685734,1794413,1371510,188113,0.48685363620923267,0.37211312590653584
 Xoc,26478035,3767658,1864768,1564890,335015,0.4949408890085034,0.41534820835649094
 Eugenocide,35812928,3142842,1492787,1251862,310691,0.474979970358039,0.39832164645884205
 fsck-u,47829329,2554094,1262254,1058700,79652,0.4942081223322243,0.4145109772780485
 mmmd,28177875,1930024,1116353,532590,352836,0.5784140508097309,0.2759499363738482
 
- 
					
					
					
					
 Thanks @Sparadraph for the info. How does the GCL reported there match up to the GCL value reported on my overview page? 
 
- 
					
					
					
					
 Ah, I see what you mean. This is only the control points for the requested season. You could use /api/user/find?username=<name>, that gives you a response with the total Control Point as gcl if I'm not mistaken. This is just a quick script I did with my poor js understanding, feel free to tweak it to get the data you want  
 
- 
					
					
					
					
 It seems that find?username=x reports GCL in the same way as the stats. None of the endpoints that I can see on my overview page are reporting GCL=3, they're all reporting the high number of upgrade points. I'm guessing there is an (unpublished?) algorithm that converts upgrade points into GCL. I further assume that the overview page can help to glean the upgrade points, e.g. at the moment my overview says I'm 6.44M/8.68M into GCL 3. This roughly matches with the stats API which says I have 6.54M upgradeControl points (the overview page seems to use cached data so it's a bit behind, whereas the stats API seems to update virtually every time I call it). It seems then that we can get the report to produce the desired data by filtering on stats.energyControl, we just need to know all of the cutoff points for each GCL. 8.68M is the GCL 4 cutoff according to my overview page. 
 
- 
					
					
					
					
 If you need any help calculating the GLC from stats.energyControl you can check this code. 
 
- 
					
					
					
					
 Thanks to both of you. I modified your code @Sparadraph and added the GCL calculation from @stybbe and now I'm able to see the data I was looking for. Here is the modified code: var https = require('https');
 var _ = require('lodash');
 var min_gcl = 0;
 var max_gcl = 3;
 var interval = 180; // 8 => 1hour, 180 => 24hour, 1440 => 7days
 var results_per_page = 10; // Must be 10? API gives error with other values
 var max_ranking = 500; // players with rank higher than this won't be included
 var result = [];
 var active_responses = 0;
 var pages = [];
 function onResponseBegin() {
 active_responses++;
 //console.log('>> response '+active_responses);
 process.stdout.write('+');
 }
 function onResponseEnd() {
 active_responses--;
 //console.log('<< response '+active_responses);
 process.stdout.write('-');
 if (active_responses == 0) {
 if (pages.length) {
 //console.log('-- callback '+pages.length);
 process.stdout.write('X');
 let callback = pages.shift();
 callback();
 }
 else {
 endReport();
 }
 }
 }
 function endReport() {
 process.stdout.write('\n');
 let sorted = _.orderBy(result, ['rank']);
 _.forEach(sorted, row => console.log(JSON.stringify(row)));
 }
 function getUserInfo(userId, stats) {
 //console.log(`getUserInfo(${userId})`);
 var query = '/api/user/find?id=' + userId;
 var options = {
 hostname: 'screeps.com',
 port: 443,
 path: query,
 method: 'GET',
 headers: {
 'Content-Type': 'application/json; charset=utf-8',
 },
 };
 var data = '';
 onResponseBegin();
 https.request(options, function(response) {
 response.on('data', function (chunk) {
 data += chunk;
 });
 response.on('end', function() {
 //console.log(JSON.stringify(JSON.parse(data),null,4));
 var info = JSON.parse(data),
 gcl = Math.floor(Math.pow(info.user.gcl/1000000,1/2.4))+1;
 if (gcl >= min_gcl && gcl <= max_gcl) {
 result.push(_.merge({
 username: info.user.username,
 gclLevel: gcl,
 gcl: info.user.gcl,
 }, stats));
 }
 onResponseEnd();
 });
 }).end();
 }
 function getUser(userId, interval, extra) {
 //console.log(`getUser(${userId}) `+JSON.stringify(extra));
 var query = '/api/user/stats?id=' + userId + '&interval=' + interval;
 var options = {
 hostname: 'screeps.com',
 port: 443,
 path: query,
 method: 'GET',
 headers: {
 'Content-Type': 'application/json; charset=utf-8',
 },
 };
 var data = '';
 onResponseBegin();
 https.request(options, function(response) {
 response.on('data', function (chunk) {
 data += chunk;
 });
 response.on('end', function() {
 //console.log(JSON.stringify(JSON.parse(data),null,4));
 var stats = JSON.parse(data).stats;
 getUserInfo(userId, _.merge(extra, stats));
 onResponseEnd();
 })
 }).end();
 }
 function getBoard(offset, interval, maxOffset) {
 var query = '/api/leaderboard/list?limit='+ results_per_page +'&mode=world&offset=' + offset + '&season=2016-12';
 var options = {
 hostname: 'screeps.com',
 port: 443,
 path: query,
 method: 'GET',
 headers: {
 'Content-Type': 'application/json; charset=utf-8',
 },
 };
 var data = '';
 onResponseBegin();
 if (offset < maxOffset) {
 pages.push(_.bind(getBoard, null, offset + results_per_page, interval, maxOffset));
 }
 https.request(options, function(response) {
 response.on('data', function (chunk) {
 data += chunk;
 });
 response.on('end', function() {
 //console.log(JSON.stringify(JSON.parse(data),null,4));
 var users = JSON.parse(data).users,
 userIds = _.keys(users);
 for (let i = 0, n = userIds.length; i < n; i++) {
 getUser(users[userIds[i]]._id, interval, {rank: offset+i});
 }
 onResponseEnd();
 });
 }).end();
 }
 getBoard(0, interval, max_ranking);And some sample output: {"username":"Sheeo","gclLevel":3,"gcl":13940772,"rank":299,"creepsProduced":4056,"creepsLost":514,"energyConstruction":229926,"energyHarvested":2440138,"energyControl":842438,"energyCre
 eps":1119574}
 {"username":"Cookie_93","gclLevel":3,"gcl":13160598,"rank":312,"creepsLost":1437,"creepsProduced":2598,"energyHarvested":351988,"energyControl":183161,"energyCreeps":210540,"energyConst
 ruction":12014}
 {"username":"Dreconus","gclLevel":3,"gcl":13111983,"rank":317,"creepsProduced":5207,"energyControl":852961,"energyCreeps":399700,"energyHarvested":1320768,"energyConstruction":97901}
 {"username":"AdaIsDead","gclLevel":3,"gcl":13460123,"rank":318,"creepsLost":51,"creepsProduced":12211,"energyControl":757253,"energyCreeps":829560,"energyHarvested":1950776,"energyConst
 ruction":398040}
 {"username":"Xist","gclLevel":3,"gcl":12688833,"rank":319,"creepsLost":504,"creepsProduced":13594,"energyConstruction":302867,"energyControl":909569,"energyCreeps":1130200,"energyHarves
 ted":2504260}
 {"username":"nxxcxx","gclLevel":3,"gcl":12971281,"rank":327,"creepsProduced":2963,"energyHarvested":881074,"energyControl":474144,"energyCreeps":198450,"energyConstruction":129917}
 {"username":"Ranamar","gclLevel":3,"gcl":12861738,"rank":328,"creepsLost":33,"energyConstruction":168275,"energyHarvested":1459402,"energyControl":627356,"energyCreeps":568800,"creepsPr
 oduced":7978}I am now quite confused about how the overall ranking is put together though, because it shows me in 5th place ranking-wise over the past 24 hours, even though I have harvested more energy and upgraded my controller more than the 4 people ranked better than me. I'm upgrading faster than they are in both the 24 hour and the 7 day stats reports, yet I'm ranked lower than they are in the ranks. What else does the ranking system look at that cannot be seen in the stats? I thought it was a ranking of controller upgrade speed. 
 
- 
					
					
					
					
 @Xist , cool work! Can you put that on the github? 
 
- 
					
					
					
					
 Sorry, the formatting was pretty messed up when I posted here. I made a gist on github, and updated the OP. https://gist.github.com/gamrxist/ae1c945fccdda5b32496d0939a0994b3