Error in engine_processor spawning creep after setting custom terrain



  • Here's the error I'm getting, in engine_processor1.log. The server is ticking, but no creeps are spawning (from my single spawn).

    ```

    Error processing room W6N6: TypeError: terrain.charAt is not a function
        at Object.exports.checkTerrain (/home/ocean/server/modules/engine/dist/utils.js:320:88)
        at module.exports (/home/ocean/server/modules/engine/dist/processor/intents/spawns/_born-creep.js:28:67)
        at module.exports (/home/ocean/server/modules/engine/dist/processor/intents/spawns/tick.js:19:50)
        at /home/ocean/server/modules/engine/dist/processor.js:239:83
        at /home/ocean/server/modules/engine/node_modules/lodash/index.js:3073:15
        at baseForOwn (/home/ocean/server/modules/engine/node_modules/lodash/index.js:2046:14)
        at /home/ocean/server/modules/engine/node_modules/lodash/index.js:3043:18
        at Function.<anonymous> (/home/ocean/server/modules/engine/node_modules/lodash/index.js:3346:13)
        at /home/ocean/server/modules/engine/dist/processor.js:229:11
        at _fulfilled (/home/ocean/server/modules/engine/node_modules/q/q.js:834:54)

    ```


    This error occurs every tick.

     

    I set up this server by copying the server files over from the steam directory to a dedicated VPS. I reset all data, then ran `map.closeRoom()` on all rooms, then `map.generateRoom(..., exits: {(all sides): [1, 2, 3, 46, 47, 48], sources: 4` on the center 9 rooms. I spawned in W6N6.

     

    I was also getting this error occasionally - but it seems to have gone away with a fresh build of version 31.

    ```

    Unhandled rejection: SyntaxError: Unexpected token u in JSON at position 0
        at Object.parse (native)
        at env.get.then.data (/home/ocean/server/modules/driver/lib/history.js:16:35)
        at _fulfilled (/home/ocean/server/modules/common/node_modules/q/q.js:834:54)
        at self.promiseDispatch.done (/home/ocean/server/modules/common/node_modules/q/q.js:863:30)
        at Promise.promise.promiseDispatch (/home/ocean/server/modules/common/node_modules/q/q.js:796:13)
        at /home/ocean/server/modules/common/node_modules/q/q.js:604:44
        at runSingle (/home/ocean/server/modules/common/node_modules/q/q.js:137:13)
        at flush (/home/ocean/server/modules/common/node_modules/q/q.js:125:13)
        at _combinedTickCallback (internal/process/next_tick.js:67:7)
        at process._tickCallback (internal/process/next_tick.js:98:9)

    ```

     

    For anyone else running into this: there's a very-temporary very-hacky hack to fix this posted below.



  •  It seems like what's being passed into `checkTerrain` isn't a string, but rather an object? This is what I get when I catch the error, and print `terrain` at line 16 of `modules/driver/lib/history.js`:

     

    ```

    {"b36ee575fe89ebe":{"room":"W4N4","terrain":"1000111111111111111111111111111111111111111111000100000111111111111111111111111111111111111111102200000000000000000111111111111111111111111111110022200000000000000200011111111111111111111111111000020010000000000000000001111111111111111111111100000001110000000000000000000111111111111111111110000000111110000000000000000000013311111111111111000000011111100000000000000000000023111111111111100200000111111000000000000000000000221111112000000002200001111110020000000000000000000011110000000000000000011111100000000000000000000000111000020002201100000111111000000000000000000000000000000000022211000001111111000000000000000000000000000000000002000000011111110000000002000000000000000000000000000000000111111110000000000000000000000000000000000000000021111111100000000000000000000000000000200000000000011111111100000000000000000000000000000000000000000111111111000000000000000000000000000000000000000001111111110000001111000000000000000000000000000000011111111100002111110000000000000000000000000000000111111111000001111000000000000000000000000000000001111111110000011100000000000000000000020000000000011111111100000000000000000000000000000002000000000111111111000000000000000000200000000000020000000001111111110000000000000000022200000000000200000000011111111100000000000000000000000000000000000000000111111111020000000000000000000000000000000000000001111111110000000000000000000000000000000000000000011111111100000001100000000002220000000000000000000111111111000000111002000000000000000000000000000001111111110000011100020000000000000000000000000000011111111100000110000200000000000001110000200000000111111111000000000000020000000000111110000000000001111111110000000000000000000000001111100000111000011111111100000000000000000000000000000022001110000111111111220000000000000022000000000000000001000001111111112200000000000000000000000000000000000000011111111100000000000000000000000000000000000000000111111111000000000000000000000000000000000000000001111111110000000020000000000000000000000000000002211111111100000000000000000000000000200000000000220111111110000000000000000000111111113311110000000001111111000000000000000000001111111111111110000220011111100000000000000000000111111111111111110000000111110000000000002222220001111111111111111110000020111000000000000002222200111111111111111111110000000100000000000000000000111111111111111111111110000000000000000000000000111111111111111111111111110000000000111111111111111111111111111111111111111110000010001111111111111111111111111111111111111111110001","_id":"b36ee575fe89ebe","meta":{"revision":0,"created":1478246227944,"version":0},"$loki":145}}

    ```

     

    I don't know entirely what to make of this - could this information help determine if this is a bug or user error?


  • Dev Team

    Could you please attach your db.json file?



  • I can't seem to upload a file directly to this chat. However, here's a dropbox link for the DB.json: --

    EDIT: link removed, updated db.json in comment below.



  • If I edit `modules/engine/dist/processor.js` like the following, it prevents the first `terrain.charAt` error, but does not prevent the second one:

     

    ```

    diff --git a/modules/engine/dist/processor.js b/modules/engine/dist/processor-edited.js
    index 4db00cb..deda481 100755
    --- a/modules/engine/dist/processor.js
    +++ b/modules/engine/dist/processor-edited.js
    @@ -32,7 +32,7 @@ function processRoom(roomId, intents, objects, terrain, gameTime, roomInfo, flag
             roomInfo.active = false;
     
             var terrainItem = terrain[_.findKey(terrain)];
    -        if (terrainItem.type == 'terrain') {
    +        if (terrainItem.type == 'terrain' || (!terrainItem.type && terrainItem.terrain)) {
                 terrain = terrainItem.terrain;
             }

    ```

     

    I just made this change as a debugging effort - with it, creeps do spawn, but pathfinding still does not work, and the second error persists. (all PathFinder.search() calls return an incomplete, empty path).



  • Testing more with the game client, it seems that `Game.map.getTerrainAt()` returns "wall" for all positions.



  • I was testing all of this on Build 29 - I'm going to start a completely new server directory with Build 31 and see if it will still occur.



  • With a completely fresh, reset server version 31, the error does still occur. After closing all rooms, removing all rooms, regenerating all rooms, and respawning into one of them, I get a single error repeated ever tick in engine_processor1.log, as follows:

     

    Error processing room W1N1: TypeError: terrain.charAt is not a function
        at Object.exports.checkTerrain (/home/ocean/server/modules/engine/dist/utils.js:320:88)
        at module.exports (/home/ocean/server/modules/engine/dist/processor/intents/spawns/_born-creep.js:28:67)
        at module.exports (/home/ocean/server/modules/engine/dist/processor/intents/spawns/tick.js:19:50)
        at /home/ocean/server/modules/engine/dist/processor.js:239:83
        at /home/ocean/server/modules/engine/node_modules/lodash/index.js:3073:15
        at baseForOwn (/home/ocean/server/modules/engine/node_modules/lodash/index.js:2046:14)
        at /home/ocean/server/modules/engine/node_modules/lodash/index.js:3043:18
        at Function.<anonymous> (/home/ocean/server/modules/engine/node_modules/lodash/index.js:3346:13)
        at /home/ocean/server/modules/engine/dist/processor.js:229:11

     

     

    A snapshot of the data for this reset server is available here: http://ocean.daboross.net/data/db.json


    I have not yet gotten the "Unexpected token u in JSON at position 0" error on this server, so that may have just been corrupted data? However, I do get the above error, after the complete reset and with doing nothing but regenerating all rooms.

    To be clear, here's a list of steps I did to the fresh server in order to get to this error:

    1. Use map.closeRoom(name).then(() => map.removeRoom(name)) on every room.

    2. Use map.generateRoom(name).then(() => map.closeRoom(name)) on every room.

    3. Use map.openRoom(name) on a 4x4 section of rooms.

    4. Spawn into one of the newly opened rooms.



  • For anyone else who is running into this:

    Through editing two of the server files, I seem to have been able to temporarily stop this error and fix pathfinding. I wouldn't recommend this as a permanent solution, as it is really quite a hack, but it did seem to work in my case:

     

    Patch 1, to fix the terrain.charAt is not a function error, and to allow creeps to spawn:

    diff --git a/modules/engine/dist/processor-original.js b/modules/engine/dist/processor.js
    index 9abd76b..84c2193 100755
    --- a/modules/engine/dist/processor-original.js
    +++ b/modules/engine/dist/processor.js
    @@ -32,7 +32,7 @@ function processRoom(roomId, intents, objects, terrain, gameTime, roomInfo, flag
             roomInfo.active = false;
     
             var terrainItem = terrain[_.findKey(terrain)];
    -        if (terrainItem.type == 'terrain') {
    +        if (terrainItem.type == 'terrain' || (terrainItem.type === undefined && terrainItem.terrain !== undefined)) {
                 terrain = terrainItem.terrain;
             }
     

    Patch 2, to fix pathfinding not working at all:

     

    diff --git a/modules/backend/lib/tools-original.js b/modules/backend/lib/tools.js
    index a340124..21861b6 100755
    --- a/modules/backend/lib/tools-original.js
    +++ b/modules/backend/lib/tools.js
    @@ -62,7 +62,7 @@ exports.updateTerrainData = function updateTerrainData() {
     
                 rooms.forEach(room => {
                     if(room.status == 'out of borders') {
    -                    _.find(terrain, {room: room._id}).terrain = walled;
    +                    // _.find(terrain, {room: room._id}).terrain = walled;
                     }
                     var m = room._id.match(/(W|E)(\d+)(N|S)(\d+)/);
                     var roomH = m[1]+(+m[2]+1)+m[3]+m[4], roomV = m[1]+m[2]+m[3]+(+m[4]+1);



  • Pull request submitted for an actual fix (not just a hack around the issue): https://github.com/screeps/backend-local/pull/1


  • Dev Team

    This is fixed in 2.0.0.