Spawn.transferEnergy fails but returns OK



  • My code (note that my source variable is not a Source object, but a Spawn):

                var source = Game.getObjectById(creep.memory.sourceId);
                if (source) {
                    creep.moveTo(source);
                    console.log("Before: Mine: " + creep.energy + "/" + creep.energyCapacity + " - theirs: " + source.energy + "/" + source.energyCapacity);
                    var result = source.transferEnergy(creep);
                    console.log("Transferring energy from " + source + " - result: " + result);
                    console.log("After: Mine: " + creep.energy + "/" + creep.energyCapacity + " - theirs: " + source.energy + "/" + source.energyCapacity);
                } else {
                    console.log("Invalid source ID, finding new spawn");
                    source = creep.pos.findClosest(FIND_MY_SPAWNS);
                    creep.memory.sourceId = source.id;
                    creep.moveTo(source);
                    source.transferEnergy(creep);
                }
    

    Output:

    [11:23:30 AM]Before: Mine: 0/50 - theirs: 3277/6000
    [11:23:30 AM]Transferring energy from [spawn Spawn1] - result: 0
    [11:23:30 AM]After: Mine: 0/50 - theirs: 3277/6000
    [11:23:31 AM]Before: Mine: 0/50 - theirs: 3280/6000
    [11:23:31 AM]Transferring energy from [spawn Spawn1] - result: 0
    [11:23:31 AM]After: Mine: 0/50 - theirs: 3280/6000

    The creep is right next to the spawn, so there's no reason for it to fail, and in fact it returns 0, OK. But the energy is not transferred.

    This same creep was doing this operation successfully several times, and then it suddenly encountered this bug. I think it will stay this way until it dies of old age, and the new one I build to replace it will operate correctly for a while and then encounter the bug (Otherwise my whole operation would surely have broken by now).



  • One more piece of info: if I use the console to transfer energy to the creep, it receives it, and goes about its normal operations until it returns to the spawn for more energy, at which point it returns to the state described above. I'm fairly certain it's not doing anything like putting the energy back as soon as it takes it out. If it was, though, would using the console override that? Is it possible to transfer energy back and forth multiple times in one tick?



  • I think the console is executed after the script, so yeah, it probably can override actions.



  • You can not transfer energy back and forth in one tick like that, no.

    When you transfer energy to a creep, you can only transfer its maximum capacity - current energy, regardless of any energy it is transferring to something else.



  • Ok, so given tscmoo's answer, this must be a real bug in the game, and not just a problem with my script. If the transfer from the spawn to the creep was succeeding the first time, the console command wouldn't make a difference.



  • Wait a minute... can you also not transfer energy out of a spawn more than once in a tick, even if there's plenty of energy to go around? E.g. spawn.transferEnergy(creep1), spawn.transferEnergy(creep2). Will the second creep always receive no energy?



  • Indeed, you can only transferEnergy once per tick from a structure or creep. You can transfer from multiple sources to a single destination, but not from a single source to multiple destinations.



  • A call of any method in the game script suggests its queuing for execution rather than instant execution. It will be executed after the current tick is finished and the execution stage of all players commands commences. This is why the amount of energy before and after the call of the transferEnergy method will be the same, it will change only in the next tick.

    Furthermore, the next call of the same command always cancels the previous one. That is, the latest successfully called command will be executed.

    See more in the articles Simultaneous execution of creep actions and Understanding game loop, time and ticks.



  • Okay, I guess I'll have to create some kind of priority system to make sure that energy gets delivered to the creeps that need it most, since only one can receive it each tick.