screeps-pathfinding icon indicating copy to clipboard operation
screeps-pathfinding copied to clipboard

Harvesters keep swapping at source, without harvesting

Open sandercuppen opened this issue 3 years ago • 2 comments

Hi NesCafe62, another small issue.

My harvester creeps keep swapping in place, when multiple of them are actively harvesting a source. Is there a paramater i can set to prevent this behavior? Setting priority doesn't work, because all harvester creeps have the same priority.

Thanks for the support and your great pathing code!

sandercuppen avatar Mar 11 '21 09:03 sandercuppen

Good that you noticed that problem.

Current behavior is if source have N free spots N creeps will take that spots. If there is N+1 creep or more some of them will not have space. But because movement logic runs only for creeps that are not near source it will result in pushing away other creeps that are working there.

Priority can help if you make them higher as soon as creep gets in range. Simply increase it creep.memory._t.priority = higherValue or call moveTo when in range with higher priority value.

But it is not very convenient way, it complicates the code and slightly reduces it's performance (with moveTo call when in range).

I'm solving this problem by assigning as much creeps for source mining as needed. If it is static container mining I only assing one creep. If it is worker creeps when no static creeps yet due to low RCL or other reasons, I assign maximum as much of them as there are free spots for standing near source.

Also should mention that with repair and build logic I just let them swap constantly if they can't fit in range. But I have logic that utilizes simultaneous actions, if in range I call build/repair method and then if creep get pushed it still does work. it is just become less efficient 2 creeps working speed reduces to speed of one creep working.

NesCafe62 avatar Mar 12 '21 17:03 NesCafe62

I can probably make a change to moveTo fucntion to be like this (added line marked with "<<<" comment.):

if (!Creep.prototype.originalMoveTo) {
	Creep.prototype.originalMoveTo = Creep.prototype.moveTo;
	Creep.prototype.moveTo = function(target, defaultOptions = {}) {
		const options = {

			range: DEFAULT_RANGE,

			visualizePathStyle: DEFAULT_PATH_STYLE,

			// uncomment this line to enable moveOffRoad behavior:
			// moveOffRoad: true,

			...defaultOptions,
			// convenient way of providing role specific movement options (remove previous line to use):
			// ...CreepRoles[this.memory.role].getMoveOptions(defaultOptions)
		};

		// >> this part is optional. can remove it if you have own implementation of "getCreepWorkingTarget"
		const targetPos = target.pos || target;
		this.memory._t = {
			pos: [targetPos.x, targetPos.y, targetPos.roomName],
			range: options.range,
			priority: options.priority
		};
		// <<

		if (
			this.pos.inRangeTo(target, options.range) &&
			(options.moveOffExit === false || !Utils.isPosExit(this.pos))
		) {
		
			this.memory._t.priority += 1; // <<< added line
			
			if (options.moveOffRoad) {
				Pathing.moveOffRoad(this, {...options, priority: -1000});
			}
			return IN_RANGE;
		}
		return Pathing.moveTo(this, target, options);
	};
}

But I'm not sure should this behavior be by default. Or should I make an option to make it togglable, either boolean, or priorityIncrement option (that will be added if creep is in range) or just separate workingPriority option.

Initially what goes below this lines

// ============================
// PathingManager configuration
// can customize for your own needs

Meant to be user code. You can change it for your needs or remove and write alternative logic, it can even be in another file. (It is what I do in my codebase). I thought maybe should extract that setup section of library into different file pathing.setup.js

NesCafe62 avatar Mar 12 '21 17:03 NesCafe62