Cannot use moveTo, harvest, or transferEnergy on target stored in memory



  • For some reason, I cannot tell a creep to moveTo, harvest, or transferEnergy to an object that has been stored in memory. Below is an example.

    creep.memory.target = creep.room.find(FIND_SOURCES)[0];
    creep.moveTo(creep.memory.target);
    

    Instead I have to do the following:

    creep.memory.target = creep.room.find(FIND_SOURCES)[0];
    creep.moveTo(Game.getObjectById(creep.memory.target.id));
    

    However, calling creep.memory.target.pos.x is defined, so I am not sure why this is happening.



  • One way to fix this might be to copy objects into the memory attribute by reference (as one would expect with javascript) instead of by cloning (this seems to be the current case, since memory doesn't seem to reflect changes to the real world).



  • Try this:

    var pos = RoomPosition(creep.memory.target.pos.x, creep.memory.target.pos.y, creep.memory.target.pos.roomName);
    

    The second example isn't that bad, though not as convenient as it would be in the first example.

    Know though that moveTo and similar commands also have to process the input as well, and giving it a lot of use cases might result in a very complicated function on its own. Then users might find it more convenient to use their own implementations if there is a need for it...



  • Thanks @avdg_ for responding.

    I think I need to rephrase my question. My confusion is why

    creep.moveTo(creep.room.find(FIND_SOURCES)[0]);
    

    works, but

    creep.moveTo(creep.memory.target);
    

    does not.

    IMHO, objects should be copied to Memory by reference, and therefore should be the exact same thing.



  • what you store in the memory object is not the real object, but rather the stringified version of it. (by implicitly calling toString()). thus it is lacking it's prototype, and all the methods associated with it.


  • Dev Team

    This is not a bug. From the article Working with Memory:

    You should not store full game objects in Memory. The Memory object is for storing JSON data and cannot contain links to live objects. Their data will not be relevant. Moreover, it will waste your memory which is limited.

    Instead of storing full objects, it is better to store the id property that any game object has, and then use Game.getObjectById to retrieve the game object by its id.


  • Dev Team

    IMHO, objects should be copied to Memory by reference, and therefore should be the exact same thing.

    Please keep in mind that Game and Memory are being recreated every game tick. It's not possible to store live references in stringified JSON memory data.

    The Memory object itself is under your full control. If you want to copy object references, it's up to you how to achieve that. If you just copy the entire object, its JSON data is copied. The game does not interfere with how you work with your Memory object.



  • I'll just leave this here, it is a helper function that deals with the room position issue without needing to use the Game.getObjectById function:

    /**
     * @param {number|object} x
     * @param {number} [y]
     * @param {string} [roomName]
     * @returns {RoomPosition|boolean}
     */
    var getRoomPosition = function (x, y, roomName) {
        if (!x) return false;
    
        if (typeof x == 'object') {
            var object = x;
    
            x = object.x;
            y = object.y;
            roomName = object.roomName || object.room;
        }
    
        return new RoomPosition(x, y, roomName);
    };
    
    global.pos = getRoomPosition;
    
    // Usage:
    creep.memory.target = creep.room.find(FIND_SOURCES)[0];
    
    creep.moveTo(pos(creep.memory.target));