@xoposhiy: You mean you don't specify the roles when creating creeps, but assign them dynamicaly based on their capabilities? That makes it easier, i like it. Although, this way, you could lose some strategic control.
Blade
@Blade
Posts made by Blade
-
RE: Functional Roles
-
RE: Functional Roles
Oh my. Code format is totally screwed up. But I can't find the Edit Post feature :(.
-
Functional Roles
Hi, community!
I’m totally new to Screeps and I have quite a lot of fun.
I just wanted to share my approach to creep roles implementation in functional style. The idea is that roles could be implemented as functions, returning boolean value of whether this role is being fulfilled. This way we can define prioritized chain of roles for each creep. For example, a creep with WORK and CARRY can fulfill the role “repair” if it sees something that needs repairing, and fall back to “harvest” role if there is nothing to repair.
This chain could be gracefully implemented using modern JS features.Here is an example of implementation:
var roles = {}; roles.repair = function() { var target = this.pos.findClosestByRange(FIND_MY_STRUCTURES, { // NOTE: FIND_MY_STRUCTURES does not return constructed walls filter: (obj) => obj.hits < obj.hitsMax }); if (target) { if (this.repair(target) == OK) { return true; } if (this.carry.energy < this.carryCapacity) { // Go take some energy from base var base = Game.spawns.Spawn1; if (base.transferEnergy(this) == OK || this.moveTo(base) == OK) { return true; } } if (this.moveTo(target) == OK) { return true; } } return false; // nothing to repair, role is not fulfilled }; roles.harvest = function() { // Drop all energy to base if (this.carry.energy == this.carryCapacity) { var base = Game.spawns.Spawn1; if (this.transferEnergy(base) == OK || this.moveTo(base) == OK) { return true; } } var source = this.pos.findClosestByPath(FIND_SOURCES); if (source) { if (this.harvest(source) == OK || this.moveTo(source) == OK) { return true; } } return false; // could not approach or harvest from source, role is not fulfilled }; module.exports.loop = function() { // ... Create creep with roles like this. This creep will try to fulfill "repair" role first. If it can't it will do "harvest". // `roles` are best stored in Memory as an array of strings. Game.spawns.Spawn1.createCreep([MOVE, WORK, CARRY], 'Worker', { roles: [ 'repair', 'harvest' ] }); // Execute creep roles Object.keys(Game.creeps).forEach((creepId) => { var creep = Game.creeps[creepId]; creep.memory.roles.some((role) => roles[role].call(creep)); // will stop on first function returning true }); };
With this approach, creep's behavior can be composed in many different ways. It can also help to build universal creeps that change their roles according to some conditions. Another example is harvesters, that switch to attacking if there are hostile creeps nearby. Or harvesters, that pickup dropped energy if there is any and then resume the harvesting.
I will gladly welcome comments. And please share if this trick was helpful to you.