My code for unloading energy is very inefficient. Can i have some help, please?



  • Hello everyone!

    Thanks to @wtfrank i've been able to get accurate information on where i use more cpu. I discovered that my creeps unloading energy at extensions and spawns are consuming a lot of cpu. When this happens, my args are ['extensions', 'spawns'].

    This is my current function to unload energy on most cases...

    //"args" is an array of strings like "unload(creep, ['containers', 'terminals']);
    run: function(creep, args) {
        let unloadResult;
        let target = null;
        //Check if target structure is already in creep's memory
        if(!creep.memory.unloadTo || creep.memory.unloadTo == 0){
    
            let atContainers = false;
            let atLinks = false;
            let atStorages = false;
            let atSpawns = false;
            let atTowers = false;
            let atExtensions = false;
            let atTerminals = false;
            
            //Check what structures does the creep want to unload to
            if(args && args.length){
                
                for(let i in args){
                    switch(args[i]){
                        case 'containers':      atContainers = true;        break;
                        case 'links':           atLinks = true;             break;
                        case 'storages':        atStorages = true;          break;
                        case 'spawns':          atSpawns = true;            break;
                        case 'towers':          atTowers = true;            break;
                        case 'extensions':      atExtensions = true;        break;
                        case 'terminals':       atTerminals = true;         break;
                        case 'any':             atContainers = true;
                                                atLinks = true;
                                                atStorages = true;
                                                atSapwns = true;
                                                atTowers = true;
                                                atExtensions = true;
                                                atTerminals = true;
                        break;
                        default:                console.log('Invalid input at UnloadEnergy(): '+args[i]);
                        break;
                    }
                }
            }
            //Find desired structures according to creep's preferences and making sure that structure isn't full aready
            //For containers, i also check that i don't choose containers i use for drop-mining
            target = creep.pos.findClosestByPath(FIND_STRUCTURES, {
                filter: function(structure){
                    return (
                        
                        (atLinks &&         structure.structureType == STRUCTURE_LINK)         ||
                        (atContainers &&    structure.structureType == STRUCTURE_CONTAINER      &&      _.sum(structure.store)     <   structure.storeCapacity     && (structure.storeCapacity - _.sum(structure.store) > creep.carry.energy)   &&  structure.id != creep.room.memory.mineralContainer)  ||
                        (atStorages &&      structure.structureType == STRUCTURE_STORAGE        &&      _.sum(structure.store)     <   structure.storeCapacity     && (structure.storeCapacity - _.sum(structure.store) > creep.carry.energy))      ||
                        (atTerminals &&     structure.structureType == STRUCTURE_TERMINAL       &&      _.sum(structure.store)     <   structure.storeCapacity     &&   structure.store.energy < 2000)     ||
                        (atSpawns &&        structure.structureType == STRUCTURE_SPAWN          &&         structure.energy        <   structure.energyCapacity)        ||
                        (atTowers&&         structure.structureType == STRUCTURE_TOWER          &&         structure.energy        <   structure.energyCapacity)        ||
                        (atExtensions &&    structure.structureType == STRUCTURE_EXTENSION      &&         structure.energy        <   structure.energyCapacity)
    
                    );
                }
            });
            //Did i find a target?
            if(target){
                creep.memory.unloadTo = target.id;
            }else{
                creep.memory.unloadTo = 0;
            }
        //If target structure is already stored into creep's memory, i just use it
        }else{
            target = Game.getObjectById(creep.memory.unloadTo);
        }
    
        //Now...if i have a valid target...
        if(target != null) {
            
            
            //Is creep near enough to unload?
            if(creep.pos.isNearTo(target)){
                //Unload energy and reset the target stored in memory
                unloadResult = creep.transfer(target, RESOURCE_ENERGY);
                creep.memory.unloadTo = 0;
            //If not near enough, move towards target structure
            }else{
                creep.travelTo(target);
                unloadResult = ERR_NOT_IN_RANGE;
            }
            //If after all the process i didn't find a valid target...
        }else{
            unloadResult = 'noTarget';
        }
        return unloadResult;
    
    }
    

    Can you guys take a look and tell me if you see any reason why it would consume so much cpu?

    EDIT: The creep consuming a lot of cpu, what actually does is:

    let unloadResult = UnloadEnergy.run(creep, ['extensions', 'spawns']);
    if(unloadResult != OK && unloadResult != ERR_NOT_IN_RANGE){
        unloadResult = UnloadEnergy.run(creep, ['towers']);
        if(unloadResult != OK && unloadResult != ERR_NOT_IN_RANGE){
            unloadResult = UnloadEnergy.run(creep, ['terminals']);
        }
    }
    

    I just replaced the above with the following, but it didn't make a big difference...

    if(creep.room.energyAvailable < creep.room.energyCapacityAvailable){
        UnloadEnergy.run(creep, ['extensions', 'spawns']);
    }else{
        let unloadResult = UnloadEnergy.run(creep, ['towers']);
        if(unloadResult != OK && unloadResult != ERR_NOT_IN_RANGE){
             unloadResult = UnloadEnergy.run(creep, ['terminals']);
        }
    }
    

    And sometimes it may consume up to 4~5 cpu in a single tick 😕



  • What is travelTo ?. Try checking the CPU of each section to see how much each bit uses so you can narrow it down



  • @obamallama Ok!! I'll take a deeper look. Thank you.

    P.S. It's travelTo() instead of moveTo() because of Traveler.



  • @calfa The only thing I can think of that uses a lot of CPU is findClosestByPath but thats definitely not gonna use 4 or 5 cpu. How are you recording CPU at the moment? is it per loop or per function run? How many creeps are running it?



  • @obamallama To record the cpu used, i do...

    let start;
    let end;
    let debug = true;
    if(debug){
       start = Game.cpu.getUsed();
    }
        //Here is my code
    
    if(debug){
       end= Game.cpu.getUsed();
       console.log(creep.name, " - ", end-start);
    }
    

    When i do this in a module that many creeps use in the same tick, there's a single output for each creep, right?

    How many rooms can you manage with 20 cpu? At this moment, i use about 23cpu average to manage 4 rooms (room level 7, 7, 7, 6) and remote mining on 5 more rooms (1 miner, 1 hauler and 1 reserver on each).



  • @calfa thatll definitely record the CPU usage for each time its run so once for each creep. Over the last few months Ive been rewritting my code over and over again in simulation so idk how many rooms I can really work in