├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .editorconfig ├── .eslintrc.js ├── .gitattributes ├── .gitignore ├── .prettierrc ├── .vscode ├── extensions.json └── settings.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── book.json ├── docs ├── .gitbook │ └── assets │ │ ├── authenticating-1.png │ │ ├── authenticating-2.png │ │ ├── authenticating-3.png │ │ ├── authenticating-4.png │ │ ├── deploying-2.png │ │ └── remote-container.png ├── README.md ├── SUMMARY.md ├── getting-started │ ├── authenticating.md │ ├── deploying.md │ ├── img │ │ ├── authenticating-1.png │ │ ├── authenticating-2.png │ │ ├── authenticating-3.png │ │ ├── authenticating-4.png │ │ ├── deploying-1.png │ │ └── deploying-2.png │ └── installation.md └── in-depth │ ├── contributing.md │ ├── cookbook │ ├── README.md │ ├── environment-variables.md │ └── one-line-powershell.md │ ├── deploy-destinations.md │ ├── module-bundling.md │ ├── prettier.md │ ├── remote-development.md │ ├── testing.md │ ├── troubleshooting.md │ └── typescript.md ├── package.json ├── rollup.config.js ├── screeps.sample.json ├── src ├── main.ts └── utils │ └── ErrorMapper.ts ├── test ├── integration │ ├── helper.ts │ └── integration.test.ts ├── mocha.opts ├── setup-mocha.js └── unit │ ├── main.test.ts │ └── mock.ts ├── tsconfig.json └── tsconfig.test.json /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:12-alpine 2 | 3 | RUN apk add --update --no-cache git ca-certificates openssl openssh 4 | RUN npm install -g rollup 5 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.166.0/containers/docker-existing-dockerfile 3 | { 4 | "name": "Screeps-TypeScript-Starter", 5 | 6 | // Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename. 7 | "dockerFile": "Dockerfile", 8 | 9 | // Set *default* container specific settings.json values on container create. 10 | "settings": { 11 | "terminal.integrated.shell.linux": null 12 | }, 13 | 14 | // Add the IDs of extensions you want installed when the container is created. 15 | "extensions": [] 16 | 17 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 18 | // "forwardPorts": [], 19 | 20 | // Uncomment the next line to run commands after the container is created - for example installing curl. 21 | // "postCreateCommand": "apt-get update && apt-get install -y curl", 22 | 23 | // Uncomment when using a ptrace-based debugger like C++, Go, and Rust 24 | // "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ], 25 | 26 | // Uncomment to use the Docker CLI from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker. 27 | // "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ], 28 | 29 | // Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root. 30 | // "remoteUser": "vscode" 31 | } 32 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 2 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.py] 13 | indent_style = space 14 | indent_size = 4 15 | 16 | [*.rb] 17 | indent_style = space 18 | indent_size = 4 19 | -------------------------------------------------------------------------------- /.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 | "plugin:import/errors", 14 | "plugin:import/warnings", 15 | "plugin:import/typescript" 16 | ], 17 | parser: "@typescript-eslint/parser", 18 | parserOptions: { 19 | project: "tsconfig.json", 20 | sourceType: "module" 21 | }, 22 | plugins: ["@typescript-eslint", "import"], 23 | settings: { 24 | "import/parsers": { 25 | "@typescript-eslint/parser": [".ts", ".tsx"] 26 | }, 27 | "import/resolver": { 28 | typescript: {} 29 | } 30 | }, 31 | rules: { 32 | "@typescript-eslint/array-type": "error", 33 | "@typescript-eslint/consistent-type-assertions": "error", 34 | "@typescript-eslint/consistent-type-definitions": "error", 35 | "@typescript-eslint/explicit-function-return-type": "off", 36 | "@typescript-eslint/explicit-member-accessibility": [ 37 | "error", 38 | { 39 | accessibility: "explicit" 40 | } 41 | ], 42 | "@typescript-eslint/no-explicit-any": "off", 43 | "@typescript-eslint/no-parameter-properties": "off", 44 | "@typescript-eslint/no-shadow": [ 45 | "error", 46 | { 47 | hoist: "all" 48 | } 49 | ], 50 | "@typescript-eslint/no-unused-expressions": "error", 51 | "@typescript-eslint/no-use-before-define": ["error", { functions: false }], 52 | "@typescript-eslint/prefer-for-of": "error", 53 | "@typescript-eslint/space-within-parens": ["off", "never"], 54 | "@typescript-eslint/unified-signatures": "error", 55 | "arrow-parens": ["off", "as-needed"], 56 | camelcase: "error", 57 | complexity: "off", 58 | "dot-notation": "error", 59 | "eol-last": "off", 60 | eqeqeq: ["error", "smart"], 61 | "guard-for-in": "off", 62 | "id-blacklist": ["error", "any", "Number", "number", "String", "string", "Boolean", "boolean", "Undefined"], 63 | "id-match": "error", 64 | "linebreak-style": "off", 65 | "max-classes-per-file": ["error", 1], 66 | "new-parens": "off", 67 | "newline-per-chained-call": "off", 68 | "no-bitwise": "error", 69 | "no-caller": "error", 70 | "no-cond-assign": "error", 71 | "no-console": "off", 72 | "no-eval": "error", 73 | "no-invalid-this": "off", 74 | "no-multiple-empty-lines": "off", 75 | "no-new-wrappers": "error", 76 | "no-shadow": "off", 77 | "no-throw-literal": "error", 78 | "no-trailing-spaces": "off", 79 | "no-undef-init": "error", 80 | "no-underscore-dangle": "warn", 81 | "no-var": "error", 82 | "object-shorthand": "error", 83 | "one-var": ["error", "never"], 84 | "quote-props": "off", 85 | radix: "error", 86 | "sort-imports": "warn", 87 | "spaced-comment": "error", 88 | } 89 | }; 90 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # yarn lock file 2 | /yarn.lock 3 | 4 | # npm lock file (v5.0.0+) 5 | /package-lock.json 6 | 7 | # Ignore basic folders 8 | /dist 9 | /.rpt2_cache 10 | /tsc-out 11 | /node_modules 12 | /_book 13 | /build/* 14 | 15 | # TypeScript definitions installed by Typings 16 | /typings 17 | 18 | # Screeps Config 19 | screeps.json 20 | 21 | # ScreepsServer data from integration tests 22 | /server 23 | 24 | # Numerous always-ignore extensions 25 | *.diff 26 | *.err 27 | *.orig 28 | *.log 29 | *.rej 30 | *.swo 31 | *.swp 32 | *.zip 33 | *.vi 34 | *~ 35 | 36 | # Editor folders 37 | .cache 38 | .project 39 | .settings 40 | .tmproj 41 | *.esproj 42 | nbproject 43 | *.sublime-project 44 | *.sublime-workspace 45 | .idea 46 | 47 | # ========================= 48 | # Operating System Files 49 | # ========================= 50 | 51 | # OSX 52 | # ========================= 53 | 54 | .DS_Store 55 | .AppleDouble 56 | .LSOverride 57 | 58 | # Thumbnails 59 | ._* 60 | 61 | # Files that might appear on external disk 62 | .Spotlight-V100 63 | .Trashes 64 | 65 | # Directories potentially created on remote AFP share 66 | .AppleDB 67 | .AppleDesktop 68 | Network Trash Folder 69 | Temporary Items 70 | .apdisk 71 | 72 | # Windows 73 | # ========================= 74 | 75 | # Windows image file caches 76 | Thumbs.db 77 | ehthumbs.db 78 | 79 | # Folder config file 80 | Desktop.ini 81 | 82 | # Recycle Bin used on file shares 83 | $RECYCLE.BIN/ 84 | 85 | # Windows Installer files 86 | *.cab 87 | *.msi 88 | *.msm 89 | *.msp 90 | 91 | # Windows shortcuts 92 | *.lnk 93 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "ms-vscode-remote.vscode-remote-extensionpack" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.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 | "eslint.enable": true 28 | } 29 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing guidelines 2 | 3 | This document outlines guides to get started on developing the starter kit. 4 | 5 | ## Contributing to the docs 6 | 7 | Contributions to the docs are also welcome! We've documented the steps to do so [here](./docs/in-depth/contributing.md). 8 | 9 | ## The Five Golden Rules 10 | 11 | The simple steps of contributing to any GitHub project are as follows: 12 | 13 | 1. [Fork the repository](https://github.com/screepers/screeps-typescript-starter/fork) 14 | 2. Create your feature branch: `git checkout -b my-new-feature` 15 | 3. Commit your changes: `git commit -am 'Add some feature'` 16 | 4. Push to the branch: `git push -u origin my-new-feature` 17 | 5. Create a [Pull Request](https://github.com/screepers/screeps-typescript-starter/pulls)! 18 | 19 | To keep your fork of in sync with this repository, [follow this guide](https://help.github.com/articles/syncing-a-fork/). 20 | 21 | ## Submitting a pull request 22 | 23 | We accept almost all pull requests, as long as the following criterias are met: 24 | 25 | * Your code must pass all of the linter checks (`npm run lint`) 26 | * When adding a new feature, make sure it doesn't increase the complexity of the tooling. We want this starter kit to be approachable to folks who have little to no knowledge of TypeScript, or even JavaScript. 27 | * When making changes that are potentially breaking, careful discussion must be done with the community at large. Generally we do this either on the [#typescript](https://screeps.slack.com/messages/typecript/) channel on the Screeps Slack, or on the corresponding pull request discussion thread. 28 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Screeps Typescript Starter 2 | 3 | Screeps Typescript Starter is a starting point for a Screeps AI written in Typescript. It provides everything you need to start writing your AI whilst leaving `main.ts` as empty as possible. 4 | 5 | ## Basic Usage 6 | 7 | You will need: 8 | 9 | - [Node.JS](https://nodejs.org/en/download) (10.x || 12.x) 10 | - A Package Manager ([Yarn](https://yarnpkg.com/en/docs/getting-started) or [npm](https://docs.npmjs.com/getting-started/installing-node)) 11 | - Rollup CLI (Optional, install via `npm install -g rollup`) 12 | 13 | Download the latest source [here](https://github.com/screepers/screeps-typescript-starter/archive/master.zip) and extract it to a folder. 14 | 15 | Open the folder in your terminal and run your package manager to install the required packages and TypeScript declaration files: 16 | 17 | ```bash 18 | # npm 19 | npm install 20 | 21 | # yarn 22 | yarn 23 | ``` 24 | 25 | Fire up your preferred editor with typescript installed and you are good to go! 26 | 27 | ### Rollup and code upload 28 | 29 | Screeps Typescript Starter uses rollup to compile your typescript and upload it to a screeps server. 30 | 31 | Move or copy `screeps.sample.json` to `screeps.json` and edit it, changing the credentials and optionally adding or removing some of the destinations. 32 | 33 | Running `rollup -c` will compile your code and do a "dry run", preparing the code for upload but not actually pushing it. Running `rollup -c --environment DEST:main` will compile your code, and then upload it to a screeps server using the `main` config from `screeps.json`. 34 | 35 | You can use `-cw` instead of `-c` to automatically re-run when your source code changes - for example, `rollup -cw --environment DEST:main` will automatically upload your code to the `main` configuration every time your code is changed. 36 | 37 | Finally, there are also NPM scripts that serve as aliases for these commands in `package.json` for IDE integration. Running `npm run push-main` is equivalent to `rollup -c --environment DEST:main`, and `npm run watch-sim` is equivalent to `rollup -cw --dest sim`. 38 | 39 | #### Important! To upload code to a private server, you must have [screepsmod-auth](https://github.com/ScreepsMods/screepsmod-auth) installed and configured! 40 | 41 | ## Typings 42 | 43 | The type definitions for Screeps come from [typed-screeps](https://github.com/screepers/typed-screeps). If you find a problem or have a suggestion, please open an issue there. 44 | 45 | ## Documentation 46 | 47 | We've also spent some time reworking the documentation from the ground-up, which is now generated through [Gitbooks](https://www.gitbook.com/). Includes all the essentials to get you up and running with Screeps AI development in TypeScript, as well as various other tips and tricks to further improve your development workflow. 48 | 49 | Maintaining the docs will also become a more community-focused effort, which means you too, can take part in improving the docs for this starter kit. 50 | 51 | To visit the docs, [click here](https://screepers.gitbook.io/screeps-typescript-starter/). 52 | 53 | ## Contributing 54 | 55 | Issues, Pull Requests, and contribution to the docs are welcome! See our [Contributing Guidelines](CONTRIBUTING.md) for more details. 56 | -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Screeps Typescript Starter", 3 | "description": "Starter kit for TypeScript-based Screeps AI codes.", 4 | "root": "./docs" 5 | } 6 | -------------------------------------------------------------------------------- /docs/.gitbook/assets/authenticating-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/screepers/screeps-typescript-starter/cd90f22c1da5928d562c510f0406ffb98a9e312b/docs/.gitbook/assets/authenticating-1.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/authenticating-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/screepers/screeps-typescript-starter/cd90f22c1da5928d562c510f0406ffb98a9e312b/docs/.gitbook/assets/authenticating-2.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/authenticating-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/screepers/screeps-typescript-starter/cd90f22c1da5928d562c510f0406ffb98a9e312b/docs/.gitbook/assets/authenticating-3.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/authenticating-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/screepers/screeps-typescript-starter/cd90f22c1da5928d562c510f0406ffb98a9e312b/docs/.gitbook/assets/authenticating-4.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/deploying-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/screepers/screeps-typescript-starter/cd90f22c1da5928d562c510f0406ffb98a9e312b/docs/.gitbook/assets/deploying-2.png -------------------------------------------------------------------------------- /docs/.gitbook/assets/remote-container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/screepers/screeps-typescript-starter/cd90f22c1da5928d562c510f0406ffb98a9e312b/docs/.gitbook/assets/remote-container.png -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Screeps Typescript Starter is a starting point for a Screeps AI written in [Typescript](http://www.typescriptlang.org/). It provides everything you need to start writing your AI whilst leaving `main.ts` as empty as possible. 4 | 5 | [View on GitHub](https://github.com/screepers/screeps-typescript-starter) 6 | 7 | ## What's new \(v3.0\) 8 | 9 | ### Simpler setup! 10 | 11 | Over the past few months, we've felt that the TypeScript starter needed a lot of work. We were starting to realise that it had become too opinionated and was making too many decisions regarding AI design. 12 | 13 | The new version does away with all this and only provides only the code and tools necessary to base your TypeScript AI off of. This means you'll spend far less time configuring the starter kit, and more time actually writing your code. 14 | 15 | ### Rollup! 16 | 17 | We have swapped the bundler from Webpack to [Rollup](https://rollupjs.org/). Rollup is easier to configure and can be set up to do everything needed for Screeps. It also comes with various improvements over Webpack, which you can learn more about [here](in-depth/module-bundling.md). 18 | 19 | ### Better docs! 20 | 21 | We've also spent some time reworking the documentation from the ground-up, which is now generated through [Gitbooks](https://www.gitbook.com/). Includes all the essentials to get you up and running with Screeps AI development in TypeScript, as well as various other tips and tricks to further improve your development workflow. 22 | 23 | Maintaining the docs will also become a more community-focused effort, which means you too, can take part in improving the docs for this starter kit. 24 | 25 | ## Download 26 | 27 | Download the latest source [here](https://github.com/screepers/screeps-typescript-starter/archive/master.zip), or clone this repo. 28 | 29 | ```bash 30 | git clone https://github.com/screepers/screeps-typescript-starter.git 31 | ``` 32 | 33 | Extract it to a folder, and [let's get started](getting-started/installation.md)! 34 | 35 | -------------------------------------------------------------------------------- /docs/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | - [Introduction](README.md) 4 | 5 | ## Getting Started 6 | 7 | - [Installation](getting-started/installation.md) 8 | - [Authenticating with Screeps](getting-started/authenticating.md) 9 | - [Deploying](getting-started/deploying.md) 10 | 11 | ## In-Depth 12 | 13 | - [Module bundling](in-depth/module-bundling.md) 14 | - [Deploy destinations](in-depth/deploy-destinations.md) 15 | - [TypeScript](in-depth/typescript.md) 16 | - [Prettier](in-depth/prettier.md) 17 | - [Testing](in-depth/testing.md) 18 | - [Cookbook](in-depth/cookbook/README.md) 19 | - [Environment variables](in-depth/cookbook/environment-variables.md) 20 | - [One-line PowerShell setup](in-depth/cookbook/one-line-powershell.md) 21 | - [Remote Development](in-depth/remote-development.md) 22 | - [Troubleshooting](in-depth/troubleshooting.md) 23 | - [Contributing to the docs](in-depth/contributing.md) 24 | -------------------------------------------------------------------------------- /docs/getting-started/authenticating.md: -------------------------------------------------------------------------------- 1 | # Authenticating with Screeps 2 | 3 | Screeps has recently introduced a [token-based auth system](http://blog.screeps.com/2017/12/auth-tokens/), and the old authentication system will be deprecated by 01 February 2018. The starter kit has been updated to support this new authentication process. 4 | 5 | ## Migrating to the new auth system 6 | 7 | If you have an existing copy of your starter kit, follow these steps: 8 | 9 | * Remove the `"username"` and `"password"` keys from your `screeps.json` file, and replace them with `"token"`. 10 | * Upgrade `rollup-plugin-screeps` to version 0.1.1. 11 | * Follow the authentication steps as defined below. 12 | 13 | ## Setting up Screeps authentication 14 | 15 | The authentication token is pulled by the starter kit from a file named `screeps.json`. A sample config file \(`screeps.sample.json`\) is provided within the project, to use it, simply make a copy and rename it to `screeps.json`. 16 | 17 | ```bash 18 | cp screeps.sample.json screeps.json 19 | ``` 20 | 21 | {% hint style="danger" %} 22 | **IMPORTANT:** The `screeps.json` file contains your Screeps credentials! If you use any source control to store your codebase, **DO NOT** check in this file into your repository. 23 | {% endhint %} 24 | 25 | ## Generating an auth token 26 | 27 | To generate an authentication token, click **\[your username\] > Manage account**. You should see the **Auth tokens** in the options now, click it. 28 | 29 | ![authenticating-1](../.gitbook/assets/authenticating-1.png) 30 | 31 | On the next screen, we'll create a full access token. We pick the **Full access** option, then click the **Generate Token** button. 32 | 33 | ![authenticating-2](../.gitbook/assets/authenticating-2.png) 34 | 35 | Your generated token should now be shown on your screen. Copy it to your clipboard. 36 | 37 | ![authenticating-3](../.gitbook/assets/authenticating-3.png) 38 | 39 | > **Note:** This token will be displayed **only once**! Make sure to never lose it. However, if you did lose it, simply remove said token from your account, and create a new one. 40 | 41 | Now, paste it to your `screeps.json` file. 42 | 43 | ![authenticating-4](../.gitbook/assets/authenticating-4.png) 44 | 45 | ## Sanity check 46 | 47 | Now we'll do a quick check if things are running properly. Let's perform a quick deploy. 48 | 49 | ```bash 50 | npm run push-main 51 | ``` 52 | 53 | Now go to your Screeps client and check if the `main` branch is created, or if said branch already exists, the code is overwriten to it. 54 | 55 | It works? Good, you've successfully authenticated! 56 | 57 | Next up, we'll configure our environment and [run our first code deploy](deploying.md). 58 | 59 | -------------------------------------------------------------------------------- /docs/getting-started/deploying.md: -------------------------------------------------------------------------------- 1 | # Deploying 2 | 3 | ## Building your configuration file 4 | 5 | The starter kit builds your code using `rollup`, which uses a `screeps.json` file we built on the previous section as its configuration file. 6 | 7 | The `screeps.json` file is a JSON configuration file separated into multiple environments. We're going to focus on the `main` environment to get you started. If you'd like to deploy to a different branch, be sure to change the `branch` key to the branch you'd like to deploy to. 8 | 9 | {% hint style="info" %} 10 | You don't have to manually create the target branch in your Screeps client if it doesn't exist yet. `rollup-plugin-screeps` will do it for you. 11 | {% endhint %} 12 | 13 | ## Running your first deploy 14 | 15 | Once you're done, run the following command: 16 | 17 | ```bash 18 | npm run push-main 19 | ``` 20 | 21 | You're done! Now go to your Screeps client and make sure your code is deployed properly. 22 | 23 | ![deploying-2](../.gitbook/assets/deploying-2.png) 24 | 25 | ## Deploying to a private server 26 | 27 | Screeps also lets you run your own private server. This can be a great way to test your code in a safe environment, and you can add mods that allow you to customize your server as well, such as drastically increasing the tickrate. 28 | 29 | To find out more about how to use or run your own private server, see the official server repository [here](https://github.com/screeps/screeps). 30 | 31 | To deploy to a private server, run the following command: 32 | 33 | ```bash 34 | npm run push-pserver 35 | ``` 36 | 37 | If you are having trouble pushing your code, make sure to check your `screeps.json`. 38 | 39 | For `"pserver"` the json properties are a little confusing: 40 | 41 | - `"email"` should actually contain the username of your account on the private server you are trying to connect to, __which may be different from your account on the official Screeps shards!__ 42 | 43 | - `"password"` will need to be set for that account manually on the private server, [see here](https://github.com/screeps/screeps#authentication) 44 | 45 | - `"hostname"` is the IP address of the server. If you are hosting your own server locally, the default localhost IP for most networks is `127.0.0.1` 46 | 47 | Ready for something extra? [Read on.](../in-depth/module-bundling.md) 48 | 49 | -------------------------------------------------------------------------------- /docs/getting-started/img/authenticating-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/screepers/screeps-typescript-starter/cd90f22c1da5928d562c510f0406ffb98a9e312b/docs/getting-started/img/authenticating-1.png -------------------------------------------------------------------------------- /docs/getting-started/img/authenticating-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/screepers/screeps-typescript-starter/cd90f22c1da5928d562c510f0406ffb98a9e312b/docs/getting-started/img/authenticating-2.png -------------------------------------------------------------------------------- /docs/getting-started/img/authenticating-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/screepers/screeps-typescript-starter/cd90f22c1da5928d562c510f0406ffb98a9e312b/docs/getting-started/img/authenticating-3.png -------------------------------------------------------------------------------- /docs/getting-started/img/authenticating-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/screepers/screeps-typescript-starter/cd90f22c1da5928d562c510f0406ffb98a9e312b/docs/getting-started/img/authenticating-4.png -------------------------------------------------------------------------------- /docs/getting-started/img/deploying-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/screepers/screeps-typescript-starter/cd90f22c1da5928d562c510f0406ffb98a9e312b/docs/getting-started/img/deploying-1.png -------------------------------------------------------------------------------- /docs/getting-started/img/deploying-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/screepers/screeps-typescript-starter/cd90f22c1da5928d562c510f0406ffb98a9e312b/docs/getting-started/img/deploying-2.png -------------------------------------------------------------------------------- /docs/getting-started/installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | ## Requirements 4 | 5 | You will need: 6 | 7 | - [Node.JS](https://nodejs.org/en/download) (10.x || 12.x) 8 | - A Package Manager \([Yarn](https://yarnpkg.com/en/docs/getting-started) or [npm](https://docs.npmjs.com/getting-started/installing-node)\) 9 | - Rollup CLI \(Optional, install via `npm install -g rollup`\) 10 | 11 | ## Installing `npm` modules 12 | 13 | Open the folder in your terminal and run your package manager to install install the required packages and TypeScript declaration files: 14 | 15 | ```bash 16 | # npm 17 | npm install 18 | 19 | # yarn 20 | yarn 21 | ``` 22 | 23 | Once that's all done, let's [authenticate with the Screeps server](authenticating.md). 24 | -------------------------------------------------------------------------------- /docs/in-depth/contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to the docs 2 | 3 | We welcome contributions to the docs! We're looking for ways to make the starter kit documentation better, as well as many other tips and tricks about Screeps AI development in TypeScript. If you feel like some parts of the docs need fixing/improving, definitely create a pull request. 4 | 5 | For guidelines on contributing to the starter kit, [click here](https://github.com/screepers/screeps-typescript-starter/blob/master/CONTRIBUTING.md). 6 | 7 | ## Gitbook 8 | 9 | Our documentation is built using [Gitbook](https://www.gitbook.com/), and are accessible [here](https://screepers.gitbooks.io/screeps-typescript-starter/). You can also start working on the docs locally by installing the Gitbook CLI. 10 | 11 | ```bash 12 | npm install -g gitbook-cli 13 | ``` 14 | 15 | To run a local Gitbook server, run the following command on the project's root directory. 16 | 17 | ```bash 18 | gitbook serve 19 | ``` 20 | 21 | -------------------------------------------------------------------------------- /docs/in-depth/cookbook/README.md: -------------------------------------------------------------------------------- 1 | # Cookbook 2 | 3 | This section contains a community-maintained list of slightly more advanced tips and tricks to help better improve your Screeps AI development workflow with TypeScript. Feel free to [contribute your own](https://github.com/screepers/screeps-typescript-starter/tree/master/docs)! 4 | 5 | -------------------------------------------------------------------------------- /docs/in-depth/cookbook/environment-variables.md: -------------------------------------------------------------------------------- 1 | # Environment variables 2 | 3 | Environment variables provide a more streamlined way to manage your build process. We can also use it to define "build toggles", or environment-based variables that will be injected into your scripts to be used during runtime. 4 | 5 | ## Setting it up 6 | 7 | Let's say that we want to set `NODE_ENV` to `production` for uploading to our main branch, and `development` for uploading to our Simulation branch. First we'll catch the environment variable and assign the compile target based on it. 8 | 9 | ```javascript 10 | // rollup.config.js 11 | 12 | const isProduction = process.env.NODE_ENV === 'production' 13 | 14 | // use the `main` target from `screeps.json` in production mode 15 | const cfg = isProduction ? 'main' : 'sim'; 16 | 17 | export default { 18 | // ... 19 | plugins: [ 20 | // ... 21 | screeps({ 22 | config: require("./screeps")[cfg], 23 | // if `NODE_ENV` is local, perform a dry run 24 | dryRun: process.env.NODE_ENV === 'local' 25 | }) 26 | ] 27 | } 28 | ``` 29 | 30 | ## Running a deploy 31 | 32 | Then we'll change the build tasks on `package.json` to pass the environment variable before running the rollup command. 33 | 34 | ```javascript 35 | { 36 | "tasks": { 37 | "deploy-prod": "NODE_ENV=production rollup -c", 38 | "deploy-dev": "NODE_ENV=development rollup -c", 39 | } 40 | } 41 | ``` 42 | 43 | {% hint style="warning" %} 44 | On Windows, setting the environment variables as defined above will not work. For a cross-platform solution to define environment variables, use `cross-env`. 45 | {% endhint %} 46 | 47 | ```bash 48 | npm install --save-dev cross-env 49 | ``` 50 | 51 | ```javascript 52 | { 53 | "tasks": { 54 | "deploy-prod": "cross-env NODE_ENV=production rollup -c", 55 | "deploy-dev": "cross-env NODE_ENV=development rollup -c", 56 | } 57 | } 58 | ``` 59 | 60 | Now let's give it a try! Run `npm run deploy-dev` or `npm run deploy-prod` and see if your code is uploaded properly. 61 | 62 | ## Setting up build toggles 63 | 64 | You can also setup deployment-dependent variables \(aka. "build toggles"\) that are injected to your code during build time to allow for more advanced optimisations like dead code elimination. 65 | 66 | To do this, install `rollup-plugin-replace`. 67 | 68 | ```bash 69 | # npm 70 | $ npm install --save-dev rollup-plugin-replace 71 | 72 | # yarn 73 | $ yarn add --dev rollup-plugin-replace 74 | ``` 75 | 76 | Then configure your `rollup.config.js` to include your desired variables. 77 | 78 | ```javascript 79 | // rollup.config.js 80 | import replace from 'rollup-plugin-replace'; 81 | 82 | export default { 83 | plugins: [ 84 | replace({ 85 | // returns 'true' if code is bundled in prod mode 86 | PRODUCTION: JSON.stringify(isProduction), 87 | // you can also use this to include deploy-related data, such as 88 | // date + time of build, as well as latest commit ID from git 89 | __BUILD_TIME__: JSON.stringify(Date.now()), 90 | __REVISION__: JSON.stringify(require('git-rev-sync').short()), 91 | }) 92 | ] 93 | }; 94 | ``` 95 | 96 | {% hint style="info" %} 97 | Generally, you need to ensure that `rollup-plugin-replace` goes _before_ other plugins, so we can be sure Rollup replaces these variables correctly and the remaining plugins can apply any optimisations \(e.g. dead code elimination\) correctly. 98 | {% endhint %} 99 | 100 | {% hint style="warning" %} 101 | Because these values are evaluated once as a string \(for the find-and-replace\), and once as an expression, they need to be wrapped in `JSON.stringify`. 102 | {% endhint %} 103 | 104 | Variables set by this plugin will be replaced in the actual output JS code. When compiling your code, Rollup will replace the variable names with the output of the supplied expression or value. 105 | 106 | Once it's set up, you use it in your code. 107 | 108 | ```typescript 109 | // log the latest commit ID from git 110 | if (__REVISION__) { 111 | console.log(`Revision ID: ${__REVISION__}`) 112 | } 113 | 114 | export function loop() { 115 | if (!PRODUCTION) { 116 | // will only be included in development mode 117 | devLogger.log('loop started') 118 | } 119 | } 120 | ``` 121 | 122 | ### Notes 123 | 124 | Since TypeScript won't recognise these variables if you pass it blindly into your code, you will still need to declare them in a type definition \(.d.ts\) file. 125 | 126 | ```typescript 127 | // file.d.ts 128 | 129 | declare const __REVISION__: string; 130 | declare const __BUILD_TIME__: string; 131 | ``` 132 | 133 | Also, be careful not to use too common of a name, because it will replace it throughout your code without warning. A good standard is to make the variables all caps, and surrounded by double underscores, so they stand out \(e.g. `__REVISION__`\). 134 | 135 | -------------------------------------------------------------------------------- /docs/in-depth/cookbook/one-line-powershell.md: -------------------------------------------------------------------------------- 1 | # One-line PowerShell setup 2 | 3 | {% hint style="warning" %} 4 | **Note:** As of v3.0, this no longer works. This issue is being tracked [here](https://github.com/ChrisTaylorRocks/screeps-typescript-starter-setup/issues/1). 5 | {% endhint %} 6 | 7 | [@ChrisTaylorRocks](https://github.com/ChrisTaylorRocks) has made a PowerShell script to get the starter kit up and running with a single command. Go check it out [here](https://github.com/ChrisTaylorRocks/screeps-typescript-starter-setup)! 8 | 9 | ## Usage 10 | 11 | PowerShell < 5.0: 12 | 13 | ```text 14 | PS> (new-object Net.WebClient).DownloadString('http://bit.ly/2z2QDJI') | iex; New-ScreepsTypeScriptSetup 15 | ``` 16 | 17 | PowerShell 5.0+: 18 | 19 | ```text 20 | PS> curl http://bit.ly/2z2QDJI | iex; New-ScreepsTypeScriptSetup 21 | ``` 22 | 23 | -------------------------------------------------------------------------------- /docs/in-depth/deploy-destinations.md: -------------------------------------------------------------------------------- 1 | # Deploy destinations 2 | 3 | The `screeps.json` file is a JSON configuration file separated into multiple deploy destinations. We've given you four primary destinations by default. 4 | 5 | See [here](/docs/getting-started/authenticating.md) for steps to generate your API token. 6 | 7 | ```javascript 8 | { 9 | // Used for deploying to the main world 10 | "main": { 11 | "token": "YOUR_TOKEN", 12 | "protocol": "https", 13 | "hostname": "screeps.com", 14 | "port": 443, 15 | "path": "/", 16 | "branch": "main" 17 | }, 18 | // Used for deploying to Simulation mode 19 | "sim": { 20 | "token": "YOUR_TOKEN", 21 | "protocol": "https", 22 | "hostname": "screeps.com", 23 | "port": 443, 24 | "path": "/", 25 | "branch": "sim" 26 | }, 27 | // Used for deploying to Seasonal Event server 28 | "season": { 29 | "token": "YOUR_TOKEN", 30 | "protocol": "https", 31 | "hostname": "screeps.com", 32 | "port": 443, 33 | "path": "/season", 34 | "branch": "main" 35 | }, 36 | // Used for deploying to a private server 37 | "pserver": { 38 | "token": "YOUR_TOKEN", 39 | "protocol": "http", 40 | "hostname": "1.2.3.4", 41 | "port": 21025, 42 | "path": "/", 43 | "branch": "main" 44 | } 45 | } 46 | ``` 47 | 48 | You can make as many separate destinations as you want. Just make a copy of any config object and perform the necessary changes. Once you're done, use the `--environment DEST:` argument on the `rollup` command to specify which environment to upload to. 49 | 50 | ```bash 51 | rollup -c --environment DEST:main 52 | ``` 53 | 54 | Omitting the destination will perform a dry run, which will compile and bundle the code without uploading it. 55 | -------------------------------------------------------------------------------- /docs/in-depth/module-bundling.md: -------------------------------------------------------------------------------- 1 | # Module bundling 2 | 3 | Bundling your Screeps codebase using module bundlers like [Webpack](https://webpack.js.org/) or [Rollup](https://rollupjs.org/) allows you to improve your Screeps AI development workflow. 4 | 5 | For instance, it allows you to easily include third-party libraries, like [screeps-profiler](https://github.com/screepers/screeps-profiler). Instead of manually copy-pasting these libraries into your code, you can simply install it as an `npm` module: 6 | 7 | ```bash 8 | npm install screeps-profiler 9 | ``` 10 | 11 | Then you can import these libraries just like you would any other `npm` module. When you run the module bundler, it will bundle up all your files and third-party modules into one single JS file. 12 | 13 | Some module bundlers even support performing further optimisations like eliminating unused module functions from your final bundled code \(aka. _tree-shaking_\), reducing the size of your final bundled JS even further. 14 | 15 | ## Rollup 16 | 17 | From version 3.0 onwards, the starter kit uses Rollup as its main module bundler. Some useful features of Rollup include: 18 | 19 | * Bundled modules are entirely flat \(no weird boilerplate code emitted like in Webpack\) 20 | * Advanced tree-shaking \(eliminates unused modules from the final bundle\) 21 | * Simpler configuration \(compared to Webpack\) 22 | 23 | If you're still comfortable with using Webpack, the old version of the starter kit is available [here](https://github.com/screepers/screeps-typescript-starter/tree/legacy/webpack), but moving forward, no new features will be added to the Webpack version. 24 | 25 | ### Note: Rollup and named exports 26 | 27 | By default, Rollup recognises ES6 modules. This means that some adjustments are necessary in order for Rollup to work well with CommonJS modules, particularly those with named exports like `screeps-profiler`. \(See [\#77](https://github.com/screepers/screeps-typescript-starter/issues/77)\) 28 | 29 | In this case, you will have to manually specify the named exports you use, which is where the `rollup-plugin-commonjs` plugin comes into play. This plugin resolves any CommonJS modules and converts them to ES6 modules, which can be bundled. 30 | 31 | Simply include the modules you want to bundle complete with its named exports, like so: 32 | 33 | ```javascript 34 | commonjs({ 35 | namedExports: { 36 | // left-hand side can be an absolute path, a path 37 | // relative to the current directory, or the name 38 | // of a module in node_modules 39 | 'node_modules/my-lib/index.js': ['named'] 40 | } 41 | }) 42 | ``` 43 | 44 | **For more info:** [`rollup-plugin-commonjs` docs](https://github.com/rollup/rollup-plugin-commonjs) 45 | 46 | -------------------------------------------------------------------------------- /docs/in-depth/prettier.md: -------------------------------------------------------------------------------- 1 | # Prettier 2 | 3 | [Prettier](https://prettier.io/) is an automatic code formatter which supports various languages, including TypeScript. It also has extensions for various text editors like [VSCode](https://github.com/prettier/prettier-vscode), [Atom](https://github.com/prettier/prettier-atom), and even [Vim](https://github.com/prettier/vim-prettier). If you have installed these extensions, it will use Prettier's service to automatically format your code after saving. 4 | 5 | If you would rather not use Prettier instead, you can easily disable it too. In VSCode, open `.vscode/settings.json`, then change the `"editor.formatOnSave"` option to `false`: 6 | 7 | ```javascript 8 | { 9 | "[json]": { 10 | "editor.formatOnSave": false 11 | }, 12 | "[javascript]": { 13 | "editor.formatOnSave": false 14 | }, 15 | "[typescript]": { 16 | "editor.formatOnSave": false 17 | } 18 | } 19 | ``` 20 | 21 | ## Configuring ESLint for Prettier 22 | 23 | The `.prettierrc` file configures how Prettier formats your code. By default we use the following options. 24 | 25 | ```json 26 | { 27 | "semi": true, 28 | "tabWidth": 2, 29 | "printWidth": 120, 30 | "singleQuote": false, 31 | "trailingComma": "none", 32 | "arrowParens": "avoid", 33 | "endOfLine": "auto" 34 | } 35 | ``` 36 | 37 | We can use ESLint config and plugin for Prettier to override some ESLint rules to not conflict with Prettier. 38 | 39 | ```bash 40 | $ yarn add --dev eslint-plugin-prettier eslint-config-prettier prettier 41 | ``` 42 | 43 | Then in your `.eslintrc` file, add the following: 44 | 45 | ```javascript 46 | module.exports = { 47 | // other configuration omitted for brevity 48 | extends: ["prettier", "prettier/@typescript-eslint", "plugin:prettier/recommended"], 49 | plugins: ["prettier"], 50 | rules: { 51 | "prettier/prettier": "error" 52 | } 53 | }; 54 | ``` 55 | -------------------------------------------------------------------------------- /docs/in-depth/remote-development.md: -------------------------------------------------------------------------------- 1 | # Remote Development 2 | 3 | It may be the case you don't want to install and maintain multiple versions of Node _(10, 12, 14... future releases)_ in your machine, or you don't want to install npm packages globally. 4 | 5 | Keep your Screeps-TypeScript project isolated with its dependencies within a container! 6 | 7 | VS Code supports remote development and allows you to use a container as a full-featured development environment. You can open a project mounted into a Docker container to edit with full code completions, code navigation, debugging, and more. 8 | 9 | Refer to VS Code documentation if you want to understand more about remote development: 10 | 11 | - Use a [Docker Container](https://www.docker.com/) as your [development container](https://code.visualstudio.com/docs/remote/containers#_indepth-setting-up-a-folder-to-run-in-a-container) 12 | - Switch your development environment by [connecting to a container](https://code.visualstudio.com/docs/remote/containers) 13 | 14 | ## Using a Docker Container 15 | 16 | Follow these instructions for remote development using a Docker Container. 17 | 18 | ### Install 19 | 20 | To start remote development in dev container, install: 21 | 22 | - Docker Desktop. For system requirements and installation instructions, see: 23 | - [Windows](https://docs.docker.com/docker-for-windows/install/): Currently Docker desktop for windows supports only Linux Containers and [not Windows Containers](https://code.visualstudio.com/docs/remote/containers#_known-limitations). During the install process, ensure you use the default option of Linux Containers. 24 | - [Mac](https://docs.docker.com/docker-for-mac/install/) 25 | - [Linux](https://docs.docker.com/engine/install/debian/) 26 | - Latest version of [VS Code](https://code.visualstudio.com/download) 27 | - Latest version of [VS Code Remote Development Extension Pack](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack). After you install VS Code and Docker - Desktop for your operating system: 28 | - For Windows, set source code locations you want to open in a container. In Docker, right-click and select **Settings / Preferences > Shared Drives / File Sharing**. See [Container tips](https://code.visualstudio.com/docs/remote/troubleshooting#_container-tips) if you hit trouble with sharing. 29 | - For Linux, see [supported platforms](https://docs.docker.com/get-docker/). From the terminal, run `sudo usermod -aG docker $USER` to add your user to the docker group. This setting takes effect after you sign out and back in again. 30 | 31 | ### Open a Project in a Dev Container 32 | 33 | 1. Open the project you want to work with or create a new project 34 | 2. From the Command Palette, run **Remote-Containers: Reopen in Container**. If you are unable to see this command, make sure that you have installed the latest version of VS Code Remote Development Extension Pack. 35 | 36 | VS Code creates a dev container the first time you open the project. After the dev container is built, the project folder in your local system automatically connects and maps to the container, and the side bar shows `Dev Container: Screeps-TypeScript-Starter`. 37 | 38 | ![remote-container](../.gitbook/assets/remote-container.png) 39 | 40 | The container pre-installs and configures all Pre-Requisites for this project + other utils for your daily basis: 41 | 42 | - Node 12 43 | - git 44 | - ca-certificates 45 | - openssl 46 | - openssh 47 | -------------------------------------------------------------------------------- /docs/in-depth/testing.md: -------------------------------------------------------------------------------- 1 | # Testing 2 | 3 | Automated testing helps prevent regressions and reproduce complex failure 4 | scenarios for bug fixing or feature implementation. This project comes with 5 | support for both unit and integration testing with your Screeps code. 6 | 7 | You can read more about [unit and integration testing on 8 | Wikipedia](https://en.wikipedia.org/wiki/Test-driven_development). 9 | 10 | This documentation will cover the testing setup for those already familiar with 11 | the process of test driven design. 12 | 13 | Tests are written via [Mocha](https://mochajs.org/) and executed as tests only 14 | if they include `.test.ts` in their filename. If you have written a test file 15 | but aren't seeing it executed, this is probably why. There are two separate test 16 | commands and configurations, as unit tests don't need the complete Screeps 17 | server run-time as integration tests do. 18 | 19 | ## Running Tests 20 | 21 | The standard `npm test` will execute all unit and integration tests in sequence. 22 | This is helpful for CI/CD and pre-publish checks, however during active 23 | development it's better to run just a subset of interesting tests. 24 | 25 | You can use `npm run test-unit` or `npm run test-integration` to run just one of 26 | the test suites. Additionally you can supply Mocha options to these test 27 | commands to further control the testing behavior. As an example, the following 28 | command will only execute integration tests with the word `memory` in their 29 | description: 30 | 31 | ``` 32 | npm run test-integration -- -g memory 33 | ``` 34 | 35 | Note that arguments after the initial `--` will be passed to `mocha` directly. 36 | 37 | ## Unit Testing 38 | 39 | You can test code with simple run-time dependencies via the unit testing 40 | support. Since unit testing is much faster than integration testing by orders of 41 | magnitude, it is recommended to prefer unit tests wherever possible. 42 | 43 | ## Integration Testing 44 | 45 | ### Installing Screeps Server Mockup 46 | 47 | Before starting to use integration testing, you must install [screeps-server-mockup](https://github.com/screepers/screeps-server-mockup) to your project. 48 | Please view that repository for more instruction on installation. 49 | 50 | ```bash 51 | # Using yarn: 52 | yarn add -D screeps-server-mockup 53 | # Using npm 54 | npm install --save-dev screeps-server-mockup 55 | ``` 56 | 57 | You will also need to add scripts to run integration tests. 58 | 59 | In `package.json`, add a new `test-integration` script and add the new integration testing to the main `test` script. 60 | 61 | ```json 62 | "scripts": { 63 | "test": "npm run test-unit && npm run test-integration", 64 | "test-integration": "npm run build && mocha test/integration/**/*.ts", 65 | } 66 | ``` 67 | 68 | Now you can run integration tests by using the `test-integration` script or run both unit and integration tests using the `test` script. 69 | 70 | ### Integration Testing with Screeps Server Mockup 71 | 72 | Integration testing is for code that depends heavily on having a full game 73 | environment. Integration tests are completely representative of the real game 74 | (in fact they run with an actual Screeps server). This comes at the cost of 75 | performance and very involved setup when creating specific scenarios. 76 | 77 | Server testing support is implemented via 78 | [screeps-server-mockup](https://github.com/screepers/screeps-server-mockup). View 79 | this repository for more information on the API. 80 | 81 | By default the test helper will create a "stub" world with a 3x3 grid of rooms 82 | with sources and controllers. Additionally it spawns a bot called "player" 83 | running the compiled main.js file from this repository. 84 | 85 | It falls on the user to properly set up preconditions using the 86 | screeps-server-mockup API. Importantly, most methods exposed with this API are 87 | asynchronous, so using them requires frequent use of the `await` keyword to get 88 | a result and ensure order of execution. If you find that some of your 89 | preconditions don't seem to take effect, or that you receive a Promise object 90 | rather than an expected value, you're likely missing `await` on an API method. 91 | 92 | Finally, please note that screeps-server-mockup, and this repo by extension, 93 | come with a specific screeps server version at any given time. It's possible 94 | that either your local package.json, or the screeps-server-mockup package itself 95 | are out of date and pulling in an older version of the [screeps 96 | server](https://github.com/screeps/screeps). If you notice that test environment 97 | behavior differs from the MMO server, ensure that all of these dependencies are 98 | correctly up to date. 99 | -------------------------------------------------------------------------------- /docs/in-depth/troubleshooting.md: -------------------------------------------------------------------------------- 1 | # Troubleshooting 2 | 3 | This page outlines any common issues that you'll run into while setting up the TypeScript starter, as well as how to fix them. 4 | 5 | ## Unable to upload code to Screeps private server 6 | 7 | If you're getting the following error: 8 | 9 | ```text 10 | (node:80116) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Cannot POST /api/auth/signin 11 | ``` 12 | 13 | Make sure you have [screepsmod-auth](https://github.com/ScreepsMods/screepsmod-auth) installed on your private server, and you've set a password on the account in your private server as well. 14 | 15 | ## Unable to extend type interfaces \(e.g. `Game`, `Memory`\) 16 | 17 | Make sure you declare any extensions to the type interfaces as an [_ambient declaration_](https://stackoverflow.com/a/40916055). You can either: 18 | 19 | * put them inside a `*.d.ts` file, or 20 | * in an existing `.ts` file \(with at least one `import` or `export`\), you can use `declare global { interface CreepMemory { ... } }` to accomplish the same effect. 21 | 22 | **For more info:** [https://github.com/screepers/typed-screeps/issues/27](https://github.com/screepers/typed-screeps/issues/27) 23 | 24 | -------------------------------------------------------------------------------- /docs/in-depth/typescript.md: -------------------------------------------------------------------------------- 1 | # TypeScript 2 | 3 | TypeScript is, in our opinion, the best language to write your Screeps codebase in. It combines the familiarity of JavaScript with the power of static typing. 4 | 5 | Static type checkers like TypeScript and [Flow](https://flow.org/) help reduce the amount of bugs in your code by detecting type errors during compile time. In general, using static typing in your JavaScript code [can help prevent about 15%](https://blog.acolyer.org/2017/09/19/to-type-or-not-to-type-quantifying-detectable-bugs-in-javascript/) of the bugs that end up in committed code. Not only static typing, TypeScript also provides various productivity enhancements like advanced statement completion, as well as smart code refactoring. 6 | 7 | To read more about how TypeScript can help you in Screeps, read [this Screeps World article](https://screepsworld.com/2017/07/typescreeps-getting-started-with-ts-in-screeps/) by [@bonzaiferroni](https://github.com/bonzaiferroni). 8 | 9 | This section provides TypeScript-specific tips & tricks for you to make the best out of the ecosystem. 10 | 11 | ## Strict mode 12 | 13 | The `--strict` compiler flag was introduced in TypeScript 2.3 which activates TypeScript's "strict mode". The strict mode sets all strict typechecking options to `true` by default. 14 | 15 | As of TypeScript 2.7, the affected options are: 16 | 17 | * `--noImplicitAny` 18 | * `--noImplicitThis` 19 | * `--alwaysStrict` 20 | * `--strictNullChecks` 21 | * `--strictFunctionTypes` 22 | * `--strictPropertyInitialization` 23 | 24 | Starting from version 2.0 of the starter kit, we've enabled the `--strict` flag in `tsconfig.json`. If this gives you compile time errors, you can try setting `"strict"` to `false`, or by overriding one or more of the options listed above. 25 | 26 | **For more info:** [https://blog.mariusschulz.com/2017/06/09/typescript-2-3-the-strict-compiler-option](https://blog.mariusschulz.com/2017/06/09/typescript-2-3-the-strict-compiler-option) 27 | 28 | ## ESLint 29 | 30 | ESLint checks your TypeScript (and JavaScript) code for readability, maintainability, and functionality errors, and can also enforce coding style standards. 31 | 32 | This project provides ESLint rules through a `.eslintrc.js` file, which extends the recommended rules from ESLint defined [here](https://eslint.org/docs/rules/). 33 | 34 | We've made some changes to these rules, which we considered necessary and/or relevant to a proper Screeps project: 35 | 36 | * set the [guard-for-in](https://eslint.org/docs/rules/guard-for-in) rule to `off`, it was forcing `for ( ... in ...)` loops to check if object members were not coming from the class prototype. 37 | * set the [no-console](https://eslint.org/docs/rules/no-console) rule to `off`, in order to allow using `console`. 38 | * set the [no-underscore-dangle](https://eslint.org/docs/rules/no-underscore-dangle) to `warn`. 39 | 40 | ### Customising ESLint 41 | 42 | You can also customise your `.eslintrc.js` file to match the preferences of your codebase. Click [here](https://eslint.org/docs/user-guide/configuring/), to find out how, and click [here](https://eslint.org/docs/rules/) for a complete list of rules available. 43 | 44 | If you believe that some rules should not apply to a part of your code \(e.g. for one-off cases like having to use `require()` to include a module\), you can use flags to let ESLint know about it: [https://eslint.org/docs/user-guide/configuring/rules#disabling-rules](https://eslint.org/docs/user-guide/configuring/rules#disabling-rules) 45 | 46 | **More info about ESLint:** [https://eslint.org/](https://eslint.org/) 47 | 48 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "screeps-typescript-starter", 3 | "version": "3.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "//": "If you add or change the names of destinations in screeps.json, make sure you update these scripts to reflect the changes", 7 | "scripts": { 8 | "lint": "eslint \"src/**/*.ts\"", 9 | "build": "rollup -c", 10 | "push-main": "rollup -c --environment DEST:main", 11 | "push-pserver": "rollup -c --environment DEST:pserver", 12 | "push-season": "rollup -c --environment DEST:season", 13 | "push-sim": "rollup -c --environment DEST:sim", 14 | "test": "npm run test-unit", 15 | "test-unit": "mocha test/unit/**/*.ts", 16 | "test-integration": "echo 'See docs/in-depth/testing.md for instructions on enabling integration tests'", 17 | "watch-main": "rollup -cw --environment DEST:main", 18 | "watch-pserver": "rollup -cw --environment DEST:pserver", 19 | "watch-season": "rollup -cw --environment DEST:season", 20 | "watch-sim": "rollup -cw --environment DEST:sim" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/screepers/screeps-typescript-starter.git" 25 | }, 26 | "author": "", 27 | "license": "Unlicense", 28 | "bugs": { 29 | "url": "https://github.com/screepers/screeps-typescript-starter/issues" 30 | }, 31 | "homepage": "https://github.com/screepers/screeps-typescript-starter#readme", 32 | "engines": { 33 | "node": "10.x || 12.x" 34 | }, 35 | "devDependencies": { 36 | "@rollup/plugin-commonjs": "^20.0.0", 37 | "@rollup/plugin-node-resolve": "^13.0.4", 38 | "@types/chai": "^4.1.6", 39 | "@types/lodash": "3.10.2", 40 | "@types/mocha": "^5.2.5", 41 | "@types/node": "^13.13.1", 42 | "@types/screeps": "^3.2.3", 43 | "@types/sinon": "^5.0.5", 44 | "@types/sinon-chai": "^3.2.0", 45 | "@typescript-eslint/eslint-plugin": "^4.29.1", 46 | "@typescript-eslint/parser": "^4.29.1", 47 | "@typescript-eslint/typescript-estree": "^4.29.1", 48 | "chai": "^4.2.0", 49 | "eslint": "^7.32.0", 50 | "eslint-config-prettier": "^8.3.0", 51 | "eslint-import-resolver-typescript": "^2.4.0", 52 | "eslint-plugin-import": "^2.24.0", 53 | "eslint-plugin-prettier": "^3.4.0", 54 | "lodash": "^3.10.1", 55 | "mocha": "^5.2.0", 56 | "prettier": "^2.3.2", 57 | "rollup": "^2.56.2", 58 | "rollup-plugin-clear": "^2.0.7", 59 | "rollup-plugin-screeps": "^1.0.1", 60 | "rollup-plugin-typescript2": "^0.31.0", 61 | "sinon": "^6.3.5", 62 | "sinon-chai": "^3.2.0", 63 | "ts-node": "^10.2.0", 64 | "tsconfig-paths": "^3.10.1", 65 | "typescript": "^4.3.5" 66 | }, 67 | "dependencies": { 68 | "source-map": "~0.6.1" 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | import clear from 'rollup-plugin-clear'; 4 | import resolve from '@rollup/plugin-node-resolve'; 5 | import commonjs from '@rollup/plugin-commonjs'; 6 | import typescript from 'rollup-plugin-typescript2'; 7 | import screeps from 'rollup-plugin-screeps'; 8 | 9 | let cfg; 10 | const dest = process.env.DEST; 11 | if (!dest) { 12 | console.log("No destination specified - code will be compiled but not uploaded"); 13 | } else if ((cfg = require("./screeps.json")[dest]) == null) { 14 | throw new Error("Invalid upload destination"); 15 | } 16 | 17 | export default { 18 | input: "src/main.ts", 19 | output: { 20 | file: "dist/main.js", 21 | format: "cjs", 22 | sourcemap: true 23 | }, 24 | 25 | plugins: [ 26 | clear({ targets: ["dist"] }), 27 | resolve({ rootDir: "src" }), 28 | commonjs(), 29 | typescript({tsconfig: "./tsconfig.json"}), 30 | screeps({config: cfg, dryRun: cfg == null}) 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /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": "Password", 29 | "protocol": "http", 30 | "hostname": "1.2.3.4", 31 | "port": 21025, 32 | "path": "/", 33 | "branch": "main" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { ErrorMapper } from "utils/ErrorMapper"; 2 | 3 | declare global { 4 | /* 5 | Example types, expand on these or remove them and add your own. 6 | Note: Values, properties defined here do no fully *exist* by this type definiton alone. 7 | You must also give them an implemention if you would like to use them. (ex. actually setting a `role` property in a Creeps memory) 8 | 9 | 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). 10 | Interfaces matching on name from @types/screeps will be merged. This is how you can extend the 'built-in' interfaces from @types/screeps. 11 | */ 12 | // Memory extension samples 13 | interface Memory { 14 | uuid: number; 15 | log: any; 16 | } 17 | 18 | interface CreepMemory { 19 | role: string; 20 | room: string; 21 | working: boolean; 22 | } 23 | 24 | // Syntax for adding proprties to `global` (ex "global.log") 25 | namespace NodeJS { 26 | interface Global { 27 | log: any; 28 | } 29 | } 30 | } 31 | 32 | // When compiling TS to JS and bundling with rollup, the line numbers and file names in error messages change 33 | // This utility uses source maps to get the line numbers and file names of the original, TS source code 34 | export const loop = ErrorMapper.wrapLoop(() => { 35 | console.log(`Current game tick is ${Game.time}`); 36 | 37 | // Automatically delete memory of missing creeps 38 | for (const name in Memory.creeps) { 39 | if (!(name in Game.creeps)) { 40 | delete Memory.creeps[name]; 41 | } 42 | } 43 | }); 44 | -------------------------------------------------------------------------------- /src/utils/ErrorMapper.ts: -------------------------------------------------------------------------------- 1 | import { SourceMapConsumer } from "source-map"; 2 | 3 | export class ErrorMapper { 4 | // Cache consumer 5 | private static _consumer?: SourceMapConsumer; 6 | 7 | public static get consumer(): SourceMapConsumer { 8 | if (this._consumer == null) { 9 | this._consumer = new SourceMapConsumer(require("main.js.map")); 10 | } 11 | 12 | return this._consumer; 13 | } 14 | 15 | // Cache previously mapped traces to improve performance 16 | public static cache: { [key: string]: string } = {}; 17 | 18 | /** 19 | * Generates a stack trace using a source map generate original symbol names. 20 | * 21 | * WARNING - EXTREMELY high CPU cost for first call after reset - >30 CPU! Use sparingly! 22 | * (Consecutive calls after a reset are more reasonable, ~0.1 CPU/ea) 23 | * 24 | * @param {Error | string} error The error or original stack trace 25 | * @returns {string} The source-mapped stack trace 26 | */ 27 | public static sourceMappedStackTrace(error: Error | string): string { 28 | const stack: string = error instanceof Error ? (error.stack as string) : error; 29 | if (Object.prototype.hasOwnProperty.call(this.cache, stack)) { 30 | return this.cache[stack]; 31 | } 32 | 33 | // eslint-disable-next-line no-useless-escape 34 | const re = /^\s+at\s+(.+?\s+)?\(?([0-z._\-\\\/]+):(\d+):(\d+)\)?$/gm; 35 | let match: RegExpExecArray | null; 36 | let outStack = error.toString(); 37 | 38 | while ((match = re.exec(stack))) { 39 | if (match[2] === "main") { 40 | const pos = this.consumer.originalPositionFor({ 41 | column: parseInt(match[4], 10), 42 | line: parseInt(match[3], 10) 43 | }); 44 | 45 | if (pos.line != null) { 46 | if (pos.name) { 47 | outStack += `\n at ${pos.name} (${pos.source}:${pos.line}:${pos.column})`; 48 | } else { 49 | if (match[1]) { 50 | // no original source file name known - use file name from given trace 51 | outStack += `\n at ${match[1]} (${pos.source}:${pos.line}:${pos.column})`; 52 | } else { 53 | // no original source file name known or in given trace - omit name 54 | outStack += `\n at ${pos.source}:${pos.line}:${pos.column}`; 55 | } 56 | } 57 | } else { 58 | // no known position 59 | break; 60 | } 61 | } else { 62 | // no more parseable lines 63 | break; 64 | } 65 | } 66 | 67 | this.cache[stack] = outStack; 68 | return outStack; 69 | } 70 | 71 | public static wrapLoop(loop: () => void): () => void { 72 | return () => { 73 | try { 74 | loop(); 75 | } catch (e) { 76 | if (e instanceof Error) { 77 | if ("sim" in Game.rooms) { 78 | const message = `Source maps don't work in the simulator - displaying original error`; 79 | console.log(`${message}
${_.escape(e.stack)}
`); 80 | } else { 81 | console.log(`${_.escape(this.sourceMappedStackTrace(e))}`); 82 | } 83 | } else { 84 | // can't handle it 85 | throw e; 86 | } 87 | } 88 | }; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /test/integration/helper.ts: -------------------------------------------------------------------------------- 1 | const { readFileSync } = require('fs'); 2 | const _ = require('lodash'); 3 | const { ScreepsServer, stdHooks } = require('screeps-server-mockup'); 4 | const DIST_MAIN_JS = 'dist/main.js'; 5 | 6 | /* 7 | * Helper class for creating a ScreepsServer and resetting it between tests. 8 | * See https://github.com/Hiryus/screeps-server-mockup for instructions on 9 | * manipulating the terrain and game state. 10 | */ 11 | class IntegrationTestHelper { 12 | private _server: any; 13 | private _player: any; 14 | 15 | get server() { 16 | return this._server; 17 | } 18 | 19 | get player() { 20 | return this._player; 21 | } 22 | 23 | async beforeEach() { 24 | this._server = new ScreepsServer(); 25 | 26 | // reset world but add invaders and source keepers bots 27 | await this._server.world.reset(); 28 | 29 | // create a stub world composed of 9 rooms with sources and controller 30 | await this._server.world.stubWorld(); 31 | 32 | // add a player with the built dist/main.js file 33 | const modules = { 34 | main: readFileSync(DIST_MAIN_JS).toString(), 35 | }; 36 | this._player = await this._server.world.addBot({ username: 'player', room: 'W0N1', x: 15, y: 15, modules }); 37 | 38 | // Start server 39 | await this._server.start(); 40 | } 41 | 42 | async afterEach() { 43 | await this._server.stop(); 44 | } 45 | } 46 | 47 | beforeEach(async () => { 48 | await helper.beforeEach(); 49 | }); 50 | 51 | afterEach(async () => { 52 | await helper.afterEach(); 53 | }); 54 | 55 | before(() => { 56 | stdHooks.hookWrite(); 57 | }); 58 | 59 | export const helper = new IntegrationTestHelper(); 60 | -------------------------------------------------------------------------------- /test/integration/integration.test.ts: -------------------------------------------------------------------------------- 1 | import {assert} from "chai"; 2 | import {helper} from "./helper"; 3 | 4 | describe("main", () => { 5 | it("runs a server and matches the game tick", async function () { 6 | for (let i = 1; i < 10; i += 1) { 7 | assert.equal(await helper.server.world.gameTime, i); 8 | await helper.server.tick(); 9 | } 10 | }); 11 | 12 | it("writes and reads to memory", async function () { 13 | await helper.player.console(`Memory.foo = 'bar'`); 14 | await helper.server.tick(); 15 | const memory = JSON.parse(await helper.player.memory); 16 | assert.equal(memory.foo, 'bar'); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --require test/setup-mocha.js 2 | --require ts-node/register 3 | --require tsconfig-paths/register 4 | --ui bdd 5 | 6 | --reporter spec 7 | --bail 8 | --full-trace 9 | --watch-extensions tsx,ts 10 | --colors 11 | 12 | --recursive 13 | --timeout 5000 14 | --exit 15 | -------------------------------------------------------------------------------- /test/setup-mocha.js: -------------------------------------------------------------------------------- 1 | //inject mocha globally to allow custom interface refer without direct import - bypass bundle issue 2 | global._ = require('lodash'); 3 | global.mocha = require('mocha'); 4 | global.chai = require('chai'); 5 | global.sinon = require('sinon'); 6 | global.chai.use(require('sinon-chai')); 7 | 8 | // Override ts-node compiler options 9 | process.env.TS_NODE_PROJECT = 'tsconfig.test.json' 10 | -------------------------------------------------------------------------------- /test/unit/main.test.ts: -------------------------------------------------------------------------------- 1 | import {assert} from "chai"; 2 | import {loop} from "../../src/main"; 3 | import {Game, Memory} from "./mock" 4 | 5 | describe("main", () => { 6 | before(() => { 7 | // runs before all test in this block 8 | }); 9 | 10 | beforeEach(() => { 11 | // runs before each test in this block 12 | // @ts-ignore : allow adding Game to global 13 | global.Game = _.clone(Game); 14 | // @ts-ignore : allow adding Memory to global 15 | global.Memory = _.clone(Memory); 16 | }); 17 | 18 | it("should export a loop function", () => { 19 | assert.isTrue(typeof loop === "function"); 20 | }); 21 | 22 | it("should return void when called with no context", () => { 23 | assert.isUndefined(loop()); 24 | }); 25 | 26 | it("Automatically delete memory of missing creeps", () => { 27 | Memory.creeps.persistValue = "any value"; 28 | Memory.creeps.notPersistValue = "any value"; 29 | 30 | Game.creeps.persistValue = "any value"; 31 | 32 | loop(); 33 | 34 | assert.isDefined(Memory.creeps.persistValue); 35 | assert.isUndefined(Memory.creeps.notPersistValue); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /test/unit/mock.ts: -------------------------------------------------------------------------------- 1 | export const Game: { 2 | creeps: { [name: string]: any }; 3 | rooms: any; 4 | spawns: any; 5 | time: any; 6 | } = { 7 | creeps: {}, 8 | rooms: [], 9 | spawns: {}, 10 | time: 12345 11 | }; 12 | 13 | export const Memory: { 14 | creeps: { [name: string]: any }; 15 | } = { 16 | creeps: {} 17 | }; 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "esnext", 4 | "lib": ["es2018"], 5 | "target": "es2018", 6 | "moduleResolution": "Node", 7 | "outDir": "dist", 8 | "baseUrl": "src/", 9 | "sourceMap": true, 10 | "strict": true, 11 | "experimentalDecorators": true, 12 | "noImplicitReturns": true, 13 | "allowSyntheticDefaultImports": true, 14 | "allowUnreachableCode": false 15 | }, 16 | "exclude": [ 17 | "node_modules" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "CommonJs" 5 | } 6 | } 7 | --------------------------------------------------------------------------------