[{"data":1,"prerenderedAt":5097},["ShallowReactive",2],{"navigation-docs_en":3,"changelog":140,"next-docs":205,"mdc-rwjiqt-key":206,"mdc--ib3x3i-key":345,"mdc--sie7mm-key":446,"mdc-c28aal-key":547,"mdc--pucxqt-key":770,"mdc--2eh68j-key":1117,"mdc--lwq6cb-key":1390,"mdc--wrs5ty-key":1617,"mdc--ohzeac-key":2196,"mdc--ityaww-key":2204,"mdc-txennw-key":2212,"mdc-uhv7fj-key":4510,"mdc-mavv6t-key":4553},[4,35,61,91,109,123,133],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":34},"Getting started","i-lucide-rocket","\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started",[10,14,18,22,26,30],{"title":11,"path":12,"stem":13},"Introduction","\u002Fdocs\u002Fgetting-started\u002Fintroduction","docs\u002F1.getting-started\u002F01.introduction",{"title":15,"path":16,"stem":17},"Quick start","\u002Fdocs\u002Fgetting-started\u002Fquick-start","docs\u002F1.getting-started\u002F02.quick-start",{"title":19,"path":20,"stem":21},"CLI","\u002Fdocs\u002Fgetting-started\u002Fcli","docs\u002F1.getting-started\u002F03.cli",{"title":23,"path":24,"stem":25},"Installing on a server","\u002Fdocs\u002Fgetting-started\u002Finstall","docs\u002F1.getting-started\u002F04.install",{"title":27,"path":28,"stem":29},"A server in Docker","\u002Fdocs\u002Fgetting-started\u002Fdocker","docs\u002F1.getting-started\u002F05.docker",{"title":31,"path":32,"stem":33},"Limitations","\u002Fdocs\u002Fgetting-started\u002Flimitations","docs\u002F1.getting-started\u002F06.limitations",false,{"title":36,"icon":37,"path":38,"stem":39,"children":40,"page":34},"Core","i-lucide-zap","\u002Fdocs\u002Fcore","docs\u002F2.core",[41,45,49,53,57],{"title":42,"path":43,"stem":44},"Plugin","\u002Fdocs\u002Fcore\u002Fplugin","docs\u002F2.core\u002F01.plugin",{"title":46,"path":47,"stem":48},"Game events","\u002Fdocs\u002Fcore\u002Fhooks","docs\u002F2.core\u002F02.hooks",{"title":50,"path":51,"stem":52},"Forwards","\u002Fdocs\u002Fcore\u002Fforwards","docs\u002F2.core\u002F03.forwards",{"title":54,"path":55,"stem":56},"Async and promises","\u002Fdocs\u002Fcore\u002Fasync","docs\u002F2.core\u002F04.async",{"title":58,"path":59,"stem":60},"Performance","\u002Fdocs\u002Fcore\u002Fperformance","docs\u002F2.core\u002F05.performance",{"title":62,"icon":63,"path":64,"stem":65,"children":66,"page":34},"Game","i-lucide-gamepad-2","\u002Fdocs\u002Fgame","docs\u002F3.game",[67,71,75,79,83,87],{"title":68,"path":69,"stem":70},"Players and entities","\u002Fdocs\u002Fgame\u002Fentities","docs\u002F3.game\u002F01.entities",{"title":72,"path":73,"stem":74},"Players: actions","\u002Fdocs\u002Fgame\u002Fplayers","docs\u002F3.game\u002F02.players",{"title":76,"path":77,"stem":78},"Effects","\u002Fdocs\u002Fgame\u002Feffects","docs\u002F3.game\u002F03.effects",{"title":80,"path":81,"stem":82},"Flags","\u002Fdocs\u002Fgame\u002Fflags","docs\u002F3.game\u002F04.flags",{"title":84,"path":85,"stem":86},"Cvars","\u002Fdocs\u002Fgame\u002Fcvars","docs\u002F3.game\u002F05.cvars",{"title":88,"path":89,"stem":90},"Messages","\u002Fdocs\u002Fgame\u002Fmessages","docs\u002F3.game\u002F06.messages",{"title":92,"icon":93,"path":94,"stem":95,"children":96,"page":34},"Data","i-lucide-database","\u002Fdocs\u002Fdata","docs\u002F4.data",[97,101,105],{"title":98,"path":99,"stem":100},"Storage","\u002Fdocs\u002Fdata\u002Fstorage","docs\u002F4.data\u002F01.storage",{"title":102,"path":103,"stem":104},"Files","\u002Fdocs\u002Fdata\u002Ffs","docs\u002F4.data\u002F02.fs",{"title":106,"path":107,"stem":108},"HTTP","\u002Fdocs\u002Fdata\u002Fhttp","docs\u002F4.data\u002F03.http",{"title":110,"icon":111,"path":112,"stem":113,"children":114,"page":34},"Modules","i-lucide-package","\u002Fdocs\u002Fmodules","docs\u002F5.modules",[115,119],{"title":116,"path":117,"stem":118},"Shared modules","\u002Fdocs\u002Fmodules\u002Fshared-modules","docs\u002F5.modules\u002F01.shared-modules",{"title":120,"path":121,"stem":122},"Creating a module","\u002Fdocs\u002Fmodules\u002Fcreating-a-module","docs\u002F5.modules\u002F02.creating-a-module",{"title":124,"icon":125,"path":126,"stem":127,"children":128,"page":34},"Pawn","i-lucide-plug","\u002Fdocs\u002Fpawn","docs\u002F6.pawn",[129],{"title":130,"path":131,"stem":132},"Natives","\u002Fdocs\u002Fpawn\u002Fnatives","docs\u002F6.pawn\u002F01.natives",{"title":134,"path":135,"stem":136,"children":137,"icon":139},"Testing","\u002Fdocs\u002Ftesting","docs\u002F7.testing\u002F01.index",[138],{"title":134,"path":135,"stem":136},"i-lucide-flask-conical",[141,147,152,158,164,168,173,179,183,187,191,196,201],{"repo":142,"version":143,"date":144,"body":145,"url":146},"config-core","v0.1.2","2026-10-04T18:46:46Z","[compare changes](https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcompare\u002Fv0.1.1...v0.1.2)\n\n### Summary\n\nBuilt for `@amxts\u002Fcore` 0.2.2: the package's prebuilt plugin is compiled with that core, so a project on 0.2.2 takes it as it is instead of compiling the module on its first build. The module's API does not change.\n\n### ⬆️ Upgrade guide\n\n`npx amxts upgrade` in the project takes it with the core.\n\n### 📦 Dependencies\n\n| Package | Range |\n| --- | --- |\n| `@amxts\u002Fcore` | `^0.2.0`, prebuilt for 0.2.2 |\n\n### ❤️ Contributors\n\n- Ernest Manukyan ([@kukson777](https:\u002F\u002Fgithub.com\u002Fkukson777))\n","https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Freleases\u002Ftag\u002Fv0.1.2",{"repo":148,"version":143,"date":149,"body":150,"url":151},"resemiclip","2026-10-04T18:46:43Z","[compare changes](https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcompare\u002Fv0.1.1...v0.1.2)\n\n### Summary\n\nBuilt for `@amxts\u002Fcore` 0.2.2: the package's prebuilt plugin is compiled with that core, so a project on 0.2.2 takes it as it is instead of compiling the module on its first build. The module's API does not change.\n\n### ⬆️ Upgrade guide\n\n`npx amxts upgrade` in the project takes it with the core.\n\n### 📦 Dependencies\n\n| Package | Range |\n| --- | --- |\n| `@amxts\u002Fcore` | `^0.2.0`, prebuilt for 0.2.2 |\n\n### ❤️ Contributors\n\n- Ernest Manukyan ([@kukson777](https:\u002F\u002Fgithub.com\u002Fkukson777))\n","https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Freleases\u002Ftag\u002Fv0.1.2",{"repo":153,"version":154,"date":155,"body":156,"url":157},"menu-core","v0.2.1","2026-10-04T18:46:40Z","[compare changes](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcompare\u002Fv0.2.0...v0.2.1)\n\n### Summary\n\nBuilt for `@amxts\u002Fcore` 0.2.2: the package's prebuilt plugin is compiled with that core, so a project on 0.2.2 takes it as it is instead of compiling the module on its first build. The module's API does not change.\n\n### ⬆️ Upgrade guide\n\n`npx amxts upgrade` in the project takes it with the core.\n\n### 📦 Dependencies\n\n| Package | Range |\n| --- | --- |\n| `@amxts\u002Fcore` | `^0.2.0`, prebuilt for 0.2.2 |\n\n### ❤️ Contributors\n\n- Ernest Manukyan ([@kukson777](https:\u002F\u002Fgithub.com\u002Fkukson777))\n","https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Freleases\u002Ftag\u002Fv0.2.1",{"repo":159,"version":160,"date":161,"body":162,"url":163},"amxts","v0.2.2","2026-10-04T18:46:08Z","[compare changes](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcompare\u002Fv0.2.1...v0.2.2)\n\n### Summary\n\nA fix for a server that crashed at start on some AMX Mod X builds: the module registered its server commands with fewer arguments than AMX Mod X reads, and AMX Mod X read a command's description from leftover memory. Whether it crashed depended on the AMX Mod X build and the plugins loaded - most often with one or two plugins. The server suites run on AMX Mod X 1.9 and the newest 1.10 as well from now on.\n\n### ⬆️ Upgrade guide\n\n`npx amxts upgrade` in the project, with the server stopped: it moves `@amxts\u002Fcore` to 0.2.2, builds the plugins again and puts the 0.2.2 module on the server named in `.env`. A server installed by hand takes the module (and `amxts-compile`, where it has one) from this release, and its plugins are built again.\n\n### 🩹 Fixes\n\n- **runtime:** No crash at start on some AMX Mod X builds: every native the module calls - `register_srvcmd`, `register_clcmd`, `set_task`, `RegisterHam` - gets all its parameters ([c02eb1e](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcommit\u002Fc02eb1e))\n\n### ❤️ Contributors\n\n- Ernest Manukyan ([@kukson777](https:\u002F\u002Fgithub.com\u002Fkukson777))\n\n### 📦 Files\n\n- `amxts-server-windows-x64.zip`, `amxts-server-linux-x64.tar.gz` - the server kit: the module, and the compiler for `.ts` plugins written on the server.\n- `amxts_amxx.dll`, `amxts_amxx_i386.so` - the module alone.\n- `amxts-compile-*`, `wamrc-*` - the on-server compiler and WAMR's AOT compiler, per system.\n- `amxts-windows.json`, `amxts-linux.json` - what each was built from, with every file's sha256.\n","https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Freleases\u002Ftag\u002Fv0.2.2",{"repo":159,"version":154,"date":165,"body":166,"url":167},"2026-10-04T13:50:26Z","[compare changes](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcompare\u002Fv0.2.0...v0.2.1)\n\n### Summary\n\nFixes for 0.2.0: a plugin's call could fail at random when a native wrote into a buffer near the end of its memory, a build after an upgrade could keep plugins of the old version that the new module refuses, `amxts upgrade` rewrote the module's own files when the project lives in the server's folder, and the editor marked `error.message` in a `catch` as an error.\n\n### ⬆️ Upgrade guide\n\n`npx amxts upgrade` in the project: it moves `@amxts\u002Fcore` to 0.2.1, builds the plugins again and puts the 0.2.1 module on the server named in `.env`. A server installed by hand takes the module (and `amxts-compile`, where it has one) from this release; the plugins are built again, since the module loads only plugins of its own release.\n\n### 🩹 Fixes\n\n- **module:** Start on a server with an older Visual C++ runtime: the network thread's lock crashed Windows servers whose `msvcp140.dll` predates Visual Studio 2022 17.10 ([04dbe6b](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcommit\u002F04dbe6b))\n- **runtime:** A native whose array size the include does not give - `get_players`, which `server.players` calls, among them - no longer fails the plugin's call when the array lies near the end of the plugin's memory ([e5dee94](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcommit\u002Fe5dee94))\n- **editor:** `catch (error)` reads `error.message` without a cast, as the compiler and the docs do ([d2875cf](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcommit\u002Fd2875cf))\n- **build:** A plugin is compiled again when the core's version changes: after an upgrade the build cache could hand back a plugin of the old version, which the new module refuses ([7abae6c](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcommit\u002F7abae6c))\n- **upgrade:** The module's own files are left alone - the API it writes into `addons\u002Famxts\u002Fplugins\u002F` - when the project lives in the server's folder ([c400c24](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcommit\u002Fc400c24))\n- **testing:** The test server raises `configsQueued` and `configsExecuted` when the map starts, as AMX Mod X does ([2be9123](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcommit\u002F2be9123))\n\n### ❤️ Contributors\n\n- Ernest Manukyan ([@kukson777](https:\u002F\u002Fgithub.com\u002Fkukson777))\n\n### 📦 Files\n\n- `amxts-server-windows-x64.zip`, `amxts-server-linux-x64.tar.gz` - the server kit: the module, and the compiler for `.ts` plugins written on the server.\n- `amxts_amxx.dll`, `amxts_amxx_i386.so` - the module alone.\n- `amxts-compile-*`, `wamrc-*` - the on-server compiler and WAMR's AOT compiler, per system.\n- `amxts-windows.json`, `amxts-linux.json` - what each was built from, with every file's sha256.\n","https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Freleases\u002Ftag\u002Fv0.2.1",{"repo":159,"version":169,"date":170,"body":171,"url":172},"v0.2.0","2026-10-04T07:14:52Z","[compare changes](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcompare\u002Fv0.1.0...v0.2.0)\n\n### Summary\n\n0.2.0 makes a server one module to install and runs it on Valve's own HLDS as well as ReHLDS. Plugins get commands with typed arguments, menus, `fetch`, FTP and SFTP, bots, game messages by name, errors that point at their TypeScript, and names in the player's words. A 0.1.0 project moves over with `amxts upgrade`.\n\n### ✨ Highlights\n\n#### One module to install\n\nA server needs the `addons\u002F` folder of the server kit and one line in `modules.ini`:\n\n```\namxts_amxx\n```\n\nNothing goes into `plugins.ini`: the module brings its host plugin itself, writes it next to AMX Mod X's plugins when it starts, and removes it when it stops. An install from 0.1.0 can drop its `amxts_host.amxx` line; the console says so once.\n\n#### Plain HLDS\n\namxts runs on Valve's own HLDS as well as on ReHLDS. The same plugin works on both, unchanged:\n\n- every property of an entity and a player;\n- the game events Ham Sandwich shares with ReAPI - `takeDamage`, `spawn`, `killed`, `jump` and more;\n- rounds (`newRound`, `roundStart`, `roundEnd`), spawns, purchases, money and the bomb, heard through the game's own log lines and messages - after the fact, so `preventDefault()` on them says once that it cannot stop them.\n\nWhat plain HLDS cannot give at all - ReGameDLL's own functions - prints one line in the console when a plugin listens for it, and a project with `target: \"hlds\"` does not build with such a listener. Each event's page says how it behaves on plain HLDS.\n\n#### Faster properties\n\n`entity.origin`, `player.health`, `player.money` and every other field are read and written where the game keeps them, on both servers, without a native call. A field the player sees on the HUD - `money`, the armor type, the flashlight's battery, night vision, the defuse kit - is sent to the player as the game sends it.\n\n#### Commands with typed arguments\n\nThe usage is the command's help and its parser at once: `\u003Cname>` is required, `[name]` optional, and the interface you name says what each one is.\n\n```ts\ninterface KickArgs {\n\ttarget: Player;\n\treason?: string;\n}\n\nserver.addCommand\u003CKickArgs>(\"\u002Fkick \u003Ctarget> [reason]\", ({ player, target, reason }) => {\n\ttarget.kick(reason ?? `Kicked by ${player.name}`);\n}, { access: \"Kick\", description: \"Kick a player\" });\n```\n\n- a `Player` is found by `#userid`, by the whole name or by a part of it;\n- a `number` is parsed, a union of words is one of them, the last text argument takes the rest of the line;\n- a player nobody's name matches, several whose do, or a word too many answers the one who typed it with the usage, and the handler does not run;\n- without the type argument every argument is text.\n\n`player` is always the one who typed the command. `server.commands` lists every command with its usage, description and access, for a `\u002Fhelp` of your own.\n\n#### Menus\n\n`Menu` is AMX Mod X's own menu - number keys, pages with Back and More, Exit - written as objects. Each item has a title, and may say when it is shown (`visible`) and when it can be chosen (`enabled`, drawn grey otherwise); both are asked again at every `show`, for the player it is shown to. Choosing an item runs its `onSelect` and closes the menu.\n\n```ts\nconst shop = new Menu(\"Shop\");\n\nshop.addItem({\n\ttitle: \"Armor - $1000\",\n\tenabled: ({ player }) => player.money >= 1000,\n\tonSelect: ({ player }) => {\n\t\tplayer.armor = 100;\n\t\tplayer.money -= 1000;\n\t},\n});\n\nshop.addItem({\n\ttitle: ({ player }) => `Heal (${player.health} HP)`,\n\tvisible: ({ player }) => player.isAlive,\n\tonSelect: ({ player }) => {\n\t\tplayer.health = 100;\n\t},\n});\n\nserver.addCommand(\"\u002Fshop\", ({ player }) => shop.show(player));\n```\n\nA menu of the players on the server is a loop over `server.players`, one item for each. The official `@amxts\u002Fmenu-core` takes the same shape in code - `menus.create(...)`, `addItem({ title, visible, enabled, onSelect })` with `({ player })` - and adds menus read from INI, YAML or JSON files, named conditions and actions, and lists with a row per player (`({ player, target })`).\n\n#### `fetch` and `useFetch`, as in the browser\n\nHTTPS, redirects, timeouts and retries, on a thread of their own, so the game never waits. `useFetch` never throws: it gives back `data` (the JSON, read as the type you name), `error` and `status`.\n\n```ts\ninterface Weather {\n\ttemperature: number;\n}\n\nserver.addCommand(\"\u002Fweather\", async ({ player }) => {\n\tconst { data } = await useFetch\u003CWeather>(\"https:\u002F\u002Fapi.example.com\u002Fweather\", {\n\t\tquery: { city: \"Riga\" },\n\t\ttimeout: 5000,\n\t\tretry: 2,\n\t});\n\n\tif (data) print(player, `${data.temperature}°`);\n\telse print(player, \"The weather service is not answering\");\n});\n```\n\n`fetch` is the browser's own beneath it, for a raw `Response`, headers and streams.\n\n#### `@amxts\u002Fftp`\n\nA new official module: FTP, FTPS and SFTP, since game hosts give access to a server by those. Every call is a promise on the same network thread as `fetch`; files go between the game folder and the other server whole, binary included (maps, demos), without passing through the plugin.\n\n```ts\nimport { ftp } from \"@amxts\u002Fftp\";\n\nconst client = await ftp.connect(\"sftp:\u002F\u002Fbackup@example.com\", { password: settings.password });\nawait client.upload(\"addons\u002Famxmodx\u002Flogs\u002Ftoday.log\", \"logs\u002Ftoday.log\");\nawait client.download(\"\u002Fmaps\u002Fde_dust2.bsp\", \"maps\u002Fde_dust2.bsp\");\nconst entries = await client.list(\"\u002Fconfigs\");\nawait client.close();\n```\n\nSFTP takes a password or an RSA key, and can check the host's key. Keep the password in a config, not in the code.\n\n#### Bots\n\nA fake client is a player like any other: it is in `server.players`, it joins a team, it can be kicked. It has no AI of its own; `move` drives it, one frame at a time.\n\n```ts\nconst bot = server.addBot(\"Spectator\");   \u002F\u002F Player | null when the server is full\nbot?.joinTeam(\"SPECTATOR\");\n\nconst runner = server.addBot(\"Runner\");\nserver.addEventListener(\"frame\", () => runner?.move({ forward: 250, buttons: [\"jump\"], angles: [0, 90, 0] }));\n```\n\nThe natives with a `...` tail - `engfunc`, `dllfunc`, `pev`, `ExecuteHam` and the rest - take text, floats and vectors as well as numbers, and what a native writes back is read through `Ref`:\n\n```ts\nconst id = engfunc(EngFunc_CreateFakeClient, \"Dummy\");\nconst reason = new Ref(\"\");\ndllfunc(DLLFunc_ClientConnect, id, \"Dummy\", \"127.0.0.1\", reason);\n```\n\n#### Game messages by name\n\nA message the game sends a player is heard by its name, in the player's words, with typed fields:\n\n```ts\nserver.addMessageListener(\"death\", (event) => {\n\tif (event.headshot) print(0, `${event.killer?.name} - headshot - ${event.victim?.name}`);\n});\n\nserver.addMessageListener(\"progressBar\", (event) => {\n\tconsole.log(`a bar for ${event.seconds} s, from ${event.startPercent}%`);\n});\n```\n\nEvery message has a description, with the game's own name (`DeathMsg`, `BarTime`) beside it, so a Pawn author finds it. Where the game sends one thing in several messages, one name hears them all: `progressBar` (from zero or from a percent), `spectatedHealth` (the health of the player a spectator watches), `hint` (the hint box, with or without texts put into it). `player.screen.progressBar(5, { startPercent: 40 })` shows one.\n\n#### Errors that point at your code\n\nWhen a call fails - a `null` read with `!`, an error nobody catches, a stack overflow - the console prints the TypeScript stack, file, line and column, with the source line itself:\n\n```\n[amxts] shop.aot: TypeError: Unexpected 'null'\n    at price (plugins\u002Fshop\u002Fshop.ts:26:9)\n      26 |   return item!.price;\n    at onSelect (plugins\u002Fshop\u002Fshop.ts:30:15)\n```\n\n`console.error(error)` and `error.stack` give the same stack. The map from the plugin's code to its TypeScript travels inside each `.aot`; the source line appears where the `.ts` is next to the plugin, as in `amxts dev`.\n\n#### Names in the player's words\n\nThe API speaks the way players and plugin authors do, not the way the game's source does:\n\n| 0.1.0 | 0.2.0 |\n| --- | --- |\n| `Player.all()` | `server.players` |\n| `player.account` | `player.money` |\n| `restartRound`, `onRoundFreezeEnd` | `newRound`, `roundStart` |\n| `flPlayerFallDamage`, `fPlayerCanTakeDamage` | `fallDamage`, `canTakeDamage` |\n| `fireBullets3` | `shoot` |\n| `game.c4Guy`, `game.numCtWins` | `game.bomber`, `game.ctWins` |\n| `server.addEventListener(\"message:DeathMsg\", ...)` | `server.addMessageListener(\"death\", ...)` |\n| `buttons: [\"Jump\"]`, access `\"Kick\"` | `buttons: [\"jump\"]`, access `\"kick\"` |\n\nGame messages have named, typed fields too: `event.killer`, `event.victim`, `event.headshot` on `DeathMsg`. Fields that mean nothing to a plugin - the AI members of a player, Condition Zero's career - are left to `@amxts\u002Fcore\u002Fnatives`.\n\n`amxts upgrade` rewrites a 0.1.0 project: imports, command handlers, `Player.all` and every renamed field and event. What it cannot be sure of, it lists.\n\n### ⚠️ Breaking changes\n\n- `Player.all(filter)` is `server.players`; filter it with `.filter(...)`.\n- Renamed fields and events: `player.account` is `player.money`; `restartRound`, `onRoundFreezeEnd` and `addAccount` are `newRound`, `roundStart` and `addMoney`; `fireBullets3` is `shoot`; about a hundred more follow the same rule (the full list is in `amxts upgrade`'s output). Internal fields left the API and are reached through `@amxts\u002Fcore\u002Fnatives`.\n- A command's handler takes one object: `({ player }) => ...`, not `(player, args) => ...`.\n- `@amxts\u002Fcore\u002Fhttp` is gone: `fetch` and `useFetch` are globals. easy_http is no longer needed on the server.\n- The core's API is imported by its package name (`@amxts\u002Fcore\u002Fnatives`, `\u002Ffs`, ...); `~\u002F` is the project's own files only.\n- Game messages are heard with `server.addMessageListener(name, ...)`, by their new names; the `message:` prefix of `addEventListener` is gone.\n- The names of every flag set are lowerCamelCase: `\"jump\"`, `\"muzzleFlash\"`, `\"kick\"`.\n- `@amxts\u002Fmenu-core`'s code API takes one options object and one context: `addItem({ title, onSelect: ({ player }) => ... })`.\n- The module and `amxts-compile` must come from the same release: the module refuses a compiler of another build.\n- A plugin's id is `steamId`, not `authid`; server events are named as authors say them: `putInServer`, `configsExecuted`, `pluginsLoaded`, `changeLevel`.\n- A plugin built by 0.1.0 is not loaded: the console names it and says to build it again.\n\n### ⬆️ Upgrade guide\n\nFrom 0.1.0, update the command first, with the package manager the project uses: `npm install @amxts\u002Fcli@latest`, `bun add @amxts\u002Fcli@latest`, `pnpm add @amxts\u002Fcli@latest` or `yarn add @amxts\u002Fcli@latest`. Then run `npx amxts upgrade` in the project: it updates the packages, rewrites the code, builds, and updates the server named in `.env`.\n\n### 🧭 Known issues\n\n- On plain HLDS, rounds, purchases, money and the bomb are heard after the fact; `preventDefault()` on them says once that it cannot stop them. ReGameDLL's own functions are not heard at all.\n- A stack shows the source line only where the plugin's `.ts` is next to it; in a full build, small functions are inlined and a frame may show its caller's name.\n- SFTP keys are RSA in PEM; Ed25519 and ECDSA keys are not read.\n\n### 🚀 Enhancements\n\n- One module to install: the host plugin comes inside `amxts_amxx`\n- Plain HLDS: fields read in memory, a player's events through Ham Sandwich, rounds, spawns, purchases, money and the bomb through the game's own logs and messages\n- `target: \"hlds\"` stops a build that listens for what plain HLDS cannot hear\n- **commands:** Typed arguments, and `server.commands` for a `\u002Fhelp`\n- **menus:** `Menu` over AMX Mod X's menus\n- **fetch:** `fetch` and `useFetch` as globals, over libcurl and mbedTLS inside the module\n- **kit:** `request` over HTTP, FTP, FTPS and SFTP, for modules\n- **modules:** Library packages, compiled into each plugin that imports them\n- `@amxts\u002Fftp` among the official modules\n- **messages:** Every known game message's arguments typed and named\n- **events:** Enum arguments of game events as names; a game event's vector arguments writable\n- **players:** `server.players` replaces `Player.all`\n- **api:** Fields and events in the player's words; internal ones left to `@amxts\u002Fcore\u002Fnatives`\n- **runtime:** A failed call prints the TypeScript stack, from a map carried in each plugin\n- **module:** A reload removes the old plugin's timers and hooks\n- **module:** A compiler of another build is refused, with one clear line\n- **module:** A plugin built for another amxts is refused, not run\n- **players:** `server.addBot` and `bot.move`; a fake client joins the spectators on both servers\n- **natives:** A native's `...` tail takes text, floats, vectors and players; `Ref` reads what it writes back\n- **messages:** `server.addMessageListener` by the player's names, with a description for each\n- **entities:** A field the HUD shows is sent to the player when written\n- **build:** `AMXTS_SERVER` may name the server's root or its `cstrike` folder\n- **server:** `amxts_load`, `amxts_unload` and `amxts_reload \u003Cplugin>` for one plugin; `amxts_plugins` shows each one's state\n- **dev:** Saving a plugin reloads only the plugins that changed, and a menu it made stays open through the reload\n- **natives:** Reunion, VTC, ReChecker and GeoIP natives; `player.authType`, `protocol` and `authKey` from Reunion\n- **modules:** A shared module hears when a plugin that uses it stops (`onPluginStop`), and drops what it gave\n- **menu-core:** The code API in the same shape as `Menu`\n- The core's API by its package name: `@amxts\u002Fcore\u002Fnatives`, `\u002Fconstants`, `\u002Ffs`, `\u002Fos`, `\u002Fkit`, `\u002Fcheck`\n- **upgrade:** `amxts upgrade` rewrites imports, command handlers, `Player.all` and every renamed field and event\n- **docker:** The server image is `ghcr.io\u002Famxts\u002Fserver`\n\n### 🔥 Performance\n\n- **build:** Modules from npm come with their analysis, not compiled again\n- **build:** Plugins compile in parallel\n- **build:** Each file is read once per build\n\n### 🩹 Fixes\n\n- **module:** The API files are written only when they changed ([#1](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fissues\u002F1))\n- **compiler:** `boolean | function` fields, `has ? get : fallback`, a caught error read off a return, `new Map(entries)` and `new Set(values)`, narrowing on assignment\n- **commands:** Typed arguments go where their interface does\n- **editor:** `Date.UTC` with fewer arguments\n- **host:** A missing native answers 0 and says so once\n- **events:** Removing the last listener switches its hook off\n- **runtime:** A function a plugin hands a module at its top level is called back, and a reloaded plugin's old functions are never called\n- **runtime:** A plugin loaded while another one runs no longer stalls that one's `await`, and a reload of all loads each plugin once\n\n### ❤️ Contributors\n\n- Ernest Manukyan ([@kukson777](https:\u002F\u002Fgithub.com\u002Fkukson777))\n\n### 📦 Files\n\n- `amxts-server-windows-x64.zip`, `amxts-server-linux-x64.tar.gz` - the server kit: the module, and the compiler for `.ts` plugins written on the server.\n- `amxts_amxx.dll`, `amxts_amxx_i386.so` - the module alone.\n- `amxts-compile-*`, `wamrc-*` - the on-server compiler and WAMR's AOT compiler, per system.\n- `amxts-windows.json`, `amxts-linux.json` - what each was built from, with every file's sha256.\n","https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Freleases\u002Ftag\u002Fv0.2.0",{"repo":174,"version":175,"date":176,"body":177,"url":178},"ftp","v0.1.0","2026-10-04T06:21:46Z","The first release: FTP, FTPS and SFTP for amxts plugins. Upload, download and list files on another server; every call is a promise on amxts's network thread, so the game never waits, and files go between the game folder and the other server whole, binary included.\n\n```ts\nimport { ftp } from \"@amxts\u002Fftp\";\n\nconst client = await ftp.connect(\"sftp:\u002F\u002Fbackup@example.com\", { password: settings.password });\nawait client.upload(\"addons\u002Famxmodx\u002Flogs\u002Ftoday.log\", \"logs\u002Ftoday.log\");\nawait client.close();\n```\n\nSFTP takes a password or an RSA key in PEM, and can check the host's key.\n\n### ❤️ Contributors\n\n- Ernest Manukyan ([@kukson777](https:\u002F\u002Fgithub.com\u002Fkukson777))\n","https:\u002F\u002Fgithub.com\u002Famxts\u002Fftp\u002Freleases\u002Ftag\u002Fv0.1.0",{"repo":153,"version":169,"date":180,"body":181,"url":182},"2026-10-04T06:21:41Z","[compare changes](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcompare\u002Fv0.1.0...v0.2.0)\n\n### Summary\n\nmenu-core for amxts 0.2.0: every menu function takes the menu's context, items take one options object as the core's `Menu` does, and a menu stays open while its plugin reloads.\n\n### ✨ Highlights\n\n#### The menu's context\n\nA title, `visible`, `enabled` and `onSelect` take one object, `{ player, target, row, menu }`:\n\n```ts\nconst shop = menus.create(\"SHOP\", { title: ({ player }) => `Shop - $${player.money}` });\n\nshop.addItem({\n\ttitle: ({ player }) => `Heal (${player.health} HP)`,\n\tvisible: ({ player }) => player.health \u003C 100,\n\tonSelect: ({ player }) => {\n\t\tplayer.health = 100;\n\t},\n});\n```\n\nIn a list of players, `target` is the player of the row.\n\n#### A menu kept through a reload\n\nWhen the plugin that made a menu reloads - a save under `amxts dev`, `amxts_reload` - a player looking at the menu keeps it, on the same page, drawn from the new code. When the plugin is unloaded, its menus, items, placeholders and conditions go with it.\n\n### ⚠️ Breaking changes\n\n- Every function a menu takes gets the context object: `({ player }) => ...`, not `(player) => ...`.\n- `addItem` takes one options object: `addItem({ title, onSelect })`, not `addItem(\"Title\", { onSelect })`.\n- Conditions registered by name keep their `(player, viewer, name)` arguments.\n\n### ⬆️ Upgrade guide\n\n`npx amxts upgrade` rewrites both: the functions to the context and `addItem` to its options. Files of menus (INI, YAML, JSON) do not change.\n\n### 📦 Dependencies\n\n| Package | From | To |\n| --- | --- | --- |\n| `@amxts\u002Fcore` | `^0.1.0` | `^0.2.0` |\n| `@amxts\u002Fconfig-core` | `^0.1.0` | `^0.1.1` |\n\n### 🚀 Enhancements\n\n- ⚠️  Every menu function takes the menu's context ([496431b](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002F496431b))\n- Keep a menu open through its plugin's reload ([1a3ab54](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002F1a3ab54))\n\n### 🩹 Fixes\n\n- The plugin's version is the package's ([a646c2c](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Fa646c2c))\n- Drop what a stopped plugin gave the menus ([fa68648](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Ffa68648))\n\n### 💅 Refactors\n\n- Import the core's API by its package name ([d838de0](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Fd838de0))\n- Command handlers take one object ([c6aa029](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Fc6aa029))\n- `server.players` over `Player.all` ([0a8c748](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002F0a8c748))\n- Admin right by its `lowerCamelCase` name ([13b2645](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002F13b2645))\n- Hear `putInServer` by its new name ([ac6243e](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Fac6243e))\n\n### 📖 Documentation\n\n- The player's money is `player.money` ([0e0f3ca](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002F0e0f3ca))\n- The Pawn natives without a plugin the reader never met ([d320b06](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Fd320b06))\n- The menu's context in the README ([ffe1920](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Fffe1920))\n- The README without a status note ([ee841d7](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Fee841d7))\n\n#### ⚠️ Breaking Changes\n\n- ⚠️  Every menu function takes the menu's context ([496431b](https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002F496431b))\n\n### ❤️ Contributors\n\n- Ernest Manukyan ([@kukson777](https:\u002F\u002Fgithub.com\u002Fkukson777))\n\n","https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Freleases\u002Ftag\u002Fv0.2.0",{"repo":148,"version":184,"date":180,"body":185,"url":186},"v0.1.1","[compare changes](https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcompare\u002Fv0.1.0...v0.1.1)\n\n### Summary\n\nresemiclip for amxts 0.2.0. Its API is unchanged; the rule a plugin sets goes when that plugin stops, so ReSemiclip gets its own rules back.\n\n### ⚠️ Breaking changes\n\nNone in resemiclip itself; it needs `@amxts\u002Fcore` 0.2.\n\n### ⬆️ Upgrade guide\n\n`npx amxts upgrade` in the project updates it with the core.\n\n### 📦 Dependencies\n\n| Package | From | To |\n| --- | --- | --- |\n| `@amxts\u002Fcore` | `^0.1.0` | `^0.2.0` |\n\n### 🩹 Fixes\n\n- Give the rules back when the plugin that set the rule stops ([62e06a8](https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcommit\u002F62e06a8))\n\n### 💅 Refactors\n\n- Import the core's API by its package name ([4024ec5](https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcommit\u002F4024ec5))\n- Command handlers take one object ([16b55d1](https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcommit\u002F16b55d1))\n- `server.players` over `Player.all` ([ab12133](https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcommit\u002Fab12133))\n- Listen to the team message by its new name ([c8a31d9](https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcommit\u002Fc8a31d9))\n- Hear `putInServer` and `playerChange` by their new names ([9b407b7](https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcommit\u002F9b407b7))\n\n### 📖 Documentation\n\n- The rule goes with the plugin that set it ([7a4ce5b](https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcommit\u002F7a4ce5b))\n\n### ❤️ Contributors\n\n- Ernest Manukyan ([@kukson777](https:\u002F\u002Fgithub.com\u002Fkukson777))\n\n","https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Freleases\u002Ftag\u002Fv0.1.1",{"repo":142,"version":184,"date":188,"body":189,"url":190},"2026-10-04T06:21:36Z","[compare changes](https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcompare\u002Fv0.1.0...v0.1.1)\n\n### Summary\n\nconfig-core for amxts 0.2.0. Its API is unchanged: a plugin that reads its configs needs nothing new.\n\n### ⚠️ Breaking changes\n\nNone in config-core itself; it needs `@amxts\u002Fcore` 0.2.\n\n### ⬆️ Upgrade guide\n\n`npx amxts upgrade` in the project updates it with the core.\n\n### 📦 Dependencies\n\n| Package | From | To |\n| --- | --- | --- |\n| `@amxts\u002Fcore` | `^0.1.0` | `^0.2.0` |\n\n### 🩹 Fixes\n\n- The plugin's version is the package's ([c53a7ee](https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcommit\u002Fc53a7ee))\n\n### 💅 Refactors\n\n- Import the core's API by its package name ([7e12991](https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcommit\u002F7e12991))\n- Command handlers take one object ([4240f17](https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcommit\u002F4240f17))\n- Admin right by its `lowerCamelCase` name ([74c8ddf](https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcommit\u002F74c8ddf))\n\n### 📖 Documentation\n\n- The Pawn natives without a plugin the reader never met ([7de1140](https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcommit\u002F7de1140))\n- The natives' limits without comparing to Pawn ([cedf727](https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcommit\u002Fcedf727))\n\n### ❤️ Contributors\n\n- Ernest Manukyan ([@kukson777](https:\u002F\u002Fgithub.com\u002Fkukson777))\n\n","https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Freleases\u002Ftag\u002Fv0.1.1",{"repo":192,"version":169,"date":193,"body":194,"url":195},"amxts-cli","2026-10-04T06:21:35Z","[compare changes](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcompare\u002Fv0.1.0...v0.2.0)\n\n\n### Summary\n\nThe command for amxts 0.2.0. `amxts upgrade` moves a 0.1.0 project over in one step, and a new project starts from 0.2.0's API.\n\n### ✨ Highlights\n\n#### `amxts upgrade`\n\nOne command updates the packages, rewrites the code for the renamed API, builds, and puts the release's module, compiler and `wamrc` on the server named in `.env`, with a backup of each file it replaces. `--dry-run` shows what it would do; `--no-server` and `--server-only` do half of it.\n\n#### A new project\n\n`hello.ts` has a typed config and a menu that greets the player by name; with `@amxts\u002Fmenu-core`, its starter menu takes the menu's context.\n\n#### The server's folder\n\n`AMXTS_SERVER` may name the server's root or its `cstrike` folder.\n\n### ⚠️ Breaking changes\n\n- The command drives `@amxts\u002Fcore` 0.2.x only. A 0.1.0 project runs `amxts upgrade` first.\n\n### ⬆️ Upgrade guide\n\nUpdate the command with the package manager the project uses - `npm install @amxts\u002Fcli@latest`, `bun add @amxts\u002Fcli@latest`, `pnpm add @amxts\u002Fcli@latest` or `yarn add @amxts\u002Fcli@latest` - then run `npx amxts upgrade`.\n\n### 🧭 Known issues\n\n- The server step of `amxts upgrade` downloads the release from GitHub; without network access run it with `--no-server` and install the server kit by hand.\n\n### 📦 Dependencies\n\n| Package | From | To |\n| --- | --- | --- |\n| `@amxts\u002Fcore` | `^0.1.0` | `^0.2.0` |\n\n### 🚀 Enhancements\n\n- **server:** Take the server's folder or its cstrike ([f41a1d7](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002Ff41a1d7))\n- **init:** Typed config and the core's Menu in `hello.ts` ([50a7343](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F50a7343))\n- **init:** The starter menu greets by name in its title ([f38a850](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002Ff38a850))\n- **init:** The menu-core starter menu takes its context ([3e590ab](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F3e590ab))\n- **upgrade:** One command moves a project to a release ([00d3974](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F00d3974))\n\n- **upgrade:** Each package to its own version for the core ([426f2a9](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F426f2a9))\n- New modules at their version for the core ([a2be088](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002Fa2be088))\n\n### 🩹 Fixes\n\n- **init:** `knip` 6 in a new project ([868f2e3](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F868f2e3))\n- **init:** Keep a linked core's own `.bin` on yarn ([1262f55](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F1262f55))\n- **templates:** The starter hears `putInServer` ([e20acbe](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002Fe20acbe))\n\n### 💅 Refactors\n\n- Command handlers take one object ([5bd680c](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F5bd680c))\n\n### 📖 Documentation\n\n- The packages are on npm ([9770340](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F9770340))\n- `amxts` upgrade in the READMEs and CONTRIBUTING ([7c69105](https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F7c69105))\n\n### ❤️ Contributors\n\n- Ernest Manukyan ([@kukson777](https:\u002F\u002Fgithub.com\u002Fkukson777))\n\n","https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Freleases\u002Ftag\u002Fv0.2.0",{"repo":197,"version":175,"date":198,"body":199,"url":200},"amxts-vscode","2026-10-01T04:55:30Z","The first release. Install from the .vsix below: VS Code → Extensions → ··· → Install from VSIX. On Open VSX (Cursor, VSCodium, Windsurf): search for amxts.","https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-vscode\u002Freleases\u002Ftag\u002Fv0.1.0",{"repo":159,"version":175,"date":202,"body":203,"url":204},"2026-10-01T03:48:53Z","amxts 0.1.0","https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Freleases\u002Ftag\u002Fv0.1.0",true,{"data":207,"body":208},{},{"type":209,"children":210},"root",[211,226,233,247,253,264,270,320,326],{"type":212,"tag":213,"props":214,"children":215},"element","p",{},[216],{"type":212,"tag":217,"props":218,"children":222},"a",{"href":219,"rel":220},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcompare\u002Fv0.1.1...v0.1.2",[221],"nofollow",[223],{"type":224,"value":225},"text","compare changes",{"type":212,"tag":227,"props":228,"children":230},"h3",{"id":229},"summary",[231],{"type":224,"value":232},"Summary",{"type":212,"tag":213,"props":234,"children":235},{},[236,238,245],{"type":224,"value":237},"Built for ",{"type":212,"tag":239,"props":240,"children":242},"code",{"className":241},[],[243],{"type":224,"value":244},"@amxts\u002Fcore",{"type":224,"value":246}," 0.2.2: the package's prebuilt plugin is compiled with that core, so a project on 0.2.2 takes it as it is instead of compiling the module on its first build. The module's API does not change.",{"type":212,"tag":227,"props":248,"children":250},{"id":249},"️-upgrade-guide",[251],{"type":224,"value":252},"⬆️ Upgrade guide",{"type":212,"tag":213,"props":254,"children":255},{},[256,262],{"type":212,"tag":239,"props":257,"children":259},{"className":258},[],[260],{"type":224,"value":261},"npx amxts upgrade",{"type":224,"value":263}," in the project takes it with the core.",{"type":212,"tag":227,"props":265,"children":267},{"id":266},"dependencies",[268],{"type":224,"value":269},"📦 Dependencies",{"type":212,"tag":271,"props":272,"children":273},"table",{},[274,293],{"type":212,"tag":275,"props":276,"children":277},"thead",{},[278],{"type":212,"tag":279,"props":280,"children":281},"tr",{},[282,288],{"type":212,"tag":283,"props":284,"children":285},"th",{},[286],{"type":224,"value":287},"Package",{"type":212,"tag":283,"props":289,"children":290},{},[291],{"type":224,"value":292},"Range",{"type":212,"tag":294,"props":295,"children":296},"tbody",{},[297],{"type":212,"tag":279,"props":298,"children":299},{},[300,309],{"type":212,"tag":301,"props":302,"children":303},"td",{},[304],{"type":212,"tag":239,"props":305,"children":307},{"className":306},[],[308],{"type":224,"value":244},{"type":212,"tag":301,"props":310,"children":311},{},[312,318],{"type":212,"tag":239,"props":313,"children":315},{"className":314},[],[316],{"type":224,"value":317},"^0.2.0",{"type":224,"value":319},", prebuilt for 0.2.2",{"type":212,"tag":227,"props":321,"children":323},{"id":322},"️-contributors",[324],{"type":224,"value":325},"❤️ Contributors",{"type":212,"tag":327,"props":328,"children":329},"ul",{},[330],{"type":212,"tag":331,"props":332,"children":333},"li",{},[334,336,343],{"type":224,"value":335},"Ernest Manukyan (",{"type":212,"tag":217,"props":337,"children":340},{"href":338,"rel":339},"https:\u002F\u002Fgithub.com\u002Fkukson777",[221],[341],{"type":224,"value":342},"@kukson777",{"type":224,"value":344},")",{"data":346,"body":347},{},{"type":209,"children":348},[349,358,362,372,376,385,389,429,433],{"type":212,"tag":213,"props":350,"children":351},{},[352],{"type":212,"tag":217,"props":353,"children":356},{"href":354,"rel":355},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcompare\u002Fv0.1.1...v0.1.2",[221],[357],{"type":224,"value":225},{"type":212,"tag":227,"props":359,"children":360},{"id":229},[361],{"type":224,"value":232},{"type":212,"tag":213,"props":363,"children":364},{},[365,366,371],{"type":224,"value":237},{"type":212,"tag":239,"props":367,"children":369},{"className":368},[],[370],{"type":224,"value":244},{"type":224,"value":246},{"type":212,"tag":227,"props":373,"children":374},{"id":249},[375],{"type":224,"value":252},{"type":212,"tag":213,"props":377,"children":378},{},[379,384],{"type":212,"tag":239,"props":380,"children":382},{"className":381},[],[383],{"type":224,"value":261},{"type":224,"value":263},{"type":212,"tag":227,"props":386,"children":387},{"id":266},[388],{"type":224,"value":269},{"type":212,"tag":271,"props":390,"children":391},{},[392,406],{"type":212,"tag":275,"props":393,"children":394},{},[395],{"type":212,"tag":279,"props":396,"children":397},{},[398,402],{"type":212,"tag":283,"props":399,"children":400},{},[401],{"type":224,"value":287},{"type":212,"tag":283,"props":403,"children":404},{},[405],{"type":224,"value":292},{"type":212,"tag":294,"props":407,"children":408},{},[409],{"type":212,"tag":279,"props":410,"children":411},{},[412,420],{"type":212,"tag":301,"props":413,"children":414},{},[415],{"type":212,"tag":239,"props":416,"children":418},{"className":417},[],[419],{"type":224,"value":244},{"type":212,"tag":301,"props":421,"children":422},{},[423,428],{"type":212,"tag":239,"props":424,"children":426},{"className":425},[],[427],{"type":224,"value":317},{"type":224,"value":319},{"type":212,"tag":227,"props":430,"children":431},{"id":322},[432],{"type":224,"value":325},{"type":212,"tag":327,"props":434,"children":435},{},[436],{"type":212,"tag":331,"props":437,"children":438},{},[439,440,445],{"type":224,"value":335},{"type":212,"tag":217,"props":441,"children":443},{"href":338,"rel":442},[221],[444],{"type":224,"value":342},{"type":224,"value":344},{"data":447,"body":448},{},{"type":209,"children":449},[450,459,463,473,477,486,490,530,534],{"type":212,"tag":213,"props":451,"children":452},{},[453],{"type":212,"tag":217,"props":454,"children":457},{"href":455,"rel":456},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcompare\u002Fv0.2.0...v0.2.1",[221],[458],{"type":224,"value":225},{"type":212,"tag":227,"props":460,"children":461},{"id":229},[462],{"type":224,"value":232},{"type":212,"tag":213,"props":464,"children":465},{},[466,467,472],{"type":224,"value":237},{"type":212,"tag":239,"props":468,"children":470},{"className":469},[],[471],{"type":224,"value":244},{"type":224,"value":246},{"type":212,"tag":227,"props":474,"children":475},{"id":249},[476],{"type":224,"value":252},{"type":212,"tag":213,"props":478,"children":479},{},[480,485],{"type":212,"tag":239,"props":481,"children":483},{"className":482},[],[484],{"type":224,"value":261},{"type":224,"value":263},{"type":212,"tag":227,"props":487,"children":488},{"id":266},[489],{"type":224,"value":269},{"type":212,"tag":271,"props":491,"children":492},{},[493,507],{"type":212,"tag":275,"props":494,"children":495},{},[496],{"type":212,"tag":279,"props":497,"children":498},{},[499,503],{"type":212,"tag":283,"props":500,"children":501},{},[502],{"type":224,"value":287},{"type":212,"tag":283,"props":504,"children":505},{},[506],{"type":224,"value":292},{"type":212,"tag":294,"props":508,"children":509},{},[510],{"type":212,"tag":279,"props":511,"children":512},{},[513,521],{"type":212,"tag":301,"props":514,"children":515},{},[516],{"type":212,"tag":239,"props":517,"children":519},{"className":518},[],[520],{"type":224,"value":244},{"type":212,"tag":301,"props":522,"children":523},{},[524,529],{"type":212,"tag":239,"props":525,"children":527},{"className":526},[],[528],{"type":224,"value":317},{"type":224,"value":319},{"type":212,"tag":227,"props":531,"children":532},{"id":322},[533],{"type":224,"value":325},{"type":212,"tag":327,"props":535,"children":536},{},[537],{"type":212,"tag":331,"props":538,"children":539},{},[540,541,546],{"type":224,"value":335},{"type":212,"tag":217,"props":542,"children":544},{"href":338,"rel":543},[221],[545],{"type":224,"value":342},{"type":224,"value":344},{"data":548,"body":549},{},{"type":209,"children":550},[551,560,564,569,573,606,612,664,668,681,687],{"type":212,"tag":213,"props":552,"children":553},{},[554],{"type":212,"tag":217,"props":555,"children":558},{"href":556,"rel":557},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcompare\u002Fv0.2.1...v0.2.2",[221],[559],{"type":224,"value":225},{"type":212,"tag":227,"props":561,"children":562},{"id":229},[563],{"type":224,"value":232},{"type":212,"tag":213,"props":565,"children":566},{},[567],{"type":224,"value":568},"A fix for a server that crashed at start on some AMX Mod X builds: the module registered its server commands with fewer arguments than AMX Mod X reads, and AMX Mod X read a command's description from leftover memory. Whether it crashed depended on the AMX Mod X build and the plugins loaded - most often with one or two plugins. The server suites run on AMX Mod X 1.9 and the newest 1.10 as well from now on.",{"type":212,"tag":227,"props":570,"children":571},{"id":249},[572],{"type":224,"value":252},{"type":212,"tag":213,"props":574,"children":575},{},[576,581,583,588,590,596,598,604],{"type":212,"tag":239,"props":577,"children":579},{"className":578},[],[580],{"type":224,"value":261},{"type":224,"value":582}," in the project, with the server stopped: it moves ",{"type":212,"tag":239,"props":584,"children":586},{"className":585},[],[587],{"type":224,"value":244},{"type":224,"value":589}," to 0.2.2, builds the plugins again and puts the 0.2.2 module on the server named in ",{"type":212,"tag":239,"props":591,"children":593},{"className":592},[],[594],{"type":224,"value":595},".env",{"type":224,"value":597},". A server installed by hand takes the module (and ",{"type":212,"tag":239,"props":599,"children":601},{"className":600},[],[602],{"type":224,"value":603},"amxts-compile",{"type":224,"value":605},", where it has one) from this release, and its plugins are built again.",{"type":212,"tag":227,"props":607,"children":609},{"id":608},"fixes",[610],{"type":224,"value":611},"🩹 Fixes",{"type":212,"tag":327,"props":613,"children":614},{},[615],{"type":212,"tag":331,"props":616,"children":617},{},[618,624,626,632,634,640,641,647,648,654,656,663],{"type":212,"tag":619,"props":620,"children":621},"strong",{},[622],{"type":224,"value":623},"runtime:",{"type":224,"value":625}," No crash at start on some AMX Mod X builds: every native the module calls - ",{"type":212,"tag":239,"props":627,"children":629},{"className":628},[],[630],{"type":224,"value":631},"register_srvcmd",{"type":224,"value":633},", ",{"type":212,"tag":239,"props":635,"children":637},{"className":636},[],[638],{"type":224,"value":639},"register_clcmd",{"type":224,"value":633},{"type":212,"tag":239,"props":642,"children":644},{"className":643},[],[645],{"type":224,"value":646},"set_task",{"type":224,"value":633},{"type":212,"tag":239,"props":649,"children":651},{"className":650},[],[652],{"type":224,"value":653},"RegisterHam",{"type":224,"value":655}," - gets all its parameters (",{"type":212,"tag":217,"props":657,"children":660},{"href":658,"rel":659},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcommit\u002Fc02eb1e",[221],[661],{"type":224,"value":662},"c02eb1e",{"type":224,"value":344},{"type":212,"tag":227,"props":665,"children":666},{"id":322},[667],{"type":224,"value":325},{"type":212,"tag":327,"props":669,"children":670},{},[671],{"type":212,"tag":331,"props":672,"children":673},{},[674,675,680],{"type":224,"value":335},{"type":212,"tag":217,"props":676,"children":678},{"href":338,"rel":677},[221],[679],{"type":224,"value":342},{"type":224,"value":344},{"type":212,"tag":227,"props":682,"children":684},{"id":683},"files",[685],{"type":224,"value":686},"📦 Files",{"type":212,"tag":327,"props":688,"children":689},{},[690,716,734,752],{"type":212,"tag":331,"props":691,"children":692},{},[693,699,700,706,708,714],{"type":212,"tag":239,"props":694,"children":696},{"className":695},[],[697],{"type":224,"value":698},"amxts-server-windows-x64.zip",{"type":224,"value":633},{"type":212,"tag":239,"props":701,"children":703},{"className":702},[],[704],{"type":224,"value":705},"amxts-server-linux-x64.tar.gz",{"type":224,"value":707}," - the server kit: the module, and the compiler for ",{"type":212,"tag":239,"props":709,"children":711},{"className":710},[],[712],{"type":224,"value":713},".ts",{"type":224,"value":715}," plugins written on the server.",{"type":212,"tag":331,"props":717,"children":718},{},[719,725,726,732],{"type":212,"tag":239,"props":720,"children":722},{"className":721},[],[723],{"type":224,"value":724},"amxts_amxx.dll",{"type":224,"value":633},{"type":212,"tag":239,"props":727,"children":729},{"className":728},[],[730],{"type":224,"value":731},"amxts_amxx_i386.so",{"type":224,"value":733}," - the module alone.",{"type":212,"tag":331,"props":735,"children":736},{},[737,743,744,750],{"type":212,"tag":239,"props":738,"children":740},{"className":739},[],[741],{"type":224,"value":742},"amxts-compile-*",{"type":224,"value":633},{"type":212,"tag":239,"props":745,"children":747},{"className":746},[],[748],{"type":224,"value":749},"wamrc-*",{"type":224,"value":751}," - the on-server compiler and WAMR's AOT compiler, per system.",{"type":212,"tag":331,"props":753,"children":754},{},[755,761,762,768],{"type":212,"tag":239,"props":756,"children":758},{"className":757},[],[759],{"type":224,"value":760},"amxts-windows.json",{"type":224,"value":633},{"type":212,"tag":239,"props":763,"children":765},{"className":764},[],[766],{"type":224,"value":767},"amxts-linux.json",{"type":224,"value":769}," - what each was built from, with every file's sha256.",{"data":771,"body":772},{},{"type":209,"children":773},[774,783,787,816,820,850,854,1027,1031,1044,1048],{"type":212,"tag":213,"props":775,"children":776},{},[777],{"type":212,"tag":217,"props":778,"children":781},{"href":779,"rel":780},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcompare\u002Fv0.2.0...v0.2.1",[221],[782],{"type":224,"value":225},{"type":212,"tag":227,"props":784,"children":785},{"id":229},[786],{"type":224,"value":232},{"type":212,"tag":213,"props":788,"children":789},{},[790,792,798,800,806,808,814],{"type":224,"value":791},"Fixes for 0.2.0: a plugin's call could fail at random when a native wrote into a buffer near the end of its memory, a build after an upgrade could keep plugins of the old version that the new module refuses, ",{"type":212,"tag":239,"props":793,"children":795},{"className":794},[],[796],{"type":224,"value":797},"amxts upgrade",{"type":224,"value":799}," rewrote the module's own files when the project lives in the server's folder, and the editor marked ",{"type":212,"tag":239,"props":801,"children":803},{"className":802},[],[804],{"type":224,"value":805},"error.message",{"type":224,"value":807}," in a ",{"type":212,"tag":239,"props":809,"children":811},{"className":810},[],[812],{"type":224,"value":813},"catch",{"type":224,"value":815}," as an error.",{"type":212,"tag":227,"props":817,"children":818},{"id":249},[819],{"type":224,"value":252},{"type":212,"tag":213,"props":821,"children":822},{},[823,828,830,835,837,842,843,848],{"type":212,"tag":239,"props":824,"children":826},{"className":825},[],[827],{"type":224,"value":261},{"type":224,"value":829}," in the project: it moves ",{"type":212,"tag":239,"props":831,"children":833},{"className":832},[],[834],{"type":224,"value":244},{"type":224,"value":836}," to 0.2.1, builds the plugins again and puts the 0.2.1 module on the server named in ",{"type":212,"tag":239,"props":838,"children":840},{"className":839},[],[841],{"type":224,"value":595},{"type":224,"value":597},{"type":212,"tag":239,"props":844,"children":846},{"className":845},[],[847],{"type":224,"value":603},{"type":224,"value":849},", where it has one) from this release; the plugins are built again, since the module loads only plugins of its own release.",{"type":212,"tag":227,"props":851,"children":852},{"id":608},[853],{"type":224,"value":611},{"type":212,"tag":327,"props":855,"children":856},{},[857,883,916,949,967,993],{"type":212,"tag":331,"props":858,"children":859},{},[860,865,867,873,875,882],{"type":212,"tag":619,"props":861,"children":862},{},[863],{"type":224,"value":864},"module:",{"type":224,"value":866}," Start on a server with an older Visual C++ runtime: the network thread's lock crashed Windows servers whose ",{"type":212,"tag":239,"props":868,"children":870},{"className":869},[],[871],{"type":224,"value":872},"msvcp140.dll",{"type":224,"value":874}," predates Visual Studio 2022 17.10 (",{"type":212,"tag":217,"props":876,"children":879},{"href":877,"rel":878},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcommit\u002F04dbe6b",[221],[880],{"type":224,"value":881},"04dbe6b",{"type":224,"value":344},{"type":212,"tag":331,"props":884,"children":885},{},[886,890,892,898,900,906,908,915],{"type":212,"tag":619,"props":887,"children":888},{},[889],{"type":224,"value":623},{"type":224,"value":891}," A native whose array size the include does not give - ",{"type":212,"tag":239,"props":893,"children":895},{"className":894},[],[896],{"type":224,"value":897},"get_players",{"type":224,"value":899},", which ",{"type":212,"tag":239,"props":901,"children":903},{"className":902},[],[904],{"type":224,"value":905},"server.players",{"type":224,"value":907}," calls, among them - no longer fails the plugin's call when the array lies near the end of the plugin's memory (",{"type":212,"tag":217,"props":909,"children":912},{"href":910,"rel":911},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcommit\u002Fe5dee94",[221],[913],{"type":224,"value":914},"e5dee94",{"type":224,"value":344},{"type":212,"tag":331,"props":917,"children":918},{},[919,924,926,932,934,939,941,948],{"type":212,"tag":619,"props":920,"children":921},{},[922],{"type":224,"value":923},"editor:",{"type":224,"value":925}," ",{"type":212,"tag":239,"props":927,"children":929},{"className":928},[],[930],{"type":224,"value":931},"catch (error)",{"type":224,"value":933}," reads ",{"type":212,"tag":239,"props":935,"children":937},{"className":936},[],[938],{"type":224,"value":805},{"type":224,"value":940}," without a cast, as the compiler and the docs do (",{"type":212,"tag":217,"props":942,"children":945},{"href":943,"rel":944},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcommit\u002Fd2875cf",[221],[946],{"type":224,"value":947},"d2875cf",{"type":224,"value":344},{"type":212,"tag":331,"props":950,"children":951},{},[952,957,959,966],{"type":212,"tag":619,"props":953,"children":954},{},[955],{"type":224,"value":956},"build:",{"type":224,"value":958}," A plugin is compiled again when the core's version changes: after an upgrade the build cache could hand back a plugin of the old version, which the new module refuses (",{"type":212,"tag":217,"props":960,"children":963},{"href":961,"rel":962},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcommit\u002F7abae6c",[221],[964],{"type":224,"value":965},"7abae6c",{"type":224,"value":344},{"type":212,"tag":331,"props":968,"children":969},{},[970,975,977,983,985,992],{"type":212,"tag":619,"props":971,"children":972},{},[973],{"type":224,"value":974},"upgrade:",{"type":224,"value":976}," The module's own files are left alone - the API it writes into ",{"type":212,"tag":239,"props":978,"children":980},{"className":979},[],[981],{"type":224,"value":982},"addons\u002Famxts\u002Fplugins\u002F",{"type":224,"value":984}," - when the project lives in the server's folder (",{"type":212,"tag":217,"props":986,"children":989},{"href":987,"rel":988},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcommit\u002Fc400c24",[221],[990],{"type":224,"value":991},"c400c24",{"type":224,"value":344},{"type":212,"tag":331,"props":994,"children":995},{},[996,1001,1003,1009,1011,1017,1019,1026],{"type":212,"tag":619,"props":997,"children":998},{},[999],{"type":224,"value":1000},"testing:",{"type":224,"value":1002}," The test server raises ",{"type":212,"tag":239,"props":1004,"children":1006},{"className":1005},[],[1007],{"type":224,"value":1008},"configsQueued",{"type":224,"value":1010}," and ",{"type":212,"tag":239,"props":1012,"children":1014},{"className":1013},[],[1015],{"type":224,"value":1016},"configsExecuted",{"type":224,"value":1018}," when the map starts, as AMX Mod X does (",{"type":212,"tag":217,"props":1020,"children":1023},{"href":1021,"rel":1022},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcommit\u002F2be9123",[221],[1024],{"type":224,"value":1025},"2be9123",{"type":224,"value":344},{"type":212,"tag":227,"props":1028,"children":1029},{"id":322},[1030],{"type":224,"value":325},{"type":212,"tag":327,"props":1032,"children":1033},{},[1034],{"type":212,"tag":331,"props":1035,"children":1036},{},[1037,1038,1043],{"type":224,"value":335},{"type":212,"tag":217,"props":1039,"children":1041},{"href":338,"rel":1040},[221],[1042],{"type":224,"value":342},{"type":224,"value":344},{"type":212,"tag":227,"props":1045,"children":1046},{"id":683},[1047],{"type":224,"value":686},{"type":212,"tag":327,"props":1049,"children":1050},{},[1051,1072,1087,1102],{"type":212,"tag":331,"props":1052,"children":1053},{},[1054,1059,1060,1065,1066,1071],{"type":212,"tag":239,"props":1055,"children":1057},{"className":1056},[],[1058],{"type":224,"value":698},{"type":224,"value":633},{"type":212,"tag":239,"props":1061,"children":1063},{"className":1062},[],[1064],{"type":224,"value":705},{"type":224,"value":707},{"type":212,"tag":239,"props":1067,"children":1069},{"className":1068},[],[1070],{"type":224,"value":713},{"type":224,"value":715},{"type":212,"tag":331,"props":1073,"children":1074},{},[1075,1080,1081,1086],{"type":212,"tag":239,"props":1076,"children":1078},{"className":1077},[],[1079],{"type":224,"value":724},{"type":224,"value":633},{"type":212,"tag":239,"props":1082,"children":1084},{"className":1083},[],[1085],{"type":224,"value":731},{"type":224,"value":733},{"type":212,"tag":331,"props":1088,"children":1089},{},[1090,1095,1096,1101],{"type":212,"tag":239,"props":1091,"children":1093},{"className":1092},[],[1094],{"type":224,"value":742},{"type":224,"value":633},{"type":212,"tag":239,"props":1097,"children":1099},{"className":1098},[],[1100],{"type":224,"value":749},{"type":224,"value":751},{"type":212,"tag":331,"props":1103,"children":1104},{},[1105,1110,1111,1116],{"type":212,"tag":239,"props":1106,"children":1108},{"className":1107},[],[1109],{"type":224,"value":760},{"type":224,"value":633},{"type":212,"tag":239,"props":1112,"children":1114},{"className":1113},[],[1115],{"type":224,"value":767},{"type":224,"value":769},{"data":1118,"body":1119},{},{"type":209,"children":1120},[1121,1130,1134,1139,1145,1157,1161,1171,1175,1229,1233,1249,1255,1351,1357,1373,1377],{"type":212,"tag":213,"props":1122,"children":1123},{},[1124],{"type":212,"tag":217,"props":1125,"children":1128},{"href":1126,"rel":1127},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcompare\u002Fv0.1.0...v0.1.1",[221],[1129],{"type":224,"value":225},{"type":212,"tag":227,"props":1131,"children":1132},{"id":229},[1133],{"type":224,"value":232},{"type":212,"tag":213,"props":1135,"children":1136},{},[1137],{"type":224,"value":1138},"resemiclip for amxts 0.2.0. Its API is unchanged; the rule a plugin sets goes when that plugin stops, so ReSemiclip gets its own rules back.",{"type":212,"tag":227,"props":1140,"children":1142},{"id":1141},"️-breaking-changes",[1143],{"type":224,"value":1144},"⚠️ Breaking changes",{"type":212,"tag":213,"props":1146,"children":1147},{},[1148,1150,1155],{"type":224,"value":1149},"None in resemiclip itself; it needs ",{"type":212,"tag":239,"props":1151,"children":1153},{"className":1152},[],[1154],{"type":224,"value":244},{"type":224,"value":1156}," 0.2.",{"type":212,"tag":227,"props":1158,"children":1159},{"id":249},[1160],{"type":224,"value":252},{"type":212,"tag":213,"props":1162,"children":1163},{},[1164,1169],{"type":212,"tag":239,"props":1165,"children":1167},{"className":1166},[],[1168],{"type":224,"value":261},{"type":224,"value":1170}," in the project updates it with the core.",{"type":212,"tag":227,"props":1172,"children":1173},{"id":266},[1174],{"type":224,"value":269},{"type":212,"tag":271,"props":1176,"children":1177},{},[1178,1198],{"type":212,"tag":275,"props":1179,"children":1180},{},[1181],{"type":212,"tag":279,"props":1182,"children":1183},{},[1184,1188,1193],{"type":212,"tag":283,"props":1185,"children":1186},{},[1187],{"type":224,"value":287},{"type":212,"tag":283,"props":1189,"children":1190},{},[1191],{"type":224,"value":1192},"From",{"type":212,"tag":283,"props":1194,"children":1195},{},[1196],{"type":224,"value":1197},"To",{"type":212,"tag":294,"props":1199,"children":1200},{},[1201],{"type":212,"tag":279,"props":1202,"children":1203},{},[1204,1212,1221],{"type":212,"tag":301,"props":1205,"children":1206},{},[1207],{"type":212,"tag":239,"props":1208,"children":1210},{"className":1209},[],[1211],{"type":224,"value":244},{"type":212,"tag":301,"props":1213,"children":1214},{},[1215],{"type":212,"tag":239,"props":1216,"children":1218},{"className":1217},[],[1219],{"type":224,"value":1220},"^0.1.0",{"type":212,"tag":301,"props":1222,"children":1223},{},[1224],{"type":212,"tag":239,"props":1225,"children":1227},{"className":1226},[],[1228],{"type":224,"value":317},{"type":212,"tag":227,"props":1230,"children":1231},{"id":608},[1232],{"type":224,"value":611},{"type":212,"tag":327,"props":1234,"children":1235},{},[1236],{"type":212,"tag":331,"props":1237,"children":1238},{},[1239,1241,1248],{"type":224,"value":1240},"Give the rules back when the plugin that set the rule stops (",{"type":212,"tag":217,"props":1242,"children":1245},{"href":1243,"rel":1244},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcommit\u002F62e06a8",[221],[1246],{"type":224,"value":1247},"62e06a8",{"type":224,"value":344},{"type":212,"tag":227,"props":1250,"children":1252},{"id":1251},"refactors",[1253],{"type":224,"value":1254},"💅 Refactors",{"type":212,"tag":327,"props":1256,"children":1257},{},[1258,1271,1284,1310,1323],{"type":212,"tag":331,"props":1259,"children":1260},{},[1261,1263,1270],{"type":224,"value":1262},"Import the core's API by its package name (",{"type":212,"tag":217,"props":1264,"children":1267},{"href":1265,"rel":1266},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcommit\u002F4024ec5",[221],[1268],{"type":224,"value":1269},"4024ec5",{"type":224,"value":344},{"type":212,"tag":331,"props":1272,"children":1273},{},[1274,1276,1283],{"type":224,"value":1275},"Command handlers take one object (",{"type":212,"tag":217,"props":1277,"children":1280},{"href":1278,"rel":1279},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcommit\u002F16b55d1",[221],[1281],{"type":224,"value":1282},"16b55d1",{"type":224,"value":344},{"type":212,"tag":331,"props":1285,"children":1286},{},[1287,1292,1294,1300,1302,1309],{"type":212,"tag":239,"props":1288,"children":1290},{"className":1289},[],[1291],{"type":224,"value":905},{"type":224,"value":1293}," over ",{"type":212,"tag":239,"props":1295,"children":1297},{"className":1296},[],[1298],{"type":224,"value":1299},"Player.all",{"type":224,"value":1301}," (",{"type":212,"tag":217,"props":1303,"children":1306},{"href":1304,"rel":1305},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcommit\u002Fab12133",[221],[1307],{"type":224,"value":1308},"ab12133",{"type":224,"value":344},{"type":212,"tag":331,"props":1311,"children":1312},{},[1313,1315,1322],{"type":224,"value":1314},"Listen to the team message by its new name (",{"type":212,"tag":217,"props":1316,"children":1319},{"href":1317,"rel":1318},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcommit\u002Fc8a31d9",[221],[1320],{"type":224,"value":1321},"c8a31d9",{"type":224,"value":344},{"type":212,"tag":331,"props":1324,"children":1325},{},[1326,1328,1334,1335,1341,1343,1350],{"type":224,"value":1327},"Hear ",{"type":212,"tag":239,"props":1329,"children":1331},{"className":1330},[],[1332],{"type":224,"value":1333},"putInServer",{"type":224,"value":1010},{"type":212,"tag":239,"props":1336,"children":1338},{"className":1337},[],[1339],{"type":224,"value":1340},"playerChange",{"type":224,"value":1342}," by their new names (",{"type":212,"tag":217,"props":1344,"children":1347},{"href":1345,"rel":1346},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcommit\u002F9b407b7",[221],[1348],{"type":224,"value":1349},"9b407b7",{"type":224,"value":344},{"type":212,"tag":227,"props":1352,"children":1354},{"id":1353},"documentation",[1355],{"type":224,"value":1356},"📖 Documentation",{"type":212,"tag":327,"props":1358,"children":1359},{},[1360],{"type":212,"tag":331,"props":1361,"children":1362},{},[1363,1365,1372],{"type":224,"value":1364},"The rule goes with the plugin that set it (",{"type":212,"tag":217,"props":1366,"children":1369},{"href":1367,"rel":1368},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fresemiclip\u002Fcommit\u002F7a4ce5b",[221],[1370],{"type":224,"value":1371},"7a4ce5b",{"type":224,"value":344},{"type":212,"tag":227,"props":1374,"children":1375},{"id":322},[1376],{"type":224,"value":325},{"type":212,"tag":327,"props":1378,"children":1379},{},[1380],{"type":212,"tag":331,"props":1381,"children":1382},{},[1383,1384,1389],{"type":224,"value":335},{"type":212,"tag":217,"props":1385,"children":1387},{"href":338,"rel":1386},[221],[1388],{"type":224,"value":342},{"type":224,"value":344},{"data":1391,"body":1392},{},{"type":209,"children":1393},[1394,1403,1407,1412,1416,1427,1431,1440,1444,1495,1499,1515,1519,1567,1571,1600,1604],{"type":212,"tag":213,"props":1395,"children":1396},{},[1397],{"type":212,"tag":217,"props":1398,"children":1401},{"href":1399,"rel":1400},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcompare\u002Fv0.1.0...v0.1.1",[221],[1402],{"type":224,"value":225},{"type":212,"tag":227,"props":1404,"children":1405},{"id":229},[1406],{"type":224,"value":232},{"type":212,"tag":213,"props":1408,"children":1409},{},[1410],{"type":224,"value":1411},"config-core for amxts 0.2.0. Its API is unchanged: a plugin that reads its configs needs nothing new.",{"type":212,"tag":227,"props":1413,"children":1414},{"id":1141},[1415],{"type":224,"value":1144},{"type":212,"tag":213,"props":1417,"children":1418},{},[1419,1421,1426],{"type":224,"value":1420},"None in config-core itself; it needs ",{"type":212,"tag":239,"props":1422,"children":1424},{"className":1423},[],[1425],{"type":224,"value":244},{"type":224,"value":1156},{"type":212,"tag":227,"props":1428,"children":1429},{"id":249},[1430],{"type":224,"value":252},{"type":212,"tag":213,"props":1432,"children":1433},{},[1434,1439],{"type":212,"tag":239,"props":1435,"children":1437},{"className":1436},[],[1438],{"type":224,"value":261},{"type":224,"value":1170},{"type":212,"tag":227,"props":1441,"children":1442},{"id":266},[1443],{"type":224,"value":269},{"type":212,"tag":271,"props":1445,"children":1446},{},[1447,1465],{"type":212,"tag":275,"props":1448,"children":1449},{},[1450],{"type":212,"tag":279,"props":1451,"children":1452},{},[1453,1457,1461],{"type":212,"tag":283,"props":1454,"children":1455},{},[1456],{"type":224,"value":287},{"type":212,"tag":283,"props":1458,"children":1459},{},[1460],{"type":224,"value":1192},{"type":212,"tag":283,"props":1462,"children":1463},{},[1464],{"type":224,"value":1197},{"type":212,"tag":294,"props":1466,"children":1467},{},[1468],{"type":212,"tag":279,"props":1469,"children":1470},{},[1471,1479,1487],{"type":212,"tag":301,"props":1472,"children":1473},{},[1474],{"type":212,"tag":239,"props":1475,"children":1477},{"className":1476},[],[1478],{"type":224,"value":244},{"type":212,"tag":301,"props":1480,"children":1481},{},[1482],{"type":212,"tag":239,"props":1483,"children":1485},{"className":1484},[],[1486],{"type":224,"value":1220},{"type":212,"tag":301,"props":1488,"children":1489},{},[1490],{"type":212,"tag":239,"props":1491,"children":1493},{"className":1492},[],[1494],{"type":224,"value":317},{"type":212,"tag":227,"props":1496,"children":1497},{"id":608},[1498],{"type":224,"value":611},{"type":212,"tag":327,"props":1500,"children":1501},{},[1502],{"type":212,"tag":331,"props":1503,"children":1504},{},[1505,1507,1514],{"type":224,"value":1506},"The plugin's version is the package's (",{"type":212,"tag":217,"props":1508,"children":1511},{"href":1509,"rel":1510},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcommit\u002Fc53a7ee",[221],[1512],{"type":224,"value":1513},"c53a7ee",{"type":224,"value":344},{"type":212,"tag":227,"props":1516,"children":1517},{"id":1251},[1518],{"type":224,"value":1254},{"type":212,"tag":327,"props":1520,"children":1521},{},[1522,1534,1546],{"type":212,"tag":331,"props":1523,"children":1524},{},[1525,1526,1533],{"type":224,"value":1262},{"type":212,"tag":217,"props":1527,"children":1530},{"href":1528,"rel":1529},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcommit\u002F7e12991",[221],[1531],{"type":224,"value":1532},"7e12991",{"type":224,"value":344},{"type":212,"tag":331,"props":1535,"children":1536},{},[1537,1538,1545],{"type":224,"value":1275},{"type":212,"tag":217,"props":1539,"children":1542},{"href":1540,"rel":1541},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcommit\u002F4240f17",[221],[1543],{"type":224,"value":1544},"4240f17",{"type":224,"value":344},{"type":212,"tag":331,"props":1547,"children":1548},{},[1549,1551,1557,1559,1566],{"type":224,"value":1550},"Admin right by its ",{"type":212,"tag":239,"props":1552,"children":1554},{"className":1553},[],[1555],{"type":224,"value":1556},"lowerCamelCase",{"type":224,"value":1558}," name (",{"type":212,"tag":217,"props":1560,"children":1563},{"href":1561,"rel":1562},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcommit\u002F74c8ddf",[221],[1564],{"type":224,"value":1565},"74c8ddf",{"type":224,"value":344},{"type":212,"tag":227,"props":1568,"children":1569},{"id":1353},[1570],{"type":224,"value":1356},{"type":212,"tag":327,"props":1572,"children":1573},{},[1574,1587],{"type":212,"tag":331,"props":1575,"children":1576},{},[1577,1579,1586],{"type":224,"value":1578},"The Pawn natives without a plugin the reader never met (",{"type":212,"tag":217,"props":1580,"children":1583},{"href":1581,"rel":1582},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcommit\u002F7de1140",[221],[1584],{"type":224,"value":1585},"7de1140",{"type":224,"value":344},{"type":212,"tag":331,"props":1588,"children":1589},{},[1590,1592,1599],{"type":224,"value":1591},"The natives' limits without comparing to Pawn (",{"type":212,"tag":217,"props":1593,"children":1596},{"href":1594,"rel":1595},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fconfig-core\u002Fcommit\u002Fcedf727",[221],[1597],{"type":224,"value":1598},"cedf727",{"type":224,"value":344},{"type":212,"tag":227,"props":1601,"children":1602},{"id":322},[1603],{"type":224,"value":325},{"type":212,"tag":327,"props":1605,"children":1606},{},[1607],{"type":212,"tag":331,"props":1608,"children":1609},{},[1610,1611,1616],{"type":224,"value":335},{"type":212,"tag":217,"props":1612,"children":1614},{"href":338,"rel":1613},[221],[1615],{"type":224,"value":342},{"type":224,"value":344},{"data":1618,"body":1619},{},{"type":209,"children":1620},[1621,1630,1634,1646,1652,1662,1705,1711,1730,1736,1755,1759,1781,1785,1827,1833,1855,1859,1910,1916,2042,2046,2122,2126,2141,2145,2179,2183],{"type":212,"tag":213,"props":1622,"children":1623},{},[1624],{"type":212,"tag":217,"props":1625,"children":1628},{"href":1626,"rel":1627},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcompare\u002Fv0.1.0...v0.2.0",[221],[1629],{"type":224,"value":225},{"type":212,"tag":227,"props":1631,"children":1632},{"id":229},[1633],{"type":224,"value":232},{"type":212,"tag":213,"props":1635,"children":1636},{},[1637,1639,1644],{"type":224,"value":1638},"The command for amxts 0.2.0. ",{"type":212,"tag":239,"props":1640,"children":1642},{"className":1641},[],[1643],{"type":224,"value":797},{"type":224,"value":1645}," moves a 0.1.0 project over in one step, and a new project starts from 0.2.0's API.",{"type":212,"tag":227,"props":1647,"children":1649},{"id":1648},"highlights",[1650],{"type":224,"value":1651},"✨ Highlights",{"type":212,"tag":1653,"props":1654,"children":1656},"h4",{"id":1655},"amxts-upgrade",[1657],{"type":212,"tag":239,"props":1658,"children":1660},{"className":1659},[],[1661],{"type":224,"value":797},{"type":212,"tag":213,"props":1663,"children":1664},{},[1665,1667,1673,1675,1680,1682,1688,1690,1696,1697,1703],{"type":224,"value":1666},"One command updates the packages, rewrites the code for the renamed API, builds, and puts the release's module, compiler and ",{"type":212,"tag":239,"props":1668,"children":1670},{"className":1669},[],[1671],{"type":224,"value":1672},"wamrc",{"type":224,"value":1674}," on the server named in ",{"type":212,"tag":239,"props":1676,"children":1678},{"className":1677},[],[1679],{"type":224,"value":595},{"type":224,"value":1681},", with a backup of each file it replaces. ",{"type":212,"tag":239,"props":1683,"children":1685},{"className":1684},[],[1686],{"type":224,"value":1687},"--dry-run",{"type":224,"value":1689}," shows what it would do; ",{"type":212,"tag":239,"props":1691,"children":1693},{"className":1692},[],[1694],{"type":224,"value":1695},"--no-server",{"type":224,"value":1010},{"type":212,"tag":239,"props":1698,"children":1700},{"className":1699},[],[1701],{"type":224,"value":1702},"--server-only",{"type":224,"value":1704}," do half of it.",{"type":212,"tag":1653,"props":1706,"children":1708},{"id":1707},"a-new-project",[1709],{"type":224,"value":1710},"A new project",{"type":212,"tag":213,"props":1712,"children":1713},{},[1714,1720,1722,1728],{"type":212,"tag":239,"props":1715,"children":1717},{"className":1716},[],[1718],{"type":224,"value":1719},"hello.ts",{"type":224,"value":1721}," has a typed config and a menu that greets the player by name; with ",{"type":212,"tag":239,"props":1723,"children":1725},{"className":1724},[],[1726],{"type":224,"value":1727},"@amxts\u002Fmenu-core",{"type":224,"value":1729},", its starter menu takes the menu's context.",{"type":212,"tag":1653,"props":1731,"children":1733},{"id":1732},"the-servers-folder",[1734],{"type":224,"value":1735},"The server's folder",{"type":212,"tag":213,"props":1737,"children":1738},{},[1739,1745,1747,1753],{"type":212,"tag":239,"props":1740,"children":1742},{"className":1741},[],[1743],{"type":224,"value":1744},"AMXTS_SERVER",{"type":224,"value":1746}," may name the server's root or its ",{"type":212,"tag":239,"props":1748,"children":1750},{"className":1749},[],[1751],{"type":224,"value":1752},"cstrike",{"type":224,"value":1754}," folder.",{"type":212,"tag":227,"props":1756,"children":1757},{"id":1141},[1758],{"type":224,"value":1144},{"type":212,"tag":327,"props":1760,"children":1761},{},[1762],{"type":212,"tag":331,"props":1763,"children":1764},{},[1765,1767,1772,1774,1779],{"type":224,"value":1766},"The command drives ",{"type":212,"tag":239,"props":1768,"children":1770},{"className":1769},[],[1771],{"type":224,"value":244},{"type":224,"value":1773}," 0.2.x only. A 0.1.0 project runs ",{"type":212,"tag":239,"props":1775,"children":1777},{"className":1776},[],[1778],{"type":224,"value":797},{"type":224,"value":1780}," first.",{"type":212,"tag":227,"props":1782,"children":1783},{"id":249},[1784],{"type":224,"value":252},{"type":212,"tag":213,"props":1786,"children":1787},{},[1788,1790,1796,1797,1803,1804,1810,1812,1818,1820,1825],{"type":224,"value":1789},"Update the command with the package manager the project uses - ",{"type":212,"tag":239,"props":1791,"children":1793},{"className":1792},[],[1794],{"type":224,"value":1795},"npm install @amxts\u002Fcli@latest",{"type":224,"value":633},{"type":212,"tag":239,"props":1798,"children":1800},{"className":1799},[],[1801],{"type":224,"value":1802},"bun add @amxts\u002Fcli@latest",{"type":224,"value":633},{"type":212,"tag":239,"props":1805,"children":1807},{"className":1806},[],[1808],{"type":224,"value":1809},"pnpm add @amxts\u002Fcli@latest",{"type":224,"value":1811}," or ",{"type":212,"tag":239,"props":1813,"children":1815},{"className":1814},[],[1816],{"type":224,"value":1817},"yarn add @amxts\u002Fcli@latest",{"type":224,"value":1819}," - then run ",{"type":212,"tag":239,"props":1821,"children":1823},{"className":1822},[],[1824],{"type":224,"value":261},{"type":224,"value":1826},".",{"type":212,"tag":227,"props":1828,"children":1830},{"id":1829},"known-issues",[1831],{"type":224,"value":1832},"🧭 Known issues",{"type":212,"tag":327,"props":1834,"children":1835},{},[1836],{"type":212,"tag":331,"props":1837,"children":1838},{},[1839,1841,1846,1848,1853],{"type":224,"value":1840},"The server step of ",{"type":212,"tag":239,"props":1842,"children":1844},{"className":1843},[],[1845],{"type":224,"value":797},{"type":224,"value":1847}," downloads the release from GitHub; without network access run it with ",{"type":212,"tag":239,"props":1849,"children":1851},{"className":1850},[],[1852],{"type":224,"value":1695},{"type":224,"value":1854}," and install the server kit by hand.",{"type":212,"tag":227,"props":1856,"children":1857},{"id":266},[1858],{"type":224,"value":269},{"type":212,"tag":271,"props":1860,"children":1861},{},[1862,1880],{"type":212,"tag":275,"props":1863,"children":1864},{},[1865],{"type":212,"tag":279,"props":1866,"children":1867},{},[1868,1872,1876],{"type":212,"tag":283,"props":1869,"children":1870},{},[1871],{"type":224,"value":287},{"type":212,"tag":283,"props":1873,"children":1874},{},[1875],{"type":224,"value":1192},{"type":212,"tag":283,"props":1877,"children":1878},{},[1879],{"type":224,"value":1197},{"type":212,"tag":294,"props":1881,"children":1882},{},[1883],{"type":212,"tag":279,"props":1884,"children":1885},{},[1886,1894,1902],{"type":212,"tag":301,"props":1887,"children":1888},{},[1889],{"type":212,"tag":239,"props":1890,"children":1892},{"className":1891},[],[1893],{"type":224,"value":244},{"type":212,"tag":301,"props":1895,"children":1896},{},[1897],{"type":212,"tag":239,"props":1898,"children":1900},{"className":1899},[],[1901],{"type":224,"value":1220},{"type":212,"tag":301,"props":1903,"children":1904},{},[1905],{"type":212,"tag":239,"props":1906,"children":1908},{"className":1907},[],[1909],{"type":224,"value":317},{"type":212,"tag":227,"props":1911,"children":1913},{"id":1912},"enhancements",[1914],{"type":224,"value":1915},"🚀 Enhancements",{"type":212,"tag":327,"props":1917,"children":1918},{},[1919,1937,1961,1978,1995,2012,2029],{"type":212,"tag":331,"props":1920,"children":1921},{},[1922,1927,1929,1936],{"type":212,"tag":619,"props":1923,"children":1924},{},[1925],{"type":224,"value":1926},"server:",{"type":224,"value":1928}," Take the server's folder or its cstrike (",{"type":212,"tag":217,"props":1930,"children":1933},{"href":1931,"rel":1932},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002Ff41a1d7",[221],[1934],{"type":224,"value":1935},"f41a1d7",{"type":224,"value":344},{"type":212,"tag":331,"props":1938,"children":1939},{},[1940,1945,1947,1952,1953,1960],{"type":212,"tag":619,"props":1941,"children":1942},{},[1943],{"type":224,"value":1944},"init:",{"type":224,"value":1946}," Typed config and the core's Menu in ",{"type":212,"tag":239,"props":1948,"children":1950},{"className":1949},[],[1951],{"type":224,"value":1719},{"type":224,"value":1301},{"type":212,"tag":217,"props":1954,"children":1957},{"href":1955,"rel":1956},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F50a7343",[221],[1958],{"type":224,"value":1959},"50a7343",{"type":224,"value":344},{"type":212,"tag":331,"props":1962,"children":1963},{},[1964,1968,1970,1977],{"type":212,"tag":619,"props":1965,"children":1966},{},[1967],{"type":224,"value":1944},{"type":224,"value":1969}," The starter menu greets by name in its title (",{"type":212,"tag":217,"props":1971,"children":1974},{"href":1972,"rel":1973},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002Ff38a850",[221],[1975],{"type":224,"value":1976},"f38a850",{"type":224,"value":344},{"type":212,"tag":331,"props":1979,"children":1980},{},[1981,1985,1987,1994],{"type":212,"tag":619,"props":1982,"children":1983},{},[1984],{"type":224,"value":1944},{"type":224,"value":1986}," The menu-core starter menu takes its context (",{"type":212,"tag":217,"props":1988,"children":1991},{"href":1989,"rel":1990},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F3e590ab",[221],[1992],{"type":224,"value":1993},"3e590ab",{"type":224,"value":344},{"type":212,"tag":331,"props":1996,"children":1997},{},[1998,2002,2004,2011],{"type":212,"tag":619,"props":1999,"children":2000},{},[2001],{"type":224,"value":974},{"type":224,"value":2003}," One command moves a project to a release (",{"type":212,"tag":217,"props":2005,"children":2008},{"href":2006,"rel":2007},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F00d3974",[221],[2009],{"type":224,"value":2010},"00d3974",{"type":224,"value":344},{"type":212,"tag":331,"props":2013,"children":2014},{},[2015,2019,2021,2028],{"type":212,"tag":619,"props":2016,"children":2017},{},[2018],{"type":224,"value":974},{"type":224,"value":2020}," Each package to its own version for the core (",{"type":212,"tag":217,"props":2022,"children":2025},{"href":2023,"rel":2024},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F426f2a9",[221],[2026],{"type":224,"value":2027},"426f2a9",{"type":224,"value":344},{"type":212,"tag":331,"props":2030,"children":2031},{},[2032,2034,2041],{"type":224,"value":2033},"New modules at their version for the core (",{"type":212,"tag":217,"props":2035,"children":2038},{"href":2036,"rel":2037},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002Fa2be088",[221],[2039],{"type":224,"value":2040},"a2be088",{"type":224,"value":344},{"type":212,"tag":227,"props":2043,"children":2044},{"id":608},[2045],{"type":224,"value":611},{"type":212,"tag":327,"props":2047,"children":2048},{},[2049,2073,2098],{"type":212,"tag":331,"props":2050,"children":2051},{},[2052,2056,2057,2063,2065,2072],{"type":212,"tag":619,"props":2053,"children":2054},{},[2055],{"type":224,"value":1944},{"type":224,"value":925},{"type":212,"tag":239,"props":2058,"children":2060},{"className":2059},[],[2061],{"type":224,"value":2062},"knip",{"type":224,"value":2064}," 6 in a new project (",{"type":212,"tag":217,"props":2066,"children":2069},{"href":2067,"rel":2068},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F868f2e3",[221],[2070],{"type":224,"value":2071},"868f2e3",{"type":224,"value":344},{"type":212,"tag":331,"props":2074,"children":2075},{},[2076,2080,2082,2088,2090,2097],{"type":212,"tag":619,"props":2077,"children":2078},{},[2079],{"type":224,"value":1944},{"type":224,"value":2081}," Keep a linked core's own ",{"type":212,"tag":239,"props":2083,"children":2085},{"className":2084},[],[2086],{"type":224,"value":2087},".bin",{"type":224,"value":2089}," on yarn (",{"type":212,"tag":217,"props":2091,"children":2094},{"href":2092,"rel":2093},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F1262f55",[221],[2095],{"type":224,"value":2096},"1262f55",{"type":224,"value":344},{"type":212,"tag":331,"props":2099,"children":2100},{},[2101,2106,2108,2113,2114,2121],{"type":212,"tag":619,"props":2102,"children":2103},{},[2104],{"type":224,"value":2105},"templates:",{"type":224,"value":2107}," The starter hears ",{"type":212,"tag":239,"props":2109,"children":2111},{"className":2110},[],[2112],{"type":224,"value":1333},{"type":224,"value":1301},{"type":212,"tag":217,"props":2115,"children":2118},{"href":2116,"rel":2117},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002Fe20acbe",[221],[2119],{"type":224,"value":2120},"e20acbe",{"type":224,"value":344},{"type":212,"tag":227,"props":2123,"children":2124},{"id":1251},[2125],{"type":224,"value":1254},{"type":212,"tag":327,"props":2127,"children":2128},{},[2129],{"type":212,"tag":331,"props":2130,"children":2131},{},[2132,2133,2140],{"type":224,"value":1275},{"type":212,"tag":217,"props":2134,"children":2137},{"href":2135,"rel":2136},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F5bd680c",[221],[2138],{"type":224,"value":2139},"5bd680c",{"type":224,"value":344},{"type":212,"tag":227,"props":2142,"children":2143},{"id":1353},[2144],{"type":224,"value":1356},{"type":212,"tag":327,"props":2146,"children":2147},{},[2148,2161],{"type":212,"tag":331,"props":2149,"children":2150},{},[2151,2153,2160],{"type":224,"value":2152},"The packages are on npm (",{"type":212,"tag":217,"props":2154,"children":2157},{"href":2155,"rel":2156},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F9770340",[221],[2158],{"type":224,"value":2159},"9770340",{"type":224,"value":344},{"type":212,"tag":331,"props":2162,"children":2163},{},[2164,2169,2171,2178],{"type":212,"tag":239,"props":2165,"children":2167},{"className":2166},[],[2168],{"type":224,"value":159},{"type":224,"value":2170}," upgrade in the READMEs and CONTRIBUTING (",{"type":212,"tag":217,"props":2172,"children":2175},{"href":2173,"rel":2174},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts-cli\u002Fcommit\u002F7c69105",[221],[2176],{"type":224,"value":2177},"7c69105",{"type":224,"value":344},{"type":212,"tag":227,"props":2180,"children":2181},{"id":322},[2182],{"type":224,"value":325},{"type":212,"tag":327,"props":2184,"children":2185},{},[2186],{"type":212,"tag":331,"props":2187,"children":2188},{},[2189,2190,2195],{"type":224,"value":335},{"type":212,"tag":217,"props":2191,"children":2193},{"href":338,"rel":2192},[221],[2194],{"type":224,"value":342},{"type":224,"value":344},{"data":2197,"body":2198},{},{"type":209,"children":2199},[2200],{"type":212,"tag":213,"props":2201,"children":2202},{},[2203],{"type":224,"value":199},{"data":2205,"body":2206},{},{"type":209,"children":2207},[2208],{"type":212,"tag":213,"props":2209,"children":2210},{},[2211],{"type":224,"value":203},{"data":2213,"body":2214},{},{"type":209,"children":2215},[2216,2225,2229,2248,2252,2258,2279,2291,2312,2318,2323,2400,2413,2419,2452,2458,2479,2490,2536,2563,2569,2612,2620,2670,2688,2722,2730,2748,2758,2770,2778,2783,2789,2809,2817,2866,2874,2880,2885,2893,2945,2951,2972,2981,3021,3027,3032,3275,3316,3333,3337,3653,3657,3700,3704,3736,3740,4245,4251,4281,4285,4415,4419,4432,4436,4505],{"type":212,"tag":213,"props":2217,"children":2218},{},[2219],{"type":212,"tag":217,"props":2220,"children":2223},{"href":2221,"rel":2222},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fcompare\u002Fv0.1.0...v0.2.0",[221],[2224],{"type":224,"value":225},{"type":212,"tag":227,"props":2226,"children":2227},{"id":229},[2228],{"type":224,"value":232},{"type":212,"tag":213,"props":2230,"children":2231},{},[2232,2234,2240,2242,2247],{"type":224,"value":2233},"0.2.0 makes a server one module to install and runs it on Valve's own HLDS as well as ReHLDS. Plugins get commands with typed arguments, menus, ",{"type":212,"tag":239,"props":2235,"children":2237},{"className":2236},[],[2238],{"type":224,"value":2239},"fetch",{"type":224,"value":2241},", FTP and SFTP, bots, game messages by name, errors that point at their TypeScript, and names in the player's words. A 0.1.0 project moves over with ",{"type":212,"tag":239,"props":2243,"children":2245},{"className":2244},[],[2246],{"type":224,"value":797},{"type":224,"value":1826},{"type":212,"tag":227,"props":2249,"children":2250},{"id":1648},[2251],{"type":224,"value":1651},{"type":212,"tag":1653,"props":2253,"children":2255},{"id":2254},"one-module-to-install",[2256],{"type":224,"value":2257},"One module to install",{"type":212,"tag":213,"props":2259,"children":2260},{},[2261,2263,2269,2271,2277],{"type":224,"value":2262},"A server needs the ",{"type":212,"tag":239,"props":2264,"children":2266},{"className":2265},[],[2267],{"type":224,"value":2268},"addons\u002F",{"type":224,"value":2270}," folder of the server kit and one line in ",{"type":212,"tag":239,"props":2272,"children":2274},{"className":2273},[],[2275],{"type":224,"value":2276},"modules.ini",{"type":224,"value":2278},":",{"type":212,"tag":2280,"props":2281,"children":2285},"pre",{"className":2282,"code":2284,"language":224},[2283],"language-text","amxts_amxx\n",[2286],{"type":212,"tag":239,"props":2287,"children":2289},{"__ignoreMap":2288},"",[2290],{"type":224,"value":2284},{"type":212,"tag":213,"props":2292,"children":2293},{},[2294,2296,2302,2304,2310],{"type":224,"value":2295},"Nothing goes into ",{"type":212,"tag":239,"props":2297,"children":2299},{"className":2298},[],[2300],{"type":224,"value":2301},"plugins.ini",{"type":224,"value":2303},": the module brings its host plugin itself, writes it next to AMX Mod X's plugins when it starts, and removes it when it stops. An install from 0.1.0 can drop its ",{"type":212,"tag":239,"props":2305,"children":2307},{"className":2306},[],[2308],{"type":224,"value":2309},"amxts_host.amxx",{"type":224,"value":2311}," line; the console says so once.",{"type":212,"tag":1653,"props":2313,"children":2315},{"id":2314},"plain-hlds",[2316],{"type":224,"value":2317},"Plain HLDS",{"type":212,"tag":213,"props":2319,"children":2320},{},[2321],{"type":224,"value":2322},"amxts runs on Valve's own HLDS as well as on ReHLDS. The same plugin works on both, unchanged:",{"type":212,"tag":327,"props":2324,"children":2325},{},[2326,2331,2365],{"type":212,"tag":331,"props":2327,"children":2328},{},[2329],{"type":224,"value":2330},"every property of an entity and a player;",{"type":212,"tag":331,"props":2332,"children":2333},{},[2334,2336,2342,2343,2349,2350,2356,2357,2363],{"type":224,"value":2335},"the game events Ham Sandwich shares with ReAPI - ",{"type":212,"tag":239,"props":2337,"children":2339},{"className":2338},[],[2340],{"type":224,"value":2341},"takeDamage",{"type":224,"value":633},{"type":212,"tag":239,"props":2344,"children":2346},{"className":2345},[],[2347],{"type":224,"value":2348},"spawn",{"type":224,"value":633},{"type":212,"tag":239,"props":2351,"children":2353},{"className":2352},[],[2354],{"type":224,"value":2355},"killed",{"type":224,"value":633},{"type":212,"tag":239,"props":2358,"children":2360},{"className":2359},[],[2361],{"type":224,"value":2362},"jump",{"type":224,"value":2364}," and more;",{"type":212,"tag":331,"props":2366,"children":2367},{},[2368,2370,2376,2377,2383,2384,2390,2392,2398],{"type":224,"value":2369},"rounds (",{"type":212,"tag":239,"props":2371,"children":2373},{"className":2372},[],[2374],{"type":224,"value":2375},"newRound",{"type":224,"value":633},{"type":212,"tag":239,"props":2378,"children":2380},{"className":2379},[],[2381],{"type":224,"value":2382},"roundStart",{"type":224,"value":633},{"type":212,"tag":239,"props":2385,"children":2387},{"className":2386},[],[2388],{"type":224,"value":2389},"roundEnd",{"type":224,"value":2391},"), spawns, purchases, money and the bomb, heard through the game's own log lines and messages - after the fact, so ",{"type":212,"tag":239,"props":2393,"children":2395},{"className":2394},[],[2396],{"type":224,"value":2397},"preventDefault()",{"type":224,"value":2399}," on them says once that it cannot stop them.",{"type":212,"tag":213,"props":2401,"children":2402},{},[2403,2405,2411],{"type":224,"value":2404},"What plain HLDS cannot give at all - ReGameDLL's own functions - prints one line in the console when a plugin listens for it, and a project with ",{"type":212,"tag":239,"props":2406,"children":2408},{"className":2407},[],[2409],{"type":224,"value":2410},"target: \"hlds\"",{"type":224,"value":2412}," does not build with such a listener. Each event's page says how it behaves on plain HLDS.",{"type":212,"tag":1653,"props":2414,"children":2416},{"id":2415},"faster-properties",[2417],{"type":224,"value":2418},"Faster properties",{"type":212,"tag":213,"props":2420,"children":2421},{},[2422,2428,2429,2435,2436,2442,2444,2450],{"type":212,"tag":239,"props":2423,"children":2425},{"className":2424},[],[2426],{"type":224,"value":2427},"entity.origin",{"type":224,"value":633},{"type":212,"tag":239,"props":2430,"children":2432},{"className":2431},[],[2433],{"type":224,"value":2434},"player.health",{"type":224,"value":633},{"type":212,"tag":239,"props":2437,"children":2439},{"className":2438},[],[2440],{"type":224,"value":2441},"player.money",{"type":224,"value":2443}," and every other field are read and written where the game keeps them, on both servers, without a native call. A field the player sees on the HUD - ",{"type":212,"tag":239,"props":2445,"children":2447},{"className":2446},[],[2448],{"type":224,"value":2449},"money",{"type":224,"value":2451},", the armor type, the flashlight's battery, night vision, the defuse kit - is sent to the player as the game sends it.",{"type":212,"tag":1653,"props":2453,"children":2455},{"id":2454},"commands-with-typed-arguments",[2456],{"type":224,"value":2457},"Commands with typed arguments",{"type":212,"tag":213,"props":2459,"children":2460},{},[2461,2463,2469,2471,2477],{"type":224,"value":2462},"The usage is the command's help and its parser at once: ",{"type":212,"tag":239,"props":2464,"children":2466},{"className":2465},[],[2467],{"type":224,"value":2468},"\u003Cname>",{"type":224,"value":2470}," is required, ",{"type":212,"tag":239,"props":2472,"children":2474},{"className":2473},[],[2475],{"type":224,"value":2476},"[name]",{"type":224,"value":2478}," optional, and the interface you name says what each one is.",{"type":212,"tag":2280,"props":2480,"children":2485},{"className":2481,"code":2482,"language":2483,"meta":2288,"style":2484},"language-ts","interface KickArgs {\n    target: Player;\n    reason?: string;\n}\n\nserver.addCommand\u003CKickArgs>(\"\u002Fkick \u003Ctarget> [reason]\", ({ player, target, reason }) => {\n    target.kick(reason ?? `Kicked by ${player.name}`);\n}, { access: \"Kick\", description: \"Kick a player\" });\n","ts","undefined",[2486],{"type":212,"tag":239,"props":2487,"children":2488},{"__ignoreMap":2288},[2489],{"type":224,"value":2482},{"type":212,"tag":327,"props":2491,"children":2492},{},[2493,2514,2526,2531],{"type":212,"tag":331,"props":2494,"children":2495},{},[2496,2498,2504,2506,2512],{"type":224,"value":2497},"a ",{"type":212,"tag":239,"props":2499,"children":2501},{"className":2500},[],[2502],{"type":224,"value":2503},"Player",{"type":224,"value":2505}," is found by ",{"type":212,"tag":239,"props":2507,"children":2509},{"className":2508},[],[2510],{"type":224,"value":2511},"#userid",{"type":224,"value":2513},", by the whole name or by a part of it;",{"type":212,"tag":331,"props":2515,"children":2516},{},[2517,2518,2524],{"type":224,"value":2497},{"type":212,"tag":239,"props":2519,"children":2521},{"className":2520},[],[2522],{"type":224,"value":2523},"number",{"type":224,"value":2525}," is parsed, a union of words is one of them, the last text argument takes the rest of the line;",{"type":212,"tag":331,"props":2527,"children":2528},{},[2529],{"type":224,"value":2530},"a player nobody's name matches, several whose do, or a word too many answers the one who typed it with the usage, and the handler does not run;",{"type":212,"tag":331,"props":2532,"children":2533},{},[2534],{"type":224,"value":2535},"without the type argument every argument is text.",{"type":212,"tag":213,"props":2537,"children":2538},{},[2539,2545,2547,2553,2555,2561],{"type":212,"tag":239,"props":2540,"children":2542},{"className":2541},[],[2543],{"type":224,"value":2544},"player",{"type":224,"value":2546}," is always the one who typed the command. ",{"type":212,"tag":239,"props":2548,"children":2550},{"className":2549},[],[2551],{"type":224,"value":2552},"server.commands",{"type":224,"value":2554}," lists every command with its usage, description and access, for a ",{"type":212,"tag":239,"props":2556,"children":2558},{"className":2557},[],[2559],{"type":224,"value":2560},"\u002Fhelp",{"type":224,"value":2562}," of your own.",{"type":212,"tag":1653,"props":2564,"children":2566},{"id":2565},"menus",[2567],{"type":224,"value":2568},"Menus",{"type":212,"tag":213,"props":2570,"children":2571},{},[2572,2578,2580,2586,2588,2594,2596,2602,2604,2610],{"type":212,"tag":239,"props":2573,"children":2575},{"className":2574},[],[2576],{"type":224,"value":2577},"Menu",{"type":224,"value":2579}," is AMX Mod X's own menu - number keys, pages with Back and More, Exit - written as objects. Each item has a title, and may say when it is shown (",{"type":212,"tag":239,"props":2581,"children":2583},{"className":2582},[],[2584],{"type":224,"value":2585},"visible",{"type":224,"value":2587},") and when it can be chosen (",{"type":212,"tag":239,"props":2589,"children":2591},{"className":2590},[],[2592],{"type":224,"value":2593},"enabled",{"type":224,"value":2595},", drawn grey otherwise); both are asked again at every ",{"type":212,"tag":239,"props":2597,"children":2599},{"className":2598},[],[2600],{"type":224,"value":2601},"show",{"type":224,"value":2603},", for the player it is shown to. Choosing an item runs its ",{"type":212,"tag":239,"props":2605,"children":2607},{"className":2606},[],[2608],{"type":224,"value":2609},"onSelect",{"type":224,"value":2611}," and closes the menu.",{"type":212,"tag":2280,"props":2613,"children":2615},{"className":2481,"code":2614,"language":2483,"meta":2288,"style":2484},"const shop = new Menu(\"Shop\");\n\nshop.addItem({\n    title: \"Armor - $1000\",\n    enabled: ({ player }) => player.money >= 1000,\n    onSelect: ({ player }) => {\n        player.armor = 100;\n        player.money -= 1000;\n    },\n});\n\nshop.addItem({\n    title: ({ player }) => `Heal (${player.health} HP)`,\n    visible: ({ player }) => player.isAlive,\n    onSelect: ({ player }) => {\n        player.health = 100;\n    },\n});\n\nserver.addCommand(\"\u002Fshop\", ({ player }) => shop.show(player));\n",[2616],{"type":212,"tag":239,"props":2617,"children":2618},{"__ignoreMap":2288},[2619],{"type":224,"value":2614},{"type":212,"tag":213,"props":2621,"children":2622},{},[2623,2625,2630,2632,2637,2639,2645,2646,2652,2654,2660,2662,2668],{"type":224,"value":2624},"A menu of the players on the server is a loop over ",{"type":212,"tag":239,"props":2626,"children":2628},{"className":2627},[],[2629],{"type":224,"value":905},{"type":224,"value":2631},", one item for each. The official ",{"type":212,"tag":239,"props":2633,"children":2635},{"className":2634},[],[2636],{"type":224,"value":1727},{"type":224,"value":2638}," takes the same shape in code - ",{"type":212,"tag":239,"props":2640,"children":2642},{"className":2641},[],[2643],{"type":224,"value":2644},"menus.create(...)",{"type":224,"value":633},{"type":212,"tag":239,"props":2647,"children":2649},{"className":2648},[],[2650],{"type":224,"value":2651},"addItem({ title, visible, enabled, onSelect })",{"type":224,"value":2653}," with ",{"type":212,"tag":239,"props":2655,"children":2657},{"className":2656},[],[2658],{"type":224,"value":2659},"({ player })",{"type":224,"value":2661}," - and adds menus read from INI, YAML or JSON files, named conditions and actions, and lists with a row per player (",{"type":212,"tag":239,"props":2663,"children":2665},{"className":2664},[],[2666],{"type":224,"value":2667},"({ player, target })",{"type":224,"value":2669},").",{"type":212,"tag":1653,"props":2671,"children":2673},{"id":2672},"fetch-and-usefetch-as-in-the-browser",[2674,2679,2680,2686],{"type":212,"tag":239,"props":2675,"children":2677},{"className":2676},[],[2678],{"type":224,"value":2239},{"type":224,"value":1010},{"type":212,"tag":239,"props":2681,"children":2683},{"className":2682},[],[2684],{"type":224,"value":2685},"useFetch",{"type":224,"value":2687},", as in the browser",{"type":212,"tag":213,"props":2689,"children":2690},{},[2691,2693,2698,2700,2706,2708,2714,2715,2721],{"type":224,"value":2692},"HTTPS, redirects, timeouts and retries, on a thread of their own, so the game never waits. ",{"type":212,"tag":239,"props":2694,"children":2696},{"className":2695},[],[2697],{"type":224,"value":2685},{"type":224,"value":2699}," never throws: it gives back ",{"type":212,"tag":239,"props":2701,"children":2703},{"className":2702},[],[2704],{"type":224,"value":2705},"data",{"type":224,"value":2707}," (the JSON, read as the type you name), ",{"type":212,"tag":239,"props":2709,"children":2711},{"className":2710},[],[2712],{"type":224,"value":2713},"error",{"type":224,"value":1010},{"type":212,"tag":239,"props":2716,"children":2718},{"className":2717},[],[2719],{"type":224,"value":2720},"status",{"type":224,"value":1826},{"type":212,"tag":2280,"props":2723,"children":2725},{"className":2481,"code":2724,"language":2483,"meta":2288,"style":2484},"interface Weather {\n    temperature: number;\n}\n\nserver.addCommand(\"\u002Fweather\", async ({ player }) => {\n    const { data } = await useFetch\u003CWeather>(\"https:\u002F\u002Fapi.example.com\u002Fweather\", {\n        query: { city: \"Riga\" },\n        timeout: 5000,\n        retry: 2,\n    });\n\n    if (data) print(player, `${data.temperature}°`);\n    else print(player, \"The weather service is not answering\");\n});\n",[2726],{"type":212,"tag":239,"props":2727,"children":2728},{"__ignoreMap":2288},[2729],{"type":224,"value":2724},{"type":212,"tag":213,"props":2731,"children":2732},{},[2733,2738,2740,2746],{"type":212,"tag":239,"props":2734,"children":2736},{"className":2735},[],[2737],{"type":224,"value":2239},{"type":224,"value":2739}," is the browser's own beneath it, for a raw ",{"type":212,"tag":239,"props":2741,"children":2743},{"className":2742},[],[2744],{"type":224,"value":2745},"Response",{"type":224,"value":2747},", headers and streams.",{"type":212,"tag":1653,"props":2749,"children":2751},{"id":2750},"amxtsftp",[2752],{"type":212,"tag":239,"props":2753,"children":2755},{"className":2754},[],[2756],{"type":224,"value":2757},"@amxts\u002Fftp",{"type":212,"tag":213,"props":2759,"children":2760},{},[2761,2763,2768],{"type":224,"value":2762},"A new official module: FTP, FTPS and SFTP, since game hosts give access to a server by those. Every call is a promise on the same network thread as ",{"type":212,"tag":239,"props":2764,"children":2766},{"className":2765},[],[2767],{"type":224,"value":2239},{"type":224,"value":2769},"; files go between the game folder and the other server whole, binary included (maps, demos), without passing through the plugin.",{"type":212,"tag":2280,"props":2771,"children":2773},{"className":2481,"code":2772,"language":2483,"meta":2288,"style":2484},"import { ftp } from \"@amxts\u002Fftp\";\n\nconst client = await ftp.connect(\"sftp:\u002F\u002Fbackup@example.com\", { password: settings.password });\nawait client.upload(\"addons\u002Famxmodx\u002Flogs\u002Ftoday.log\", \"logs\u002Ftoday.log\");\nawait client.download(\"\u002Fmaps\u002Fde_dust2.bsp\", \"maps\u002Fde_dust2.bsp\");\nconst entries = await client.list(\"\u002Fconfigs\");\nawait client.close();\n",[2774],{"type":212,"tag":239,"props":2775,"children":2776},{"__ignoreMap":2288},[2777],{"type":224,"value":2772},{"type":212,"tag":213,"props":2779,"children":2780},{},[2781],{"type":224,"value":2782},"SFTP takes a password or an RSA key, and can check the host's key. Keep the password in a config, not in the code.",{"type":212,"tag":1653,"props":2784,"children":2786},{"id":2785},"bots",[2787],{"type":224,"value":2788},"Bots",{"type":212,"tag":213,"props":2790,"children":2791},{},[2792,2794,2799,2801,2807],{"type":224,"value":2793},"A fake client is a player like any other: it is in ",{"type":212,"tag":239,"props":2795,"children":2797},{"className":2796},[],[2798],{"type":224,"value":905},{"type":224,"value":2800},", it joins a team, it can be kicked. It has no AI of its own; ",{"type":212,"tag":239,"props":2802,"children":2804},{"className":2803},[],[2805],{"type":224,"value":2806},"move",{"type":224,"value":2808}," drives it, one frame at a time.",{"type":212,"tag":2280,"props":2810,"children":2812},{"className":2481,"code":2811,"language":2483,"meta":2288,"style":2484},"const bot = server.addBot(\"Spectator\");   \u002F\u002F Player | null when the server is full\nbot?.joinTeam(\"SPECTATOR\");\n\nconst runner = server.addBot(\"Runner\");\nserver.addEventListener(\"frame\", () => runner?.move({ forward: 250, buttons: [\"jump\"], angles: [0, 90, 0] }));\n",[2813],{"type":212,"tag":239,"props":2814,"children":2815},{"__ignoreMap":2288},[2816],{"type":224,"value":2811},{"type":212,"tag":213,"props":2818,"children":2819},{},[2820,2822,2828,2830,2836,2837,2843,2844,2850,2851,2857,2859,2865],{"type":224,"value":2821},"The natives with a ",{"type":212,"tag":239,"props":2823,"children":2825},{"className":2824},[],[2826],{"type":224,"value":2827},"...",{"type":224,"value":2829}," tail - ",{"type":212,"tag":239,"props":2831,"children":2833},{"className":2832},[],[2834],{"type":224,"value":2835},"engfunc",{"type":224,"value":633},{"type":212,"tag":239,"props":2838,"children":2840},{"className":2839},[],[2841],{"type":224,"value":2842},"dllfunc",{"type":224,"value":633},{"type":212,"tag":239,"props":2845,"children":2847},{"className":2846},[],[2848],{"type":224,"value":2849},"pev",{"type":224,"value":633},{"type":212,"tag":239,"props":2852,"children":2854},{"className":2853},[],[2855],{"type":224,"value":2856},"ExecuteHam",{"type":224,"value":2858}," and the rest - take text, floats and vectors as well as numbers, and what a native writes back is read through ",{"type":212,"tag":239,"props":2860,"children":2862},{"className":2861},[],[2863],{"type":224,"value":2864},"Ref",{"type":224,"value":2278},{"type":212,"tag":2280,"props":2867,"children":2869},{"className":2481,"code":2868,"language":2483,"meta":2288,"style":2484},"const id = engfunc(EngFunc_CreateFakeClient, \"Dummy\");\nconst reason = new Ref(\"\");\ndllfunc(DLLFunc_ClientConnect, id, \"Dummy\", \"127.0.0.1\", reason);\n",[2870],{"type":212,"tag":239,"props":2871,"children":2872},{"__ignoreMap":2288},[2873],{"type":224,"value":2868},{"type":212,"tag":1653,"props":2875,"children":2877},{"id":2876},"game-messages-by-name",[2878],{"type":224,"value":2879},"Game messages by name",{"type":212,"tag":213,"props":2881,"children":2882},{},[2883],{"type":224,"value":2884},"A message the game sends a player is heard by its name, in the player's words, with typed fields:",{"type":212,"tag":2280,"props":2886,"children":2888},{"className":2481,"code":2887,"language":2483,"meta":2288,"style":2484},"server.addMessageListener(\"death\", (event) => {\n    if (event.headshot) print(0, `${event.killer?.name} - headshot - ${event.victim?.name}`);\n});\n\nserver.addMessageListener(\"progressBar\", (event) => {\n    console.log(`a bar for ${event.seconds} s, from ${event.startPercent}%`);\n});\n",[2889],{"type":212,"tag":239,"props":2890,"children":2891},{"__ignoreMap":2288},[2892],{"type":224,"value":2887},{"type":212,"tag":213,"props":2894,"children":2895},{},[2896,2898,2904,2905,2911,2913,2919,2921,2927,2929,2935,2937,2943],{"type":224,"value":2897},"Every message has a description, with the game's own name (",{"type":212,"tag":239,"props":2899,"children":2901},{"className":2900},[],[2902],{"type":224,"value":2903},"DeathMsg",{"type":224,"value":633},{"type":212,"tag":239,"props":2906,"children":2908},{"className":2907},[],[2909],{"type":224,"value":2910},"BarTime",{"type":224,"value":2912},") beside it, so a Pawn author finds it. Where the game sends one thing in several messages, one name hears them all: ",{"type":212,"tag":239,"props":2914,"children":2916},{"className":2915},[],[2917],{"type":224,"value":2918},"progressBar",{"type":224,"value":2920}," (from zero or from a percent), ",{"type":212,"tag":239,"props":2922,"children":2924},{"className":2923},[],[2925],{"type":224,"value":2926},"spectatedHealth",{"type":224,"value":2928}," (the health of the player a spectator watches), ",{"type":212,"tag":239,"props":2930,"children":2932},{"className":2931},[],[2933],{"type":224,"value":2934},"hint",{"type":224,"value":2936}," (the hint box, with or without texts put into it). ",{"type":212,"tag":239,"props":2938,"children":2940},{"className":2939},[],[2941],{"type":224,"value":2942},"player.screen.progressBar(5, { startPercent: 40 })",{"type":224,"value":2944}," shows one.",{"type":212,"tag":1653,"props":2946,"children":2948},{"id":2947},"errors-that-point-at-your-code",[2949],{"type":224,"value":2950},"Errors that point at your code",{"type":212,"tag":213,"props":2952,"children":2953},{},[2954,2956,2962,2964,2970],{"type":224,"value":2955},"When a call fails - a ",{"type":212,"tag":239,"props":2957,"children":2959},{"className":2958},[],[2960],{"type":224,"value":2961},"null",{"type":224,"value":2963}," read with ",{"type":212,"tag":239,"props":2965,"children":2967},{"className":2966},[],[2968],{"type":224,"value":2969},"!",{"type":224,"value":2971},", an error nobody catches, a stack overflow - the console prints the TypeScript stack, file, line and column, with the source line itself:",{"type":212,"tag":2280,"props":2973,"children":2976},{"className":2974,"code":2975,"language":224},[2283],"[amxts] shop.aot: TypeError: Unexpected 'null'\n    at price (plugins\u002Fshop\u002Fshop.ts:26:9)\n      26 |   return item!.price;\n    at onSelect (plugins\u002Fshop\u002Fshop.ts:30:15)\n",[2977],{"type":212,"tag":239,"props":2978,"children":2979},{"__ignoreMap":2288},[2980],{"type":224,"value":2975},{"type":212,"tag":213,"props":2982,"children":2983},{},[2984,2990,2991,2997,2999,3005,3007,3012,3014,3020],{"type":212,"tag":239,"props":2985,"children":2987},{"className":2986},[],[2988],{"type":224,"value":2989},"console.error(error)",{"type":224,"value":1010},{"type":212,"tag":239,"props":2992,"children":2994},{"className":2993},[],[2995],{"type":224,"value":2996},"error.stack",{"type":224,"value":2998}," give the same stack. The map from the plugin's code to its TypeScript travels inside each ",{"type":212,"tag":239,"props":3000,"children":3002},{"className":3001},[],[3003],{"type":224,"value":3004},".aot",{"type":224,"value":3006},"; the source line appears where the ",{"type":212,"tag":239,"props":3008,"children":3010},{"className":3009},[],[3011],{"type":224,"value":713},{"type":224,"value":3013}," is next to the plugin, as in ",{"type":212,"tag":239,"props":3015,"children":3017},{"className":3016},[],[3018],{"type":224,"value":3019},"amxts dev",{"type":224,"value":1826},{"type":212,"tag":1653,"props":3022,"children":3024},{"id":3023},"names-in-the-players-words",[3025],{"type":224,"value":3026},"Names in the player's words",{"type":212,"tag":213,"props":3028,"children":3029},{},[3030],{"type":224,"value":3031},"The API speaks the way players and plugin authors do, not the way the game's source does:",{"type":212,"tag":271,"props":3033,"children":3034},{},[3035,3051],{"type":212,"tag":275,"props":3036,"children":3037},{},[3038],{"type":212,"tag":279,"props":3039,"children":3040},{},[3041,3046],{"type":212,"tag":283,"props":3042,"children":3043},{},[3044],{"type":224,"value":3045},"0.1.0",{"type":212,"tag":283,"props":3047,"children":3048},{},[3049],{"type":224,"value":3050},"0.2.0",{"type":212,"tag":294,"props":3052,"children":3053},{},[3054,3074,3094,3127,3162,3183,3218,3239],{"type":212,"tag":279,"props":3055,"children":3056},{},[3057,3066],{"type":212,"tag":301,"props":3058,"children":3059},{},[3060],{"type":212,"tag":239,"props":3061,"children":3063},{"className":3062},[],[3064],{"type":224,"value":3065},"Player.all()",{"type":212,"tag":301,"props":3067,"children":3068},{},[3069],{"type":212,"tag":239,"props":3070,"children":3072},{"className":3071},[],[3073],{"type":224,"value":905},{"type":212,"tag":279,"props":3075,"children":3076},{},[3077,3086],{"type":212,"tag":301,"props":3078,"children":3079},{},[3080],{"type":212,"tag":239,"props":3081,"children":3083},{"className":3082},[],[3084],{"type":224,"value":3085},"player.account",{"type":212,"tag":301,"props":3087,"children":3088},{},[3089],{"type":212,"tag":239,"props":3090,"children":3092},{"className":3091},[],[3093],{"type":224,"value":2441},{"type":212,"tag":279,"props":3095,"children":3096},{},[3097,3113],{"type":212,"tag":301,"props":3098,"children":3099},{},[3100,3106,3107],{"type":212,"tag":239,"props":3101,"children":3103},{"className":3102},[],[3104],{"type":224,"value":3105},"restartRound",{"type":224,"value":633},{"type":212,"tag":239,"props":3108,"children":3110},{"className":3109},[],[3111],{"type":224,"value":3112},"onRoundFreezeEnd",{"type":212,"tag":301,"props":3114,"children":3115},{},[3116,3121,3122],{"type":212,"tag":239,"props":3117,"children":3119},{"className":3118},[],[3120],{"type":224,"value":2375},{"type":224,"value":633},{"type":212,"tag":239,"props":3123,"children":3125},{"className":3124},[],[3126],{"type":224,"value":2382},{"type":212,"tag":279,"props":3128,"children":3129},{},[3130,3146],{"type":212,"tag":301,"props":3131,"children":3132},{},[3133,3139,3140],{"type":212,"tag":239,"props":3134,"children":3136},{"className":3135},[],[3137],{"type":224,"value":3138},"flPlayerFallDamage",{"type":224,"value":633},{"type":212,"tag":239,"props":3141,"children":3143},{"className":3142},[],[3144],{"type":224,"value":3145},"fPlayerCanTakeDamage",{"type":212,"tag":301,"props":3147,"children":3148},{},[3149,3155,3156],{"type":212,"tag":239,"props":3150,"children":3152},{"className":3151},[],[3153],{"type":224,"value":3154},"fallDamage",{"type":224,"value":633},{"type":212,"tag":239,"props":3157,"children":3159},{"className":3158},[],[3160],{"type":224,"value":3161},"canTakeDamage",{"type":212,"tag":279,"props":3163,"children":3164},{},[3165,3174],{"type":212,"tag":301,"props":3166,"children":3167},{},[3168],{"type":212,"tag":239,"props":3169,"children":3171},{"className":3170},[],[3172],{"type":224,"value":3173},"fireBullets3",{"type":212,"tag":301,"props":3175,"children":3176},{},[3177],{"type":212,"tag":239,"props":3178,"children":3180},{"className":3179},[],[3181],{"type":224,"value":3182},"shoot",{"type":212,"tag":279,"props":3184,"children":3185},{},[3186,3202],{"type":212,"tag":301,"props":3187,"children":3188},{},[3189,3195,3196],{"type":212,"tag":239,"props":3190,"children":3192},{"className":3191},[],[3193],{"type":224,"value":3194},"game.c4Guy",{"type":224,"value":633},{"type":212,"tag":239,"props":3197,"children":3199},{"className":3198},[],[3200],{"type":224,"value":3201},"game.numCtWins",{"type":212,"tag":301,"props":3203,"children":3204},{},[3205,3211,3212],{"type":212,"tag":239,"props":3206,"children":3208},{"className":3207},[],[3209],{"type":224,"value":3210},"game.bomber",{"type":224,"value":633},{"type":212,"tag":239,"props":3213,"children":3215},{"className":3214},[],[3216],{"type":224,"value":3217},"game.ctWins",{"type":212,"tag":279,"props":3219,"children":3220},{},[3221,3230],{"type":212,"tag":301,"props":3222,"children":3223},{},[3224],{"type":212,"tag":239,"props":3225,"children":3227},{"className":3226},[],[3228],{"type":224,"value":3229},"server.addEventListener(\"message:DeathMsg\", ...)",{"type":212,"tag":301,"props":3231,"children":3232},{},[3233],{"type":212,"tag":239,"props":3234,"children":3236},{"className":3235},[],[3237],{"type":224,"value":3238},"server.addMessageListener(\"death\", ...)",{"type":212,"tag":279,"props":3240,"children":3241},{},[3242,3259],{"type":212,"tag":301,"props":3243,"children":3244},{},[3245,3251,3253],{"type":212,"tag":239,"props":3246,"children":3248},{"className":3247},[],[3249],{"type":224,"value":3250},"buttons: [\"Jump\"]",{"type":224,"value":3252},", access ",{"type":212,"tag":239,"props":3254,"children":3256},{"className":3255},[],[3257],{"type":224,"value":3258},"\"Kick\"",{"type":212,"tag":301,"props":3260,"children":3261},{},[3262,3268,3269],{"type":212,"tag":239,"props":3263,"children":3265},{"className":3264},[],[3266],{"type":224,"value":3267},"buttons: [\"jump\"]",{"type":224,"value":3252},{"type":212,"tag":239,"props":3270,"children":3272},{"className":3271},[],[3273],{"type":224,"value":3274},"\"kick\"",{"type":212,"tag":213,"props":3276,"children":3277},{},[3278,3280,3286,3287,3293,3294,3300,3302,3307,3309,3315],{"type":224,"value":3279},"Game messages have named, typed fields too: ",{"type":212,"tag":239,"props":3281,"children":3283},{"className":3282},[],[3284],{"type":224,"value":3285},"event.killer",{"type":224,"value":633},{"type":212,"tag":239,"props":3288,"children":3290},{"className":3289},[],[3291],{"type":224,"value":3292},"event.victim",{"type":224,"value":633},{"type":212,"tag":239,"props":3295,"children":3297},{"className":3296},[],[3298],{"type":224,"value":3299},"event.headshot",{"type":224,"value":3301}," on ",{"type":212,"tag":239,"props":3303,"children":3305},{"className":3304},[],[3306],{"type":224,"value":2903},{"type":224,"value":3308},". Fields that mean nothing to a plugin - the AI members of a player, Condition Zero's career - are left to ",{"type":212,"tag":239,"props":3310,"children":3312},{"className":3311},[],[3313],{"type":224,"value":3314},"@amxts\u002Fcore\u002Fnatives",{"type":224,"value":1826},{"type":212,"tag":213,"props":3317,"children":3318},{},[3319,3324,3326,3331],{"type":212,"tag":239,"props":3320,"children":3322},{"className":3321},[],[3323],{"type":224,"value":797},{"type":224,"value":3325}," rewrites a 0.1.0 project: imports, command handlers, ",{"type":212,"tag":239,"props":3327,"children":3329},{"className":3328},[],[3330],{"type":224,"value":1299},{"type":224,"value":3332}," and every renamed field and event. What it cannot be sure of, it lists.",{"type":212,"tag":227,"props":3334,"children":3335},{"id":1141},[3336],{"type":224,"value":1144},{"type":212,"tag":327,"props":3338,"children":3339},{},[3340,3365,3448,3468,3492,3519,3548,3573,3590,3602,3648],{"type":212,"tag":331,"props":3341,"children":3342},{},[3343,3349,3351,3356,3358,3364],{"type":212,"tag":239,"props":3344,"children":3346},{"className":3345},[],[3347],{"type":224,"value":3348},"Player.all(filter)",{"type":224,"value":3350}," is ",{"type":212,"tag":239,"props":3352,"children":3354},{"className":3353},[],[3355],{"type":224,"value":905},{"type":224,"value":3357},"; filter it with ",{"type":212,"tag":239,"props":3359,"children":3361},{"className":3360},[],[3362],{"type":224,"value":3363},".filter(...)",{"type":224,"value":1826},{"type":212,"tag":331,"props":3366,"children":3367},{},[3368,3370,3375,3376,3381,3383,3388,3389,3394,3395,3401,3403,3408,3409,3414,3415,3421,3422,3427,3428,3433,3435,3440,3442,3447],{"type":224,"value":3369},"Renamed fields and events: ",{"type":212,"tag":239,"props":3371,"children":3373},{"className":3372},[],[3374],{"type":224,"value":3085},{"type":224,"value":3350},{"type":212,"tag":239,"props":3377,"children":3379},{"className":3378},[],[3380],{"type":224,"value":2441},{"type":224,"value":3382},"; ",{"type":212,"tag":239,"props":3384,"children":3386},{"className":3385},[],[3387],{"type":224,"value":3105},{"type":224,"value":633},{"type":212,"tag":239,"props":3390,"children":3392},{"className":3391},[],[3393],{"type":224,"value":3112},{"type":224,"value":1010},{"type":212,"tag":239,"props":3396,"children":3398},{"className":3397},[],[3399],{"type":224,"value":3400},"addAccount",{"type":224,"value":3402}," are ",{"type":212,"tag":239,"props":3404,"children":3406},{"className":3405},[],[3407],{"type":224,"value":2375},{"type":224,"value":633},{"type":212,"tag":239,"props":3410,"children":3412},{"className":3411},[],[3413],{"type":224,"value":2382},{"type":224,"value":1010},{"type":212,"tag":239,"props":3416,"children":3418},{"className":3417},[],[3419],{"type":224,"value":3420},"addMoney",{"type":224,"value":3382},{"type":212,"tag":239,"props":3423,"children":3425},{"className":3424},[],[3426],{"type":224,"value":3173},{"type":224,"value":3350},{"type":212,"tag":239,"props":3429,"children":3431},{"className":3430},[],[3432],{"type":224,"value":3182},{"type":224,"value":3434},"; about a hundred more follow the same rule (the full list is in ",{"type":212,"tag":239,"props":3436,"children":3438},{"className":3437},[],[3439],{"type":224,"value":797},{"type":224,"value":3441},"'s output). Internal fields left the API and are reached through ",{"type":212,"tag":239,"props":3443,"children":3445},{"className":3444},[],[3446],{"type":224,"value":3314},{"type":224,"value":1826},{"type":212,"tag":331,"props":3449,"children":3450},{},[3451,3453,3459,3461,3467],{"type":224,"value":3452},"A command's handler takes one object: ",{"type":212,"tag":239,"props":3454,"children":3456},{"className":3455},[],[3457],{"type":224,"value":3458},"({ player }) => ...",{"type":224,"value":3460},", not ",{"type":212,"tag":239,"props":3462,"children":3464},{"className":3463},[],[3465],{"type":224,"value":3466},"(player, args) => ...",{"type":224,"value":1826},{"type":212,"tag":331,"props":3469,"children":3470},{},[3471,3477,3479,3484,3485,3490],{"type":212,"tag":239,"props":3472,"children":3474},{"className":3473},[],[3475],{"type":224,"value":3476},"@amxts\u002Fcore\u002Fhttp",{"type":224,"value":3478}," is gone: ",{"type":212,"tag":239,"props":3480,"children":3482},{"className":3481},[],[3483],{"type":224,"value":2239},{"type":224,"value":1010},{"type":212,"tag":239,"props":3486,"children":3488},{"className":3487},[],[3489],{"type":224,"value":2685},{"type":224,"value":3491}," are globals. easy_http is no longer needed on the server.",{"type":212,"tag":331,"props":3493,"children":3494},{},[3495,3497,3502,3503,3509,3511,3517],{"type":224,"value":3496},"The core's API is imported by its package name (",{"type":212,"tag":239,"props":3498,"children":3500},{"className":3499},[],[3501],{"type":224,"value":3314},{"type":224,"value":633},{"type":212,"tag":239,"props":3504,"children":3506},{"className":3505},[],[3507],{"type":224,"value":3508},"\u002Ffs",{"type":224,"value":3510},", ...); ",{"type":212,"tag":239,"props":3512,"children":3514},{"className":3513},[],[3515],{"type":224,"value":3516},"~\u002F",{"type":224,"value":3518}," is the project's own files only.",{"type":212,"tag":331,"props":3520,"children":3521},{},[3522,3524,3530,3532,3538,3540,3546],{"type":224,"value":3523},"Game messages are heard with ",{"type":212,"tag":239,"props":3525,"children":3527},{"className":3526},[],[3528],{"type":224,"value":3529},"server.addMessageListener(name, ...)",{"type":224,"value":3531},", by their new names; the ",{"type":212,"tag":239,"props":3533,"children":3535},{"className":3534},[],[3536],{"type":224,"value":3537},"message:",{"type":224,"value":3539}," prefix of ",{"type":212,"tag":239,"props":3541,"children":3543},{"className":3542},[],[3544],{"type":224,"value":3545},"addEventListener",{"type":224,"value":3547}," is gone.",{"type":212,"tag":331,"props":3549,"children":3550},{},[3551,3553,3559,3560,3566,3567,3572],{"type":224,"value":3552},"The names of every flag set are lowerCamelCase: ",{"type":212,"tag":239,"props":3554,"children":3556},{"className":3555},[],[3557],{"type":224,"value":3558},"\"jump\"",{"type":224,"value":633},{"type":212,"tag":239,"props":3561,"children":3563},{"className":3562},[],[3564],{"type":224,"value":3565},"\"muzzleFlash\"",{"type":224,"value":633},{"type":212,"tag":239,"props":3568,"children":3570},{"className":3569},[],[3571],{"type":224,"value":3274},{"type":224,"value":1826},{"type":212,"tag":331,"props":3574,"children":3575},{},[3576,3581,3583,3589],{"type":212,"tag":239,"props":3577,"children":3579},{"className":3578},[],[3580],{"type":224,"value":1727},{"type":224,"value":3582},"'s code API takes one options object and one context: ",{"type":212,"tag":239,"props":3584,"children":3586},{"className":3585},[],[3587],{"type":224,"value":3588},"addItem({ title, onSelect: ({ player }) => ... })",{"type":224,"value":1826},{"type":212,"tag":331,"props":3591,"children":3592},{},[3593,3595,3600],{"type":224,"value":3594},"The module and ",{"type":212,"tag":239,"props":3596,"children":3598},{"className":3597},[],[3599],{"type":224,"value":603},{"type":224,"value":3601}," must come from the same release: the module refuses a compiler of another build.",{"type":212,"tag":331,"props":3603,"children":3604},{},[3605,3607,3613,3614,3620,3622,3627,3628,3633,3634,3640,3641,3647],{"type":224,"value":3606},"A plugin's id is ",{"type":212,"tag":239,"props":3608,"children":3610},{"className":3609},[],[3611],{"type":224,"value":3612},"steamId",{"type":224,"value":3460},{"type":212,"tag":239,"props":3615,"children":3617},{"className":3616},[],[3618],{"type":224,"value":3619},"authid",{"type":224,"value":3621},"; server events are named as authors say them: ",{"type":212,"tag":239,"props":3623,"children":3625},{"className":3624},[],[3626],{"type":224,"value":1333},{"type":224,"value":633},{"type":212,"tag":239,"props":3629,"children":3631},{"className":3630},[],[3632],{"type":224,"value":1016},{"type":224,"value":633},{"type":212,"tag":239,"props":3635,"children":3637},{"className":3636},[],[3638],{"type":224,"value":3639},"pluginsLoaded",{"type":224,"value":633},{"type":212,"tag":239,"props":3642,"children":3644},{"className":3643},[],[3645],{"type":224,"value":3646},"changeLevel",{"type":224,"value":1826},{"type":212,"tag":331,"props":3649,"children":3650},{},[3651],{"type":224,"value":3652},"A plugin built by 0.1.0 is not loaded: the console names it and says to build it again.",{"type":212,"tag":227,"props":3654,"children":3655},{"id":249},[3656],{"type":224,"value":252},{"type":212,"tag":213,"props":3658,"children":3659},{},[3660,3662,3667,3668,3673,3674,3679,3680,3685,3687,3692,3694,3699],{"type":224,"value":3661},"From 0.1.0, update the command first, with the package manager the project uses: ",{"type":212,"tag":239,"props":3663,"children":3665},{"className":3664},[],[3666],{"type":224,"value":1795},{"type":224,"value":633},{"type":212,"tag":239,"props":3669,"children":3671},{"className":3670},[],[3672],{"type":224,"value":1802},{"type":224,"value":633},{"type":212,"tag":239,"props":3675,"children":3677},{"className":3676},[],[3678],{"type":224,"value":1809},{"type":224,"value":1811},{"type":212,"tag":239,"props":3681,"children":3683},{"className":3682},[],[3684],{"type":224,"value":1817},{"type":224,"value":3686},". Then run ",{"type":212,"tag":239,"props":3688,"children":3690},{"className":3689},[],[3691],{"type":224,"value":261},{"type":224,"value":3693}," in the project: it updates the packages, rewrites the code, builds, and updates the server named in ",{"type":212,"tag":239,"props":3695,"children":3697},{"className":3696},[],[3698],{"type":224,"value":595},{"type":224,"value":1826},{"type":212,"tag":227,"props":3701,"children":3702},{"id":1829},[3703],{"type":224,"value":1832},{"type":212,"tag":327,"props":3705,"children":3706},{},[3707,3719,3731],{"type":212,"tag":331,"props":3708,"children":3709},{},[3710,3712,3717],{"type":224,"value":3711},"On plain HLDS, rounds, purchases, money and the bomb are heard after the fact; ",{"type":212,"tag":239,"props":3713,"children":3715},{"className":3714},[],[3716],{"type":224,"value":2397},{"type":224,"value":3718}," on them says once that it cannot stop them. ReGameDLL's own functions are not heard at all.",{"type":212,"tag":331,"props":3720,"children":3721},{},[3722,3724,3729],{"type":224,"value":3723},"A stack shows the source line only where the plugin's ",{"type":212,"tag":239,"props":3725,"children":3727},{"className":3726},[],[3728],{"type":224,"value":713},{"type":224,"value":3730}," is next to it; in a full build, small functions are inlined and a frame may show its caller's name.",{"type":212,"tag":331,"props":3732,"children":3733},{},[3734],{"type":224,"value":3735},"SFTP keys are RSA in PEM; Ed25519 and ECDSA keys are not read.",{"type":212,"tag":227,"props":3737,"children":3738},{"id":1912},[3739],{"type":224,"value":1915},{"type":212,"tag":327,"props":3741,"children":3742},{},[3743,3754,3759,3769,3791,3807,3829,3846,3856,3866,3876,3886,3907,3922,3931,3940,3949,3958,3981,4005,4021,4031,4052,4090,4100,4131,4148,4163,4207,4229],{"type":212,"tag":331,"props":3744,"children":3745},{},[3746,3748],{"type":224,"value":3747},"One module to install: the host plugin comes inside ",{"type":212,"tag":239,"props":3749,"children":3751},{"className":3750},[],[3752],{"type":224,"value":3753},"amxts_amxx",{"type":212,"tag":331,"props":3755,"children":3756},{},[3757],{"type":224,"value":3758},"Plain HLDS: fields read in memory, a player's events through Ham Sandwich, rounds, spawns, purchases, money and the bomb through the game's own logs and messages",{"type":212,"tag":331,"props":3760,"children":3761},{},[3762,3767],{"type":212,"tag":239,"props":3763,"children":3765},{"className":3764},[],[3766],{"type":224,"value":2410},{"type":224,"value":3768}," stops a build that listens for what plain HLDS cannot hear",{"type":212,"tag":331,"props":3770,"children":3771},{},[3772,3777,3779,3784,3786],{"type":212,"tag":619,"props":3773,"children":3774},{},[3775],{"type":224,"value":3776},"commands:",{"type":224,"value":3778}," Typed arguments, and ",{"type":212,"tag":239,"props":3780,"children":3782},{"className":3781},[],[3783],{"type":224,"value":2552},{"type":224,"value":3785}," for a ",{"type":212,"tag":239,"props":3787,"children":3789},{"className":3788},[],[3790],{"type":224,"value":2560},{"type":212,"tag":331,"props":3792,"children":3793},{},[3794,3799,3800,3805],{"type":212,"tag":619,"props":3795,"children":3796},{},[3797],{"type":224,"value":3798},"menus:",{"type":224,"value":925},{"type":212,"tag":239,"props":3801,"children":3803},{"className":3802},[],[3804],{"type":224,"value":2577},{"type":224,"value":3806}," over AMX Mod X's menus",{"type":212,"tag":331,"props":3808,"children":3809},{},[3810,3815,3816,3821,3822,3827],{"type":212,"tag":619,"props":3811,"children":3812},{},[3813],{"type":224,"value":3814},"fetch:",{"type":224,"value":925},{"type":212,"tag":239,"props":3817,"children":3819},{"className":3818},[],[3820],{"type":224,"value":2239},{"type":224,"value":1010},{"type":212,"tag":239,"props":3823,"children":3825},{"className":3824},[],[3826],{"type":224,"value":2685},{"type":224,"value":3828}," as globals, over libcurl and mbedTLS inside the module",{"type":212,"tag":331,"props":3830,"children":3831},{},[3832,3837,3838,3844],{"type":212,"tag":619,"props":3833,"children":3834},{},[3835],{"type":224,"value":3836},"kit:",{"type":224,"value":925},{"type":212,"tag":239,"props":3839,"children":3841},{"className":3840},[],[3842],{"type":224,"value":3843},"request",{"type":224,"value":3845}," over HTTP, FTP, FTPS and SFTP, for modules",{"type":212,"tag":331,"props":3847,"children":3848},{},[3849,3854],{"type":212,"tag":619,"props":3850,"children":3851},{},[3852],{"type":224,"value":3853},"modules:",{"type":224,"value":3855}," Library packages, compiled into each plugin that imports them",{"type":212,"tag":331,"props":3857,"children":3858},{},[3859,3864],{"type":212,"tag":239,"props":3860,"children":3862},{"className":3861},[],[3863],{"type":224,"value":2757},{"type":224,"value":3865}," among the official modules",{"type":212,"tag":331,"props":3867,"children":3868},{},[3869,3874],{"type":212,"tag":619,"props":3870,"children":3871},{},[3872],{"type":224,"value":3873},"messages:",{"type":224,"value":3875}," Every known game message's arguments typed and named",{"type":212,"tag":331,"props":3877,"children":3878},{},[3879,3884],{"type":212,"tag":619,"props":3880,"children":3881},{},[3882],{"type":224,"value":3883},"events:",{"type":224,"value":3885}," Enum arguments of game events as names; a game event's vector arguments writable",{"type":212,"tag":331,"props":3887,"children":3888},{},[3889,3894,3895,3900,3902],{"type":212,"tag":619,"props":3890,"children":3891},{},[3892],{"type":224,"value":3893},"players:",{"type":224,"value":925},{"type":212,"tag":239,"props":3896,"children":3898},{"className":3897},[],[3899],{"type":224,"value":905},{"type":224,"value":3901}," replaces ",{"type":212,"tag":239,"props":3903,"children":3905},{"className":3904},[],[3906],{"type":224,"value":1299},{"type":212,"tag":331,"props":3908,"children":3909},{},[3910,3915,3917],{"type":212,"tag":619,"props":3911,"children":3912},{},[3913],{"type":224,"value":3914},"api:",{"type":224,"value":3916}," Fields and events in the player's words; internal ones left to ",{"type":212,"tag":239,"props":3918,"children":3920},{"className":3919},[],[3921],{"type":224,"value":3314},{"type":212,"tag":331,"props":3923,"children":3924},{},[3925,3929],{"type":212,"tag":619,"props":3926,"children":3927},{},[3928],{"type":224,"value":623},{"type":224,"value":3930}," A failed call prints the TypeScript stack, from a map carried in each plugin",{"type":212,"tag":331,"props":3932,"children":3933},{},[3934,3938],{"type":212,"tag":619,"props":3935,"children":3936},{},[3937],{"type":224,"value":864},{"type":224,"value":3939}," A reload removes the old plugin's timers and hooks",{"type":212,"tag":331,"props":3941,"children":3942},{},[3943,3947],{"type":212,"tag":619,"props":3944,"children":3945},{},[3946],{"type":224,"value":864},{"type":224,"value":3948}," A compiler of another build is refused, with one clear line",{"type":212,"tag":331,"props":3950,"children":3951},{},[3952,3956],{"type":212,"tag":619,"props":3953,"children":3954},{},[3955],{"type":224,"value":864},{"type":224,"value":3957}," A plugin built for another amxts is refused, not run",{"type":212,"tag":331,"props":3959,"children":3960},{},[3961,3965,3966,3972,3973,3979],{"type":212,"tag":619,"props":3962,"children":3963},{},[3964],{"type":224,"value":3893},{"type":224,"value":925},{"type":212,"tag":239,"props":3967,"children":3969},{"className":3968},[],[3970],{"type":224,"value":3971},"server.addBot",{"type":224,"value":1010},{"type":212,"tag":239,"props":3974,"children":3976},{"className":3975},[],[3977],{"type":224,"value":3978},"bot.move",{"type":224,"value":3980},"; a fake client joins the spectators on both servers",{"type":212,"tag":331,"props":3982,"children":3983},{},[3984,3989,3991,3996,3998,4003],{"type":212,"tag":619,"props":3985,"children":3986},{},[3987],{"type":224,"value":3988},"natives:",{"type":224,"value":3990}," A native's ",{"type":212,"tag":239,"props":3992,"children":3994},{"className":3993},[],[3995],{"type":224,"value":2827},{"type":224,"value":3997}," tail takes text, floats, vectors and players; ",{"type":212,"tag":239,"props":3999,"children":4001},{"className":4000},[],[4002],{"type":224,"value":2864},{"type":224,"value":4004}," reads what it writes back",{"type":212,"tag":331,"props":4006,"children":4007},{},[4008,4012,4013,4019],{"type":212,"tag":619,"props":4009,"children":4010},{},[4011],{"type":224,"value":3873},{"type":224,"value":925},{"type":212,"tag":239,"props":4014,"children":4016},{"className":4015},[],[4017],{"type":224,"value":4018},"server.addMessageListener",{"type":224,"value":4020}," by the player's names, with a description for each",{"type":212,"tag":331,"props":4022,"children":4023},{},[4024,4029],{"type":212,"tag":619,"props":4025,"children":4026},{},[4027],{"type":224,"value":4028},"entities:",{"type":224,"value":4030}," A field the HUD shows is sent to the player when written",{"type":212,"tag":331,"props":4032,"children":4033},{},[4034,4038,4039,4044,4045,4050],{"type":212,"tag":619,"props":4035,"children":4036},{},[4037],{"type":224,"value":956},{"type":224,"value":925},{"type":212,"tag":239,"props":4040,"children":4042},{"className":4041},[],[4043],{"type":224,"value":1744},{"type":224,"value":1746},{"type":212,"tag":239,"props":4046,"children":4048},{"className":4047},[],[4049],{"type":224,"value":1752},{"type":224,"value":4051}," folder",{"type":212,"tag":331,"props":4053,"children":4054},{},[4055,4059,4060,4066,4067,4073,4074,4080,4082,4088],{"type":212,"tag":619,"props":4056,"children":4057},{},[4058],{"type":224,"value":1926},{"type":224,"value":925},{"type":212,"tag":239,"props":4061,"children":4063},{"className":4062},[],[4064],{"type":224,"value":4065},"amxts_load",{"type":224,"value":633},{"type":212,"tag":239,"props":4068,"children":4070},{"className":4069},[],[4071],{"type":224,"value":4072},"amxts_unload",{"type":224,"value":1010},{"type":212,"tag":239,"props":4075,"children":4077},{"className":4076},[],[4078],{"type":224,"value":4079},"amxts_reload \u003Cplugin>",{"type":224,"value":4081}," for one plugin; ",{"type":212,"tag":239,"props":4083,"children":4085},{"className":4084},[],[4086],{"type":224,"value":4087},"amxts_plugins",{"type":224,"value":4089}," shows each one's state",{"type":212,"tag":331,"props":4091,"children":4092},{},[4093,4098],{"type":212,"tag":619,"props":4094,"children":4095},{},[4096],{"type":224,"value":4097},"dev:",{"type":224,"value":4099}," Saving a plugin reloads only the plugins that changed, and a menu it made stays open through the reload",{"type":212,"tag":331,"props":4101,"children":4102},{},[4103,4107,4109,4115,4116,4122,4123,4129],{"type":212,"tag":619,"props":4104,"children":4105},{},[4106],{"type":224,"value":3988},{"type":224,"value":4108}," Reunion, VTC, ReChecker and GeoIP natives; ",{"type":212,"tag":239,"props":4110,"children":4112},{"className":4111},[],[4113],{"type":224,"value":4114},"player.authType",{"type":224,"value":633},{"type":212,"tag":239,"props":4117,"children":4119},{"className":4118},[],[4120],{"type":224,"value":4121},"protocol",{"type":224,"value":1010},{"type":212,"tag":239,"props":4124,"children":4126},{"className":4125},[],[4127],{"type":224,"value":4128},"authKey",{"type":224,"value":4130}," from Reunion",{"type":212,"tag":331,"props":4132,"children":4133},{},[4134,4138,4140,4146],{"type":212,"tag":619,"props":4135,"children":4136},{},[4137],{"type":224,"value":3853},{"type":224,"value":4139}," A shared module hears when a plugin that uses it stops (",{"type":212,"tag":239,"props":4141,"children":4143},{"className":4142},[],[4144],{"type":224,"value":4145},"onPluginStop",{"type":224,"value":4147},"), and drops what it gave",{"type":212,"tag":331,"props":4149,"children":4150},{},[4151,4156,4158],{"type":212,"tag":619,"props":4152,"children":4153},{},[4154],{"type":224,"value":4155},"menu-core:",{"type":224,"value":4157}," The code API in the same shape as ",{"type":212,"tag":239,"props":4159,"children":4161},{"className":4160},[],[4162],{"type":224,"value":2577},{"type":212,"tag":331,"props":4164,"children":4165},{},[4166,4168,4173,4174,4180,4181,4186,4187,4193,4194,4200,4201],{"type":224,"value":4167},"The core's API by its package name: ",{"type":212,"tag":239,"props":4169,"children":4171},{"className":4170},[],[4172],{"type":224,"value":3314},{"type":224,"value":633},{"type":212,"tag":239,"props":4175,"children":4177},{"className":4176},[],[4178],{"type":224,"value":4179},"\u002Fconstants",{"type":224,"value":633},{"type":212,"tag":239,"props":4182,"children":4184},{"className":4183},[],[4185],{"type":224,"value":3508},{"type":224,"value":633},{"type":212,"tag":239,"props":4188,"children":4190},{"className":4189},[],[4191],{"type":224,"value":4192},"\u002Fos",{"type":224,"value":633},{"type":212,"tag":239,"props":4195,"children":4197},{"className":4196},[],[4198],{"type":224,"value":4199},"\u002Fkit",{"type":224,"value":633},{"type":212,"tag":239,"props":4202,"children":4204},{"className":4203},[],[4205],{"type":224,"value":4206},"\u002Fcheck",{"type":212,"tag":331,"props":4208,"children":4209},{},[4210,4214,4215,4220,4222,4227],{"type":212,"tag":619,"props":4211,"children":4212},{},[4213],{"type":224,"value":974},{"type":224,"value":925},{"type":212,"tag":239,"props":4216,"children":4218},{"className":4217},[],[4219],{"type":224,"value":797},{"type":224,"value":4221}," rewrites imports, command handlers, ",{"type":212,"tag":239,"props":4223,"children":4225},{"className":4224},[],[4226],{"type":224,"value":1299},{"type":224,"value":4228}," and every renamed field and event",{"type":212,"tag":331,"props":4230,"children":4231},{},[4232,4237,4239],{"type":212,"tag":619,"props":4233,"children":4234},{},[4235],{"type":224,"value":4236},"docker:",{"type":224,"value":4238}," The server image is ",{"type":212,"tag":239,"props":4240,"children":4242},{"className":4241},[],[4243],{"type":224,"value":4244},"ghcr.io\u002Famxts\u002Fserver",{"type":212,"tag":227,"props":4246,"children":4248},{"id":4247},"performance",[4249],{"type":224,"value":4250},"🔥 Performance",{"type":212,"tag":327,"props":4252,"children":4253},{},[4254,4263,4272],{"type":212,"tag":331,"props":4255,"children":4256},{},[4257,4261],{"type":212,"tag":619,"props":4258,"children":4259},{},[4260],{"type":224,"value":956},{"type":224,"value":4262}," Modules from npm come with their analysis, not compiled again",{"type":212,"tag":331,"props":4264,"children":4265},{},[4266,4270],{"type":212,"tag":619,"props":4267,"children":4268},{},[4269],{"type":224,"value":956},{"type":224,"value":4271}," Plugins compile in parallel",{"type":212,"tag":331,"props":4273,"children":4274},{},[4275,4279],{"type":212,"tag":619,"props":4276,"children":4277},{},[4278],{"type":224,"value":956},{"type":224,"value":4280}," Each file is read once per build",{"type":212,"tag":227,"props":4282,"children":4283},{"id":608},[4284],{"type":224,"value":611},{"type":212,"tag":327,"props":4286,"children":4287},{},[4288,4305,4345,4354,4370,4380,4389,4398],{"type":212,"tag":331,"props":4289,"children":4290},{},[4291,4295,4297,4304],{"type":212,"tag":619,"props":4292,"children":4293},{},[4294],{"type":224,"value":864},{"type":224,"value":4296}," The API files are written only when they changed (",{"type":212,"tag":217,"props":4298,"children":4301},{"href":4299,"rel":4300},"https:\u002F\u002Fgithub.com\u002Famxts\u002Famxts\u002Fissues\u002F1",[221],[4302],{"type":224,"value":4303},"#1",{"type":224,"value":344},{"type":212,"tag":331,"props":4306,"children":4307},{},[4308,4313,4314,4320,4322,4328,4330,4336,4337,4343],{"type":212,"tag":619,"props":4309,"children":4310},{},[4311],{"type":224,"value":4312},"compiler:",{"type":224,"value":925},{"type":212,"tag":239,"props":4315,"children":4317},{"className":4316},[],[4318],{"type":224,"value":4319},"boolean | function",{"type":224,"value":4321}," fields, ",{"type":212,"tag":239,"props":4323,"children":4325},{"className":4324},[],[4326],{"type":224,"value":4327},"has ? get : fallback",{"type":224,"value":4329},", a caught error read off a return, ",{"type":212,"tag":239,"props":4331,"children":4333},{"className":4332},[],[4334],{"type":224,"value":4335},"new Map(entries)",{"type":224,"value":1010},{"type":212,"tag":239,"props":4338,"children":4340},{"className":4339},[],[4341],{"type":224,"value":4342},"new Set(values)",{"type":224,"value":4344},", narrowing on assignment",{"type":212,"tag":331,"props":4346,"children":4347},{},[4348,4352],{"type":212,"tag":619,"props":4349,"children":4350},{},[4351],{"type":224,"value":3776},{"type":224,"value":4353}," Typed arguments go where their interface does",{"type":212,"tag":331,"props":4355,"children":4356},{},[4357,4361,4362,4368],{"type":212,"tag":619,"props":4358,"children":4359},{},[4360],{"type":224,"value":923},{"type":224,"value":925},{"type":212,"tag":239,"props":4363,"children":4365},{"className":4364},[],[4366],{"type":224,"value":4367},"Date.UTC",{"type":224,"value":4369}," with fewer arguments",{"type":212,"tag":331,"props":4371,"children":4372},{},[4373,4378],{"type":212,"tag":619,"props":4374,"children":4375},{},[4376],{"type":224,"value":4377},"host:",{"type":224,"value":4379}," A missing native answers 0 and says so once",{"type":212,"tag":331,"props":4381,"children":4382},{},[4383,4387],{"type":212,"tag":619,"props":4384,"children":4385},{},[4386],{"type":224,"value":3883},{"type":224,"value":4388}," Removing the last listener switches its hook off",{"type":212,"tag":331,"props":4390,"children":4391},{},[4392,4396],{"type":212,"tag":619,"props":4393,"children":4394},{},[4395],{"type":224,"value":623},{"type":224,"value":4397}," A function a plugin hands a module at its top level is called back, and a reloaded plugin's old functions are never called",{"type":212,"tag":331,"props":4399,"children":4400},{},[4401,4405,4407,4413],{"type":212,"tag":619,"props":4402,"children":4403},{},[4404],{"type":224,"value":623},{"type":224,"value":4406}," A plugin loaded while another one runs no longer stalls that one's ",{"type":212,"tag":239,"props":4408,"children":4410},{"className":4409},[],[4411],{"type":224,"value":4412},"await",{"type":224,"value":4414},", and a reload of all loads each plugin once",{"type":212,"tag":227,"props":4416,"children":4417},{"id":322},[4418],{"type":224,"value":325},{"type":212,"tag":327,"props":4420,"children":4421},{},[4422],{"type":212,"tag":331,"props":4423,"children":4424},{},[4425,4426,4431],{"type":224,"value":335},{"type":212,"tag":217,"props":4427,"children":4429},{"href":338,"rel":4428},[221],[4430],{"type":224,"value":342},{"type":224,"value":344},{"type":212,"tag":227,"props":4433,"children":4434},{"id":683},[4435],{"type":224,"value":686},{"type":212,"tag":327,"props":4437,"children":4438},{},[4439,4460,4475,4490],{"type":212,"tag":331,"props":4440,"children":4441},{},[4442,4447,4448,4453,4454,4459],{"type":212,"tag":239,"props":4443,"children":4445},{"className":4444},[],[4446],{"type":224,"value":698},{"type":224,"value":633},{"type":212,"tag":239,"props":4449,"children":4451},{"className":4450},[],[4452],{"type":224,"value":705},{"type":224,"value":707},{"type":212,"tag":239,"props":4455,"children":4457},{"className":4456},[],[4458],{"type":224,"value":713},{"type":224,"value":715},{"type":212,"tag":331,"props":4461,"children":4462},{},[4463,4468,4469,4474],{"type":212,"tag":239,"props":4464,"children":4466},{"className":4465},[],[4467],{"type":224,"value":724},{"type":224,"value":633},{"type":212,"tag":239,"props":4470,"children":4472},{"className":4471},[],[4473],{"type":224,"value":731},{"type":224,"value":733},{"type":212,"tag":331,"props":4476,"children":4477},{},[4478,4483,4484,4489],{"type":212,"tag":239,"props":4479,"children":4481},{"className":4480},[],[4482],{"type":224,"value":742},{"type":224,"value":633},{"type":212,"tag":239,"props":4485,"children":4487},{"className":4486},[],[4488],{"type":224,"value":749},{"type":224,"value":751},{"type":212,"tag":331,"props":4491,"children":4492},{},[4493,4498,4499,4504],{"type":212,"tag":239,"props":4494,"children":4496},{"className":4495},[],[4497],{"type":224,"value":760},{"type":224,"value":633},{"type":212,"tag":239,"props":4500,"children":4502},{"className":4501},[],[4503],{"type":224,"value":767},{"type":224,"value":769},{"type":212,"tag":4506,"props":4507,"children":4508},"style",{},[4509],{"type":224,"value":2288},{"data":4511,"body":4512},{},{"type":209,"children":4513},[4514,4519,4527,4532,4536,4549],{"type":212,"tag":213,"props":4515,"children":4516},{},[4517],{"type":224,"value":4518},"The first release: FTP, FTPS and SFTP for amxts plugins. Upload, download and list files on another server; every call is a promise on amxts's network thread, so the game never waits, and files go between the game folder and the other server whole, binary included.",{"type":212,"tag":2280,"props":4520,"children":4522},{"className":2481,"code":4521,"language":2483,"meta":2288,"style":2484},"import { ftp } from \"@amxts\u002Fftp\";\n\nconst client = await ftp.connect(\"sftp:\u002F\u002Fbackup@example.com\", { password: settings.password });\nawait client.upload(\"addons\u002Famxmodx\u002Flogs\u002Ftoday.log\", \"logs\u002Ftoday.log\");\nawait client.close();\n",[4523],{"type":212,"tag":239,"props":4524,"children":4525},{"__ignoreMap":2288},[4526],{"type":224,"value":4521},{"type":212,"tag":213,"props":4528,"children":4529},{},[4530],{"type":224,"value":4531},"SFTP takes a password or an RSA key in PEM, and can check the host's key.",{"type":212,"tag":227,"props":4533,"children":4534},{"id":322},[4535],{"type":224,"value":325},{"type":212,"tag":327,"props":4537,"children":4538},{},[4539],{"type":212,"tag":331,"props":4540,"children":4541},{},[4542,4543,4548],{"type":224,"value":335},{"type":212,"tag":217,"props":4544,"children":4546},{"href":338,"rel":4545},[221],[4547],{"type":224,"value":342},{"type":224,"value":344},{"type":212,"tag":4506,"props":4550,"children":4551},{},[4552],{"type":224,"value":2288},{"data":4554,"body":4555},{},{"type":209,"children":4556},[4557,4566,4570,4582,4586,4592,4623,4631,4644,4650,4669,4673,4732,4736,4753,4757,4837,4841,4870,4874,4902,4906,4993,4997,5057,5063,5076,5080,5093],{"type":212,"tag":213,"props":4558,"children":4559},{},[4560],{"type":212,"tag":217,"props":4561,"children":4564},{"href":4562,"rel":4563},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcompare\u002Fv0.1.0...v0.2.0",[221],[4565],{"type":224,"value":225},{"type":212,"tag":227,"props":4567,"children":4568},{"id":229},[4569],{"type":224,"value":232},{"type":212,"tag":213,"props":4571,"children":4572},{},[4573,4575,4580],{"type":224,"value":4574},"menu-core for amxts 0.2.0: every menu function takes the menu's context, items take one options object as the core's ",{"type":212,"tag":239,"props":4576,"children":4578},{"className":4577},[],[4579],{"type":224,"value":2577},{"type":224,"value":4581}," does, and a menu stays open while its plugin reloads.",{"type":212,"tag":227,"props":4583,"children":4584},{"id":1648},[4585],{"type":224,"value":1651},{"type":212,"tag":1653,"props":4587,"children":4589},{"id":4588},"the-menus-context",[4590],{"type":224,"value":4591},"The menu's context",{"type":212,"tag":213,"props":4593,"children":4594},{},[4595,4597,4602,4603,4608,4609,4614,4616,4622],{"type":224,"value":4596},"A title, ",{"type":212,"tag":239,"props":4598,"children":4600},{"className":4599},[],[4601],{"type":224,"value":2585},{"type":224,"value":633},{"type":212,"tag":239,"props":4604,"children":4606},{"className":4605},[],[4607],{"type":224,"value":2593},{"type":224,"value":1010},{"type":212,"tag":239,"props":4610,"children":4612},{"className":4611},[],[4613],{"type":224,"value":2609},{"type":224,"value":4615}," take one object, ",{"type":212,"tag":239,"props":4617,"children":4619},{"className":4618},[],[4620],{"type":224,"value":4621},"{ player, target, row, menu }",{"type":224,"value":2278},{"type":212,"tag":2280,"props":4624,"children":4626},{"className":2481,"code":4625,"language":2483,"meta":2288,"style":2484},"const shop = menus.create(\"SHOP\", { title: ({ player }) => `Shop - $${player.money}` });\n\nshop.addItem({\n    title: ({ player }) => `Heal (${player.health} HP)`,\n    visible: ({ player }) => player.health \u003C 100,\n    onSelect: ({ player }) => {\n        player.health = 100;\n    },\n});\n",[4627],{"type":212,"tag":239,"props":4628,"children":4629},{"__ignoreMap":2288},[4630],{"type":224,"value":4625},{"type":212,"tag":213,"props":4632,"children":4633},{},[4634,4636,4642],{"type":224,"value":4635},"In a list of players, ",{"type":212,"tag":239,"props":4637,"children":4639},{"className":4638},[],[4640],{"type":224,"value":4641},"target",{"type":224,"value":4643}," is the player of the row.",{"type":212,"tag":1653,"props":4645,"children":4647},{"id":4646},"a-menu-kept-through-a-reload",[4648],{"type":224,"value":4649},"A menu kept through a reload",{"type":212,"tag":213,"props":4651,"children":4652},{},[4653,4655,4660,4661,4667],{"type":224,"value":4654},"When the plugin that made a menu reloads - a save under ",{"type":212,"tag":239,"props":4656,"children":4658},{"className":4657},[],[4659],{"type":224,"value":3019},{"type":224,"value":633},{"type":212,"tag":239,"props":4662,"children":4664},{"className":4663},[],[4665],{"type":224,"value":4666},"amxts_reload",{"type":224,"value":4668}," - a player looking at the menu keeps it, on the same page, drawn from the new code. When the plugin is unloaded, its menus, items, placeholders and conditions go with it.",{"type":212,"tag":227,"props":4670,"children":4671},{"id":1141},[4672],{"type":224,"value":1144},{"type":212,"tag":327,"props":4674,"children":4675},{},[4676,4694,4719],{"type":212,"tag":331,"props":4677,"children":4678},{},[4679,4681,4686,4687,4693],{"type":224,"value":4680},"Every function a menu takes gets the context object: ",{"type":212,"tag":239,"props":4682,"children":4684},{"className":4683},[],[4685],{"type":224,"value":3458},{"type":224,"value":3460},{"type":212,"tag":239,"props":4688,"children":4690},{"className":4689},[],[4691],{"type":224,"value":4692},"(player) => ...",{"type":224,"value":1826},{"type":212,"tag":331,"props":4695,"children":4696},{},[4697,4703,4705,4711,4712,4718],{"type":212,"tag":239,"props":4698,"children":4700},{"className":4699},[],[4701],{"type":224,"value":4702},"addItem",{"type":224,"value":4704}," takes one options object: ",{"type":212,"tag":239,"props":4706,"children":4708},{"className":4707},[],[4709],{"type":224,"value":4710},"addItem({ title, onSelect })",{"type":224,"value":3460},{"type":212,"tag":239,"props":4713,"children":4715},{"className":4714},[],[4716],{"type":224,"value":4717},"addItem(\"Title\", { onSelect })",{"type":224,"value":1826},{"type":212,"tag":331,"props":4720,"children":4721},{},[4722,4724,4730],{"type":224,"value":4723},"Conditions registered by name keep their ",{"type":212,"tag":239,"props":4725,"children":4727},{"className":4726},[],[4728],{"type":224,"value":4729},"(player, viewer, name)",{"type":224,"value":4731}," arguments.",{"type":212,"tag":227,"props":4733,"children":4734},{"id":249},[4735],{"type":224,"value":252},{"type":212,"tag":213,"props":4737,"children":4738},{},[4739,4744,4746,4751],{"type":212,"tag":239,"props":4740,"children":4742},{"className":4741},[],[4743],{"type":224,"value":261},{"type":224,"value":4745}," rewrites both: the functions to the context and ",{"type":212,"tag":239,"props":4747,"children":4749},{"className":4748},[],[4750],{"type":224,"value":4702},{"type":224,"value":4752}," to its options. Files of menus (INI, YAML, JSON) do not change.",{"type":212,"tag":227,"props":4754,"children":4755},{"id":266},[4756],{"type":224,"value":269},{"type":212,"tag":271,"props":4758,"children":4759},{},[4760,4778],{"type":212,"tag":275,"props":4761,"children":4762},{},[4763],{"type":212,"tag":279,"props":4764,"children":4765},{},[4766,4770,4774],{"type":212,"tag":283,"props":4767,"children":4768},{},[4769],{"type":224,"value":287},{"type":212,"tag":283,"props":4771,"children":4772},{},[4773],{"type":224,"value":1192},{"type":212,"tag":283,"props":4775,"children":4776},{},[4777],{"type":224,"value":1197},{"type":212,"tag":294,"props":4779,"children":4780},{},[4781,4808],{"type":212,"tag":279,"props":4782,"children":4783},{},[4784,4792,4800],{"type":212,"tag":301,"props":4785,"children":4786},{},[4787],{"type":212,"tag":239,"props":4788,"children":4790},{"className":4789},[],[4791],{"type":224,"value":244},{"type":212,"tag":301,"props":4793,"children":4794},{},[4795],{"type":212,"tag":239,"props":4796,"children":4798},{"className":4797},[],[4799],{"type":224,"value":1220},{"type":212,"tag":301,"props":4801,"children":4802},{},[4803],{"type":212,"tag":239,"props":4804,"children":4806},{"className":4805},[],[4807],{"type":224,"value":317},{"type":212,"tag":279,"props":4809,"children":4810},{},[4811,4820,4828],{"type":212,"tag":301,"props":4812,"children":4813},{},[4814],{"type":212,"tag":239,"props":4815,"children":4817},{"className":4816},[],[4818],{"type":224,"value":4819},"@amxts\u002Fconfig-core",{"type":212,"tag":301,"props":4821,"children":4822},{},[4823],{"type":212,"tag":239,"props":4824,"children":4826},{"className":4825},[],[4827],{"type":224,"value":1220},{"type":212,"tag":301,"props":4829,"children":4830},{},[4831],{"type":212,"tag":239,"props":4832,"children":4834},{"className":4833},[],[4835],{"type":224,"value":4836},"^0.1.1",{"type":212,"tag":227,"props":4838,"children":4839},{"id":1912},[4840],{"type":224,"value":1915},{"type":212,"tag":327,"props":4842,"children":4843},{},[4844,4857],{"type":212,"tag":331,"props":4845,"children":4846},{},[4847,4849,4856],{"type":224,"value":4848},"⚠️  Every menu function takes the menu's context (",{"type":212,"tag":217,"props":4850,"children":4853},{"href":4851,"rel":4852},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002F496431b",[221],[4854],{"type":224,"value":4855},"496431b",{"type":224,"value":344},{"type":212,"tag":331,"props":4858,"children":4859},{},[4860,4862,4869],{"type":224,"value":4861},"Keep a menu open through its plugin's reload (",{"type":212,"tag":217,"props":4863,"children":4866},{"href":4864,"rel":4865},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002F1a3ab54",[221],[4867],{"type":224,"value":4868},"1a3ab54",{"type":224,"value":344},{"type":212,"tag":227,"props":4871,"children":4872},{"id":608},[4873],{"type":224,"value":611},{"type":212,"tag":327,"props":4875,"children":4876},{},[4877,4889],{"type":212,"tag":331,"props":4878,"children":4879},{},[4880,4881,4888],{"type":224,"value":1506},{"type":212,"tag":217,"props":4882,"children":4885},{"href":4883,"rel":4884},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Fa646c2c",[221],[4886],{"type":224,"value":4887},"a646c2c",{"type":224,"value":344},{"type":212,"tag":331,"props":4890,"children":4891},{},[4892,4894,4901],{"type":224,"value":4893},"Drop what a stopped plugin gave the menus (",{"type":212,"tag":217,"props":4895,"children":4898},{"href":4896,"rel":4897},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Ffa68648",[221],[4899],{"type":224,"value":4900},"fa68648",{"type":224,"value":344},{"type":212,"tag":227,"props":4903,"children":4904},{"id":1251},[4905],{"type":224,"value":1254},{"type":212,"tag":327,"props":4907,"children":4908},{},[4909,4921,4933,4956,4974],{"type":212,"tag":331,"props":4910,"children":4911},{},[4912,4913,4920],{"type":224,"value":1262},{"type":212,"tag":217,"props":4914,"children":4917},{"href":4915,"rel":4916},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Fd838de0",[221],[4918],{"type":224,"value":4919},"d838de0",{"type":224,"value":344},{"type":212,"tag":331,"props":4922,"children":4923},{},[4924,4925,4932],{"type":224,"value":1275},{"type":212,"tag":217,"props":4926,"children":4929},{"href":4927,"rel":4928},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Fc6aa029",[221],[4930],{"type":224,"value":4931},"c6aa029",{"type":224,"value":344},{"type":212,"tag":331,"props":4934,"children":4935},{},[4936,4941,4942,4947,4948,4955],{"type":212,"tag":239,"props":4937,"children":4939},{"className":4938},[],[4940],{"type":224,"value":905},{"type":224,"value":1293},{"type":212,"tag":239,"props":4943,"children":4945},{"className":4944},[],[4946],{"type":224,"value":1299},{"type":224,"value":1301},{"type":212,"tag":217,"props":4949,"children":4952},{"href":4950,"rel":4951},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002F0a8c748",[221],[4953],{"type":224,"value":4954},"0a8c748",{"type":224,"value":344},{"type":212,"tag":331,"props":4957,"children":4958},{},[4959,4960,4965,4966,4973],{"type":224,"value":1550},{"type":212,"tag":239,"props":4961,"children":4963},{"className":4962},[],[4964],{"type":224,"value":1556},{"type":224,"value":1558},{"type":212,"tag":217,"props":4967,"children":4970},{"href":4968,"rel":4969},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002F13b2645",[221],[4971],{"type":224,"value":4972},"13b2645",{"type":224,"value":344},{"type":212,"tag":331,"props":4975,"children":4976},{},[4977,4978,4983,4985,4992],{"type":224,"value":1327},{"type":212,"tag":239,"props":4979,"children":4981},{"className":4980},[],[4982],{"type":224,"value":1333},{"type":224,"value":4984}," by its new name (",{"type":212,"tag":217,"props":4986,"children":4989},{"href":4987,"rel":4988},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Fac6243e",[221],[4990],{"type":224,"value":4991},"ac6243e",{"type":224,"value":344},{"type":212,"tag":227,"props":4994,"children":4995},{"id":1353},[4996],{"type":224,"value":1356},{"type":212,"tag":327,"props":4998,"children":4999},{},[5000,5019,5031,5044],{"type":212,"tag":331,"props":5001,"children":5002},{},[5003,5005,5010,5011,5018],{"type":224,"value":5004},"The player's money is ",{"type":212,"tag":239,"props":5006,"children":5008},{"className":5007},[],[5009],{"type":224,"value":2441},{"type":224,"value":1301},{"type":212,"tag":217,"props":5012,"children":5015},{"href":5013,"rel":5014},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002F0e0f3ca",[221],[5016],{"type":224,"value":5017},"0e0f3ca",{"type":224,"value":344},{"type":212,"tag":331,"props":5020,"children":5021},{},[5022,5023,5030],{"type":224,"value":1578},{"type":212,"tag":217,"props":5024,"children":5027},{"href":5025,"rel":5026},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Fd320b06",[221],[5028],{"type":224,"value":5029},"d320b06",{"type":224,"value":344},{"type":212,"tag":331,"props":5032,"children":5033},{},[5034,5036,5043],{"type":224,"value":5035},"The menu's context in the README (",{"type":212,"tag":217,"props":5037,"children":5040},{"href":5038,"rel":5039},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Fffe1920",[221],[5041],{"type":224,"value":5042},"ffe1920",{"type":224,"value":344},{"type":212,"tag":331,"props":5045,"children":5046},{},[5047,5049,5056],{"type":224,"value":5048},"The README without a status note (",{"type":212,"tag":217,"props":5050,"children":5053},{"href":5051,"rel":5052},"https:\u002F\u002Fgithub.com\u002Famxts\u002Fmenu-core\u002Fcommit\u002Fee841d7",[221],[5054],{"type":224,"value":5055},"ee841d7",{"type":224,"value":344},{"type":212,"tag":1653,"props":5058,"children":5060},{"id":5059},"️-breaking-changes-1",[5061],{"type":224,"value":5062},"⚠️ Breaking Changes",{"type":212,"tag":327,"props":5064,"children":5065},{},[5066],{"type":212,"tag":331,"props":5067,"children":5068},{},[5069,5070,5075],{"type":224,"value":4848},{"type":212,"tag":217,"props":5071,"children":5073},{"href":4851,"rel":5072},[221],[5074],{"type":224,"value":4855},{"type":224,"value":344},{"type":212,"tag":227,"props":5077,"children":5078},{"id":322},[5079],{"type":224,"value":325},{"type":212,"tag":327,"props":5081,"children":5082},{},[5083],{"type":212,"tag":331,"props":5084,"children":5085},{},[5086,5087,5092],{"type":224,"value":335},{"type":212,"tag":217,"props":5088,"children":5090},{"href":338,"rel":5089},[221],[5091],{"type":224,"value":342},{"type":224,"value":344},{"type":212,"tag":4506,"props":5094,"children":5095},{},[5096],{"type":224,"value":2288},1791273237962]