I'm currently writing [some scripts](https://github.com/mizzao/bot.land) for [Bot Land](http://bot.land). Bot Land is a real-time strategy game where instead of controlling your units with a mouse and keyboard, you write code to control your bots via an API, and then your bots go fight others' bots. If you're familiar with units in SC2, you can create bots that are similar to blink stalkers, siege tanks, medics, and ultralisks. (It's quite a fun game for software engineers, but that's outside the scope of this question.)

[![bot land](https://i.stack.imgur.com/q99X5.png)](http://bot.land)

Bot control has three levels of increasing complexity: a default AI, a [Scratch](https://scratch.mit.edu/)-like programming language, and a reduced set of JavaScript called BotLandScript. Although the built-in editor for BotLandScript is reasonable, you have to upload all your code as **one single file** with global top-level functions everywhere. Naturally, this starts getting painful after a while if your code starts to get long and different bots share the same functions.

[![programming environment](https://i.stack.imgur.com/CM2iW.png)](http://bot.land)

To facilitate writing code for multiple bots, reduce the chance for unintentional errors when coding in bare JS, and increase my chances of beating other players, I set up the [above TypeScript project](https://github.com/mizzao/bot.land) to provide a common library as well as code for each of my bots. The current directory structure looks like approximately like the following:

```
lib/ 
  bot.land.d.ts
  common.ts
BlinkStalker/
  BlinkStalker.ts
  tsconfig.json
Artillery/
  Artillery.ts
  tsconfig.json
SmartMelee/
  SmartMelee.ts
  tsconfig.json

```

`lib` is the common code that is shared among bots, and provides TypeScript definitions for the (non-TS) Bot Land API. Each bot then gets its own folder, with one file containing the bot code and the other a boilerplate `tsconfig.json`:

```json
{
  "compilerOptions": {
    "target": "es3",
    "module": "none",
    "sourceMap": false,
    "outFile": "bot.js"
  },
  "files": [
    "MissileKite.ts"
  ],
  "include": [
    "../lib/**/*"
  ]
}

```

When each `tsconfig.json` is built, it creates a corresponding `bot.js` that contains transpiled code from the bot itself as well as *all* the code in `common.js`. This setup is suboptimal for a few reasons, among others: it requires a lot of duplicate boilerplate, makes it hard to add new bots, includes a lot of unnecessary code for each bot, and requires each bot to be built separately.

However, based on [my research so far](https://stackoverflow.com/q/46995801/586086), it doesn't seem like there's an easy way to do what I want. In particular, using the new `tsc -b` option and references does not work, because that requires the code to be modularized and Bot Land requires a single file with all functions defined at the top level.

What's the best way to achieve as many of the following as possible?

* No new boilerplate required to add a new bot (e.g. no `tsconfig.json` per bot)
* Use `import` for common functions to avoid outputting unused code, but then...
* Still output all functions as one single file in Bot Land's specific format
* A single build step that produces multiple output files, one for each bot
* Bonus: integrating the build process with VS Code. There is a currently correspondingly boilerplate [`tasks.json`](https://github.com/mizzao/bot.land/blob/master/.vscode/tasks.json) for building each sub-project.

I vaguely surmise the answer probably involves something like Grunt in addition to `tsc`, but I don't know enough about that to be sure.