Команда amxts
amxts — команда, которой пользуется проект: создаёт проекты и модули,
добавляет модули, собирает, выкладывает, проверяет типы и запускает тесты.
Это пакет @amxts/cli, от которого зависит @amxts/core, поэтому она есть
в каждом проекте и проект запускает её через свой менеджер пакетов:
npx amxts <команда>
pnpm amxts <команда>
yarn amxts <команда>
bunx amxts <команда>
Команда работает с собственным ядром проекта — @amxts/core из его
node_modules: ядро старше или новее, чем команда знает, — это ошибка, которая
говорит, что из двух обновить. Установленная глобально
(npm install -g @amxts/cli), amxts так же работает в любом проекте, а
init — где угодно.
amxts --help перечисляет команды, amxts <команда> --help показывает
параметры команды с примерами. На опечатку команда подсказывает:
$ npx amxts buidl
✖ Unknown command buidl
Did you mean amxts build?
Ошибка — одна строка и подсказка под ней. --debug добавляет, где она
случилась, — для отчёта об ошибке.
Команды
| команда | что делает |
|---|---|
init | создаёт проект, а с --module — пакет модуля |
dev | собирает, выкладывает на сервер и снова — на каждое сохранение |
build | собирает плагины и модули в dist/ |
typecheck | проверяет плагины и amxts.config.ts так же, как редактор |
test | запускает тесты проекта на поддельном сервере |
module | module add ставит модуль и вписывает его в конфиг; module list показывает модули |
check | в пакете модуля: проверяет, что он готов к публикации |
prepare | получает include сервера и пишет .amxts/ для редактора |
upgrade | переводит проект на другой выпуск amxts: пакеты, код, сборку и сервер |
info | версии и настройки — для отчёта об ошибке |
init
Создаёт проект. Спрашивает по порядку: менеджер пакетов (выбран тот, что
запустил команду), папку, модули (из каталога модулей), oxlint и
oxfmt, git, папку сервера для dev и — когда этого не говорят include
сервера — для какого сервера проект. Потом пишет файлы, ставит зависимости,
получает include сервера и говорит, что запускать дальше:
npm create amxts@latest
pnpm create amxts
yarn create amxts
bun create amxts
npm create amxts и npx amxts init — одна и та же команда. Вопросы
выглядят так:
┌ amxts 0.2.0 · a new project
│
◇ Which package manager?
│ npm
│
◇ Where should the project go?
│ my-server
│
◇ Which modules? (space to pick, enter to go on)
│ menu-core
│
◇ Add oxlint and oxfmt? (lint and format)
│ Yes
│
◇ Initialize a git repository?
│ Yes
│
◇ Where is the server? its addons/amxts folder, for npm run dev - empty to skip
│ D:/hlds/cstrike/addons/amxts
│
◆ Created my-server in my-server
│
● config-core is listed too: menu-core needs it
│
◇ Installed dependencies with npm 11.16.0
│
◆ Includes: the server's own (D:/hlds/cstrike/addons/amxmodx/scripting/include)
│
◆ Initialized a git repository
│
◆ Prepared the editor config (.amxts/tsconfig.json)
│
◇ Next steps ──────────────────────────────────────╮
│ │
│ cd my-server │
│ npm run dev # build, deploy, rebuild on save │
│ │
├───────────────────────────────────────────────────╯
│
└ Docs: https://amxts.github.io/docs/getting-started/quick-start
У каждого вопроса есть флаг, а --yes берёт значения по умолчанию для
остального — для скрипта или CI:
npx amxts init my-server --modules menu-core,config-core --no-git --server D:/hlds/cstrike/addons/amxts --yes
pnpm dlx amxts init my-server --modules menu-core,config-core --no-git --server D:/hlds/cstrike/addons/amxts --yes
yarn dlx amxts init my-server --modules menu-core,config-core --no-git --server D:/hlds/cstrike/addons/amxts --yes
bunx amxts init my-server --modules menu-core,config-core --no-git --server D:/hlds/cstrike/addons/amxts --yes
| параметр | что делает |
|---|---|
[папка] | куда положить проект; по умолчанию my-server |
--pm <npm|pnpm|yarn|bun> | менеджер пакетов; по умолчанию тот, что запустил команду |
--modules <список> | модули через запятую, по именам в каталоге или как пакеты npm: menu-core,config-core; "" — без модулей |
--no-lint | без oxlint и oxfmt (по умолчанию они добавляются) |
--no-git | без git init |
--server <путь> | сервер: его папка, его cstrike или его addons/amxts; в .env как AMXTS_SERVER пишется addons/amxts, а сборка берёт include, которые стоят на нём |
--target <rehlds|hlds> | для какого сервера проект, когда этого не говорят include сервера: rehlds — ReHLDS, ReGameDLL и ReAPI (по умолчанию) — или hlds, обычный HLDS |
--os <windows|linux> | система сервера, когда её не видно по его папке: пишется в .env как AMXTS_SERVER_OS (система сервера) |
--no-install | записать файлы, но не ставить зависимости |
--yes, -y | ничего не спрашивать |
--force | писать в непустую папку |
--local | подключить ядро и официальные модули ссылками на их папки на этой машине, а не ставить из npm, — для работы над самим amxts; AMXTS_CORE задаёт папку ядра |
Модуль, которому нужен другой, приводит его с собой: с menu-core ставится и
config-core, а modules перечисляет его сразу за menu-core, с комментарием,
какому модулю он нужен. Сборка загружает его первым:
// amxts.config.ts
export default defineConfig({
modules: [
"@amxts/menu-core",
"@amxts/config-core", // needed by menu-core
],
target: "rehlds",
});
Проект получается такой:
my-server/
├── package.json скрипты: dev, build, typecheck, test, lint
├── amxts.config.ts выбранные модули и те, что им нужны
├── tsconfig.json { "extends": "./.amxts/tsconfig.json" }
├── .oxlintrc.json правила линтера: @antfu/eslint-config, для oxlint
├── .oxfmtrc.json oxfmt, для файлов JSON и YAML
├── knip.json точки входа для knip: плагины, конфиг, тесты
├── .env AMXTS_SERVER, если папка сервера указана; AMXTS_SERVER_OS
├── pnpm-workspace.yaml с pnpm: скрипт установки bun не нужен
├── .gitignore
├── .gitattributes LF для файлов, которые форматирует oxfmt
├── .vscode/ настройки и рекомендуемые расширения
├── README.md
├── plugins/
│ └── hello.ts плагин, который пользуется выбранными модулями
└── test/
├── hello.test.ts его тесты на поддельном сервере
└── tsconfig.json свой у тестов: типы Bun, а не плагинов
Include сервера
Там, где плагину нужен Pawn-include, — include, который он реализует,
нативы или форварды Pawn-плагина, Pawn-тест — сборка ищет сначала в
includes/ проекта, потом среди include сервера, потом среди тех, что идут
с amxts (там и собственные include AMX Mod X). Include сервера — это:
- с
AMXTS_SERVER— собственнаяaddons/amxmodx/scripting/includeсервера, ровно то, что на нём стоит; - без сервера — include того сервера, который называет
targetвamxts.config.ts: для"rehlds"— ReHLDS, ReGameDLL и ReAPI, по умолчанию — amxts скачивает include ReAPI в.amxts/include, из того выпуска, из которого сделан его API;"hlds"— обычному HLDS — ничего, кроме собственных include AMX Mod X, не нужно.
// amxts.config.ts
export default defineConfig({
modules: [],
target: "hlds",
});
init спрашивает target, когда сервера нет или в его папке нет include;
--target отвечает на вопрос. prepare — после каждой установки — и каждая
сборка скачивают include, если их ещё нет.
npx amxts prepare или укажите в AMXTS_SERVER
сервер с его include.lint проверяет код oxlint'ом по правилам @antfu/eslint-config, а файлы
JSON и YAML — oxfmt; lint:fix исправляет, что может, — TypeScript
форматируют эти же правила. В VS Code то же при наборе и сохранении делает
расширение oxc, которое советует .vscode/extensions.json.
Пакет модуля
С --module создаётся пакет модуля — работающий модуль с проектом-песочницей
и тестом, — см. свой модуль:
npx amxts init --module @you/greeter # ./greeter
npx amxts init --module @you/greeter --natives # с нативами для Pawn-плагинов
npx amxts init --module greeter --dir my-greeter # в ./my-greeter
pnpm dlx amxts init --module @you/greeter # ./greeter
pnpm dlx amxts init --module @you/greeter --natives # с нативами для Pawn-плагинов
pnpm dlx amxts init --module greeter --dir my-greeter # в ./my-greeter
yarn dlx amxts init --module @you/greeter # ./greeter
yarn dlx amxts init --module @you/greeter --natives # с нативами для Pawn-плагинов
yarn dlx amxts init --module greeter --dir my-greeter # в ./my-greeter
bunx amxts init --module @you/greeter # ./greeter
bunx amxts init --module @you/greeter --natives # с нативами для Pawn-плагинов
bunx amxts init --module greeter --dir my-greeter # в ./my-greeter
dev
npx amxts dev
pnpm amxts dev
yarn amxts dev
bunx amxts dev
Собирает все плагины и модули, копирует их на сервер из AMXTS_SERVER,
перезагружает его, а потом следит за папкой плагинов и модулями проекта:
сохранение пересобирает плагины, которые импортируют сохранённый файл.
amxts 0.2.0 · dev
Core @amxts/core 0.2.0
Modules menu-core 0.2.0 · config-core 0.1.1
Server D:/hlds/cstrike/addons/amxts · Windows · ReHLDS · running
Plugins 1 in plugins/
✔ hello · 6.2s
✔ 14:02:11 deployed, the server reloaded config-core, menu-core, hello (7.1s)
◇ watching plugins - save a plugin and it goes to the server (Ctrl+C stops)
✔ hello · 4.1s
✔ 14:03:40 plugins/hello.ts changed: deployed, the server reloaded hello (4.2s)
Сначала — с чем она работает: ядро и модули с версиями — модуль, которым не пользуется ни
один плагин, — так и говорит (no plugin uses it), модуль из папки на этой
машине, а не из npm, — local; затем сервер — его папка, система
(ниже), ReHLDS или обычный HLDS и запущен ли он; и
сколько плагинов.
Каждый плагин и модуль виден, пока компилируется: ◇ compiling hello 1/1,
пока идёт, ✔ hello · 6.2s, когда готов, — в терминале одна строка сменяет
другую, в логе (CI) остаются обе. Плагин проходит два компилятора, в
WebAssembly и затем в машинный код, — на это сборка и тратит время. Поэтому:
- официальные модули приходят из npm уже скомпилированными для Windows и
Linux, и сборка берёт их как есть, ничего не компилируя. Если проект скомпилировал бы
модуль иначе — его настройки заданы в
amxts.config.ts, ядро другой версии, — сборка говорит почему (menu-core 0.2.0 was built for @amxts/core 0.2.0, the project has 0.2.1 - compiling it here) и компилирует его, один раз. Плагин, который пользуется модулем, тоже компилируется по тому, с чем модуль пришёл, а не разбирает модуль сначала сам; - плагин, для которого с прошлой сборки ничего не изменилось — ни его файл,
ни то, что он импортирует, — заново не компилируется: он берётся готовым из
node_modules/.cache/amxts.dev, запущенный снова, выкладывает плагины на сервер за секунды; - несколько плагинов компилируются сразу, каждый в своём процессе: столько,
сколько помещается в 3 ГБ памяти — одной компиляции нужен примерно
гигабайт, — и не больше, чем у машины ядер процессора. В терминале строка
называет их все:
◇ compiling hello, shop 2/3.AMXTS_BUILD_MEMORYв.envили в окружении задаёт память в мегабайтах (AMXTS_BUILD_MEMORY=6144),AMXTS_BUILD_JOBS— прямо число компиляций (1— по одной). Плагин получается одинаковым в любом случае.
Сохранение пересобирает, только когда в файле что-то изменилось: редактор, сохранивший файл без изменений, или менеджер пакетов, заново записавший модуль, — не изменение, — и строка называет файл.
dev компилирует на скорость: маленький плагин — за несколько секунд, там
где build тратит около десяти. Его плагины делают то же самое, чуть
медленнее, — на сервер, где играют, выкладывайте npx amxts build --deploy.
AMXTS_SERVER — папка addons/amxts сервера с amxts
(установка на сервер), в .env проекта:
AMXTS_SERVER=D:/hlds/cstrike/addons/amxts
Можно указать и папку самого сервера (D:/hlds), его cstrike или
cstrike/addons: сборка берёт cstrike/addons/amxts внутри неё, а строка
Server говорит, какая это папка. Папка, которая не подходит ни под один
вариант, останавливает сборку одной строкой о том, где она искала.
Без него dev и build --deploy спрашивают папку, как init, и
записывают её в .env. В CI или когда вывод идёт в конвейер ничего не
спрашивается: сборка останавливается и говорит, что AMXTS_SERVER не задан.
Когда модуль сервера из другого выпуска, чем ядро проекта, dev и build
сначала говорят об этом — плагины, которые собирает проект, загружаются только
модулем его выпуска:
▲ the server runs amxts 0.1.0, this project 0.2.0 - run amxts upgrade
upgrade обновляет и сервер. Выпуск читается из файла модуля, а
не у запущенного сервера.
Перезагрузка идёт через rcon на 127.0.0.1:27015 (другой порт задаёт
AMXTS_PORT), с rcon_password из cstrike/server.cfg сервера. См.
горячую перезагрузку. --os — как у build.
npx amxts dev --docker
pnpm amxts dev --docker
yarn amxts dev --docker
bunx amxts dev --docker
То же для сервера в Docker, который монтирует проект: собирает
для Linux в dist/ и снова при каждом сохранении, ничего не выкладывает —
сервер читает dist/ и перезагружает плагин, файл которого изменился, — и
показывает под сборкой строки amxts из консоли этого сервера.
AMXTS_SERVER не используется.
build
npx amxts build # dist/: файлы .aot и plugins.ini
npx amxts build --deploy # и копирует их в AMXTS_SERVER, перезагружая сервер
npx amxts build --os linux # для сервера на Linux
npx amxts build --watch # и снова при каждом сохранении, без выкладки
pnpm amxts build # dist/: файлы .aot и plugins.ini
pnpm amxts build --deploy # и копирует их в AMXTS_SERVER, перезагружая сервер
pnpm amxts build --os linux # для сервера на Linux
pnpm amxts build --watch # и снова при каждом сохранении, без выкладки
yarn amxts build # dist/: файлы .aot и plugins.ini
yarn amxts build --deploy # и копирует их в AMXTS_SERVER, перезагружая сервер
yarn amxts build --os linux # для сервера на Linux
yarn amxts build --watch # и снова при каждом сохранении, без выкладки
bunx amxts build # dist/: файлы .aot и plugins.ini
bunx amxts build --deploy # и копирует их в AMXTS_SERVER, перезагружая сервер
bunx amxts build --os linux # для сервера на Linux
bunx amxts build --watch # и снова при каждом сохранении, без выкладки
plugins.ini перечисляет сначала модули, каждый после тех, что ему нужны,
потом плагины проекта. Модуль, которым не пользуется ни один плагин, в сборку
не попадает, если его не оставляет pawn (собирается только то, чем
пользуются). Куда писать,
меняет outDir в amxts.config.ts. Плагин, для которого с прошлой build
ничего не изменилось, берётся готовым, официальный модуль — каким пришёл
(dev); без node_modules/.cache/amxts все компилируются заново.
Система сервера
Плагин компилируется в машинный код под систему своего сервера, Windows или
Linux, и .aot, собранный под одну, не загрузится на другой. Систему сборка
берёт, по порядку:
--os windowsили--os linuxуbuildилиdev;AMXTS_SERVER_OSв окружении или.env;- папку
AMXTS_SERVER:hlds_linuxилиhlds.exeрядом с папкой игры, иначе файлы в еёaddons/amxmodx/modules; - систему машины, на которой идёт сборка.
Какую именно, говорит строка Server у dev и build: Linux. Так
проект, собранный на Windows, выкладывается на сервер на Linux как есть — когда AMXTS_SERVER указывает на него (например, на
подключённую сетевую папку) или в .env есть AMXTS_SERVER_OS=linux.
init спрашивает систему, когда её не видно по папке сервера, а info
показывает, какую выберет сборка.
.aot, собранный под другую систему, не загрузится, и консоль об этом
скажет: was compiled for a Linux server, and this one runs Windows (или
наоборот). .ts, который сервер компилирует сам, всегда собран под него.typecheck
npx amxts typecheck
pnpm amxts typecheck
yarn amxts typecheck
bunx amxts typecheck
Проверяет плагины и amxts.config.ts TypeScript'ом, так же, как редактор:
опечатку в настройке модуля, неверное имя события, поле, которого нет.
test
npx amxts test # все тесты проекта
npx amxts test hello # файлы, в имени которых есть "hello"
npx amxts test --watch # и снова на каждое сохранение
pnpm amxts test # все тесты проекта
pnpm amxts test hello # файлы, в имени которых есть "hello"
pnpm amxts test --watch # и снова на каждое сохранение
yarn amxts test # все тесты проекта
yarn amxts test hello # файлы, в имени которых есть "hello"
yarn amxts test --watch # и снова на каждое сохранение
bunx amxts test # все тесты проекта
bunx amxts test hello # файлы, в имени которых есть "hello"
bunx amxts test --watch # и снова на каждое сохранение
Запускает bun test: его параметры передаются как есть. Тест кладёт проект
на поддельный сервер через setup() — см. тесты.
module
npx amxts module add menu-core # @amxts/menu-core
npx amxts module add @you/greeter # любой пакет-модуль из npm
npx amxts module add ../greeter # модуль из папки
npx amxts module list
pnpm amxts module add menu-core # @amxts/menu-core
pnpm amxts module add @you/greeter # любой пакет-модуль из npm
pnpm amxts module add ../greeter # модуль из папки
pnpm amxts module list
yarn amxts module add menu-core # @amxts/menu-core
yarn amxts module add @you/greeter # любой пакет-модуль из npm
yarn amxts module add ../greeter # модуль из папки
yarn amxts module list
bunx amxts module add menu-core # @amxts/menu-core
bunx amxts module add @you/greeter # любой пакет-модуль из npm
bunx amxts module add ../greeter # модуль из папки
bunx amxts module list
module add ставит пакет менеджером пакетов проекта (его узнаёт по
lock-файлу) и добавляет в modules в amxts.config.ts, а за ним — модули,
которые ему нужны и которых в списке ещё нет, каждый с комментарием
// needed by menu-core; меняется только список, остальной файл остаётся как
вы его написали. Короткое имя — имя
модуля в каталоге модулей: menu-core — это @amxts/menu-core.
Пакет, которого нет в каталоге, всё равно ставится из npm, но с
предупреждением; пакет, который не модуль amxts, ставится, но в конфиг не
добавляется. Модуль из npm приходит в своей новейшей версии, которая работает
с ядром проекта. Каталог команда читает из реестра на GitHub, а без сети
берёт копию, с которой была опубликована.
| параметр | что делает |
|---|---|
--skip-install | только добавить в amxts.config.ts |
--skip-config | только поставить |
--local | официальный модуль из его папки на этой машине, ссылкой, — для работы над самим amxts |
module list показывает модули из конфига и стоят ли они, стоящие модули,
которых нет в конфиге, и модули каталога, которых у проекта ещё нет, — модуль
сообщества помечен (community):
In amxts.config.ts
✔ @amxts/menu-core 0.2.0 An opinionated way to create menus
✔ @amxts/config-core 0.1.1 Configs in INI, YAML or JSON, read into typed objects and written back
In the amxts catalog
○ resemiclip Semiclip over the ReSemiclip module - who walks through whom, as a rule over two players - npx amxts module add resemiclip
○ ftp FTP, FTPS and SFTP - upload, download and list files on another server, every call a promise - npx amxts module add ftp
check
npx amxts check
pnpm amxts check
yarn amxts check
bunx amxts check
В папке модуля, перед публикацией: поле amxts указывает на существующие
файлы, у файла модуля есть defineModule с meta.name, есть README.md и
LICENSE, а include/<имя>.inc совпадает с тем, что сборка пишет из
нативов. Ничего не записывает. См. свой модуль.
prepare
npx amxts prepare
pnpm amxts prepare
yarn amxts prepare
bunx amxts prepare
Получает include сервера, если их ещё нет, и пишет в
.amxts/ то, что читает редактор:
.amxts/tsconfig.json, который расширяетtsconfig.jsonпроекта:~/— папка плагинов,@amxts/coreи его точки входа — API ядра, модули находятся по именам, аamxts.config.tsполучает типы из них;.amxts/imports.d.ts— то, чем плагины пользуются без импорта, глобальными именами для редактора (автоимпорты);.amxts/api/— только когдаAMXTS_DOCS_LANGвыбирает не английский: копия API ядра и модулей с подсказками на этом языке, которую редактор читает вместо установленных пакетов. Пакеты вnode_modulesне меняются никогда, а собирает сборка именно их, поэтому плагины выходят одинаковыми на любом языке.
build, dev и typecheck делают это первым шагом, init — после
установки. .amxts/ принадлежит команде: она в .gitignore и пишется
заново, когда устарела.
upgrade с v0.2
npx amxts upgrade # до последнего выпуска
npx amxts upgrade --to 0.2.0 # до выпуска на ваш выбор
npx amxts upgrade --dry-run # что изменилось бы, ничего не меняя
pnpm amxts upgrade # до последнего выпуска
pnpm amxts upgrade --to 0.2.0 # до выпуска на ваш выбор
pnpm amxts upgrade --dry-run # что изменилось бы, ничего не меняя
yarn amxts upgrade # до последнего выпуска
yarn amxts upgrade --to 0.2.0 # до выпуска на ваш выбор
yarn amxts upgrade --dry-run # что изменилось бы, ничего не меняя
bunx amxts upgrade # до последнего выпуска
bunx amxts upgrade --to 0.2.0 # до выпуска на ваш выбор
bunx amxts upgrade --dry-run # что изменилось бы, ничего не меняя
::: warning Сначала сама команда
upgrade — команда пакета @amxts/cli, и проект запускает ту его версию, с которой пришло его ядро, или ту, что названа в его собственном package.json. Если в команде проекта ещё нет upgrade, сначала добавьте новейшую команду тем менеджером пакетов, что у проекта:
npm i @amxts/cli@latest # или: bun add @amxts/cli@latest, pnpm add @amxts/cli@latest, yarn add @amxts/cli@latest
npx amxts upgrade
pnpm add @amxts/cli@latest # или: bun add @amxts/cli@latest, pnpm add @amxts/cli@latest, yarn add @amxts/cli@latest
pnpm amxts upgrade
yarn add @amxts/cli@latest # или: bun add @amxts/cli@latest, pnpm add @amxts/cli@latest, yarn add @amxts/cli@latest
yarn amxts upgrade
bun add @amxts/cli@latest # или: bun add @amxts/cli@latest, pnpm add @amxts/cli@latest, yarn add @amxts/cli@latest
bunx amxts upgrade
:::
Переводит проект на другой выпуск amxts за один раз:
- Пакеты.
@amxts/coreпереходит на последнюю версию в реестре или на--to. У каждого другого пакета@amxts/вpackage.json— официальных модулей, команды — своя версия, и он переходит на свою новейшую версию, которая работает с этим ядром: модуль называет ядра, с которыми работает, в своихpeerDependencies. Каждая записывается так, как её пишет проект:^0.1.0становится^0.2.0,0.1.0—0.2.0. Пакет из папки (file:) остаётся как есть; модуль, у которого ещё нет версии для этого ядра, останавливает перевод до любых изменений. Ставит их пакетный менеджер проекта — тот, чей lock-файл в проекте, — из реестра, на который настроен npm (.npmrc,NPM_CONFIG_REGISTRY). - Код переписывается под новый API новым ядром, каждое изменение перечисляется: код, ниже.
- Сборка — как её делает
amxts build. - Сервер из
AMXTS_SERVER: его модуль — и компилятор.ts, написанных на сервере, если он там есть, — из GitHub Release новой версии, каждый файл сверяется с sha256 из списка выпуска. Заменённый файл остаётся рядом со своей версией:amxts_amxx.dll.0.1.0. Строкаamxts_host.amxxвplugins.iniAMX Mod X убирается: модуль загружает свой host-плагин сам. БезAMXTS_SERVER— для сервера в Docker — говорит, какой образ скачать. - Итог: версии, переписанные файлы, что проверить вручную и что стало с сервером.
amxts 0.2.0 · upgrade
◇ Packages: amxts 0.2.0 (latest)
i @amxts/core ^0.1.0 → ^0.2.0
i @amxts/cli ^0.1.0 → ^0.2.0
i @amxts/menu-core ^0.1.0 → ^0.2.0
i @amxts/config-core ^0.1.0 → ^0.1.1
◇ Installing with npm
✔ Installed with npm
◇ Code
plugins/hello.ts:1 ~/natives → @amxts/core/natives
plugins/hello.ts:9 player.account → player.money
◇ Build
...
✔ built hello into dist (11.4s)
◇ Server: D:/hlds/cstrike (windows)
✔ amxts_amxx.dll 0.1.0 → 0.2.0 (the old one: amxts_amxx.dll.0.1.0)
✔ Took amxts_host.amxx out of D:/hlds/cstrike/addons/amxmodx/configs/plugins.ini: the module loads it itself
Upgraded to amxts 0.2.0
@amxts/core 0.1.0 → 0.2.0
@amxts/cli 0.1.0 → 0.2.0
@amxts/menu-core 0.1.0 → 0.2.0
@amxts/config-core 0.1.0 → 0.1.1
✔ rewritten: plugins/hello.ts
▲ to check by hand:
plugins/shop.ts:14 it reads the words after the name: write them in the usage, "/give <amount>", and take them by name, ({ player, amount })
✔ built
✔ server: amxts_amxx.dll 0.1.0 → 0.2.0 - restart the server to load it
| параметр | что делает |
|---|---|
--to <version> | выпуск, на который перейти, вместо последнего |
--no-server | не трогать сервер |
--server-only | только шаг сервера — для сервера, который был запущен |
--dry-run | вывести, что было бы сделано: ничего не ставится и не пишется, из выпуска читается только список файлов |
Пробный запуск перечисляет правки кода, только когда в проекте уже стоит эта версия ядра: до установки нового ядра спросить ещё некого.
Проект запускает ту команду, с которой пришло его ядро. amxts более
старого выпуска ставит новые пакеты, а остальное — код, сборку, сервер —
передаёт новой команде проекта.
Сервер на Windows держит свой модуль, пока работает, и заменить файл тогда нельзя.
upgrade ничего не меняет на сервере, говорит об этом и делает
остальное: остановите сервер и запустите npx amxts upgrade --server-only.
На любой системе новый модуль загружается при следующем старте.Код
Новое ядро приводит код проекта к своему API и перечисляет каждую
изменённую строку. Импорт API ядра через ~/ становится импортом по имени
пакета, а импорт пакета модуля по его месту в сборке
(~/modules/menu-core) — импортом по имени модуля:
import { user_slap } from "~/natives"; // было
import { user_slap } from "@amxts/core/natives"; // стало
Код читается парсером TypeScript: меняются импорты, экспорты, import() и
declare module; строка или комментарий, которые только похожи на импорт, —
нет. Ваши собственные файлы через ~/ остаются как есть. Второй запуск
ничего не меняет. Команда проходит все .ts проекта — плагины, тесты,
исходники модуля, — но не node_modules и dist/.
Обработчик команды получает один объект
(команды): (player) => становится
({ player }) =>, а функция, переданная по имени и принимающая игрока,
вызывается из ({ player }) => name(player); (player, args) =>, который
не читает args, тоже становится ({ player }) =>. Обработчик, который читает
слова после имени команды, выводится в список со строкой — его переписывают
руками: слова идут в использование, "/give <amount>", а обработчик берёт их
по имени.
Код menu-core приводится к контексту меню
(меню): addItem("text", options) становится
addItem({ title: "text", ... }), и так же addFixedItem; (player) => и
(player, target) => становятся ({ player }) => и ({ player, target }) => — в пункте, в настройках меню, в фильтре, в источнике списка и в том, что
регистрируется по имени. Функция, переданная по имени и объявленная в файле,
вызывается из стрелки, которая передаёт ей то, что она принимала. В список —
переписать руками — попадают функция, объявленная в другом файле, имя меню,
прочитанное как текст, цель, переданная числом, и menus.runActions — это
метод меню (menu.runActions).
Имена следуют API: Player.all() становится
server.players, а его поля —
filter: Player.all({ alive: true, team: "CT" }) — это
server.players.filter(player => player.isAlive && player.team === "CT");
там, где в коде уже есть player, как в обработчике команды, игрок фильтра
зовётся other (или p), чтобы ничего не скрыть.
Поле, метод или событие игры, названные словами движка, получают слова
игрока: player.account становится player.money, player.authid —
player.steamId, game.numCtWins —
game.ctWins, weapon.inReload — weapon.isReloading, событие
restartRound — newRound, а класс события следует за его именем. Значение
считается игроком, оружием или игрой там, где файл это говорит, —
event.player, аннотация Player, Client или Weapon, { player } из события
или команды, первый параметр обработчика команды, элемент server.players, player.activeItem, game. В список,
чтобы поправить руками, выводятся: старое имя у любого другого значения, поля,
записанные не литералами, и поле или событие, которых в API нет, — до них
по-прежнему достают нативы @amxts/core/natives (get_member,
RegisterHookChain). Игрок теста тоже заходит со steamId:
server.join("Alice", { authid }) становится
server.join("Alice", { steamId: authid }).
Событие сервера называется словами автора плагина
(события сервера):
server.addEventListener("putinserver", ...) становится
server.addEventListener("putInServer", ...), "cfg" — "pluginsLoaded",
"kill" — "suicide", а собственное имя форварда ("client_putinserver") —
именем события. Событие, которое есть событие игры, слушается через game:
server.addEventListener("PreThink", ...) становится
game.addEventListener("preThink", ...), так же "PostThink", "pfnTouch"
("touch") и "infochanged" ("userInfoChange"). Поле события, названное
по параметру Pawn, получает слово автора там, где файл говорит, какое это
событие, — в обработчике или у параметра с классом события:
event.weapon_entity становится event.weapon, event.authid —
event.steamId, event.tracehandle —
event.trace, event.infobuffer — event.info, а ({ dir }) —
({ direction: dir }). В список на ручную правку попадают "CS_OnBuy" и
"CS_OnBuyAttempt" модуля cstrike: это события игры buyWeapon, buyItem,
buyAmmo и itemRestricted.
Сообщение игры слушается своим методом, по имени в словах игрока
(сообщения):
server.addEventListener("message:DeathMsg", ...) становится
server.addMessageListener("death", ...), а removeEventListener —
removeMessageListener. Имя сообщения, которого у игры нет, выводится в
список.
Имя флага — lowerCamelCase (флаги):
player.buttons.includes("Jump") становится
player.buttons.includes("jump"), { access: "Kick" } —
{ access: "kick" }. Строка считается флагом там, где файл это говорит:
она присваивается свойству-флагу или опциям buttons и access, передаётся
в includes, push или concat такого свойства или в
player.screen.hideHud, сравнивается с его элементом — в его filter,
for of, switch — или хранится в имени флагового типа (Button,
HideHud[]). Имя, переданное туда, где ждут флаги, прослеживается до
списка, с которым оно объявлено; то, чего файл не говорит, — параметр без
типа, импорт, результат функции — выводится в список.
info
npx amxts info
pnpm amxts info
yarn amxts info
bunx amxts info
Всё, что нужно для отчёта об ошибке: система, Node, Bun, менеджер пакетов,
команда, ядро и его компиляторы, модули проекта, AMXTS_SERVER и система,
под которую компилируются плагины.
amxts info - paste this into a bug report
Operating system Windows 10.0.19045 (x64)
Node.js 24.18.0
Bun 1.4.2
Package manager npm 11.16.0
@amxts/cli 0.2.0
@amxts/core 0.2.0
AssemblyScript 0.28.20 + amxts patch
WAMR 2.4.5 + amxts patch, wamrc found
Project my-server
Modules @amxts/menu-core 0.2.0
AMXTS_SERVER D:/hlds/cstrike/addons/amxts
Server system Windows (hlds.exe)
AMXTS_DOCS_LANG en
Быстрый старт
amxts запускает плагины для Counter-Strike 1.6, написанные на TypeScript, внутри AMX Mod X, рядом с вашими плагинами на Pawn. Плагин — обычный файл .ts: игроки — объекты, у событий есть типы, а редактор знает каждое поле игры. На этой странице — проект, первый плагин, как перезагружать его во время работы и чем язык отличается от привычного TypeScript.
Установка на сервер
Чтобы игровой сервер запускал плагины amxts, на нём нужны две вещи: модуль amxts_amxx и папка addons/amxts с плагинами. На этой странице — как поставить их на свой сервер. Другой путь — сервер в Docker, в котором всё это уже есть.