Re: ERR_NO_PATH when creep moveTo flag in another room
Hello!
I am trying to expand into another room but I'm running into the issue where creeps are stuck on the exit, going back and forth between rooms. I tried a lot of solutions, read a ton of posts and docs, but nothing helped. So, I'll try to explain in as much detail possible everything I tried and what were the results in order if someone can help me figure out what I am getting wrong (most likely) or if there's an actual problem with the game.
First, I played the game maybe a year ago locally on my machine and managed to get working harvesting and building in two adjacent rooms. I remember that I had this issue back then, but have been able to solve it after all.
Code that I used is the following:
harvester code:
module.exports = {
run: function(creep) {
if (creep.memory.working && creep.carry.energy === creep.carryCapacity) {
creep.memory.working = false;
creep.say('delivering');
} else if (!creep.memory.working && creep.carry.energy === 0) {
creep.memory.working = true;
creep.say('harvesting');
}
// bring the dude home if he's stuck
// const storageStructure = Game.rooms[creep.memory.storageRoom].storage;
// creep.moveTo(storageStructure, {visualizePathStyle: {stroke: '#00ff00'}});
if (creep.memory.working) {
// console.log('working');
// console.log('room', creep.room.name);
// console.log('target room', creep.memory.targetRoom);
if (creep.room.name === creep.memory.targetRoom) {
console.log('here'); // this never runs, even when the creep is in the targetRoom
const energySource = creep.pos.findClosestByPath(FIND_SOURCES, {
filter: source => source.energy > 0
});
if (creep.harvest(energySource) === ERR_NOT_IN_RANGE) {
creep.moveTo(energySource, {visualizePathStyle: {stroke: '#007700'}});
}
} else {
// console.log('move to exit'); // this runs only in the home room
const exitDirection = creep.room.findExitTo(creep.memory.targetRoom);
const exitRoom = creep.pos.findClosestByPath(exitDirection);
creep.moveTo(exitRoom);
}
} else {
console.log('not working'); // it never gets to this of course
if (creep.room.name !== creep.memory.targetRoom) {
const storageStructure = Game.rooms[creep.memory.storageRoom].storage;
if (creep.transfer(storageStructure, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) {
creep.moveTo(storageStructure, {visualizePathStyle: {stroke: '#00ff00'}});
}
} else {
const exitDirection = creep.room.findExitTo(creep.memory.storageRoom);
const exitRoom = creep.pos.findClosestByPath(exitDirection);
creep.moveTo(exitRoom);
}
}
}
};
I removed the code that I used to create and run them, but I wrote a new one to test it locally again:
I was creating them with:
const targetRoom = 'W8N2';
const storageRoom = 'W8N3';
firstSpawnInRoom.spawnCreep(body, `H-${targetRoom}-${getCreepName()}`, {
memory: {
role: 'harvesterExternal',
working: false,
targetRoom: targetRoom,
storageRoom: storageRoom
}
});
and runing them with:
const creepNamesInGame = Object.keys(Game.creeps);
creepNamesInGame && creepNamesInGame.forEach(name => {
const creep = Game.creeps[name];
const role = creep.memory.role;
creepRoles[role].run(creep);
});
They get created fine and go to the correct exit, and then they get stuck going back and forth.
So, the creep code above was the code that worked a year ago, but now it doesn't work, and I don't think other two pieces of code are creating problems.
Now, here's everything I tried in a game in the World.
The idea was to have a flag in the other room, find a flag, create a creep, make it move to the flag and once it is in the room where the flag is, find the controller and move to it/claim or whatever.
The creep code with details explained and with some alternative ways I tried to solve this:
const logObject = require('util.logObject');
const { visualizePath } = require('util.functions');
const getNextRoomName = (currentRoomName, pathThroughRooms) => {
// return the name of the next room in the path
// when in the target room, other condition will prevent calling this function
const roomIndex = pathThroughRooms.indexOf(currentRoomName);
return pathThroughRooms[roomIndex + 1];
};
module.exports = {
run: function(creep) {
// there is the issue of moving through another room;
// looks like the swapm terrain is preventing creeps from properly moving
// I have to make sure that the creep enters new room at the position with no swamp // THIS IS DONE - DOESN'T HELP
// all of the following properties/objects are passed correctly:
const flagName = creep.memory.flagName;
const flag = Game.flags[flagName];
const targetRoomName = flag.pos.roomName;
const currentRoomName = creep.room.name;
// try findPathTo; from the docs example
// the path array only contains the points in the current room;
// I guess that's fine, the problem is when the creeps exits the room, the path is empty array
// const path = creep.pos.findPathTo(flag);
// logObject(path);
// if (path.length > 0) {
// const moveOutput = creep.move(path[0].direction);
// console.log(moveOutput); // for debugging
// }
console.log('target', targetRoomName);
console.log('current', currentRoomName); // it never reads the name of the other room, only for the home room
if (currentRoomName !== targetRoomName) {
// in the home room, everything is read properly
// once out of the home room, it's like the creep is in limbo
// move room by room
// look for the exit towards the next room in the `pathThroughRooms` array (array of room names)
// const pathThroughRooms = creep.memory.pathThroughRooms;
// logObject(pathThroughRooms); // reads fine
// const nextRoomName = getNextRoomName(currentRoomName, pathThroughRooms);
// const exitDirection = creep.room.findExitTo(nextRoomName);
// const exitRoom = creep.pos.findClosestByPath(exitDirection);
// const moveOutput = creep.moveTo(exitRoom, visualizePath('#ff0000'));
// console.log('next', nextRoomName);
// move to flag; docs suggest this
const moveOutput = creep.moveTo(flag, visualizePath('#ff0000'));
// this returns 0 while moving toward the home room exit
// when creep exits the home room, it returns nothing since this whole `if` block does not execute, in fact, the whole script does not execute
// when the creeps goes back to the home room, it starts outputing -2, can't find path, but again, only when it is in the home room
console.log(moveOutput);
console.log('target', targetRoomName);
console.log('current', currentRoomName);
} else {
// this part is, of course, never reached
console.log('where I am?');
if(creep.room.controller && !creep.room.controller.my) {
// if(creep.attackController(creep.room.controller) == ERR_NOT_IN_RANGE) {
creep.moveTo(creep.room.controller);
// }
}
}
}
};
In the main module, I have this code to check if the creep should be created:
const creatingClaimer = false;
Object.keys(Game.flags).forEach(flagName => {
if (flagName.indexOf('ControllerToClaim') === -1) return;
creatingClaimer = Object.keys(Game.creeps).every(creepName => Game.creeps[creepName].memory.role !== 'claimer');
if (!creatingClaimer) return;
flagNameToClaim = flagName;
});
Then, among other checks, I have this:
if (creatingClaimer) {
// firstSpawnInRoom.spawnCreep([CLAIM, CLAIM, MOVE, MOVE, MOVE, MOVE, MOVE, MOVE], `C-${name}-${getCreepName()}`, setCreepMemory('claimer', { flagName: flagNameToClaim }));
firstSpawnInRoom.spawnCreep([MOVE,MOVE], `SCOUT-${name}-${getCreepName()}`, setCreepMemory('claimer', {
flagName: flagNameToClaim,
homeRoom: name,
pathThroughRooms: [ 'W32N45' ]
}));
}
And at the end I run all creeps same as I showed for the local game I have:
const creepNamesInGame = Object.keys(Game.creeps);
creepNamesInGame && creepNamesInGame.forEach(name => {
const creep = Game.creeps[name];
const role = creep.memory.role;
creepRoles[role].run(creep);
});
So, I want to go into the room that is two tiles away, there's one room between my home room and the target room. the path is clear, no obstacles. I also made sure that the creep does not enter the new room at the place where the terrain is swamp.
I also tried to move the flag into the room between the target room and my home room, but the result was the same. I also tried to give it hardcoded position in the adjacent room, still nothing. I tried using flag
object and flag.pos
property of the flag
object, no good.
I also tried adding maxOps
setting as suggested in the referenced thread, but still didn't help.
I liked the idea suggested in the last post there, but I don't think it will help since, after all of this, I figured out that the creep simply does not detect when it is in the other room and that is the root of the issue.
If anyone could help me and point me in the right direction how to determine if the creep knows that it is in the another room I believe that will solve this issue.
Any help greatly appreciated! Thanks for reading through all of this!