├── .npmrc ├── mod.ts ├── .prettierrc ├── src ├── types.d.ts ├── tower.ts ├── main.ts ├── role │ ├── harvester.ts │ ├── builder.ts │ └── upgrader.ts └── building.ts ├── tsconfig.json ├── .gitattributes ├── .vscode └── settings.json ├── screeps.sample.json ├── rollup.config.js ├── LICENSE ├── .gitignore ├── package.json ├── README.md └── .eslintrc.js /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npm.taobao.org 2 | -------------------------------------------------------------------------------- /mod.ts: -------------------------------------------------------------------------------- 1 | declare const module: { 2 | exports: { 3 | loop: () => void; 4 | }; 5 | }; 6 | 7 | module.exports.loop = function (): void { 8 | console.log("running..."); 9 | }; 10 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "tabWidth": 2, 4 | "printWidth": 120, 5 | "singleQuote": false, 6 | "trailingComma": "none", 7 | "arrowParens": "avoid", 8 | "endOfLine": "auto" 9 | } 10 | -------------------------------------------------------------------------------- /src/types.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // 扩展 Memory 对象 4 | interface CreepMemory { 5 | /** creep 的角色 */ 6 | role?: string; 7 | room?: string; 8 | /** 是否正在建造 */ 9 | building?: boolean; 10 | /** 是否正在升级 */ 11 | upgrading?: boolean; 12 | } 13 | 14 | interface Memory { 15 | uuid: number; 16 | log: any; 17 | } 18 | 19 | // 扩展全局对象 20 | declare namespace NodeJS { 21 | interface Global { 22 | log: any; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/tower.ts: -------------------------------------------------------------------------------- 1 | function run(tower: StructureTower): void { 2 | const closestDamagedStructure = tower.pos.findClosestByRange(FIND_STRUCTURES, { 3 | filter: structure => structure.hits < structure.hitsMax 4 | }); 5 | if (closestDamagedStructure) { 6 | tower.repair(closestDamagedStructure); 7 | } 8 | 9 | const closestHostile = tower.pos.findClosestByRange(FIND_HOSTILE_CREEPS); 10 | if (closestHostile) { 11 | tower.attack(closestHostile); 12 | } 13 | } 14 | 15 | export { run }; 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "esnext", 4 | "lib": [ 5 | "esnext" 6 | ], 7 | "target": "es2017", 8 | "moduleResolution": "Node", 9 | "outDir": "dist", 10 | "baseUrl": "src/", 11 | "sourceMap": true, 12 | "strict": true, 13 | "strictNullChecks": true, 14 | "experimentalDecorators": true, 15 | "noImplicitReturns": true, 16 | "allowSyntheticDefaultImports": true, 17 | "allowUnreachableCode": false 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[javascript]": { 3 | "editor.formatOnSave": false 4 | }, 5 | "[json]": { 6 | "editor.formatOnSave": true 7 | }, 8 | "[typescript]": { 9 | "editor.formatOnSave": false 10 | }, 11 | "editor.codeActionsOnSave": { 12 | "source.fixAll.eslint": true 13 | }, 14 | "editor.formatOnSave": true, 15 | "editor.renderWhitespace": "boundary", 16 | "files.encoding": "utf8", 17 | "files.insertFinalNewline": true, 18 | "files.trimTrailingWhitespace": true, 19 | "search.exclude": { 20 | "_book/**": true, 21 | ".rpt2_cache/**": true, 22 | "dist/**": true, 23 | "node_modules/**": true, 24 | "typings/**": true 25 | }, 26 | "typescript.tsdk": "./node_modules/typescript/lib" 27 | } 28 | -------------------------------------------------------------------------------- /screeps.sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": { 3 | "token": "YOUR_TOKEN", 4 | "protocol": "https", 5 | "hostname": "screeps.com", 6 | "port": 443, 7 | "path": "/", 8 | "branch": "main" 9 | }, 10 | "sim": { 11 | "token": "YOUR_TOKEN", 12 | "protocol": "https", 13 | "hostname": "screeps.com", 14 | "port": 443, 15 | "path": "/", 16 | "branch": "sim" 17 | }, 18 | "season": { 19 | "token": "YOUR_TOKEN", 20 | "protocol": "https", 21 | "hostname": "screeps.com", 22 | "port": 443, 23 | "path": "/season", 24 | "branch": "main" 25 | }, 26 | "pserver": { 27 | "email": "username", 28 | "password": "********", 29 | "protocol": "http", 30 | "hostname": "screeps.devtips.cn", 31 | "port": 21025, 32 | "path": "/", 33 | "branch": "main" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | "use strict"; 3 | 4 | import clear from "rollup-plugin-clear"; 5 | import resolve from "@rollup/plugin-node-resolve"; 6 | import commonjs from "@rollup/plugin-commonjs"; 7 | import typescript from "rollup-plugin-typescript2"; 8 | import screeps from "rollup-plugin-screeps"; 9 | 10 | let cfg; 11 | const dest = process.env.DEST; 12 | if (!dest) { 13 | console.log("No destination specified - code will be compiled but not uploaded"); 14 | } else if ((cfg = require("./screeps.json")[dest]) == null) { 15 | throw new Error("Invalid upload destination"); 16 | } 17 | 18 | export default { 19 | input: "src/main.ts", 20 | output: { 21 | file: "dist/main.js", 22 | format: "cjs", 23 | sourcemap: false, 24 | }, 25 | 26 | plugins: [ 27 | clear({ targets: ["dist"] }), 28 | resolve(), 29 | commonjs(), 30 | typescript({ tsconfig: "./tsconfig.json" }), 31 | screeps({ config: cfg, dryRun: cfg == null }) 32 | ] 33 | }; 34 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import * as building from "building"; 2 | import * as tower from "tower"; 3 | 4 | import { roleBuilder } from "role/builder"; 5 | import { roleHarvester } from "role/harvester"; 6 | import { roleUpgrader } from "role/upgrader"; 7 | 8 | export const loop = function (): void { 9 | building.run(Game.spawns.Spawn1); 10 | 11 | const towers = Game.spawns.Spawn1.room.find(FIND_STRUCTURES, { 12 | filter: { structureType: STRUCTURE_TOWER, my: true } 13 | }); 14 | towers.forEach(tower.run); 15 | 16 | // 根据 screep 的角色分配不同的任务 17 | for (const name in Game.creeps) { 18 | const creep = Game.creeps[name]; 19 | if (creep.memory.role === "harvester") { 20 | roleHarvester.run(creep); 21 | } 22 | if (creep.memory.role === "upgrader") { 23 | roleUpgrader.run(creep); 24 | } 25 | if (creep.memory.role === "builder") { 26 | roleBuilder.run(creep); 27 | } 28 | } 29 | 30 | // 删除 Memory 中已经死亡的 creeps 31 | for (const name in Memory.creeps) { 32 | if (!(name in Game.creeps)) { 33 | delete Memory.creeps[name]; 34 | console.log("Clearing non-existing creep memory:", name); 35 | } 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /src/role/harvester.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 采集者。 3 | * 4 | * 当把 creep 的 `role` 设置为 `"harvester"` 时,creep 在每个 tick 会执行 `roleHarvester.run` 代码。 5 | * 6 | * ```ts 7 | * Game.creeps['name'].memory.role = 'harvester'; 8 | * ``` 9 | * 10 | * creep 会移动到能量点(source)并采集能量。creep 携带能量达到上限时,让它返回出生点(spawn)。 11 | */ 12 | export const roleHarvester = { 13 | run(creep: Creep): void { 14 | if (creep.store.getFreeCapacity() > 0) { 15 | const sources = creep.room.find(FIND_SOURCES); 16 | if (creep.harvest(sources[0]) === ERR_NOT_IN_RANGE) { 17 | creep.moveTo(sources[0], { visualizePathStyle: { stroke: "#ffaa00" } }); 18 | } 19 | } else { 20 | const targets = creep.room.find(FIND_STRUCTURES, { 21 | filter: (structure: AnyStructure) => { 22 | return ( 23 | (structure.structureType === STRUCTURE_EXTENSION || 24 | structure.structureType === STRUCTURE_SPAWN || 25 | structure.structureType === STRUCTURE_TOWER) && 26 | structure.store.getFreeCapacity(RESOURCE_ENERGY) > 0 27 | ); 28 | } 29 | }); 30 | if (targets.length > 0) { 31 | if (creep.transfer(targets[0], RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) { 32 | creep.moveTo(targets[0], { visualizePathStyle: { stroke: "#ffffff" } }); 33 | } 34 | } 35 | } 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /src/role/builder.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 建筑工。 3 | * 4 | * 当把 creep 的 `role` 设置为 `"builder"` 时,creep 在每个 tick 会执行 `roleBuilder.run` 代码。 5 | * 6 | * ```ts 7 | * Game.creeps['name'].memory.role = 'builder'; 8 | * ``` 9 | * 10 | * creep 会找到建造点 (construction site) 并进行建造。当 creep 在携带的能量(energy)变为 0 时去采集能量,并在采集到足够能量之后回到建造场地。 11 | */ 12 | export const roleBuilder = { 13 | run(creep: Creep): void { 14 | // 如果当前 creep 正在建造但是没有能量了,则让此 creep 去采集能量 15 | if (creep.memory.building && creep.store[RESOURCE_ENERGY] === 0) { 16 | creep.memory.building = false; 17 | creep.say("🔄 采集"); 18 | } 19 | 20 | // 如果当前 creep 不处于建造模式,并且能量已经存满,则让此 creep 去建造 21 | if (!creep.memory.building && creep.store.getFreeCapacity() === 0) { 22 | creep.memory.building = true; 23 | creep.say("🚧 建造"); 24 | } 25 | 26 | if (creep.memory.building) { 27 | // 在 creep 所在房间中找到所有的建筑工地 28 | const targets = creep.room.find(FIND_CONSTRUCTION_SITES); 29 | if (targets.length) { 30 | if (creep.build(targets[0]) === ERR_NOT_IN_RANGE) { 31 | creep.moveTo(targets[0], { visualizePathStyle: { stroke: "#ffffff" } }); 32 | } 33 | } 34 | } else { 35 | const sources = creep.room.find(FIND_SOURCES); 36 | if (creep.harvest(sources[0]) === ERR_NOT_IN_RANGE) { 37 | creep.moveTo(sources[0], { visualizePathStyle: { stroke: "#ffaa00" } }); 38 | } 39 | } 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /src/role/upgrader.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 升级者。 3 | * 4 | * 当把 creep 的 `role` 设置为 `"upgrader"` 时,creep 在每个 tick 会执行 `roleUpgrader.run` 代码。 5 | * 6 | * ```ts 7 | * Game.creeps['name'].memory.role = 'upgrader'; 8 | * ``` 9 | * 10 | * creep 会找到控制器 (room controller) 并进行升级。当 creep 在携带的能量(energy)变为 0 时去采集能量,并在采集到足够能量之后回到控制器附近继续升级。 11 | */ 12 | export const roleUpgrader = { 13 | run(creep: Creep): void { 14 | // 如果当前 creep 正在升级但是没有能量了,则让此 creep 去采集能量 15 | if (creep.memory.upgrading && creep.store[RESOURCE_ENERGY] === 0) { 16 | creep.memory.upgrading = false; 17 | creep.say("🔄 采集"); 18 | } 19 | 20 | // 如果当前 creep 不处于升级模式,并且能量已经存满,则让此 creep 去升级 21 | if (!creep.memory.upgrading && creep.store.getFreeCapacity() === 0) { 22 | creep.memory.upgrading = true; 23 | creep.say("⚡ 升级"); 24 | } 25 | 26 | if (creep.memory.upgrading) { 27 | if (creep.room.controller == null) { 28 | console.log("房间 %s 中没有控制器", creep.room.name); 29 | } else if (creep.upgradeController(creep.room.controller) === ERR_NOT_IN_RANGE) { 30 | creep.moveTo(creep.room.controller, { visualizePathStyle: { stroke: "#ffffff" } }); 31 | } 32 | } else { 33 | const sources = creep.room.find(FIND_SOURCES); 34 | if (creep.harvest(sources[0]) === ERR_NOT_IN_RANGE) { 35 | creep.moveTo(sources[0], { visualizePathStyle: { stroke: "#ffaa00" } }); 36 | } 37 | } 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore basic folders 2 | /dist 3 | /.rpt2_cache 4 | /tsc-out 5 | /node_modules 6 | /_book 7 | /build/* 8 | 9 | # TypeScript definitions installed by Typings 10 | /typings 11 | 12 | # Screeps Config 13 | screeps.json 14 | 15 | # ScreepsServer data from integration tests 16 | /server 17 | 18 | # Numerous always-ignore extensions 19 | *.diff 20 | *.err 21 | *.orig 22 | *.log 23 | *.rej 24 | *.swo 25 | *.swp 26 | *.zip 27 | *.vi 28 | *~ 29 | 30 | # Editor folders 31 | .cache 32 | .project 33 | .settings 34 | .tmproj 35 | *.esproj 36 | nbproject 37 | *.sublime-project 38 | *.sublime-workspace 39 | .idea 40 | 41 | # ========================= 42 | # Operating System Files 43 | # ========================= 44 | 45 | # OSX 46 | # ========================= 47 | 48 | .DS_Store 49 | .AppleDouble 50 | .LSOverride 51 | 52 | # Thumbnails 53 | ._* 54 | 55 | # Files that might appear on external disk 56 | .Spotlight-V100 57 | .Trashes 58 | 59 | # Directories potentially created on remote AFP share 60 | .AppleDB 61 | .AppleDesktop 62 | Network Trash Folder 63 | Temporary Items 64 | .apdisk 65 | 66 | # Windows 67 | # ========================= 68 | 69 | # Windows image file caches 70 | Thumbs.db 71 | ehthumbs.db 72 | 73 | # Folder config file 74 | Desktop.ini 75 | 76 | # Recycle Bin used on file shares 77 | $RECYCLE.BIN/ 78 | 79 | # Windows Installer files 80 | *.cab 81 | *.msi 82 | *.msm 83 | *.msp 84 | 85 | # Windows shortcuts 86 | *.lnk 87 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "screeps-typescript-starter-zh_cn", 3 | "private": true, 4 | "scripts": { 5 | "lint": "eslint \"src/**/*.ts\"", 6 | "build": "rollup -c", 7 | "push-main": "rollup -c --environment DEST:main", 8 | "push-pserver": "rollup -c --environment DEST:pserver", 9 | "push-season": "rollup -c --environment DEST:season", 10 | "push-sim": "rollup -c --environment DEST:sim", 11 | "watch-main": "rollup -cw --environment DEST:main", 12 | "watch-pserver": "rollup -cw --environment DEST:pserver", 13 | "watch-season": "rollup -cw --environment DEST:season", 14 | "watch-sim": "rollup -cw --environment DEST:sim" 15 | }, 16 | "devDependencies": { 17 | "@rollup/plugin-commonjs": "^17.0.0", 18 | "@rollup/plugin-node-resolve": "^11.0.0", 19 | "@screepscn/types": "^1.0.0", 20 | "@types/lodash": "3.10.2", 21 | "@types/node": "^14.14.10", 22 | "@typescript-eslint/eslint-plugin": "^4.9.1", 23 | "@typescript-eslint/parser": "^4.9.1", 24 | "@typescript-eslint/typescript-estree": "^4.9.1", 25 | "eslint": "^7.15.0", 26 | "eslint-config-prettier": "^7.0.0", 27 | "eslint-import-resolver-typescript": "^2.0.0", 28 | "eslint-plugin-prettier": "^3.2.0", 29 | "prettier": "^2.2.1", 30 | "rollup": "^2.34.2", 31 | "rollup-plugin-clear": "^2.0.7", 32 | "rollup-plugin-screeps": "^1.0.0", 33 | "rollup-plugin-typescript2": "^0.29.0", 34 | "typescript": "^4.1.2" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 使用 Typescript 开发 Screeps 2 | 3 | 本项目是 [Screeps Typescript Starter](https://github.com/screepers/screeps-typescript-starter) 的简体中文版。基于此项目你可以快速地使用 Typescript 开发属于自己的 Screeps AI 程序。 4 | 5 | ## 使用 6 | 7 | 前置需求 8 | 9 | - [Node.js](https://nodejs.org/zh-cn/) 10.x 版本。目前 Node.js 最新 LTS 版为 14.x,但是和 Screeps 不兼容,所以推荐使用 Screeps 官方推荐的 10.x 版本。 10 | - 包管理工具 ([Yarn](https://yarnpkg.com/en/docs/getting-started) 或者 [npm](https://docs.npmjs.com/getting-started/installing-node)) 11 | 12 | 使用 git 克隆本仓库: 13 | 14 | ```shell 15 | git clone https://github.com/justjavac/screeps-typescript-starter-zh_CN 16 | ``` 17 | 18 | 或者直接[下载](https://github.com/justjavac/screeps-typescript-starter-zh_CN/archive/master.zip)。 19 | 20 | 打开终端运行: 21 | 22 | ```bash 23 | # npm 24 | npm install 25 | 26 | # 或者 yarn 27 | yarn 28 | ``` 29 | 30 | 如果没报错,那么你就可以打开 src 目录进行开发了。 31 | 32 | ### 部署 33 | 34 | Screeps Typescript Starter 使用 rollup 编译打包 typescript 文件,然后上传到 screeps 服务器。 35 | 36 | 将 `screeps.sample.json` 改名为 `screeps.json`,根据自己的服务器信息进行配置和修改。配置文件中包含了 3 个官服以及我自己搭建的私服 。 37 | 38 | ## 类型定义文件 39 | 40 | 本项目所用到的类型定义文件来自 [typed-screeps-zh_CN](https://github.com/justjavac/typed-screeps-zh_CN)。如果开发过程中发现了不能正确提示的地方,可以提 issue 或者 pr。 41 | 42 | ## 注意事项 43 | 44 | **重要:**请不要升级 `@types/lodash`,因为 screeps 内置了 lodash@3.x 版本,因此请不要将 `@types/lodash` 升级到最新的 4.x 版本,以免引起兼容性问题。 45 | 46 | ## 许可证 47 | 48 | 本项目 [screeps-typescript-starter-zh_CN](https://github.com/justjavac/screeps-typescript-starter-zh_CN) 基于 [Unlicense License](./LICENSE) 发行到公共领域。 49 | -------------------------------------------------------------------------------- /src/building.ts: -------------------------------------------------------------------------------- 1 | function getRandomFreePos(startPos: RoomPosition, distance: number) { 2 | let x: number; 3 | let y: number; 4 | 5 | do { 6 | x = startPos.x + Math.floor(Math.random() * (distance * 2 + 1)) - distance; 7 | y = startPos.y + Math.floor(Math.random() * (distance * 2 + 1)) - distance; 8 | } while ( 9 | (x + y) % 2 !== (startPos.x + startPos.y) % 2 || 10 | Game.map.getRoomTerrain(startPos.roomName).get(x, y) === TERRAIN_MASK_WALL 11 | ); 12 | return new RoomPosition(x, y, startPos.roomName); 13 | } 14 | 15 | function build(spawn: StructureSpawn, structureType: BuildableStructureConstant) { 16 | const structures = spawn.room.find(FIND_STRUCTURES, { filter: { structureType, my: true } }); 17 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 18 | for (let i = 0; i < CONTROLLER_STRUCTURES[structureType][spawn.room.controller!.level] - structures.length; i++) { 19 | getRandomFreePos(spawn.pos, 5).createConstructionSite(structureType); 20 | } 21 | } 22 | 23 | function calcBodyCost(body: BodyPartConstant[]): number { 24 | return _.reduce(body, (sum, part) => sum + BODYPART_COST[part], 0); 25 | } 26 | 27 | function run(spawn: StructureSpawn): void { 28 | build(spawn, STRUCTURE_EXTENSION); 29 | build(spawn, STRUCTURE_TOWER); 30 | 31 | let workerBody: BodyPartConstant[] = []; 32 | const bodyIteration = [MOVE, MOVE, WORK, CARRY]; 33 | while ( 34 | calcBodyCost(workerBody) + calcBodyCost(bodyIteration) <= Game.spawns.Spawn1.room.energyAvailable && 35 | workerBody.length + bodyIteration.length <= MAX_CREEP_SIZE 36 | ) { 37 | workerBody = workerBody.concat(bodyIteration); 38 | } 39 | 40 | spawn.spawnCreep(workerBody, `u1`, { memory: { role: "upgrader" } }); 41 | spawn.spawnCreep(workerBody, `u2`, { memory: { role: "upgrader" } }); 42 | if (spawn.room.find(FIND_CONSTRUCTION_SITES).length > 0) { 43 | spawn.spawnCreep(workerBody, `b1`, { memory: { role: "builder" } }); 44 | } 45 | spawn.spawnCreep(workerBody, `h1`, { memory: { role: "harvester" } }); 46 | spawn.spawnCreep(workerBody, `h2`, { memory: { role: "harvester" } }); 47 | } 48 | 49 | export { run }; 50 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es6: true, 5 | node: true 6 | }, 7 | extends: [ 8 | "eslint:recommended", 9 | "plugin:@typescript-eslint/recommended", 10 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 11 | "plugin:prettier/recommended", 12 | "prettier/@typescript-eslint", 13 | ], 14 | parser: "@typescript-eslint/parser", 15 | parserOptions: { 16 | project: "tsconfig.json", 17 | sourceType: "module" 18 | }, 19 | plugins: ["@typescript-eslint"], 20 | settings: { 21 | "import/parsers": { 22 | "@typescript-eslint/parser": [".ts", ".tsx"] 23 | }, 24 | "import/resolver": { 25 | typescript: {} 26 | } 27 | }, 28 | rules: { 29 | "@typescript-eslint/array-type": "error", 30 | "@typescript-eslint/restrict-plus-operands": "off", 31 | "@typescript-eslint/consistent-type-assertions": "error", 32 | "@typescript-eslint/consistent-type-definitions": "error", 33 | "@typescript-eslint/explicit-function-return-type": "off", 34 | "@typescript-eslint/explicit-member-accessibility": [ 35 | "error", 36 | { 37 | accessibility: "explicit" 38 | } 39 | ], 40 | "@typescript-eslint/no-explicit-any": "off", 41 | "@typescript-eslint/no-parameter-properties": "off", 42 | "@typescript-eslint/no-unused-expressions": "error", 43 | "@typescript-eslint/no-use-before-define": ["error", { functions: false }], 44 | "@typescript-eslint/prefer-for-of": "error", 45 | "@typescript-eslint/space-within-parens": ["off", "never"], 46 | "@typescript-eslint/unified-signatures": "error", 47 | "@typescript-eslint/no-for-in-array": "off", 48 | "arrow-parens": ["off", "as-needed"], 49 | camelcase: "error", 50 | complexity: "off", 51 | "dot-notation": "error", 52 | "eol-last": "off", 53 | eqeqeq: ["error", "smart"], 54 | "guard-for-in": "off", 55 | "id-blacklist": ["error", "any", "Number", "number", "String", "string", "Boolean", "boolean", "Undefined"], 56 | "id-match": "error", 57 | "linebreak-style": "off", 58 | "max-classes-per-file": ["error", 1], 59 | "new-parens": "off", 60 | "newline-per-chained-call": "off", 61 | "no-bitwise": "error", 62 | "no-caller": "error", 63 | "no-cond-assign": "error", 64 | "no-console": "off", 65 | "no-eval": "error", 66 | "no-invalid-this": "off", 67 | "no-multiple-empty-lines": "off", 68 | "no-new-wrappers": "error", 69 | "no-throw-literal": "error", 70 | "no-trailing-spaces": "off", 71 | "no-undef-init": "error", 72 | "no-underscore-dangle": "off", 73 | "no-var": "error", 74 | "object-shorthand": "error", 75 | "one-var": ["error", "never"], 76 | "quote-props": "off", 77 | radix: "error", 78 | "sort-imports": "warn", 79 | "spaced-comment": "error", 80 | }, 81 | "overrides": [ 82 | { 83 | "files": ["types/**"], 84 | "rules": { 85 | "@typescript-eslint/no-empty-interface": "off", 86 | "camelcase": "off" 87 | } 88 | } 89 | ] 90 | }; 91 | --------------------------------------------------------------------------------