[{"data":1,"prerenderedAt":1507},["ShallowReactive",2],{"navigation-docs_ru":3,"\u002Fru\u002Fdocs\u002Fgetting-started\u002Flimitations":140,"\u002Fru\u002Fdocs\u002Fgetting-started\u002Flimitations-surround":1501,"\u002Fru\u002Fdocs\u002Fgetting-started\u002Flimitations-current":1506},[4,35,61,91,109,123,133],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":34},"Начало работы","i-lucide-rocket","\u002Fru\u002Fdocs\u002Fgetting-started","ru\u002Fdocs\u002F1.getting-started",[10,14,18,22,26,30],{"title":11,"path":12,"stem":13},"Введение","\u002Fru\u002Fdocs\u002Fgetting-started\u002Fintroduction","ru\u002Fdocs\u002F1.getting-started\u002F01.introduction",{"title":15,"path":16,"stem":17},"Быстрый старт","\u002Fru\u002Fdocs\u002Fgetting-started\u002Fquick-start","ru\u002Fdocs\u002F1.getting-started\u002F02.quick-start",{"title":19,"path":20,"stem":21},"CLI","\u002Fru\u002Fdocs\u002Fgetting-started\u002Fcli","ru\u002Fdocs\u002F1.getting-started\u002F03.cli",{"title":23,"path":24,"stem":25},"Установка на сервер","\u002Fru\u002Fdocs\u002Fgetting-started\u002Finstall","ru\u002Fdocs\u002F1.getting-started\u002F04.install",{"title":27,"path":28,"stem":29},"Сервер в Docker","\u002Fru\u002Fdocs\u002Fgetting-started\u002Fdocker","ru\u002Fdocs\u002F1.getting-started\u002F05.docker",{"title":31,"path":32,"stem":33},"Ограничения","\u002Fru\u002Fdocs\u002Fgetting-started\u002Flimitations","ru\u002Fdocs\u002F1.getting-started\u002F06.limitations",false,{"title":36,"icon":37,"path":38,"stem":39,"children":40,"page":34},"Основы","i-lucide-zap","\u002Fru\u002Fdocs\u002Fcore","ru\u002Fdocs\u002F2.core",[41,45,49,53,57],{"title":42,"path":43,"stem":44},"Плагин","\u002Fru\u002Fdocs\u002Fcore\u002Fplugin","ru\u002Fdocs\u002F2.core\u002F01.plugin",{"title":46,"path":47,"stem":48},"События игры","\u002Fru\u002Fdocs\u002Fcore\u002Fhooks","ru\u002Fdocs\u002F2.core\u002F02.hooks",{"title":50,"path":51,"stem":52},"Форварды","\u002Fru\u002Fdocs\u002Fcore\u002Fforwards","ru\u002Fdocs\u002F2.core\u002F03.forwards",{"title":54,"path":55,"stem":56},"Async и промисы","\u002Fru\u002Fdocs\u002Fcore\u002Fasync","ru\u002Fdocs\u002F2.core\u002F04.async",{"title":58,"path":59,"stem":60},"Производительность","\u002Fru\u002Fdocs\u002Fcore\u002Fperformance","ru\u002Fdocs\u002F2.core\u002F05.performance",{"title":62,"icon":63,"path":64,"stem":65,"children":66,"page":34},"Игра","i-lucide-gamepad-2","\u002Fru\u002Fdocs\u002Fgame","ru\u002Fdocs\u002F3.game",[67,71,75,79,83,87],{"title":68,"path":69,"stem":70},"Игроки и сущности","\u002Fru\u002Fdocs\u002Fgame\u002Fentities","ru\u002Fdocs\u002F3.game\u002F01.entities",{"title":72,"path":73,"stem":74},"Игроки: действия","\u002Fru\u002Fdocs\u002Fgame\u002Fplayers","ru\u002Fdocs\u002F3.game\u002F02.players",{"title":76,"path":77,"stem":78},"Эффекты","\u002Fru\u002Fdocs\u002Fgame\u002Feffects","ru\u002Fdocs\u002F3.game\u002F03.effects",{"title":80,"path":81,"stem":82},"Флаги","\u002Fru\u002Fdocs\u002Fgame\u002Fflags","ru\u002Fdocs\u002F3.game\u002F04.flags",{"title":84,"path":85,"stem":86},"Квары","\u002Fru\u002Fdocs\u002Fgame\u002Fcvars","ru\u002Fdocs\u002F3.game\u002F05.cvars",{"title":88,"path":89,"stem":90},"Сообщения","\u002Fru\u002Fdocs\u002Fgame\u002Fmessages","ru\u002Fdocs\u002F3.game\u002F06.messages",{"title":92,"icon":93,"path":94,"stem":95,"children":96,"page":34},"Данные","i-lucide-database","\u002Fru\u002Fdocs\u002Fdata","ru\u002Fdocs\u002F4.data",[97,101,105],{"title":98,"path":99,"stem":100},"Хранилище","\u002Fru\u002Fdocs\u002Fdata\u002Fstorage","ru\u002Fdocs\u002F4.data\u002F01.storage",{"title":102,"path":103,"stem":104},"Файлы","\u002Fru\u002Fdocs\u002Fdata\u002Ffs","ru\u002Fdocs\u002F4.data\u002F02.fs",{"title":106,"path":107,"stem":108},"HTTP","\u002Fru\u002Fdocs\u002Fdata\u002Fhttp","ru\u002Fdocs\u002F4.data\u002F03.http",{"title":110,"icon":111,"path":112,"stem":113,"children":114,"page":34},"Модули","i-lucide-package","\u002Fru\u002Fdocs\u002Fmodules","ru\u002Fdocs\u002F5.modules",[115,119],{"title":116,"path":117,"stem":118},"Общие модули","\u002Fru\u002Fdocs\u002Fmodules\u002Fshared-modules","ru\u002Fdocs\u002F5.modules\u002F01.shared-modules",{"title":120,"path":121,"stem":122},"Свой модуль","\u002Fru\u002Fdocs\u002Fmodules\u002Fcreating-a-module","ru\u002Fdocs\u002F5.modules\u002F02.creating-a-module",{"title":124,"icon":125,"path":126,"stem":127,"children":128,"page":34},"Pawn","i-lucide-plug","\u002Fru\u002Fdocs\u002Fpawn","ru\u002Fdocs\u002F6.pawn",[129],{"title":130,"path":131,"stem":132},"Нативы","\u002Fru\u002Fdocs\u002Fpawn\u002Fnatives","ru\u002Fdocs\u002F6.pawn\u002F01.natives",{"title":134,"path":135,"stem":136,"children":137,"icon":139},"Тесты","\u002Fru\u002Fdocs\u002Ftesting","ru\u002Fdocs\u002F7.testing\u002F01.index",[138],{"title":134,"path":135,"stem":136},"i-lucide-flask-conical",{"id":141,"title":31,"body":142,"description":148,"extension":1496,"meta":1497,"navigation":1498,"path":32,"seo":1499,"stem":33,"__hash__":1500},"docs_ru\u002Fru\u002Fdocs\u002F1.getting-started\u002F06.limitations.md",{"type":143,"value":144,"toc":1476},"minimark",[145,149,152,157,160,547,551,641,644,695,699,910,913,1039,1042,1063,1066,1086,1089,1173,1177,1203,1207,1288,1291,1297,1332,1339,1414,1418,1453,1457],[146,147,148],"p",{},"Чего amxts пока не умеет — и что писать вместо этого. Почти о каждом пункте\nниже скажут сборка, редактор или консоль сервера; здесь можно посмотреть, что\nэто значит.",[146,150,151],{},"Как ведёт себя возможность из-за игры, AMX Mod X, протокола или формата\nфайла — таймер ждёт не меньше 0,1 секунды, у сообщения в чате один цвет\nкоманды, — написано на странице самой возможности, рядом с тем, чего это\nкасается.",[153,154,156],"h2",{"id":155},"язык","Язык",[146,158,159],{},"Плагин — это TypeScript, скомпилированный в WebAssembly, а затем в машинный\nкод. Что есть в TypeScript, но нет в плагине:",[161,162,163,207,230,264,284,296,314,342,356,375,407,446,483,528],"ul",{},[164,165,166,178,179,181,182,185,186,189,190,192,193,196,197,196,200,203,204,206],"li",{},[167,168,169,173,174,177],"strong",{},[170,171,172],"code",{},"throw"," принимает ",[170,175,176],{},"Error"," или строку,"," которая становится ",[170,180,176],{}," с ней\nв сообщении: ",[170,183,184],{},"throw 42"," не собирается. ",[170,187,188],{},"catch"," получает ",[170,191,176],{}," —\n",[170,194,195],{},"error.message",", ",[170,198,199],{},"error.name",[170,201,202],{},"instanceof"," для своего класса. Падение,\nкоторое не ошибка, — переполнение стека — завершает вызов мимо всех\n",[170,205,188],{},".",[164,208,209,216,217,220,221,223,224,229],{},[167,210,211,212,215],{},"В тестах ",[170,213,214],{},"stack"," ошибки — её первая строка:"," поддельный сервер\n(",[170,218,219],{},"amxts test",") выполняет плагин без кадров, которые хранит игровой сервер.\nПроверяй ",[170,222,195],{},"; вызовы видны на сервере (",[225,226,228],"a",{"href":227},"\u002Fru\u002Fdocs\u002Fcore\u002Fplugin#%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B8","ошибки",").",[164,231,232,235,236,239,240,243,244,247,248,251,252,255,256,259,260,263],{},[167,233,234],{},"Нет юнионов из разных типов."," ",[170,237,238],{},"number | string"," и ",[170,241,242],{},"cond ? 1 : \"a\""," не\nсобираются. Юнионы строковых литералов (",[170,245,246],{},"\"CT\" | \"TERRORIST\"","), ",[170,249,250],{},"T | null"," и\n",[170,253,254],{},"T | undefined"," работают, как и ",[170,257,258],{},"true | false | \"default\""," и настройка\n«функция или список» вроде ",[170,261,262],{},"enabled"," в menu-core. Берите два параметра, две\nфункции или общий базовый класс.",[164,265,266,235,269,272,273,276,277,280,281,206],{},[167,267,268],{},"Псевдоним типа не доходит до себя.",[170,270,271],{},"type Text = string | ((context: Context) => string)"," не собирается («Recursive types»), если у ",[170,274,275],{},"Context"," есть\nполе класса, у которого есть поле типа ",[170,278,279],{},"Text",". Запишите тип у этого поля\nцеликом: ",[170,282,283],{},"title: string | ((context: Context) => string)",[164,285,286,295],{},[167,287,288,289,239,292,206],{},"Нет ",[170,290,291],{},"any",[170,293,294],{},"unknown"," У каждого значения есть тип, когда плагин\nсобирается.",[164,297,298,301,302,305,306,309,310,313],{},[167,299,300],{},"Объектный литерал берёт тип от своих значений,"," поэтому тип нужен\nкаждому: ",[170,303,304],{},"{ owner: null }"," или ",[170,307,308],{},"{ items: [] }"," сами по себе не собираются —\nобъявите интерфейс (",[170,311,312],{},"const team: Team = { ... }",") или пишите литерал там,\nгде тип известен.",[164,315,316,319,322,323,326,327,239,330,333,334,337,338,341],{},[167,317,318],{},"Простой объект подходит туда, где ждут другой, когда поля те же:",[170,320,321],{},"{ y: 2, x: 1 }"," — это ",[170,324,325],{},"Point"," из ",[170,328,329],{},"x",[170,331,332],{},"y",", а заданный ",[170,335,336],{},"label"," подходит\nтуда, где ",[170,339,340],{},"label?"," необязателен; объект без необязательного поля — нет:\nпишите литерал там, где тип известен.",[164,343,344,351,352,355],{},[167,345,346,347,350],{},"У методов объектного литерала нет ",[170,348,349],{},"this"," объекта:"," где у интерфейса\nесть методы, литерал пишет их стрелками или как ",[170,353,354],{},"run() { ... }",", а поля\nобъекта читает через переменную.",[164,357,358,364,365,368,369,371,372,374],{},[167,359,360,361],{},"Класс подходит туда, где ждут интерфейс из полей, когда он пишет\n",[170,362,363],{},"implements"," и не расширяет другой класс: ",[170,366,367],{},"class Spot implements Point"," —\nэто ",[170,370,325],{},"; класс с теми же полями без ",[170,373,363],{}," — нет.",[164,376,377,235,383,386,387,390,391,394,395,398,399,402,403,229],{},[167,378,379,382],{},[170,380,381],{},"JSON.parse"," говорят, что он читает:",[170,384,385],{},"JSON.parse\u003CSettings>(text)"," или\n",[170,388,389],{},"JSON.parse(text) as Settings","; сам по себе он не собирается. Поле, которого\nв тексте нет и которое не необязательное и без значения по умолчанию, — это\n",[170,392,393],{},"TypeError",", а в JavaScript оно было бы ",[170,396,397],{},"undefined",". ",[170,400,401],{},"JSON.stringify"," не\nпринимает функцию-заменитель (",[225,404,406],{"href":405},"\u002Fru\u002Fdocs\u002Fdata\u002Ffs#json","JSON",[164,408,409,412,413,416,417,420,421,239,424,427,428,431,432,435,436,438,439,442,443,445],{},[167,410,411],{},"В регулярных выражениях нет ретроспективной проверки"," (",[170,414,415],{},"(?\u003C=...)","),\nименованных групп, ",[170,418,419],{},"\\p{...}"," и флагов ",[170,422,423],{},"u",[170,425,426],{},"d",": такой шаблон — это\n",[170,429,430],{},"SyntaxError",". Группа, которая не совпала, читается как ",[170,433,434],{},"\"\"",", а не\n",[170,437,397],{},"; функция, переданная в ",[170,440,441],{},"replace",", получает совпадение и до\nчетырёх групп. Совпадение дольше пяти миллионов шагов бросает ",[170,444,176],{},",\nчтобы шаблон, который перебирает без конца, не держал сервер.",[164,447,448,235,455,458,459,196,462,196,465,196,468,196,471,474,475,478,479,229],{},[167,449,450,451,454],{},"Дата знает несколько языков и не знает ",[170,452,453],{},"Intl",":",[170,456,457],{},"toLocaleString"," и\nостальные принимают язык (",[170,460,461],{},"en-US",[170,463,464],{},"en-GB",[170,466,467],{},"de",[170,469,470],{},"fr",[170,472,473],{},"ru","), а не\nнастройки, а ",[170,476,477],{},"toString"," пишет часовой пояс смещением, без его имени в\nскобках (",[225,480,482],{"href":481},"\u002Fru\u002Fdocs\u002Fcore\u002Fplugin#%D0%B2%D1%80%D0%B5%D0%BC%D1%8F-%D0%B8-%D1%81%D0%BB%D1%83%D1%87%D0%B0%D0%B9%D0%BD%D0%BE%D1%81%D1%82%D1%8C","время",[164,484,485,488],{},[167,486,487],{},"Синтаксис, который не собирается:",[489,490,491,504],"table",{},[492,493,494],"thead",{},[495,496,497,501],"tr",{},[498,499,500],"th",{},"Не собирается",[498,502,503],{},"Пишите вместо",[505,506,507],"tbody",{},[495,508,509,518],{},[510,511,512,196,515],"td",{},[170,513,514],{},"function*",[170,516,517],{},"yield",[510,519,520,521,524,525],{},"массив или ",[170,522,523],{},"async","-функции и ",[170,526,527],{},"await",[164,529,530,235,533,239,536,539,540,543,544,206],{},[167,531,532],{},"Полю класса со стрелкой, которая возвращает не простое значение, нужен\nтип:",[170,534,535],{},"onTick = () => { ... }",[170,537,538],{},"double = (n: number) => n * 2","\nсобираются; ",[170,541,542],{},"label = () => this.makeLabel()"," требует\n",[170,545,546],{},"label: () => string = () => this.makeLabel()",[153,548,550],{"id":549},"переменные-и-необязательные-значения","Переменные и необязательные значения",[161,552,553,562,585,622],{},[164,554,555,558,559,206],{},[167,556,557],{},"Метод, который выполняется рано через базовый класс,"," может прочитать\nпеременную до её объявления как пустое значение, там где JavaScript бросил\nбы ",[170,560,561],{},"ReferenceError",[164,563,564,570,571,574,575,578,579,581,582,206],{},[167,565,566,567,454],{},"Внутри замыкания незаданный булев — это ",[170,568,569],{},"false"," параметр\n",[170,572,573],{},"flag?: boolean"," или переменная с необязательным логическим полем,\nпрочитанные в стрелочной функции, созданной внутри функции, не видят, что\nих не задали, — ",[170,576,577],{},"() => flag ?? true"," даёт ",[170,580,569],{},". Прочитайте снаружи:\n",[170,583,584],{},"const loud = flag ?? true",[164,586,587,592,593,196,595,239,598,601,602,604,605,608,609,611,612,615,616,618,619,206],{},[167,588,589,591],{},[170,590,397],{}," узнаётся по типу, написанному там, где значение читают:","\nнеобязательное поле или параметр, переменная или результат функции типа\n",[170,594,254],{},[170,596,597],{},"find",[170,599,600],{},"map.get"," — и переменная, в которой лежит одно из\nних, — печатаются как ",[170,603,397],{}," и в счёте дают ",[170,606,607],{},"NaN",". Элемент массива из\n",[170,610,254],{},", прочитанный по индексу, печатает текст как ",[170,613,614],{},"null",", а число\nв счёте остаётся ",[170,617,397],{},": сначала подставьте значение через ",[170,620,621],{},"??",[164,623,624,636,637,640],{},[167,625,626,629,630,632,633,635],{},[170,627,628],{},"x!"," от ",[170,631,614],{}," сразу бросает ",[170,634,393],{},","," а в TypeScript ",[170,638,639],{},"!"," ничего\nне делает, и JavaScript бросает, только когда значение используют.",[153,642,54],{"id":643},"async-и-промисы",[161,645,646,655,678,689],{},[164,647,648,412,651,654],{},[167,649,650],{},"Async-генераторы",[170,652,653],{},"async function*",") не собираются.",[164,656,657,665,666,239,669,386,672,239,674,677],{},[167,658,659,239,662,664],{},[170,660,661],{},"Promise.race",[170,663,291],{}," нужен один тип:"," промисы ",[170,667,668],{},"number",[170,670,671],{},"string",[170,673,668],{},[170,675,676],{},"sleep"," не собираются. Дожидайтесь их по одному.",[164,679,680,686,687,229],{},[167,681,682,685],{},[170,683,684],{},"Promise.all"," из разных типов принимает до 8 промисов;"," у промисов\nодного типа и у списка такого предела нет (",[225,688,523],{"href":55},[164,690,691,694],{},[167,692,693],{},"Ожидающая async-функция хранит до 4 КБ своего состояния;"," функция,\nкоторой нужно больше, останавливается с сообщением в консоли.",[153,696,698],{"id":697},"события-форварды-и-нативы","События, форварды и нативы",[161,700,701,727,758,771,787,804,848,860,869,894],{},[164,702,703,706,707,710,711,714,715,718,719,722,723,726],{},[167,704,705],{},"Обработчик команды пишется в вызове:"," объект, который он получает, —\n",[170,708,709],{},"player"," и аргументы — тип, который сборка делает для этого вызова. Он\nидёт туда, где ждут интерфейс его аргументов: ",[170,712,713],{},"(args) => kick(args)"," для\n",[170,716,717],{},"kick(args: KickArgs)","; без интерфейса у него нет имени, чтобы дать его\nфункции, написанной отдельно: возьмите его части там,\n",[170,720,721],{},"({ player, text }) => say(player, text)",".\nАргументы команды пишутся в её использовании — на месте или после имени,\nкоторое строится при запуске, ",[170,724,725],{},"`${name} [value]`","; использование из\nпеременной аргументов не принимает.",[164,728,729,235,732,386,735,738,739,742,743,746,747,750,751,754,755,206],{},[167,730,731],{},"Имя события пишется строкой:",[170,733,734],{},"server.addEventListener(name, ...)",[170,736,737],{},"server.addMessageListener(name, ...)"," с именем в переменной не\nсобирается — по имени выбирается тип события. Так\nже пишется и поле обработчика ",[170,740,741],{},"\"playerChange\"",":\n",[170,744,745],{},"{ field: \"spawnProtected\" }",", а не переменная. Без ",[170,748,749],{},"field"," у ",[170,752,753],{},"value","\nсобытия нет типа: читайте поле у ",[170,756,757],{},"event.player",[164,759,760,763,764,767,768,229],{},[167,761,762],{},"Обработчик события игры отвечает всегда или никогда."," Тот, что должен\nотвечать лишь иногда, ничего не возвращает и вызывает\n",[170,765,766],{},"event.preventDefault()"," — или отвечает всегда, повторяя правило игры для\nостальных случаев (",[225,769,770],{"href":47},"события игры",[164,772,773,776,779,780,783,784,229],{},[167,774,775],{},"Поле-вектор события игры записывается целиком:",[170,777,778],{},"event.direction = new Vector(x, y, z)","; ",[170,781,782],{},"event.direction.x = 1"," меняет копию\n(",[225,785,770],{"href":786},"\u002Fru\u002Fdocs\u002Fcore\u002Fhooks#%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D1%8F",[164,788,789,792,793,305,796,799,800,229],{},[167,790,791],{},"Форвард плагина на Pawn доходит до TypeScript, только если он объявлен в\ninclude, который идёт с amxts,"," а аргументу ",[170,794,795],{},"Team",[170,797,798],{},"RoundWinner","\nнужно объявление форварда в include\n(",[225,801,803],{"href":802},"\u002Fru\u002Fdocs\u002Fcore\u002Fforwards#%D1%82%D0%B8%D0%BF%D1%8B-%D0%B0%D1%80%D0%B3%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2","форварды",[164,805,806,817,818,196,821,196,824,196,827,830,831,835,836,839,840,843,844,847],{},[167,807,808,809,812,813,816],{},"Число в хвосте ",[170,810,811],{},"any:..."," натива — ",[170,814,815],{},"Float:"," только там, где amxts знает,\nчто натив читает его так,"," — ",[170,819,820],{},"engfunc",[170,822,823],{},"dllfunc",[170,825,826],{},"ExecuteHam",[170,828,829],{},"pev"," и\nдругие, которые перечисляет страница ",[225,832,834],{"href":833},"\u002Fru\u002Fdocs\u002Fpawn\u002Fnatives#%D0%BD%D0%B0%D1%82%D0%B8%D0%B2%D1%8B-%D0%BD%D0%B0%D0%BF%D1%80%D1%8F%D0%BC%D1%83%D1%8E","нативы",";\nв остальных оно уходит целым. Если такой натив умеет писать и текст,\nпрочитайте его и переведите: ",[170,837,838],{},"nvault_get(vault, key, text)"," с\n",[170,841,842],{},"const text = new Ref(\"\")",", затем ",[170,845,846],{},"Number(text.value)",". Хвост принимает не\nбольше двенадцати аргументов.",[164,849,850,322,853,856,857,859],{},[167,851,852],{},"Собственные нативы плагина",[170,854,855],{},"export function"," его файла с типами\nпараметров из списка на странице ",[225,858,834],{"href":131},"; другой тип\nостанавливает сборку.",[164,861,862,865,866,229],{},[167,863,864],{},"У вашего натива до 64 аргументов"," в том виде, в каком их передаёт Pawn, —\nмассив или строковый результат считается дважды, вместе с размером; больше\nостанавливает сборку: передавайте массив (",[225,867,834],{"href":868},"\u002Fru\u002Fdocs\u002Fpawn\u002Fnatives#%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D0%B0",[164,870,871,874,875,878,879,196,882,885,886,889,890,893],{},[167,872,873],{},"Длина буфера не бывает отрицательной:"," натив, которому передан буфер и\nдлина меньше 0 — ",[170,876,877],{},"-1",", который ",[170,880,881],{},"ArrayGetArray",[170,883,884],{},"ArrayPushArray"," и другие\nнативы ",[170,887,888],{},"cellarray"," читают как «весь элемент», — не вызывается и отвечает\n",[170,891,892],{},"0",". Передавайте длину самого буфера.",[164,895,896,902,903,412,906,229],{},[167,897,898,901],{},[170,899,900],{},"lang.translate"," принимает аргументы строками:"," число передаётся\nтекстом, ",[170,904,905],{},"`${seconds}`",[225,907,909],{"href":908},"\u002Fru\u002Fdocs\u002Fcore\u002Fplugin#%D0%BF%D0%B5%D1%80%D0%B5%D0%B2%D0%BE%D0%B4%D1%8B","переводы",[153,911,68],{"id":912},"игроки-и-сущности",[161,914,915,936,947,985,1000,1018],{},[164,916,917,920,921,924,925,927,928,931,932,935],{},[167,918,919],{},"Значение, для которого нет имени",", — его записал другой плагин или мод\n— читается как ",[170,922,923],{},"\"unknown\"",", а присваивание ",[170,926,923],{}," ничего не меняет.\nЧисло читайте нативом: ",[170,929,930],{},"get_entvar(player.id, var_rendermode)",", а на\nсервере без ReAPI — ",[170,933,934],{},"entity_get_int(player.id, EV_INT_rendermode)"," модуля engine.",[164,937,938,235,941,196,944,206],{},[167,939,940],{},"Простые числа:",[170,942,943],{},"autoSwitchWeapon",[170,945,946],{},"shotgunReloadStage",[164,948,949,952,953,956,957,247,960,196,963,966,967,239,970,973,974,239,977,980,981,229],{},[167,950,951],{},"Нет свойства для:"," членов-массивов (",[170,954,955],{},"m_rgAmmo",", …; оружие — это\n",[170,958,959],{},"player.items",[170,961,962],{},"var_controller",[170,964,965],{},"var_blending",". Берите ",[170,968,969],{},"get_member",[170,971,972],{},"set_member",",\nа на сервере без ReAPI — ",[170,975,976],{},"get_ent_data",[170,978,979],{},"set_ent_data"," модуля fakemeta\n(",[225,982,984],{"href":983},"\u002Fru\u002Fdocs\u002Fgame\u002Fentities#%D0%BF%D0%BE%D0%BB%D1%8F-%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D0%B5-%D0%BD%D0%B5-%D1%81%D0%B2%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%B0","сущности",[164,986,987,990,196,993,996,997,999],{},[167,988,989],{},"Векторному или текстовому полю, прочитанному нативом, нужен его тип:",[170,991,992],{},"get_entvar\u003CVector>(id, var_origin)",[170,994,995],{},"get_member\u003Cstring>(id, m_szAnimExtention)",".\nБез него поле читается числом, а векторное или текстовое поле читается как\n",[170,998,892],{},", и в консоли появляется строка о том, что написать.",[164,1001,1002,235,1008,239,1011,1014,1015,229],{},[167,1003,1004,1005,454],{},"Список флагов пишется обратно только через ",[170,1006,1007],{},"push",[170,1009,1010],{},"pop",[170,1012,1013],{},"splice","\nменяют массив, а не игру. Чтобы убрать флаг, присвойте отфильтрованный\nмассив (",[225,1016,1017],{"href":81},"флаги",[164,1019,1020,322,1023,196,1026,196,1028,1030,1031,1034,1035,1038],{},[167,1021,1022],{},"Общие поля игрока",[170,1024,1025],{},"boolean",[170,1027,668],{},[170,1029,671],{},", юнион строковых\nлитералов, ",[170,1032,1033],{},"Player[]"," или объект из них; необязательных не бывает, и члены\nобъекта — не объекты. Имя, которое у ",[170,1036,1037],{},"Player"," уже есть, не принимается.",[153,1040,76],{"id":1041},"эффекты",[161,1043,1044],{},[164,1045,1046,1049,1050,1053,1054,239,1057,1060,1061,229],{},[167,1047,1048],{},"Нет эффектов для декалей"," (дырки от пули, рисунка на стене — им нужен\nиндекс декали), для цветов трассеров движка и для текстового сообщения\n(это ",[170,1051,1052],{},"player.showHud","); их отправляют через ",[170,1055,1056],{},"message_begin",[170,1058,1059],{},"write_*","\n(",[225,1062,1041],{"href":77},[153,1064,98],{"id":1065},"хранилище",[161,1067,1068],{},[164,1069,1070,235,1076,1079,1080,1083,1084,229],{},[167,1071,1072,1075],{},[170,1073,1074],{},"Storage"," хранит текст:",[170,1077,1078],{},"value.toString()"," внутрь, ",[170,1081,1082],{},"parseInt(value)","\nнаружу. Значение читается обратно до 255 байт UTF-8 — это около 127 букв\nкириллицы (",[225,1085,1065],{"href":99},[153,1087,106],{"id":1088},"http",[161,1090,1091,1129,1139,1151,1160],{},[164,1092,1093,235,1096,1099,1100,1103,1104,1107,1108,196,1111,196,1114,386,1117,1120,1121,839,1124,1060,1127,229],{},[167,1094,1095],{},"Тело запроса — текст:",[170,1097,1098],{},"body"," принимает строку — ",[170,1101,1102],{},"JSON.stringify(value)","\nили объект через ",[170,1105,1106],{},"useFetch","; не ",[170,1109,1110],{},"FormData",[170,1112,1113],{},"Blob",[170,1115,1116],{},"ArrayBuffer",[170,1118,1119],{},"URLSearchParams",". Форма уходит текстом: ",[170,1122,1123],{},"body: query.toString()",[170,1125,1126],{},"\"Content-Type\": \"application\u002Fx-www-form-urlencoded\"",[225,1128,106],{"href":107},[164,1130,1131,1134,1135,1138],{},[167,1132,1133],{},"Заголовки задаются объектом"," имён и значений, не ",[170,1136,1137],{},"Headers"," и не списком\nпар.",[164,1140,1141,1147,1148,206],{},[167,1142,1143,1146],{},[170,1144,1145],{},"new URLSearchParams"," принимает объект,"," а не запрос текстом: прочитать\nего можно через ",[170,1149,1150],{},"new URL(address).searchParams",[164,1152,1153,1159],{},[167,1154,1155,1156,454],{},"Нет потока ",[170,1157,1158],{},"response.body"," ответ читается целиком, так что у загрузки\nи отправки нет прогресса, за которым можно следить.",[164,1161,1162,235,1170,206],{},[167,1163,1164,750,1167,1169],{},[170,1165,1166],{},"query",[170,1168,1106],{}," принимает текст:",[170,1171,1172],{},"{ page: `${page}` }",[153,1174,1176],{"id":1175},"ftp-и-sftp","FTP и SFTP",[161,1178,1179],{},[164,1180,1181,235,1184,1187,1188,1191,1192,1195,1196,1060,1199,229],{},[167,1182,1183],{},"Ключ SSH — RSA в PEM:",[170,1185,1186],{},"ssh-keygen -t rsa -m PEM",". Ключи в собственном\nформате OpenSSH (",[170,1189,1190],{},"BEGIN OPENSSH PRIVATE KEY",", что ",[170,1193,1194],{},"ssh-keygen"," пишет по\nумолчанию), ключи ECDSA и Ed25519 не читаются, а до сервера, у которого\nключ хоста только Ed25519, не достучаться. Ключ RSA переводится в PEM командой\n",[170,1197,1198],{},"ssh-keygen -p -m PEM -f key",[225,1200,1202],{"href":1201},"\u002Fru\u002Fdocs\u002Fmodules\u002Fcreating-a-module#%D1%81%D0%B5%D1%82%D0%B5%D0%B2%D1%8B%D0%B5-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D1%8B","сетевые запросы",[153,1204,1206],{"id":1205},"конфиги","Конфиги",[161,1208,1209,1226,1240,1272],{},[164,1210,1211,1214,1215,1218,1219,1221,1222,1225],{},[167,1212,1213],{},"Сборка читает форму из исходника"," и отказывает, называя место и\nисправление: пустой список без типа, переменная со значениями по умолчанию\nбез объявленного типа, список списков списков или объектов, ",[170,1216,1217],{},"Map"," списков\nили объектов, юнион не из имён (",[170,1220,238],{},"), обобщённый интерфейс\nили интерфейс с ",[170,1223,1224],{},"extends",", поле, названное строкой, тип, содержащий сам\nсебя.",[164,1227,1228,1239],{},[167,1229,1230,1231,1233,1234,239,1236,454],{},"В ключах ",[170,1232,1217],{}," нет ",[170,1235,206],{},[170,1237,1238],{},"["," такой ключ не прочитать и не записать.",[164,1241,1242,1245,1246,1249,1250,1253,1254,1256,1257,1260,1261,305,1264,1267,1268,1271],{},[167,1243,1244],{},"Из YAML конфиги берут только часть."," Не читаются: якоря и ссылки (",[170,1247,1248],{},"&",",\n",[170,1251,1252],{},"*","), теги (",[170,1255,639],{},"), сложные ключи (",[170,1258,1259],{},"?","), директивы, несколько документов,\nпростое значение на несколько строк (возьмите его в кавычки или\nиспользуйте ",[170,1262,1263],{},"|",[170,1265,1266],{},">","), табуляция в отступах, ключ, записанный дважды,\nключ внутри ",[170,1269,1270],{},"[ ]",". Каждое — ошибка с файлом, строкой и столбцом, и файл\nчитается пустым.",[164,1273,1274,1277,1278,1281,1282,239,1285,1287],{},[167,1275,1276],{},"Сохранение"," пишет список YAML, записанный как ",[170,1279,1280],{},"[a, b]",", по элементу на\nстроку и выбрасывает комментарий после значения на той же строке и\nкомментарии внутри ",[170,1283,1284],{},"{ }",[170,1286,1270],{},". Комментарии на отдельных строках и пустые\nстроки сохраняются.",[153,1289,116],{"id":1290},"общие-модули",[146,1292,1293,1294,206],{},"Подробно — в ",[225,1295,1296],{"href":117},"общих модулях",[161,1298,1299,1324],{},[164,1300,1301,235,1304,196,1306,1249,1309,1312,1313,1315,1316,1319,1320,1323],{},[167,1302,1303],{},"То, что не передаётся между плагинами, не собирается:",[170,1305,1217],{},[170,1307,1308],{},"Set",[170,1310,1311],{},"Record"," с ключами из любых строк, обобщённый класс, класс из стандартной библиотеки, тип, который модуль не\nэкспортирует, вычисляемое значение по умолчанию, обобщённая или\n",[170,1314,523],{},"-функция, остаточный параметр, экспортированная переменная\n(",[170,1317,1318],{},"export let count",") — объект класса самого модуля\n(",[170,1321,1322],{},"export const counter = new Counter()",") передаётся.",[164,1325,1326,235,1329,1331],{},[167,1327,1328],{},"Поле-массив или поле-объект общего объекта читается как копия:",[170,1330,1007],{},"\nменяет копию. Пользуйтесь методом модуля или присваивайте поле целиком.",[153,1333,1335,1336],{"id":1334},"модули-и-команда-amxts","Модули и команда ",[170,1337,1338],{},"amxts",[161,1340,1341,1359,1387,1399],{},[164,1342,1343,1346,1347,1350,1351,1354,1355,1358],{},[167,1344,1345],{},"Модуль даёт одно имя",": себя пространством имён (",[170,1348,1349],{},"imports: [{ from, as }]",")\nили один из своих экспортов (",[170,1352,1353],{},"imports: [{ from, name }]","), а не список своих\nфункций или типов; ",[170,1356,1357],{},"menus.Menu"," — тип из пространства имён.",[164,1360,1361,1376,1377,1380,1381,1384,1385,206],{},[167,1362,1363,196,1366,196,1369,239,1372,1375],{},[170,1364,1365],{},"meta",[170,1367,1368],{},"requires",[170,1370,1371],{},"defaults",[170,1373,1374],{},"imports"," модуля — литералы:"," сборка читает их, не\nзапуская модуль. Кроме ",[170,1378,1379],{},"setup",", у ",[170,1382,1383],{},"defineModule"," нет хуков жизненного цикла:\nподписывайтесь на события сервера внутри ",[170,1386,1379],{},[164,1388,1389,1394,1395,1398],{},[167,1390,1391,1392,635],{},"Тесты запускает ",[170,1393,219],{}," то есть ",[170,1396,1397],{},"bun test","; другие тестовые\nраннеры не поддерживаются.",[164,1400,1401,1404,1405,1408,1409,1413],{},[167,1402,1403],{},"Натив, на который фейковый сервер не отвечает, останавливает тест"," с его\nименем; ответьте на него через ",[170,1406,1407],{},"server.defineNative(name, native)"," в тесте\nили в ",[225,1410,1412],{"href":1411},"\u002Fru\u002Fdocs\u002Ftesting#%D1%82%D0%B5%D1%81%D1%82%D0%BE%D0%B2%D1%8B%D0%B9-%D0%BD%D0%B0%D0%B1%D0%BE%D1%80-%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8F","тестовом наборе"," модуля.",[153,1415,1417],{"id":1416},"редактор","Редактор",[161,1419,1420,1430,1443],{},[164,1421,1422,1429],{},[167,1423,1424,1425,1428],{},"Сборка и ",[170,1426,1427],{},"amxts typecheck"," используют TypeScript 5,"," который ставит\nядро; редактор работает с TypeScript 5.9, 6 и 7.",[164,1431,1432,1435,1436,1438,1439,1442],{},[167,1433,1434],{},"Поле, которое принимает редактор, может не найтись при сборке:","\nредактор видит поля, которые добавляет ",[170,1437,1037],{}," любой файл папки плагинов,\nа сборка — только поля файлов, которые плагин импортирует. Добавьте\n",[170,1440,1441],{},"import"," файла, который его объявляет.",[164,1444,1445,1448,1449,229],{},[167,1446,1447],{},"Живая помощь в файлах меню — только в VS Code,"," через расширение amxts\n(",[225,1450,1452],{"href":1451},"\u002Fru\u002Fmodules\u002Fmenu-core#%D0%BF%D0%BE%D0%B4%D1%81%D0%BA%D0%B0%D0%B7%D0%BA%D0%B8-%D0%B2-%D1%80%D0%B5%D0%B4%D0%B0%D0%BA%D1%82%D0%BE%D1%80%D0%B5","меню",[153,1454,1456],{"id":1455},"сервер","Сервер",[161,1458,1459],{},[164,1460,1461,1467,1468,1471,1472,229],{},[167,1462,1463,1466],{},[170,1464,1465],{},".ts",", который компилирует сервер, задерживает сервер"," на секунду-две,\nпока идёт компиляция: посреди раунда игра замирает. На сервер, где играют,\nвыкладывайте ",[170,1469,1470],{},".aot",", собранные в проекте\n(",[225,1473,1475],{"href":1474},"\u002Fru\u002Fdocs\u002Fgetting-started\u002Finstall#%D0%BD%D0%B0%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BD%D0%B0-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B5","установка на сервер",{"title":1477,"searchDepth":1478,"depth":1479,"links":1480},"",2,3,[1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1494,1495],{"id":155,"depth":1478,"text":156},{"id":549,"depth":1478,"text":550},{"id":643,"depth":1478,"text":54},{"id":697,"depth":1478,"text":698},{"id":912,"depth":1478,"text":68},{"id":1041,"depth":1478,"text":76},{"id":1065,"depth":1478,"text":98},{"id":1088,"depth":1478,"text":106},{"id":1175,"depth":1478,"text":1176},{"id":1205,"depth":1478,"text":1206},{"id":1290,"depth":1478,"text":116},{"id":1334,"depth":1478,"text":1493},"Модули и команда amxts",{"id":1416,"depth":1478,"text":1417},{"id":1455,"depth":1478,"text":1456},"md",{},true,{"title":31,"description":148},"mNBfDqXj_YdufUbxMU47bHmfO6435HKYXIBU-lSy7E8",[1502,1504],{"title":27,"path":28,"stem":29,"description":1503,"children":-1},"ghcr.io\u002Famxts\u002Fserver — образ Docker с сервером Counter-Strike 1.6 на\nLinux, на котором работает amxts: HLDS с ReHLDS, ReGameDLL, Metamod-R, AMX Mod\nX 1.10 и ReAPI, модуль amxts и его компилятор. Ваш проект монтируется в него,\nи сервер запускает ваши плагины с вашими конфигами и файлами — на Windows,\nmacOS или Linux, и ставить не нужно ничего, кроме Docker.",{"title":42,"path":43,"stem":44,"description":1505,"children":-1},"Плагин — это один файл .ts в папке плагинов проекта. Работу он делает на\nверхнем уровне файла: называет себя, добавляет команды и подписывается на\nсобытия. То, чем он пользуется из ядра, — plugin, server, Player,\nprint — строки импорта не требует (автоимпорты).",null,1791273259962]