Which shard is affected?
It happened on S3 - not sure if it affects others.
What happened?
My claimer creep ran into an error. Its memory had an array of roomNames. It would go to the first in the list, .attackController
if it was owned, .claimController
otherwise, then shift it out of the array and proceed. After going through the array, it would try to go home and recycle. Full code is at the bottom.
After numerous succesful .attackController
lapses, the owner (same for all six rooms) respawned. Immediately afterwards the problems appeared. At least, based on the replay. I noticed only after it had been going on for a while.
The creep would move up to the controller, but claimController
gave the error: TypeError: Cannot read property 'novice' of undefined
During troubleshooting I disabled the claimController
line with a comment, which stopped the errors. I then manually tried claiming the controller with a console command:
let a = Game.getObjectById("..."); Game.creeps.downgrader.claimController(a)
The used id
was copy-pasted and the creep was adjacent to the controller, as you can see on the screenshot below.
The console command returned an error, again as seen on the screenshot: TypeError: Cannot read property 'novice' of undefined
and continued with runtime details.
What should have happened?
The controller should have been claimed successfully.
How can we reproduce this?
Honestly I'm not sure. The same thing happened with the controller 1 room down south, E31S5
, but I didn't look into it then because I assumed it was an error on my part and I decided against claiming that room instead of troubleshooting. It also happened in E32S4
judging by the replay, yet it claimed fine later with the same code.E33S4
claimed fine afterwards as well, again same code.
There is about
Replay link:
E31S4 - from the screenshot
The replay doesn't really show much, but the creep should have 'booped' the controller and then move on east. Interestingly this happens much later than the successful claims from below.
E32S4 - broken
E32S4 - successful claim intent at 12643142, roughly 1800 ticks after the broken attempt.
E33S4 - successful claim intent at 12643192
I did not check behavior along the rest of the route.
Piece of code which shows the bug in action:
Claimer memory shoved into spawnCreep(body, "downgrader", { memory })
:
// const memory = { downgradeNames: ["E31S5", "E31S4", "E32S4", "E33S4", "E33S5", "E32S5"] }
Full creep code: (please don't judge, this was shoved together on-demand).
function runDowngrader(creep) {
const visualizePathStyle = {
fill: 'transparent',
stroke: '#fff',
lineStyle: 'dashed',
strokeWidth: .15,
opacity: .2
}
const opts = { range:1, reusePath: 50, ignoreRoads: true, visualizePathStyle };
// Load array of target roomnames from memory
let targetRoom = creep.memory.downgradeNames[0];
let target;
// Load controller object if vision on target room
if (Game.rooms[targetRoom]) {
target = Game.rooms[targetRoom].controller;
}
// Load controller position if not visible
else {
const flatPos = Memory.rooms[targetRoom].controller.pos;
target = new RoomPosition(flatPos.x, flatPos.y, targetRoom);
}
// Proceed if target is truthy (Controller | RoomPosition)
if(target) {
creep.moveTo(target, opts)
// Attack controller
const result = creep.attackController(target)
// console.log(Game.time + " - " + result)
if (result === OK) {
creep.memory.downgradeNames.shift() // Remove roomName from memory array
console.log(creep + " succesfully attacked " + target + ", " + target.ticksToDowngrade + " remain before losing RCL " + target.level)
// Move to new target
targetRoom = creep.memory.downgradeNames[0];
const flatPos = Memory.rooms[targetRoom].controller.pos;
target = new RoomPosition(flatPos.x, flatPos.y, targetRoom)
}
// Claim if need be
else if (creep.room.name = targetRoom && target.level === 0 && creep.pos.isNearTo(target)) {
console.log(target) // These are all the `[structure (controller)]` logs from the screenshot. Commented this line eventually.
const res = creep.claimController(target); // Commented this out during troubleshooting
// console.log(res)
}
// Activate observer for pathfinding
const obs = Game.spawns.Spawn1.pos.findClosestByRange(FIND_MY_STRUCTURES, {filter: (s) => s.structureType === STRUCTURE_OBSERVER})
if (obs && targetRoom) {
obs.observeRoom(targetRoom)
}
}
// Recycle if all targets are visited
else if (!target) {
target = Game.spawns.Spawn3; // HARDCODE. The horror!
// creep.moveTo(target, opts)
if(creep.pos.isNearTo(target)) {
target.recycleCreep(creep)
}
}
}