Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring #4

Merged
merged 2 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
54 changes: 0 additions & 54 deletions .github/workflows/docs.yml

This file was deleted.

46 changes: 20 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,34 @@
[![repo](https://custom-icon-badges.demolab.com/badge/repo-dodgerblue.svg?logo=repo)](https://github.com/admon84/screeps-autonomous-framework)
[![docs](https://custom-icon-badges.demolab.com/badge/docs-seagreen.svg?logo=book)](https://admon84.github.io/screeps-autonomous-framework/)

## Screeps Autonomous Framework

Welcome to the Screeps Autonomous Framework. This framework is a structured starting point for developing your own bot for Screeps World, a strategy game for programmers.

### **Key Features**

- **Solid Foundation:** A well-organized base for you to focus on innovation.
- **Developer Friendly:** Clear and thoughtful design patterns for straightforward and error-free development.
- **Educational:** A learning tool for understanding autonomous bot creation, regardless of your Screeps experience level.
- **Flexible & Customizable:** Adaptable design allowing for extensive customization to meet your specific needs.
Screeps Autonomous Framework is a starter kit for developing your own Screeps bot with TypeScript.

## **Get Started**
Begin your Screeps bot development journey with this minimal, well-structured framework, offering a solid foundation for you to innovate and implement your unique strategies.

Leverage the Screeps Autonomous Framework as your launchpad for bot development. Customize it to create an advanced bot that aligns with your objectives.
## Get Started

### **Requirements**
### Prerequisites

- [Node.js](https://nodejs.org/en/download) (LTS recommended)
Make sure you have [Node.js](https://nodejs.org/en/download) (LTS) installed on your system.

### **Installation**
### Install

1. Clone the source code or download and extract it to your preferred directory.
2. Navigate to the project folder using your terminal.
3. Run `npm i` or `yarn` to install the dependencies.
1. Clone the source code or download and extract it.
2. Navigate to the project folder in your terminal.
3. Run `npm install` to install dependencies.

### **Rollup and Code Upload**
### Compile and Upload

The Screeps Autonomous Framework employs Rollup for compiling your TypeScript code and uploading it to a Screeps server.
Use the NPM scripts as aliases for Rollup commands to simplify the build and upload process.

1. Rename `screeps.sample.json` to `screeps.json` and update it with your Screeps credentials. Modify the destinations as needed to suit your requirements.
2. Utilize the NPM scripts in `package.json` as aliases for Rollup commands; for instance, `npm run push-main` will build and upload using the "main" destination in your `screeps.json` file.
1. Configure your Screeps server destinations.
- Rename `screeps.sample.json` to `screeps.json`.
- Update `screeps.json` with your Screeps credentials.
2. Use the NPM scripts in `package.json` as aliases for Rollup commands.
- `npm run build` will compile but not upload.
- `npm run push-main` will compile and upload to the "main" destination in `screeps.json`.

**Note:** For uploading code to a private server, [screepsmod-auth](https://github.com/ScreepsMods/screepsmod-auth) must be installed and configured properly.
**Note:** For uploading code to a private server, you must create your username and password on the server with the help of [screepsmod-auth](https://github.com/ScreepsMods/screepsmod-auth).

## **Acknowledgments**
## Kudos

Special thanks to Kasami for inspiring this project and openly sharing his innovative work on KasamiBot!
Special thanks to @kasami for inspiring this project with the original KasamiBot.
46 changes: 23 additions & 23 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,52 +1,52 @@
{
"name": "screeps-autonomous-framework",
"version": "1.0.0",
"description": "Screeps World Autonomous Bot Base Framework",
"description": "Screeps World Autonomous Bot Framework Base",
"homepage": "https://admon84.github.io/screeps-autonomous-framework/",
"repository": "github:admon84/screeps-autonomous-framework",
"bugs": "https://github.com/admon84/screeps-autonomous-framework/issues",
"main": "src/main.ts",
"scripts": {
"lint": "eslint \"src/**/*.ts\" --fix",
"lint": "eslint src --ext .ts",
"lint-fix": "npm run lint -- --fix",
"prettier": "prettier src --write",
"build": "rollup -c",
"build:docs": "typedoc",
"push-main": "rollup -c --environment DEST:main",
"push-pserver": "rollup -c --environment DEST:pserver",
"push-season": "rollup -c --environment DEST:season",
"push-pserver": "rollup -c --environment DEST:pserver",
"push-screeps": "rollup -c --environment DEST:screeps",
"push-sim": "rollup -c --environment DEST:sim",
"watch-main": "rollup -cw --environment DEST:main",
"watch-pserver": "rollup -cw --environment DEST:pserver",
"watch-season": "rollup -cw --environment DEST:season",
"watch-sim": "rollup -cw --environment DEST:sim"
},
"author": "admon84",
"license": "Unlicense",
"devDependencies": {
"@rollup/plugin-commonjs": "^25.0.5",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"@types/lodash": "3.10.x",
"@types/node": "^20.8.5",
"@types/screeps": "^3.3.4",
"@typescript-eslint/eslint-plugin": "^6.7.5",
"@typescript-eslint/parser": "^6.7.5",
"@typescript-eslint/typescript-estree": "^6.7.5",
"eslint": "^8.51.0",
"eslint-config-prettier": "^9.0.0",
"@types/node": "^20.10.7",
"@types/screeps": "^3.3.7",
"@typescript-eslint/eslint-plugin": "^6.18.0",
"@typescript-eslint/parser": "^6.18.0",
"@typescript-eslint/typescript-estree": "^6.18.0",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-prettier": "^5.0.1",
"prettier": "^3.0.3",
"prettier-plugin-organize-imports": "^3.2.3",
"rollup": "~2.79.1",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.2",
"prettier": "^3.1.1",
"prettier-plugin-organize-imports": "^3.2.4",
"rollup": "2.79.1",
"rollup-plugin-clear": "^2.0.7",
"rollup-plugin-delete": "^2.0.0",
"rollup-plugin-screeps-world": "^1.0.4",
"rollup-plugin-typescript2": "^0.36.0",
"tsconfig-paths": "^4.2.0",
"typedoc": "^0.25.2",
"typedoc": "^0.25.6",
"typedoc-plugin-missing-exports": "^2.1.0",
"typescript": "^5.2.2"
"typescript": "^5.3.3"
},
"dependencies": {
"source-map": "~0.6.1"
"source-map": "0.6.1"
}
}
15 changes: 7 additions & 8 deletions rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import fs from 'fs';
import clear from 'rollup-plugin-clear';
import del from 'rollup-plugin-delete';
import screeps from 'rollup-plugin-screeps-world';
import typescript from 'rollup-plugin-typescript2';

let config;
const dest = process.env.DEST;
if (!dest) {
console.log('No destination specified - code will be compiled but not uploaded');
} else if ((config = JSON.parse(fs.readFileSync('./screeps.json'))[dest]) == null) {
throw new Error('Invalid upload destination');
const { DEST } = process.env;
if (!DEST) {
console.log('Compiling Screeps Autonomous Framework...');
} else if (!(config = JSON.parse(fs.readFileSync('./screeps.json'))[DEST])) {
throw new Error(`Upload destination "${DEST}" not found in screeps.json`);
}

export default {
Expand All @@ -22,9 +22,8 @@ export default {
format: 'cjs',
sourcemap: true
},

plugins: [
clear({ targets: ['dist'] }),
del({ targets: 'dist/*' }),
resolve({ rootDir: 'src' }),
commonjs(),
typescript({ tsconfig: './tsconfig.json' }),
Expand Down
39 changes: 23 additions & 16 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { TowerManager } from 'managers/tower';
import { UpgradeManager } from 'managers/upgrade';
import { CreepService } from 'services/creep';
import { RoomService } from 'services/room';
import { ErrorMapper } from 'utils/errorMapper';
import { ErrorMapper, USE_ERROR_MAPPER } from 'utils/errorMapper';
import { alert, setLogLevel, warning } from 'utils/log';

/**
Expand All @@ -23,18 +23,23 @@ import { alert, setLogLevel, warning } from 'utils/log';
*/
alert('✨=== Global Reset ===✨');

/**
* Wrap the main loop with the error mapper if enabled.
*/
const loopWrapper = USE_ERROR_MAPPER ? ErrorMapper.wrapLoop.bind(ErrorMapper) : (f: () => void) => f();

/**
* The main loop is the entry point for the bot.
* @see https://docs.screeps.com/game-loop.html
*/
export const loop = ErrorMapper.wrapLoop(() => {
export const loop = loopWrapper(() => {
initSettings();

const creepService = new CreepService();
const roomService = new RoomService();

const cpuLimit = getCpuLimit();
const managerList = [

const taskManagers = [
new MemoryManager(),
new TowerManager(roomService),
new HarvestManager(roomService, creepService),
Expand All @@ -45,15 +50,15 @@ export const loop = ErrorMapper.wrapLoop(() => {

const priorityList = [Priority.Critical, Priority.Important, Priority.Standard, Priority.Low, Priority.Trivial];
for (const priority of priorityList) {
for (const manager of managerList) {
for (const manager of taskManagers) {
if (priority === Priority.Critical || Game.cpu.getUsed() < cpuLimit) {
manager.run(priority);
}
}
}

if (Game.cpu.bucket > 9500) {
for (const manager of managerList) {
for (const manager of taskManagers) {
if (Game.cpu.getUsed() < cpuLimit) {
manager.run(Priority.Overflow);
}
Expand All @@ -64,7 +69,7 @@ export const loop = ErrorMapper.wrapLoop(() => {
});

/**
* Initialize bot settings memory.
* Initialize bot settings in memory.
*/
function initSettings() {
if (!Memory.settings) {
Expand Down Expand Up @@ -94,14 +99,16 @@ function getUserNameOnSpawn() {
*/
function getCpuLimit() {
const { bucket, limit } = Game.cpu;
if (!limit) return 500; // Simulation mode
if (bucket > 9500) return limit * 1.6;
if (bucket > 9000) return limit * 1.3;
if (bucket > 8000) return limit * 1.1;
if (bucket > 5000) return limit;
if (bucket > 4000) return limit * 0.9;
if (bucket > 3000) return limit * 0.8;
if (bucket > 2000) return limit * 0.7;
if (bucket > 1000) return limit * 0.6;
if (!limit) return 500; // Sim room

const multipliers = [1.5, 1.3, 1.1, 1, 0.9, 0.8, 0.7, 0.6, 0.5];
const thresholds = [9500, 9000, 8000, 5000, 4000, 3000, 2000, 1000];

for (let i = 0; i < thresholds.length; i++) {
if (bucket > thresholds[i]) {
return limit * multipliers[i];
}
}

return limit * 0.5;
}
3 changes: 1 addition & 2 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { RoomType } from 'enums/roomType';

declare global {
/**
* Imported Lodash types.
* @hidden
* Lodash types.
*/
const _: typeof _;

Expand Down
17 changes: 17 additions & 0 deletions src/utils/errorMapper.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
import { SourceMapConsumer } from 'source-map';
import * as log from './log';

/**
* Set to `true` to enable error mapping.
*/
export const USE_ERROR_MAPPER = true;

/**
* ErrorMapper
*
* This error mapper is designed to wrap the main `loop` function in a try/catch block
* and provide stack traces which are mapped to your source code via source maps.
*
* This allows you to see the original source code when an error occurs, rather than
* the compiled code, making debugging much nicer.
*
* This does however come with a CPU cost, especially on the first call after a reset,
* so you can disable this feature by setting `USE_ERROR_MAPPER` to `false` if needed.
*/
export class ErrorMapper {
// Cache consumer
private static _consumer?: SourceMapConsumer;
Expand Down
15 changes: 4 additions & 11 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,14 @@
"lib": ["es2018"],
"target": "es2018",
"moduleResolution": "node10",
"outDir": "dist",
"baseUrl": "src/",
"outDir": "./dist/",
"baseUrl": "./src/",
"sourceMap": true,
"strict": true,
"strictPropertyInitialization": false,
"allowSyntheticDefaultImports": true,
"typeRoots": ["./node_modules/@types"]
},
"exclude": ["node_modules"],
"include": ["src/**/*"],
"typedocOptions": {
"entryPointStrategy": "expand",
"entryPoints": ["src/"],
"excludeExternals": true,
"plugin": ["typedoc-plugin-missing-exports"],
"out": "docs"
}
"include": ["./src/"],
"exclude": ["node_modules"]
}