creeps not spawning even though createCreep returned the provided creep name


  • SUN

    So ... I'm trying to understand why some creeps don't spawn.

    Are there cases where the creep won't spawn (eg, spawn.spawning is null on next tick) even though spawn.createCreep returned the provided name ?

    This seems to happen quite often and is quite disruptive for my codebase,

    How i came up to that conclusion : whenever I call spawn.createCreep and it returns ok I remember the request

    	let result = this.createCreep(body, name, memory);
    
    	let success = result === name;
    	if (success) {
    		Memory.spawning = Memory.spawning || {};
    		Memory.spawning[this.id] = {name: name, time: Game.time, needTime: body.length / 3, result: result};
    	}
    

    Then on next tick I check if that spawn is spawning

    function checkSpawns() {
    	let failed = false;
    	_.forEach(Memory.spawning, (expected, spawnId) => {
    		let spawn = Game.getObjectById(spawnId);
    		if (spawn && (!spawn.spawning || spawn.spawning.name !== expected.name)) {
    			failed = true;
    			expected.failed = true;
    		}
    	});
    	if (failed) {
    		Memory.failedSpawning = Memory.failedSpawning || {};
    		Memory.failedSpawning[Game.time] = Memory.spawning;
    	}
    	delete Memory.spawning;
    }
    
    

    Ir remember the whole spawn requests because i wanted to make sure there was not name conflicts

    Current output

    {
      "21066868": {
        "5800c9308a798b425be34e2c": {
          "name": "bridge-867-W55S43",
          "time": 21066867,
          "needTime": 3,
          "result": "bridge-867-W55S43",
          "failed": true
        }
      },
      "21067841": {
        "580feb31ba239b7c48519603": {
          "name": "tractor-1840-W52S41",
          "time": 21067840,
          "needTime": 16,
          "result": "tractor-1840-W52S41",
          "failed": true
        },
        "59880854ae5de95797792478": {
          "name": "tractor-1840-W76N67",
          "time": 21067840,
          "needTime": 16,
          "result": "tractor-1840-W76N67",
          "failed": true
        }
      },
      "21067980": {
        "583090f06fba44674ac260ed": {
          "name": "bridge-1979-W57S45",
          "time": 21067979,
          "needTime": 3,
          "result": "bridge-1979-W57S45",
          "failed": true
        }
      }
    }
    

    so ... down to my question : are there cases where the spawn intent won't be executed on server side ? I've checked also that the energyAvailable on next tick was enough for the creep to spawn



  • A very basic question: Are you absolutely certain that you don't call createCreep more than once?


  • SUN

    i am not 100% certain but the code shouldn't allow it, i'm only spawning 1 creep per room per tick.

    AND, the next tick the spawn isn't spawning anything else either (eg, spawn.spawning === undefined)


  • Overlords

    needTime: body.length / 3 should be needTime: body.length * 3


  • SUN

    you're definitely right ! i'll fix this, although this is not explaining the issue



  • @finndibaen

    Hiya Finndibaen. My code and experience in screeps is pretty entry-level compared to what appears to be par in here, but I am constantly banging my head against this very issue you describe. I have conceded that it's related to issues outlined in this article by Tedivm (below)...particularly as it seems you're running information about spawn states across multiple ticks...

    http://docs.screeps.com/contributed/caching-overview.html

    In particular: "...and code will bounce between at least four nodes at a time. This means data placed in global one tick will only have a 25% chance of appear next (although it can be added again until it's on all four nodes, bringing the change up to 100%) and that deleted data could easily show up again in the next tick."

    Maybe someone has a more definitive answer, but at the very least it gave me some relief from chasing ghosts by just living with it.


  • SUN

    @Mashee thanks for the willingness to help, but there is no caching involved here, i'm storing in (saved) memory every spawn request i'm expecting to succeed, and checking that it was realized on the next tick, otherwise resubmitting it.

    Had to do that because of the issue i describe above, which was resulting in some critical creeps missing



  • @finndibaen Yeah, I made an assumption that you are running a spawn-memory-queue instead of a static creep count fulfillment.

    In the queue instance, it's easy to generate the failures you describe when the queue is empty and the first request arrives through the pipeline. That 1st request got messed up by caching so frequently on my testing that I reverted my spawning to a more primitive method simply so I didn't have to do any error checking like your code snippet. 😄



  • Another long shot.

    If you are trying to spawn two creeps in the same room during the same tick it could be that you have energy only for one of them. You get OK from the function because the room have enough energy for the creeps individually, but when the intents are being executed one of them fails.


  • SUN

    @Mashee neither : ) I'm actually running a timer based system. whenever a creep is spawned, a timer is set to determine when a new one needs to spawn, thus sparing the cpu cost of checking untill that time. this is why this issue is particularly hurting me

    @SandGrainOne by construction my code should only ever spawn 1 creep per tick and per room. But yes, your point is valid


  • Dev Team

    There are only few checks in the processor server-side code that prevent already registered createCreep intent from being executed, see here. Most likely, the problem is in your code.