J'écris actuellement certains scripts pour Bot Land . Bot Land est un jeu de stratégie en temps réel où au lieu de contrôler vos unités avec une souris et un clavier, vous écrivez du code pour contrôler vos bots via une API, puis vos bots vont combattre les bots des autres. Si vous connaissez les unités de SC2, vous pouvez créer des robots similaires aux harceleurs clignotants, aux chars de siège, aux médecins et aux ultralisks. (C'est un jeu assez amusant pour les ingénieurs logiciels, mais cela sort du cadre de cette question.)
Le contrôle des bots a trois niveaux de complexité croissante: une IA par défaut, un langage de programmation de type Scratch , et un ensemble réduit de JavaScript appelé BotLandScript. Bien que l'éditeur intégré pour BotLandScript soit raisonnable, vous devez télécharger tout votre code en tant que un seul fichier avec des fonctions globales de premier niveau partout. Naturellement, cela commence à devenir douloureux après un certain temps si votre code commence à devenir long et que des robots différents partagent les mêmes fonctions.
Pour faciliter l'écriture de code pour plusieurs robots, réduire le risque d'erreurs involontaires lors du codage en JS nu et augmenter mes chances de battre les autres joueurs, j'ai configuré ci-dessus projet TypeScript pour fournir également une bibliothèque commune comme code pour chacun de mes robots. La structure de répertoire actuelle ressemble approximativement à la suivante:
lib/
bot.land.d.ts
common.ts
BlinkStalker/
BlinkStalker.ts
tsconfig.json
Artillery/
Artillery.ts
tsconfig.json
SmartMelee/
SmartMelee.ts
tsconfig.json
lib
est le code commun qui est partagé entre les bots et fournit des définitions TypeScript pour l'API Bot Land (non TS). Chaque bot obtient alors son propre dossier, avec un fichier contenant le code du bot et l'autre un passe-partout tsconfig.json
:
{
"compilerOptions": {
"target": "es3",
"module": "none",
"sourceMap": false,
"outFile": "bot.js"
},
"files": [
"MissileKite.ts"
],
"include": [
"../lib/**/*"
]
}
Lorsque chaque tsconfig.json
est construit, il crée un bot.js
qui contient du code transpilé du bot lui-même ainsi que tout le code dans common.js
. Cette configuration est sous-optimale pour plusieurs raisons, entre autres: elle nécessite beaucoup de passe-partout en double, rend difficile l'ajout de nouveaux bots, inclut beaucoup de code inutile pour chaque bot et nécessite que chaque bot soit construit séparément.
Cependant, d'après mes recherches jusqu'à présent , il ne semble pas qu'il existe un moyen facile de faire ce que je veux. En particulier, en utilisant le nouveau tsc -b
L'option et les références ne fonctionnent pas, car cela nécessite que le code soit modulaire et Bot Land nécessite un fichier unique avec toutes les fonctions définies au niveau supérieur.
Quelle est la meilleure façon d'obtenir le plus grand nombre possible des éléments suivants?
tsconfig.json
par bot)import
pour les fonctions courantes afin d'éviter de sortir du code inutilisé, mais alors ...tasks.json
pour la construction de chaque sous-projet.Je suppose vaguement que la réponse implique probablement quelque chose comme Grunt en plus de tsc
, mais je n'en sais pas assez pour en être sûr.
Voici mon tentative pour répondre à vos besoins.
Fichiers notables:
src/tsconfig-botland.json
contient les paramètres de tout script bot.land (y compris vos déclarations personnalisées que j'ai déplacées vers types/bot-land/index.d.ts
). Vous pouvez modifier les paramètres strict
que j'ai utilisés.src/tsconfig.json
contient des références à tous vos robots. Il s'agit du fichier à modifier chaque fois que vous souhaitez ajouter un autre script de botUn script bot est composé d'au moins deux fichiers: un tsconfig.json
et un ou plusieurs .ts
fichiers de script.
Par exemple src/AggroMiner/tsconfig.json
:
{
"extends": "../tsconfig-botland",
"compilerOptions": {
"outFile": "../../build/AggroMiner.js"
},
"files": ["index.ts"],
"include": ["**/*.ts", "../lib/**/*.ts"]
}
Dans la plupart des cas, pour démarrer un nouveau script de bot, vous devez:
src/AggroMiner
) dans un nouveau dossier sous src
src/<newBotFolder>/tsconfig.json
pour modifier le outFile
avec le nom de votre botsrc/tsconfig.json
et ajoutez une référence à src/<newBotFolder>
Le script npm
/yarn
suivant a été défini:
build
pour construire tous les botsbuild-clean
qui efface le dossier build
avant d'exécuter un build
format
pour exécuter Prettier sur tous les .ts
fichiers sous src
lint
pour exécuter une vérification tslint sur tous les scripts de botExécuter maintenant vos exigences:
Pour y parvenir, il faudrait créer un script qui énumérerait votre dossier/scripts de bots ... et configurer le per bot tsconfig.json
et exécutez tsc
. À moins que cela ne soit strictement nécessaire, une configuration minimale (décrite ci-dessus) peut être suffisante.
Tout d'abord, sachez que si vous commencez à utiliser n'importe quel module export
/import
, vous aurez besoin de tiers supplémentaires pour emballer/arborescence afin d'obtenir une sortie de fichier unique. D'après ce que j'ai pu recueillir sur Bot.land, vos scripts s'exécutent sur le serveur. À moins que le code mort n'ait un impact sur les performances de votre bot, je ne me dérangerais pas vraiment.
Terminé.
Terminé.
Les scripts npm
devraient apparaître dans la liste des tâches de vsc (du moins ils le font dans la mienne), ce qui rend le tasks.json
inutile.
Vous pouvez réellement utiliser des références de projet. Suivez ces étapes pour obtenir les mêmes résultats que vous obteniez pour vos fichiers d'origine, avec toutes les fonctions au niveau supérieur dans un seul fichier. Cependant, je n'ai pas trouvé de solution pour importer uniquement les fonctions nécessaires dans les bots. Autrement dit, sans utiliser les importations et les exportations.
Dans votre tsconfig.json à la racine
{
"files": [],
"references": [
{ "path": "./lib" }
{ "path": "./AggroMiner" }
{ "path": "./ArtilleryMicro" }
{ "path": "./MissileKite" }
{ "path": "./SmartMelee" }
{ "path": "./ZapKite" }
]
}
Ensuite, dans votre dossier lib, ajoutez un tsconfig.json comme ça
{
"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"
]
}
Nous devons faire quelques ajustements dans data.ts, movement.ts et utils.ts afin que ts ne nous dérange pas avec des erreurs de compilation.
data.ts
/// <reference path="./bot.land.d.ts"/>
(...)
mouvement.ts
/// <reference path="./data.ts"/>
/// <reference path="./utils.ts"/>
(...)
utils.ts
/// <reference path="./bot.land.d.ts"/>
(...)
Ensuite, nous ajoutons base.json à la racine (le tsconfig.json des bots va l'étendre).
base.json
{
"compilerOptions": {
"declaration": true,
"composite": true,
"rootDir": ".",
"target": "es3",
"removeComments": true,
"sourceMap": false,
}
}
et tsconfig.json des bots (adapter en fonction des bots)
{
"extends": "../base",
"compilerOptions": {
"outFile": "../build/AggroMiner.js",
},
"files": [
"AggroMiner.ts"
],
"references": [
{ "path": "../lib", "prepend": true } //note the prepend: true
]
}
C'est tout. Maintenant, lancez
tsc -b