RoomPosition behaves strange



  • I have this strange problem I'm trying to pin down for few days. From time to time I'm getting error that cannot call findInRange on undefined (or something, saying that this.target.pos is undefined in StorageWrapper class). This can happen every few minutes or sometimes more rarely.

    Below is extracted code - in each tick I iterate over all rooms, and create RoomManager for reach room. RoomManager takes storage and passes it into StorageWrapper. StorageWrapper calls findInRange on StructureStorage.pos and this fails.

    // In main.js
    
    let managers = rooms.getHandlers(jobBoard);
    
    // in rooms.js
    
    module.exports = {
        getHandlers(jobBoard) {
            let managers = [];
            _.each(Game.rooms, room => {
    			// ....
    			managers.push(new roomTypes.regular(room, jobBoard));
    
    // in roomTypes.regular.js
    
    class RoomManager extends utils.Executable {
    
        constructor(room, jobManager) {
            super();
            this.room = room;
    		// ...
    		if(this.room.storage) {
                           this.storage = new wrappers.StorageWrapper(this, this.room.storage, this.links);
    
    // in wrappers.js
    
    class StorageWrapper extends utils.Executable {
    	
        constructor(manager, storage, links) {
            super();
    
            this.manager = manager;
            this.target = storage;
    
            this.link = _.first(this.target.pos.findInRange(links, 3));
    

    What is even more strange: I've added small guard:

    if(!this.target.pos) {console.log('WHY NO POS?', this.target, '::', this.target.pos);}
    

    and this guard from time to time logs to console following:

    WHY NO POS ? [structure (storage) #someid] :: [room WaaNbb pos 23,33]
    

    So pos evaluates sometimes to falsy, yet beeing printed it is not falsy and is valid object. And in such cases, besides pos beeing falsy, calling findInRange does not throw errors.

    Please advise what I'm doing wrong because I dont know how I should guard all my code agains such cases.


  • Dev Team

    Game.rooms contains all rooms you have visibility to, not only rooms you claimed. Some of them may not contain storage. Try filtering out by the existence of storage.



  • @rudykocur said in RoomPosition behaves strange:

    if(this.room.storage) {

    I'm testing for storage existence - in RoomManager constructor



  • Additionally, because I've noticed that for some time I've not recieved exception itself, but logs from my "guard" (WHY NO POS ?...), I've experimented a bit. Conclusion for now is that logging to console this.target.pos causes exception not to be thrown, and if I comment out this if+console.log, then exceptions starts to appear.


  • Dev Team

    Are you sure that you create your classes each tick and not cache them in nodejs internal cache?



  • I'm pretty sure I dont. I know that you can assign to variables on module-level but I'm not doing so (yet ;)). Friend of mine from work looked through codebase (he knows screeps) and cant explain this issue to. If you want - code is here https://github.com/rudykocur/screeps2 - files in question are:

    I could give you tick numbers in which that happened, but I doubt that would give you any help in diagnostics ...

    Additionally, anything that comes to my mind which is maybe anything out of ordinary:

    • I (obviously) modify few prototypes, but only for getters and using data found in this of modified prototype
    • In RoomManager constructor I assing room.manager = this - can this be putting something into nodejs internal cache? AFAIK to game objects are recreated each tick?
    • In one place I cache pathfinder path in memory, and later to move by this path i replace __proto__ of objects from memory to RoomPosition.prototype here. I do this too to reconstruct cached rooms here, but both places are not used in RoomManager and has nothing to do with StructureStorage

  • Dev Team

    @rudykocur Thanks for your report, I'll try to investigate what's going on.



  • Just to add more magic to this mix - just if(!this.target.pos) { console.log("sad pos is sad");} is enough to supress exception. console.log(this.target.pos); is not necessary to somehow "fix" this behaviour

    Additionally, I replaced __proto__ = RoomPosition.prototype with regular new RoomPosition(...) just to exclude some magic connection, but that did not helped at all.


  • Dev Team

    @rudykocur could you please also check this.target.pos == null and _.isUndefined(this.target.pos)? I don't think I can see this as a game bug or issue unless we have something like 'hey, sometimes Game.getObjectById('whatever').pos is undefined'