Set up a TypeScript project with essential dependencies for creating multiple raw JavaScript output files

Currently, I am in the process of developing scripts for Bot Land, a real-time strategy game that offers a unique gameplay experience. Rather than controlling units traditionally with a mouse and keyboard, players code their bots using an API to engage in battles against other players' bots. The game allows you to create bots resembling familiar units from SC2 such as blink stalkers, siege tanks, medics, and ultralisks.

The complexity of bot control in Bot Land increases gradually with three levels: default AI, a Scratch-like programming language, and BotLandScript—a reduced set of JavaScript. While coding in BotLandScript is manageable, it has limitations like uploading all code as one single file with global functions across bots, causing inconvenience when dealing with lengthy codes or shared functions among different bots.

To mitigate these challenges and enhance my performance, I structured a TypeScript project on GitHub to provide a common library and codebase for each bot. The directory layout includes:

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

In this structure, 'lib' contains shared code and TypeScript definitions, while each bot has its folder housing the bot code and a 'tsconfig.json' file defining compilation options.

Despite the current setup being functional, certain drawbacks exist, such as redundant boilerplate, complexity in adding new bots, unnecessary bloating of output files, and separate building processes for individual bots.

The challenge lies in finding an optimal solution catering to the following requirements:

  • Adding new bots without additional boilerplate
  • Utilizing 'import' for common functions to minimize unused code generation
  • Maintaining a single file output format required by Bot Land
  • Implementing a unified build step for multiple output files per bot
  • Optionally integrating the build process with VS Code through tasks automation

While solutions like Grunt and tsc may hold potential, further exploration and expertise are needed to find the most effective approach for streamlining the bot development process in Bot Land.

Answer №1

Here is my response to address your specifications.

Key files:

  • src/tsconfig-botland.json contains settings for any bot.land script (including custom declarations moved to types/bot-land/index.d.ts). You may need to adjust the strict settings used.
  • src/tsconfig.json references all bots. This file should be edited when adding a new bot script.

A bot script consists of at least two files: a basic tsconfig.json and one or more .ts script files.

For instance, src/AggroMiner/tsconfig.json:

{
    "extends": "../tsconfig-botland",
    "compilerOptions": {
        "outFile": "../../build/AggroMiner.js"
    },
    "files": ["index.ts"],
    "include": ["**/*.ts", "../lib/**/*.ts"]
}

In most scenarios, starting a new bot script involves:

  1. Copying a bot folder (e.g., src/AggroMiner) to a new folder under src
  2. Editing
    src/<newBotFolder>/tsconfig.json
    to modify the outFile with the bot's name
  3. Updating src/tsconfig.json by adding a reference to src/<newBotFolder>

The following npm/yarn scripts have been configured:

  • build compiles all bots
  • build-clean clears the build folder before running build
  • format executes Prettier on all .ts files within src
  • lint performs a tslint check on all bot scripts

Fulfilling your requirements:

  • No additional boilerplate needed to add a new bot (no tsconfig.json per bot)

To achieve this, a script could automate the creation of pertinent per bot tsconfig.json files and execute tsc. However, a minimal setup (as described) might suffice unless absolutely necessary.

  • Utilize import statements for common functions to prevent redundant code output, but...

Note that using module export/import statements necessitates third-party tools for packing / treeshaking to generate a single output file. Unless deadcode impacts bot performance in Bot.land—where scripts run on the server—it may not be crucial.

  • Nonetheless, consolidate all functions into a single file following Bot Land's specific format

Accomplished.

  • A consolidated build step generating multiple output files, each for a distinct bot

Successfully completed.

  • Bonus: integrating the build process with VS Code. A corresponding tasks.json currently exists for building each sub-project.

The npm scripts should display in vsc's tasks list (at least in mine), rendering the tasks.json superfluous.

Answer №2

If you want to streamline your project setup, consider using project references. By following these steps, you can achieve the same outcomes as your original files, consolidating all functions at the top level in a single file. Despite my efforts, I couldn't find a way to import only necessary functions in bots without relying on imports and exports.

Firstly, update your tsconfig.json at the root directory<

{
    "files": [],
    "references": [
        { "path": "./lib" }
        { "path": "./AggroMiner" }
        { "path": "./ArtilleryMicro" }
        { "path": "./MissileKite" }
        { "path": "./SmartMelee" }
        { "path": "./ZapKite" }
    ]
}

Then, create a tsconfig.json within your lib folder with the following configuration:

{
  "compilerOptions": {
    "declaration": true,
    "declarationMap": true,
    "composite": true,
    "rootDir": ".",
    "outFile": "../build/lib.js",
    "target": "es3",
    "removeComments": true,
    "sourceMap": false,
  },
  "files": [
    "data.ts",
    "movement.ts",
    "utils.ts"
  ]
}

Make adjustments in data.ts, movement.ts, and utils.ts to avoid compilation errors:

data.ts

/// <reference path="./bot.land.d.ts"/>

(...)

movement.ts


/// <reference path="./data.ts"/>
/// <reference path="./utils.ts"/>
(...)

utils.ts

/// <reference path="./bot.land.d.ts"/>
(...)

Add base.json at the root (to be extended by bots' tsconfig.json)

base.json

{
  "compilerOptions": {
    "declaration": true,
    "composite": true,
    "rootDir": ".",
    "target": "es3",
    "removeComments": true,
    "sourceMap": false,
  }
}

Adjust the tsconfig.json for your bots accordingly:

{
  "extends": "../base",
  "compilerOptions": {
    "outFile": "../build/AggroMiner.js",
  },
  "files": [
    "AggroMiner.ts"
  ],
  "references": [
      { "path": "../lib", "prepend": true } //remember to set prepend: true
  ]
}

Once done, run this command:

tsc -b

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Troubleshooting a Peculiar Problem with Form Submission in IE10

Please take a look at the code snippet provided below: <!DOCTYPE html> <html> <body> <form name="editProfileForm" method="post" action="profileDataCollection.do"> <input type="text" id="credit-card" name="credit-card" onfocu ...

Unable to add key/value pair to object in Node

While using Node, I encountered a strange issue where I was unable to attach the key/value pair broadcastStamp = date to the object "result." Despite confirming that it is indeed an object with typeof, no errors were thrown - the key/value simply did not a ...

What is the best way to retrieve the innerHTML content of an anchor tag with Cheerio?

Looking to extract data from an HTML page, a simplified example is provided below. Upon running the code, I anticipate the output to be [ "foo", "baz", "quux", ] but instead encounter an error message stating "TypeError: anch ...

Display current weather conditions with the Open Weather API (featuring weather icons)

Hello everyone, I need some help from the community. I am currently working on a weather app using the openweather API. However, I'm facing an issue with displaying the weather conditions icon for each city. I have stored every icon id in a new array ...

What is the best way to navigate and map through an array of objects, especially when encountering an empty object?

I am currently in the process of developing a bootleg version of Amazon with a focus on creating the Questions & Answers component. The issue I have encountered is that in my dummyData, there are instances where a product may not have any questions, lead ...

Utilizing JSON data within a separate TypeScript function or within the ngOnInit lifecycle hook after successfully retrieving the data

I'm new to Angular and have a simple question. In my code, I have the following: public jsonDataResult: any; private getUrl = "../assets/data_3.json"; getScoreList(){ this.http.get(this.getUrl).subscribe((res) => { this.jsonDat ...

Grouping geoJSON data on Mapbox / Leaflet

I am currently in the process of setting up a clustered map on mapbox, similar to the example shown here: At the moment, my point data is being extracted from MYSQL and then converted into GeoJson using GeoPHP. You can view the current map setup here. I ...

A method for combining multiple arrays into a single array within a For loop

I am trying to combine multiple arrays of objects into a single array. Here is an example with a transaction array that contains two different arrays: transaction: 0:(3) [{…}, {…}, {…}] 1:(2) [{…}, {…}] I would like the combined result to loo ...

Avoid including any null or undefined values within a JSON object in order to successfully utilize the Object.keys function

My JSON data structure appears as follows: { 'total_count': 6, 'incomplete_results': false, 'items': [ { 'url': 'https://api.github.com/repos/Samhot/GenIHM/issues/2', 'repository_url' ...

Access the Vue instance from a different element instance

I've developed a leaflet map using vue.js. There's a method I've created called 'showSubmit' that needs to be triggered on the leaflet marker moveend event. Here's what I'm currently doing: this.map.markers.user.on("move ...

The bar chart in chartjs is not displaying properly due to incorrect grouping

I attempted to generate a multi bar chart using Chart.js, but encountered an issue where the jobType and jobCount were not displayed correctly based on each companyName. Below is the table: https://i.sstatic.net/ZyKZH.png Here is the PHP file (CompanySel ...

An Unexpected Token Leads to a SyntaxError in Jest's CSS-Modules

I have successfully configured my jest to allow the usage of static files by following their detailed documentation. However, despite implementing the instructions correctly, I am still encountering an error: What steps can I take to resolve this issue an ...

originalRenderPage has not been declared

I encountered an issue while working on my new nextjs app. The problem arose when I tried to add a carousel using props in my project, resulting in an error stating that 'originalRenderPage' in Document.js is not defined. Any assistance would be ...

Animation of active chat list items on Whatsapp

Has anyone figured out a simple method to create an animation like the one in Whatsapp? For example, when you are on a chat screen and go back to the chat list, have you noticed how an active element is briefly highlighted in gray (to indicate which chat ...

The second AJAX call is unsuccessful

I have created a dynamic ajax website that retrieves pages from the /pages folder and displays them within an ajax-container div on my index.php. Now, I am looking to implement a second ajax request that will only be triggered on certain pages. For examp ...

Creating a function in Typescript that transforms an array into a typed object

Recently, I have started learning TypeScript and I am working on a function to convert arrays from a web request response into objects. I have successfully written the function along with a passing unit test: import { parseDataToObject } from './Parse ...

Is it possible to execute a specified quantity of Promises simultaneously in Nodejs?

Currently, I am working on developing a web scraping application that utilizes a REST API to gather information from multiple entities on the server. The core functionality of this application can be summarized as follows: let buffer = [] for(entity in ent ...

Enhance your websites' search functionality with jQuery autocomplete using AJAX

I am attempting to implement dynamic autocomplete values for a text box. Here is my solution: echo json_encode($res) 0: {type_name: "name1"} 1: {type_name: "name2"} 2: {type_name: "name3"} 3: {type_name: "name4"} 4: {type_name: "name5"} Below is the co ...

obtaining data from a JSON object in Node.js

Retrieve response in function node.js [ { instrument_token: '12598786', exchange_token: '49214', tradingsymbol: 'AARTIIND21JAN1000CE', name: 'AARTIIND' }, { instrument_token: '125998 ...

Automatically submitting the form

Is there a way to automatically submit a form once 4 numbers are inputted into the field without having to press enter or click submit? <form action="send.php" method="POST"> <input type="number" maxlength="4"> </form> I have a basic ...