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.


  • Culture

    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