getTerrainOfRoom — fast copy of staticTerrainData[room]



  • Suggested getTerrainOfRoom() is very minor, but useful function: instead of 2500 calls of getTerrainAt() to acquire static terrain data user now can call getTerrainOfRoom() once to get copy of runtimeData.staticTerrainData[roomName] typed array.

    There are TERRAIN_MASK_* constants within existing API which can be used for future analysis of this Uint8Array: distance transform, skeletonization, convolution with CostMatrices, transferring to WASM etc. IMHO, terrain data acquiring and transferring is pretty expensive now to try some advanced path/map techniques.

    Simple test to try (spoiler):
    const room = Game.rooms[Object.keys(Game.rooms)[0]];
    let t = 0;
    
    t = Game.cpu.getUsed();
    const arr = Game.map.getTerrainOfRoom(room);
    t = Game.cpu.getUsed() - t;
    console.log(`getTerrainOfRoom   = ${t.toFixed(6)} CPU`);
    
    t = Game.cpu.getUsed();
    const own = new Uint8Array(2500);
    for(let i = 0; i < 50; ++i)
        for(let j = 0; j < 50; ++j)
            own[i + 50*j] = Game.map.getTerrainAt(i, j, room.name).charCodeAt(0);
    t = Game.cpu.getUsed() - t;
    console.log(`getTerrainAt 2500x = ${t.toFixed(6)} CPU`);
    

    Typical performance tests:

    [5:42:29 PM]getTerrainAt 2500x = 0.988422 CPU
    [5:42:30 PM]getTerrainOfRoom   = 0.015738 CPU
    

    Need reply to ensure there aren't security underwater rocks here (constructor or accessors rewriting?) Now I'm investigating it as well.

    Pull request: https://github.com/screeps/engine/pull/83

    NOTE: there is a typo inside function (.roomName instead of .name if argument is a Room object), it'll be fixed before merging.

    👍