Skip to content

Commit f4446e1

Browse files
committed
fix: Revise task logic to keep tasks down to an achieveable level, add building logic, reduce room phase checks
1 parent 0cda814 commit f4446e1

File tree

7 files changed

+66
-88
lines changed

7 files changed

+66
-88
lines changed

src/main.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
Last Updated 21st August 2025
66
77
Version: 0.0.10
8-
Build: 45
8+
Build: 46
99
*/
1010

1111
// Import functions etc
@@ -59,7 +59,7 @@ export const loop = () =>
5959
// find and track sources
6060
if (!memory.sources || Object.keys(memory.sources).length === 0) initRoom(room);
6161

62-
if (!memory.constructionQueue || memory.constructionQueue.length === 0) bunkerBuilder(roomName, 10);
62+
if ((!memory.constructionSites || Object.keys(memory.constructionSites).length === 0)) bunkerBuilder(roomName, 10);
6363

6464
// manage spawning for each room
6565
manageSpawning(room);

src/managers/buildingManager.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export function bunkerBuilder(roomName: string, roomMaxlocationDistance: number)
1212
if (roomMaxlocationDistance < 7) return false; // room not big enough for bunkers
1313

1414
const roomMemory = getRoomMemory(Game.rooms[roomName]);
15-
if (roomMemory.constructionQueue && roomMemory.constructionQueue.length > 0) return false; // Have unbuilt construction sites don't queue up more
15+
if (roomMemory.constructionSites && Object.keys(roomMemory.constructionSites).length > 0) return false; // Have unbuilt construction sites don't queue up more
1616

1717
if (!roomMemory.spawns) return false; // if room has no spawn then we dont need to be building
1818
if (roomMemory.rcl < 2) return false; // earliest time we can have extensions
@@ -71,8 +71,7 @@ export function bunkerBuilder(roomName: string, roomMaxlocationDistance: number)
7171
for (const {x , y} of offsets)
7272
{
7373
const pos = new RoomPosition(extensionAnchor.x + x, extensionAnchor.y + y, roomName);
74-
if (placeConstructionSite(pos, STRUCTURE_EXTENSION, pos.roomName) === OK) return true;
75-
else
74+
if (placeConstructionSite(pos, STRUCTURE_EXTENSION, pos.roomName) !== OK)
7675
{
7776
scanConstructionsSites(
7877
Game.rooms[roomName],
@@ -82,7 +81,6 @@ export function bunkerBuilder(roomName: string, roomMaxlocationDistance: number)
8281
x2: testPos.x + 7,
8382
y2: testPos.y + 7
8483
});
85-
return false;
8684
}
8785
}
8886
}
@@ -109,12 +107,6 @@ function placeConstructionSite(roomPosition: RoomPosition, structureType: Builda
109107
console.log(`Failed to place ${structureType} at ${roomPosition}: ${result}`);
110108
return result;
111109
}
112-
113-
if (structureType === STRUCTURE_EXTENSION)
114-
{
115-
if (roomMemory.extensions === undefined) roomMemory.extensions = 0;
116-
roomMemory.extensions++;
117-
}
118110

119111
return OK;
120112
}
@@ -134,7 +126,8 @@ function scanConstructionsSites(room: Room, area: {x1: number, y1: number, x2: n
134126
y: site.y,
135127
type: site.constructionSite.structureType,
136128
};
137-
roomMemory.constructionQueue?.push(site.constructionSite.id);
129+
if (roomMemory.constructionQueue === undefined) roomMemory.constructionQueue = [];
130+
roomMemory.constructionQueue.push(site.constructionSite.id);
138131
console.log(`Found site ${site.constructionSite.id} at (${site.x}, ${site.y}) for ${site.constructionSite.structureType}`);
139132
}
140133
}

src/managers/memoryManager.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,10 @@ export function getRoomMemory(room: Room): RoomMemory
2323
const memory = room.memory as RoomMemory;
2424

2525
if (memory.constructionSites === undefined) memory.constructionSites = {};
26+
if (memory.constructionQueue === undefined) memory.constructionQueue = [];
2627
if (!memory.controllerProgress) memory.controllerProgress = {level: 0, totalEnergyHarvested: 0};
2728
if (memory.creepCounts === undefined) memory.creepCounts = {};
2829
if (memory.creeps === undefined) memory.creeps = {};
29-
if (memory.extensions === undefined) memory.extensions = room.find(FIND_STRUCTURES, {
30-
filter: (structure) => structure.structureType === STRUCTURE_EXTENSION}).length;
3130
if (memory.maxHarvesters === undefined) memory.maxHarvesters = 0;
3231
if (memory.owner === undefined) memory.owner = room.controller?.owner ?? 'None'
3332
if (memory.phase === undefined) memory.phase = RoomPhase.UnitiatedRoom;

src/managers/spawnManager.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import { Role, RoleComposition, RoomPhase } from "types";
99
export const desiredCreepsByName: Record<keyof typeof RoomPhase, RoleComposition> =
1010
{
1111
UnitiatedRoom: {},
12-
DeathSpiral: {harvester : 2},
13-
InitialBootstrap: {harvester : 3, upgrader: 1},
14-
StableEarlyGame: {energyMiner : 2, upgrader: 2},
12+
DeathSpiral: {harvester : 2}, // Have less than 100 energy in the room and 1 or less creeps in room Make harvesters
13+
InitialBootstrap: {harvester : 3, upgrader: 1}, // RCL is less than two
14+
StableEarlyGame: {energyMiner : 2, upgrader: 2, builder: 1}, // RCL Greater than or equal to 2 and no storage
1515
MidGame: {energyMiner: 2, upgrader: 2, builder: 1, lorry: 2},
1616
NearMax: {energyMiner: 2, upgrader: 3, builder: 2, lorry: 2, repairer: 1},
1717
MaxSingleRoom: {energyMiner: 2, upgrader: 1, lorry: 3, repairer: 2},
@@ -21,9 +21,9 @@ export const desiredCreepsByName: Record<keyof typeof RoomPhase, RoleComposition
2121
const desiredCreeps: Record<RoomPhase, RoleComposition> =
2222
{
2323
[RoomPhase.UnitiatedRoom]: {},
24-
[RoomPhase.DeathSpiral]: {harvester : 2},
25-
[RoomPhase.InitialBootstrap]: {harvester : 3, upgrader: 1},
26-
[RoomPhase.StableEarlyGame]: {energyMiner : 2, upgrader: 2},
24+
[RoomPhase.DeathSpiral]: {harvester : 2}, // Have less than 100 energy in the room and 1 or less creeps in room Make harvesters
25+
[RoomPhase.InitialBootstrap]: {harvester : 3, upgrader: 1}, // RCL is less than two
26+
[RoomPhase.StableEarlyGame]: {energyMiner : 2, upgrader: 2, builder: 1}, // RCL Greater than or equal to 2 and no storage
2727
[RoomPhase.MidGame]: {energyMiner: 2, upgrader: 2, builder: 1, lorry: 2},
2828
[RoomPhase.NearMax]: {energyMiner: 2, upgrader: 3, builder: 2, lorry: 2, repairer: 1},
2929
[RoomPhase.MaxSingleRoom]: {energyMiner: 2, upgrader: 1, lorry: 3, repairer: 2},
@@ -53,7 +53,7 @@ export function manageSpawning(room: Room): void
5353
if (!spawn) return;
5454

5555
// TODO: Update to not hard code role types
56-
const currRoles: Role[] = ['harvester', 'upgrader'];
56+
const currRoles: Role[] = ['harvester', 'upgrader', 'builder'];
5757
const roomMemory = getRoomMemory(room);
5858
if (!roomMemory) return;
5959
const roomPhase = roomMemory.phase;

src/managers/taskManager.ts

Lines changed: 11 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { HANDOVER_TTL_THRESHOLD } from "consts";
99
import { getDesiredCountForRole } from "./spawnManager";
1010
import { runHarvester } from "roles/role.harvester";
1111
import { runUpgrader } from "roles/role.upgrader";
12+
import { runBuilder } from "roles/role.builder";
1213

1314
/**
1415
* Type Safe Ensure Global Tasks
@@ -50,7 +51,7 @@ const taskToRoleMap: Record<TaskType, Role> =
5051
export const roleRunners: Record<Role, (creep: Creep) => void> = {
5152
harvester: runHarvester,
5253
upgrader: runUpgrader,
53-
builder: () => {},
54+
builder: runBuilder,
5455
energyMiner: () => {},
5556
lorry: () => {},
5657
repairer: () => {},
@@ -66,38 +67,7 @@ export const roleRunners: Record<Role, (creep: Creep) => void> = {
6667
*/
6768
function runCreep(creep: Creep, role: Role):void {
6869
if (!creep) return;
69-
const mem = getCreepMemory(creep);
70-
71-
// Reassignment logic (e.g., upgrade harvester to upgrader if storage is full) and cooldown has passed
72-
const cooldownTicks = 25;
73-
const canSwitch = !mem.lastRoleChange || Game.time - mem.lastRoleChange > cooldownTicks;
74-
75-
if ((role === 'harvester' || role === 'upgrader') && canSwitch)
76-
{
77-
const room = creep.room;
78-
const roomMemory = getRoomMemory(room);
79-
if (!roomMemory) return;
80-
const roomCreepCount = roomMemory.creepCounts || {};
81-
82-
const maxUpgraders = room.controller ? room.controller.level : 1;
83-
84-
if (role === 'harvester' satisfies Role &&
85-
room.energyAvailable === room.energyCapacityAvailable &&
86-
(roomCreepCount['upgrader'] || 0) < maxUpgraders)
87-
{
88-
// Don't let harvesters stand around doing nothing, start to upgrade instead.
89-
retaskHarvesterToUpgrader(creep);
90-
}
91-
92-
if (role === 'upgrader' satisfies Role &&
93-
creep.room.energyAvailable < creep.room.energyCapacityAvailable * 0.5 &&
94-
(roomCreepCount["harvester"] || 0) < 3)
95-
{
96-
// Energy getting low in room? Convert back to harvester
97-
retaskUpgraderToHarvester(creep);
98-
}
99-
}
100-
70+
10171
const runner = roleRunners[role];
10272

10373
if (!runner)
@@ -109,30 +79,6 @@ function runCreep(creep: Creep, role: Role):void {
10979
roleRunners[role]?.(creep);
11080
}
11181

112-
/**
113-
* Swap role of harvester to upgrader
114-
* @param creep
115-
*/
116-
function retaskHarvesterToUpgrader(creep: Creep): void
117-
{
118-
const memory = getCreepMemory(creep);
119-
120-
memory.role = 'upgrader' satisfies Role;
121-
memory.lastRoleChange = Game.time;
122-
}
123-
124-
/**
125-
* Swap role of upgrader to harvester
126-
* @param creep
127-
*/
128-
function retaskUpgraderToHarvester(creep: Creep): void
129-
{
130-
const memory = getCreepMemory(creep);
131-
132-
memory.role = 'harvester' satisfies Role;
133-
memory.lastRoleChange = Game.time;
134-
}
135-
13682
/**
13783
* Swap role of harvester to builder
13884
* @param creep
@@ -141,7 +87,7 @@ function retaskCreepToBuilder(creep: Creep): void
14187
{
14288
const memory = getCreepMemory(creep);
14389

144-
memory.role = 'builder' satisfies Role;
90+
// memory.role = 'builder' satisfies Role;
14591
memory.lastRoleChange = Game.time;
14692
}
14793

@@ -330,7 +276,7 @@ function createTasks(room: Room, tasks: AnyTask[]): AnyTask[] | undefined
330276
newTasks.push(createTask(
331277
"harvest",
332278
{
333-
id: `harvest-${source}-${Game.time}`,
279+
id: `harvest-${source}`,
334280
maxCreeps: roomMemory.maxHarvesters / Object.keys(roomMemory.sources).length,
335281
targetId: source as Id<Source>,
336282
method: ResourceAcquisitionMethod.Harvest,
@@ -357,7 +303,7 @@ function createTasks(room: Room, tasks: AnyTask[]): AnyTask[] | undefined
357303
newTasks.push(createTask(
358304
"harvest",
359305
{
360-
id: `harvest-${source}-${Game.time}`,
306+
id: `harvest-${source}`,
361307
maxCreeps: roomMemory.maxHarvesters / Object.keys(roomMemory.sources).length,
362308
targetId: source as Id<Source>,
363309
method: ResourceAcquisitionMethod.Harvest,
@@ -371,7 +317,7 @@ function createTasks(room: Room, tasks: AnyTask[]): AnyTask[] | undefined
371317
newTasks.push(createTask(
372318
"upgrade",
373319
{
374-
id: `upgrade-${Game.time}`,
320+
id: `upgrade-${room.controller.id}`,
375321
maxCreeps: getDesiredCountForRole(roomMemory.phase, 'upgrader'),
376322
targetId: room.controller.id,
377323
status: "untasked",
@@ -391,12 +337,12 @@ function createTasks(room: Room, tasks: AnyTask[]): AnyTask[] | undefined
391337
continue;
392338
}
393339
if (isRoomStorageFull(room)) continue;
394-
if (taskExists("harvest", source as Id<Source>))
340+
if (!taskExists("harvest", source as Id<Source>))
395341
{
396342
newTasks.push(createTask(
397343
"harvest",
398344
{
399-
id: `energyMiner-${source}-${Game.time}`,
345+
id: `harvest-${source}`,
400346
maxCreeps: 1,
401347
targetId: source as Id<Source>,
402348
method: ResourceAcquisitionMethod.Harvest,
@@ -409,7 +355,7 @@ function createTasks(room: Room, tasks: AnyTask[]): AnyTask[] | undefined
409355
newTasks.push(createTask(
410356
"upgrade",
411357
{
412-
id: `upgrade-${Game.time}`,
358+
id: `upgrade-${room.controller.id}`,
413359
maxCreeps: getDesiredCountForRole(roomMemory.phase, 'upgrader'),
414360
targetId: room.controller.id,
415361
status: "untasked",
@@ -701,7 +647,7 @@ export const taskManager =
701647
if (mem.controllerProgress?.level === undefined) continue;
702648
if (mem.controllerProgress?.level !== room.controller?.level) mem.controllerProgress.level = room.controller?.level ?? 0;
703649

704-
mem.phase = getRoomPhase(room);
650+
if (Game.time % 500 === 0) mem.phase = getRoomPhase(room);
705651

706652
createTasks(room, tasks);
707653

src/roles/role.builder.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { getCreepMemory, getRoomMemory } from "managers/memoryManager";
2+
import { tryHarvest } from "./creepBehaviours";
3+
4+
export function runBuilder(creep: Creep)
5+
{
6+
const creepMemory = getCreepMemory(creep);
7+
const roomMemory = getRoomMemory(creep.room);
8+
9+
if (!roomMemory.sources) return;
10+
if (!creepMemory.task || !creepMemory.task.targetId) return;
11+
const sourceId = roomMemory.sources && Object.keys(roomMemory.sources)[1] as Id<Source>;
12+
const target = Game.getObjectById(creepMemory.task?.targetId as Id<ConstructionSite>);
13+
14+
if (creepMemory.task?.status === 'tasked') creepMemory.task.status = 'in_progress';
15+
16+
if (creepMemory.working && creep.store[RESOURCE_ENERGY] === 0)
17+
{
18+
creepMemory.working = false;
19+
creep.say('🚜 harvest');
20+
}
21+
if (!creepMemory.working && creep.store.getFreeCapacity() === 0)
22+
{
23+
creepMemory.working = true;
24+
creep.say('🏗️ build');
25+
}
26+
27+
if (!creepMemory.working)
28+
{
29+
tryHarvest(creep, sourceId);
30+
}
31+
else
32+
{
33+
if (target)
34+
{
35+
if (creep.build(target) === ERR_NOT_IN_RANGE)
36+
{
37+
creep.moveTo(target, {visualizePathStyle: {stroke: '#2c0276ff'}});
38+
}
39+
}
40+
}
41+
}

src/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,6 @@ export interface RoomMemory
199199
[role: string]: number;
200200
};
201201
exits:Partial<Record<ExitKey, string>>;
202-
extensions?: number;
203202
lastCleanupTick?: number;
204203
maxHarvesters: number;
205204
owner: Owner | string,

0 commit comments

Comments
 (0)