Changes to esbuild and adds initial creation of creaps

This commit is contained in:
2025-07-05 22:34:23 -03:00
parent d72f3ec851
commit 06d4eff5c9
9 changed files with 669 additions and 33 deletions

View File

@@ -1,7 +1,7 @@
import SpawnHandler from "spawnHandler";
declare global {
/*
/*
Example types, expand on these or remove them and add your own.
Note: Values, properties defined here do no fully *exist* by this type definiton alone.
You must also give them an implemention if you would like to use them. (ex. actually setting a `role` property in a Creeps memory)
@@ -9,24 +9,25 @@ declare global {
Types added in this `global` block are in an ambient, global context. This is needed because `main.ts` is a module file (uses import or export).
Interfaces matching on name from @types/screeps will be merged. This is how you can extend the 'built-in' interfaces from @types/screeps.
*/
// Memory extension samples
interface Memory {
uuid: number;
log: any;
}
interface CreepMemory {
role: string;
room: string;
working: boolean;
}
// Syntax for adding proprties to `global` (ex "global.log")
namespace NodeJS {
interface Global {
log: any;
// Memory extension samples
interface Memory {
uuid: number;
log: any;
spawnHandlers: { [name: string]: SpawnHandler };
}
interface CreepMemory {
role: string;
room: string;
working: boolean;
}
// Syntax for adding proprties to `global` (ex "global.log")
namespace NodeJS {
interface Global {
log: any;
}
}
}
}
// When compiling TS to JS and bundling with rollup, the line numbers and file names in error messages change
@@ -42,10 +43,18 @@ declare global {
// }
// });
export const loop = () => {
for (const spawn of Object.values(Game.spawns)) {
// Create a handler for each spawn
const spawnHandler = new SpawnHandler(spawn);
// Run the handler
spawnHandler.run();
}
Memory.spawnHandlers = Memory.spawnHandlers || {};
console.log(`Current game tick is ${Game.time}`);
// Check if spawn still exists
for (const spawn of Object.values(Game.spawns)) {
// Create a handler for each spawn
if (spawn.name in Memory.spawnHandlers) {
Memory.spawnHandlers[spawn.name] = new SpawnHandler(spawn);
}
// Run the handler
Memory.spawnHandlers[spawn.name].run();
}
};

View File

@@ -1,9 +1,83 @@
class SpawnHandler {
constructor(private spawn: StructureSpawn) {}
import { CreepRequisition, CreepRole, CreepRoles, RoleDefinition } from "types/creeps";
import { DEFAULT_GAME_CONFIG } from "types/gameConfig";
import { get_role_const as get_role_cost } from "utils/funcs/get_role_const";
public run(): void {
console.log(`Spawn ${this.spawn.name} in room ${this.spawn.room.name} is ready.`);
}
class SpawnHandler {
constructor(private spawn: StructureSpawn) {}
public run(): void {
if (this.spawn.spawning) {
console.log(`Spawn ${this.spawn.name} is currently spawning a creep.`);
return;
}
const creepRequisition = this.checksNeedsCreeps();
if (Object.values(creepRequisition).every(count => count <= 0)) {
console.log(`Spawn ${this.spawn.name} has no creep needs.`);
return;
}
const totalCreeps = Object.values(Game.creeps).length;
if (totalCreeps >= DEFAULT_GAME_CONFIG.maxCreeps) {
console.log(`Spawn ${this.spawn.name} cannot spawn more creeps, limit reached.`);
return;
}
const rolesToSpawn = this.sortCreepRolesByPriority(creepRequisition);
for (const role of rolesToSpawn) {
if (this.spawn.store[RESOURCE_ENERGY] < get_role_cost(role)) {
console.log(`Spawn ${this.spawn.name} does not have enough energy to spawn a ${role.name}.`);
continue;
}
const newName = `${role.name}_${Game.time}`;
const spawnResult = this.spawn.spawnCreep(role.body, newName, {
memory: {
role: role.name,
room: this.spawn.room.name,
working: false
}
});
if (spawnResult === OK) {
console.log(`Spawn ${this.spawn.name} successfully spawned a new ${role.name}: ${newName}.`);
return; // Exit after spawning one creep
} else {
console.error(`Spawn ${this.spawn.name} failed to spawn a new ${role.name}: ${spawnResult}`);
}
}
}
private checksNeedsCreeps(): CreepRequisition {
const creepCounts: Record<string, number> = {};
for (const creep of Object.values(Game.creeps)) {
const role = creep.memory.role;
creepCounts[role] = (creepCounts[role] || 0) + 1;
}
const requisition: CreepRequisition = {
harvester: 0,
upgrader: 0,
builder: 0
};
for (const role in DEFAULT_GAME_CONFIG.minCreepsPerRole) {
if (!(role in CreepRoles)) {
console.warn(`Unknown creep role: ${role}`);
continue;
}
const roleType = role as CreepRole;
requisition[roleType] = DEFAULT_GAME_CONFIG.minCreepsPerRole[roleType] - (creepCounts[role] || 0);
}
return requisition;
}
private sortCreepRolesByPriority(requisition: CreepRequisition): RoleDefinition[] {
return Object.keys(requisition)
.filter(role => requisition[role as CreepRole] > 0)
.map(role => CreepRoles[role as CreepRole])
.sort((a, b) => a.priority - b.priority);
}
}
export default SpawnHandler;

31
src/types/creeps.ts Normal file
View File

@@ -0,0 +1,31 @@
export type RoleDefinition = {
name: string;
body: BodyPartConstant[];
priority: number;
}
export const CreepRoles = {
harvester: {
name: "harvester",
body: [WORK, CARRY, MOVE],
priority: 1
},
upgrader: {
name: "upgrader",
body: [WORK, CARRY, MOVE],
priority: 2
},
builder: {
name: "builder",
body: [WORK, CARRY, MOVE],
priority: 3
}
} satisfies Record<string, RoleDefinition>;
export type CreepRole = keyof typeof CreepRoles;
export type CreepRequisition = Record<CreepRole, number>;

34
src/types/gameConfig.ts Normal file
View File

@@ -0,0 +1,34 @@
import { CreepRequisition } from "./creeps";
/**
* Configuration for the game, defining limits and minimum requirements for creeps.
* Used to manage the overall game state and ensure proper role distribution.
*/
export type GameConfig = {
/** The maximum number of creeps allowed in the game. */
maxCreeps: number;
/**
* The minimum number of creeps required for each role.
* Creeps will be spawned to meet these minimums before allocating new roles.
*/
minCreepsPerRole: CreepRequisition;
};
/**
* Default game configuration with maximum creeps and minimum creeps per role.
* This configuration is used to initialize the game state and ensure that the game runs smoothly.
*
* @type {GameConfig}
*/
export const DEFAULT_GAME_CONFIG: GameConfig = {
maxCreeps: 50,
minCreepsPerRole: {
harvester: 5,
upgrader: 5,
builder: 5
}
};

View File

@@ -0,0 +1,8 @@
import { RoleDefinition } from "types/creeps"
export const get_role_const = (role: RoleDefinition) => {
return role.body.reduce((cost, part) => {
cost += BODYPART_COST[part] || 0;
return cost;
}, 0)
}