[{"data":1,"prerenderedAt":1518},["ShallowReactive",2],{"navigation-docs_en":3,"\u002Fdocs\u002Fgetting-started\u002Flimitations":140,"\u002Fdocs\u002Fgetting-started\u002Flimitations-surround":1512,"\u002Fdocs\u002Fgetting-started\u002Flimitations-current":1517},[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",{"id":141,"title":31,"body":142,"description":148,"extension":1507,"meta":1508,"navigation":1509,"path":32,"seo":1510,"stem":33,"__hash__":1511},"docs_en\u002Fdocs\u002F1.getting-started\u002F06.limitations.md",{"type":143,"value":144,"toc":1487},"minimark",[145,149,152,157,160,548,552,643,646,700,704,917,920,1047,1050,1071,1074,1093,1096,1182,1186,1212,1216,1297,1300,1306,1343,1351,1425,1429,1464,1468],[146,147,148],"p",{},"What amxts cannot do yet, each with what to write instead. The build, the\neditor or the server console says so for almost every item below; this page\nis where to look up what it means.",[146,150,151],{},"How a feature behaves because of the game, AMX Mod X, the protocol or a file\nformat - a timer waits at least 0.1 second, a chat message has one team\ncolour - is noted on that feature's own page, beside what it concerns.",[153,154,156],"h2",{"id":155},"the-language","The language",[146,158,159],{},"A plugin is TypeScript compiled to WebAssembly and then to machine code.\nWhat TypeScript has and a plugin does not:",[161,162,163,207,230,264,284,296,314,342,356,376,408,447,484,529],"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"," takes an ",[170,175,176],{},"Error"," or a string,"," which becomes an ",[170,180,176],{}," with it\nas the message: ",[170,183,184],{},"throw 42"," does not build. A ",[170,187,188],{},"catch"," gets an ",[170,191,176],{}," -\n",[170,194,195],{},"error.message",", ",[170,198,199],{},"error.name",[170,201,202],{},"instanceof"," for a class of your own. A\ncrash that is not an error - a stack overflow - ends the call past every\n",[170,205,188],{},".",[164,208,209,216,217,220,221,223,224,229],{},[167,210,211,212,215],{},"In tests an error's ",[170,213,214],{},"stack"," is its first line:"," the fake server\n(",[170,218,219],{},"amxts test",") runs a plugin without the frames a game server keeps.\nCheck ",[170,222,195],{},"; the calls show on a server (",[225,226,228],"a",{"href":227},"\u002Fdocs\u002Fcore\u002Fplugin#errors","errors",").",[164,231,232,235,236,239,240,243,244,247,248,251,252,255,256,259,260,263],{},[167,233,234],{},"No unions of different types."," ",[170,237,238],{},"number | string",", and\n",[170,241,242],{},"cond ? 1 : \"a\"",", do not build. Unions of string literals\n(",[170,245,246],{},"\"CT\" | \"TERRORIST\"","), ",[170,249,250],{},"T | null"," and ",[170,253,254],{},"T | undefined"," work, and so do\n",[170,257,258],{},"true | false | \"default\""," and a function-or-list option such as\nmenu-core's ",[170,261,262],{},"enabled",". Use two parameters, two functions, or a common base\nclass.",[164,265,266,235,269,272,273,276,277,280,281,206],{},[167,267,268],{},"A type alias does not reach itself.",[170,270,271],{},"type Text = string | ((context: Context) => string)"," does not build (\"Recursive types\") when ",[170,274,275],{},"Context"," has\na field of a class with a field of type ",[170,278,279],{},"Text",". Write the type out at that\nfield: ",[170,282,283],{},"title: string | ((context: Context) => string)",[164,285,286,295],{},[167,287,288,289,251,292,206],{},"No ",[170,290,291],{},"any",[170,293,294],{},"unknown"," Every value has a type when the plugin is\nbuilt.",[164,297,298,301,302,305,306,309,310,313],{},[167,299,300],{},"An object literal takes its type from its values,"," so each value needs\none: ",[170,303,304],{},"{ owner: null }"," or ",[170,307,308],{},"{ items: [] }"," alone does not build - declare an\ninterface (",[170,311,312],{},"const team: Team = { ... }","), or write the literal where the\ntype is known.",[164,315,316,235,319,322,323,326,327,251,330,333,334,337,338,341],{},[167,317,318],{},"A plain object goes where another is expected when it has the same\nfields:",[170,320,321],{},"{ y: 2, x: 1 }"," is a ",[170,324,325],{},"Point"," of ",[170,328,329],{},"x",[170,331,332],{},"y",", and a ",[170,335,336],{},"label","\ngiven goes where ",[170,339,340],{},"label?"," is optional; one that leaves an optional field\nout does not - write the literal where the type is known.",[164,343,344,351,352,355],{},[167,345,346,347,350],{},"An object literal's methods have no ",[170,348,349],{},"this"," of the object:"," where an\ninterface has methods, a literal of it writes them as arrows or as\n",[170,353,354],{},"run() { ... }",", and reads the object's fields through a variable.",[164,357,358,365,366,369,370,372,373,375],{},[167,359,360,361,364],{},"A class goes where an interface of fields is expected when it says\n",[170,362,363],{},"implements",","," and extends no other class: ",[170,367,368],{},"class Spot implements Point","\nis a ",[170,371,325],{},"; a class of the same fields without ",[170,374,363],{}," is not.",[164,377,378,235,384,387,388,391,392,395,396,399,400,403,404,229],{},[167,379,380,383],{},[170,381,382],{},"JSON.parse"," is told what it reads:",[170,385,386],{},"JSON.parse\u003CSettings>(text)",", or\n",[170,389,390],{},"JSON.parse(text) as Settings","; alone it does not build. A field the text\nleaves out that is neither optional nor has a default is a ",[170,393,394],{},"TypeError",",\nwhere JavaScript leaves it ",[170,397,398],{},"undefined",". ",[170,401,402],{},"JSON.stringify"," takes no replacer\nfunction (",[225,405,407],{"href":406},"\u002Fdocs\u002Fdata\u002Ffs#json","JSON",[164,409,410,413,414,417,418,421,422,251,425,428,429,432,433,436,437,439,440,443,444,446],{},[167,411,412],{},"Regular expressions have no lookbehind"," (",[170,415,416],{},"(?\u003C=...)","), named groups,\n",[170,419,420],{},"\\p{...}"," or the ",[170,423,424],{},"u",[170,426,427],{},"d"," flags: such a pattern is a ",[170,430,431],{},"SyntaxError",". A\ngroup that did not match reads as ",[170,434,435],{},"\"\"",", not ",[170,438,398],{},"; a function given to\n",[170,441,442],{},"replace"," gets the match and up to four groups. A match that takes more\nthan five million steps throws an ",[170,445,176],{},", so that a pattern that\nbacktracks without end does not hold the server.",[164,448,449,235,456,459,460,196,463,196,466,196,469,196,472,475,476,479,480,229],{},[167,450,451,452,455],{},"A date knows a few languages and no ",[170,453,454],{},"Intl",":",[170,457,458],{},"toLocaleString"," and the\nrest take a language (",[170,461,462],{},"en-US",[170,464,465],{},"en-GB",[170,467,468],{},"de",[170,470,471],{},"fr",[170,473,474],{},"ru","), not options, and\n",[170,477,478],{},"toString"," writes the time zone as its offset, without its name in\nbrackets (",[225,481,483],{"href":482},"\u002Fdocs\u002Fcore\u002Fplugin#time-and-randomness","time",[164,485,486,489],{},[167,487,488],{},"Syntax that does not build:",[490,491,492,505],"table",{},[493,494,495],"thead",{},[496,497,498,502],"tr",{},[499,500,501],"th",{},"Does not build",[499,503,504],{},"Write instead",[506,507,508],"tbody",{},[496,509,510,519],{},[511,512,513,196,516],"td",{},[170,514,515],{},"function*",[170,517,518],{},"yield",[511,520,521,522,525,526],{},"an array, or ",[170,523,524],{},"async"," functions and ",[170,527,528],{},"await",[164,530,531,235,534,251,537,540,541,544,545,206],{},[167,532,533],{},"A class field holding an arrow that returns more than a plain value\nneeds its type:",[170,535,536],{},"onTick = () => { ... }",[170,538,539],{},"double = (n: number) => n * 2","\nbuild; ",[170,542,543],{},"label = () => this.makeLabel()"," needs\n",[170,546,547],{},"label: () => string = () => this.makeLabel()",[153,549,551],{"id":550},"variables-and-optional-values","Variables and optional values",[161,553,554,563,586,624],{},[164,555,556,559,560,206],{},[167,557,558],{},"A method that runs early through a base class"," may read a variable\nbefore its declaration as an empty value, where JavaScript throws a\n",[170,561,562],{},"ReferenceError",[164,564,565,571,572,575,576,579,580,582,583,206],{},[167,566,567,568,455],{},"Inside a closure, a boolean left out is ",[170,569,570],{},"false"," a ",[170,573,574],{},"flag?: boolean","\nparameter, or a variable that holds an optional boolean field, read in an\narrow function made inside the function does not see it was left out -\n",[170,577,578],{},"() => flag ?? true"," is ",[170,581,570],{},". Read it outside: ",[170,584,585],{},"const loud = flag ?? true",[164,587,588,593,594,196,596,251,599,602,603,605,606,609,610,612,613,616,617,619,620,623],{},[167,589,590,592],{},[170,591,398],{}," is known by the type written where it is read:"," an\noptional field or parameter, a variable or a function's result of\n",[170,595,254],{},[170,597,598],{},"find",[170,600,601],{},"map.get"," - and a variable that holds one of\nthem - print as ",[170,604,398],{}," and count as ",[170,607,608],{},"NaN",". An item read by index from\nan array of ",[170,611,254],{}," prints text as ",[170,614,615],{},"null",", and a number counted\nwith stays ",[170,618,398],{},": give it a default with ",[170,621,622],{},"??"," first.",[164,625,626,638,639,642],{},[167,627,628,631,632,634,635,637],{},[170,629,630],{},"x!"," on a ",[170,633,615],{}," throws a ",[170,636,394],{}," right there,"," where TypeScript's\n",[170,640,641],{},"!"," does nothing and JavaScript throws only where the value is used.",[153,644,54],{"id":645},"async-and-promises",[161,647,648,657,683,694],{},[164,649,650,413,653,656],{},[167,651,652],{},"Async generators",[170,654,655],{},"async function*",") do not build.",[164,658,659,667,668,671,672,675,676,678,679,682],{},[167,660,661,251,664,666],{},[170,662,663],{},"Promise.race",[170,665,291],{}," need one type:"," promises of a ",[170,669,670],{},"number"," and a\n",[170,673,674],{},"string",", or a ",[170,677,670],{}," and a ",[170,680,681],{},"sleep",", do not build. Await them one by one.",[164,684,685,691,692,229],{},[167,686,687,690],{},[170,688,689],{},"Promise.all"," of different types takes up to 8 promises;"," promises of\none type, or a list, have no such limit (",[225,693,524],{"href":55},[164,695,696,699],{},[167,697,698],{},"A waiting async function keeps up to 4 KB of its own state;"," one that\nneeds more is stopped, with a message in the console.",[153,701,703],{"id":702},"events-forwards-and-natives","Events, forwards and natives",[161,705,706,732,764,777,793,810,854,867,876,901],{},[164,707,708,711,712,715,716,719,720,723,724,727,728,731],{},[167,709,710],{},"A command's handler is written in the call:"," the object it gets -\n",[170,713,714],{},"player"," and the arguments - is a type the build makes for that call. It\ngoes where the interface of its arguments goes, ",[170,717,718],{},"(args) => kick(args)"," for\n",[170,721,722],{},"kick(args: KickArgs)","; without one it has no name to give a function\nwritten apart: take its parts there, ",[170,725,726],{},"({ player, text }) => say(player, text)",".\nA command's arguments are written in its usage - in place, or after a name\nmade at run time, ",[170,729,730],{},"`${name} [value]`","; a usage held in a variable takes\nnone.",[164,733,734,235,737,740,741,744,745,748,749,752,753,756,757,760,761,206],{},[167,735,736],{},"An event name is written out:",[170,738,739],{},"server.addEventListener(name, ...)","\nor ",[170,742,743],{},"server.addMessageListener(name, ...)"," with the name in a variable does\nnot build - the name picks the event's type. So is a ",[170,746,747],{},"\"playerChange\""," listener's field:\n",[170,750,751],{},"{ field: \"spawnProtected\" }",", not a variable. Without ",[170,754,755],{},"field",", the event's\n",[170,758,759],{},"value"," has no type: read the field from ",[170,762,763],{},"event.player",[164,765,766,769,770,773,774,229],{},[167,767,768],{},"A game listener either always answers or never does."," One that should\nanswer only sometimes returns nothing and calls ",[170,771,772],{},"event.preventDefault()",",\nor always answers, repeating the game's rule for the rest\n(",[225,775,776],{"href":47},"game events",[164,778,779,782,785,786,789,790,229],{},[167,780,781],{},"A vector field of a game event is written whole:",[170,783,784],{},"event.direction = new Vector(x, y, z)","; ",[170,787,788],{},"event.direction.x = 1"," changes a copy\n(",[225,791,776],{"href":792},"\u002Fdocs\u002Fcore\u002Fhooks#limits",[164,794,795,678,798,801,802,805,806,229],{},[167,796,797],{},"A forward from a Pawn plugin reaches TypeScript only when an include\namxts comes with declares it,",[170,799,800],{},"Team"," or a ",[170,803,804],{},"RoundWinner"," argument\nneeds the forward declared in an include\n(",[225,807,809],{"href":808},"\u002Fdocs\u002Fcore\u002Fforwards#argument-types","forwards",[164,811,812,823,824,196,827,196,830,196,833,836,837,841,842,845,846,849,850,853],{},[167,813,814,815,818,819,822],{},"A number in a native's ",[170,816,817],{},"any:..."," tail is a ",[170,820,821],{},"Float:"," only where amxts\nknows the native reads one"," - ",[170,825,826],{},"engfunc",[170,828,829],{},"dllfunc",[170,831,832],{},"ExecuteHam",[170,834,835],{},"pev","\nand the others ",[225,838,840],{"href":839},"\u002Fdocs\u002Fpawn\u002Fnatives#calling-natives-directly","natives"," lists;\nelsewhere it goes as a whole number. Where such a native also writes text,\nread that and convert it: ",[170,843,844],{},"nvault_get(vault, key, text)"," with\n",[170,847,848],{},"const text = new Ref(\"\")",", then ",[170,851,852],{},"Number(text.value)",". The tail takes at\nmost twelve arguments.",[164,855,856,859,860,863,864,866],{},[167,857,858],{},"A plugin's own natives"," are its file's ",[170,861,862],{},"export function","s, with the\nparameter types ",[225,865,840],{"href":131}," lists; another type stops the build.",[164,868,869,872,873,229],{},[167,870,871],{},"A native of your own takes up to 64 arguments"," as Pawn passes them - an\narray or a string result counts twice, with its size; more stops the build:\npass an array instead (",[225,874,840],{"href":875},"\u002Fdocs\u002Fpawn\u002Fnatives#the-rules",[164,877,878,881,882,885,886,196,889,892,893,896,897,900],{},[167,879,880],{},"A buffer's length is never negative:"," a native given a buffer and a\nlength below 0 - the ",[170,883,884],{},"-1"," that ",[170,887,888],{},"ArrayGetArray",[170,890,891],{},"ArrayPushArray"," and other\n",[170,894,895],{},"cellarray"," natives read as \"the whole item\" - is not called and answers\n",[170,898,899],{},"0",". Pass the buffer's own length.",[164,902,903,909,910,413,913,229],{},[167,904,905,908],{},[170,906,907],{},"lang.translate"," takes its arguments as strings:"," a number goes in as\ntext, ",[170,911,912],{},"`${seconds}`",[225,914,916],{"href":915},"\u002Fdocs\u002Fcore\u002Fplugin#translations","translations",[153,918,68],{"id":919},"players-and-entities",[161,921,922,942,953,991,1006,1025],{},[164,923,924,927,928,931,932,934,935,938,939,206],{},[167,925,926],{},"A value no name stands for"," - another plugin or a mod wrote it - reads\nas ",[170,929,930],{},"\"unknown\"",", and assigning ",[170,933,930],{}," changes nothing. Read the number\nwith the native: ",[170,936,937],{},"get_entvar(player.id, var_rendermode)",", or, on a server\nwithout ReAPI, the engine module's ",[170,940,941],{},"entity_get_int(player.id, EV_INT_rendermode)",[164,943,944,235,947,196,950,206],{},[167,945,946],{},"Plain numbers:",[170,948,949],{},"autoSwitchWeapon",[170,951,952],{},"shotgunReloadStage",[164,954,955,958,959,962,963,247,966,196,969,972,973,251,976,979,980,251,983,986,987,229],{},[167,956,957],{},"No property for:"," array members (",[170,960,961],{},"m_rgAmmo",", …; the weapons are\n",[170,964,965],{},"player.items",[170,967,968],{},"var_controller",[170,970,971],{},"var_blending",". Use ",[170,974,975],{},"get_member",[170,977,978],{},"set_member",",\nor fakemeta's ",[170,981,982],{},"get_ent_data",[170,984,985],{},"set_ent_data"," on a server without ReAPI\n(",[225,988,990],{"href":989},"\u002Fdocs\u002Fgame\u002Fentities#fields-that-are-not-properties","entities",[164,992,993,996,196,999,1002,1003,1005],{},[167,994,995],{},"A vector or a text field read through a native needs its type:",[170,997,998],{},"get_entvar\u003CVector>(id, var_origin)",[170,1000,1001],{},"get_member\u003Cstring>(id, m_szAnimExtention)",".\nWithout it the field reads as a number, and a vector or text field reads\nas ",[170,1004,899],{},", with a line in the console that says what to write.",[164,1007,1008,235,1015,251,1018,1021,1022,229],{},[167,1009,1010,1011,1014],{},"A flag list writes back through ",[170,1012,1013],{},"push"," only:",[170,1016,1017],{},"pop",[170,1019,1020],{},"splice"," change\nthe array, not the game. To remove a flag, assign a filtered array\n(",[225,1023,1024],{"href":81},"flags",[164,1026,1027,1030,1031,196,1034,196,1036,1038,1039,1042,1043,1046],{},[167,1028,1029],{},"Shared player fields"," are ",[170,1032,1033],{},"boolean",[170,1035,670],{},[170,1037,674],{},", a union of\nstring literals, ",[170,1040,1041],{},"Player[]"," or an object of those; never optional, and an\nobject's members are not objects. A name ",[170,1044,1045],{},"Player"," already has is refused.",[153,1048,76],{"id":1049},"effects",[161,1051,1052],{},[164,1053,1054,1057,1058,1061,1062,251,1065,1068,1069,229],{},[167,1055,1056],{},"No effect for decals"," (a bullet hole, a spray - they need a decal's\nindex), for the engine's tracer colours or for a text message\n(",[170,1059,1060],{},"player.showHud"," is that); send them with ",[170,1063,1064],{},"message_begin",[170,1066,1067],{},"write_*","\n(",[225,1070,1049],{"href":77},[153,1072,98],{"id":1073},"storage",[161,1075,1076],{},[164,1077,1078,235,1083,1086,1087,1090,1091,229],{},[167,1079,1080,1082],{},[170,1081,98],{}," holds text:",[170,1084,1085],{},"value.toString()"," in, ",[170,1088,1089],{},"parseInt(value)"," out. A\nvalue reads back up to 255 bytes of UTF-8 - about 127 Cyrillic letters\n(",[225,1092,1073],{"href":99},[153,1094,106],{"id":1095},"http",[161,1097,1098,1137,1147,1159,1168],{},[164,1099,1100,235,1103,1106,1107,1110,1111,1114,1115,196,1118,196,1121,1124,1125,1128,1129,845,1132,1068,1135,229],{},[167,1101,1102],{},"A request's body is text:",[170,1104,1105],{},"body"," takes a string - ",[170,1108,1109],{},"JSON.stringify(value)",",\nor an object through ",[170,1112,1113],{},"useFetch","; not a ",[170,1116,1117],{},"FormData",[170,1119,1120],{},"Blob",[170,1122,1123],{},"ArrayBuffer"," or\n",[170,1126,1127],{},"URLSearchParams",". A form goes as text: ",[170,1130,1131],{},"body: query.toString()",[170,1133,1134],{},"\"Content-Type\": \"application\u002Fx-www-form-urlencoded\"",[225,1136,106],{"href":107},[164,1138,1139,1142,1143,1146],{},[167,1140,1141],{},"Headers are given as an object"," of names and values, not as a ",[170,1144,1145],{},"Headers","\nor a list of pairs.",[164,1148,1149,1155,1156,206],{},[167,1150,1151,1154],{},[170,1152,1153],{},"new URLSearchParams"," takes an object,"," not a query as text: read one\nwith ",[170,1157,1158],{},"new URL(address).searchParams",[164,1160,1161,1167],{},[167,1162,288,1163,1166],{},[170,1164,1165],{},"response.body"," stream:"," a response is read whole, so a download or\nan upload has no progress to follow.",[164,1169,1170,235,1179,206],{},[167,1171,1172,1174,1175,1178],{},[170,1173,1113],{},"'s ",[170,1176,1177],{},"query"," takes text:",[170,1180,1181],{},"{ page: `${page}` }",[153,1183,1185],{"id":1184},"ftp-and-sftp","FTP and SFTP",[161,1187,1188],{},[164,1189,1190,235,1193,1196,1197,1200,1201,1204,1205,1068,1208,229],{},[167,1191,1192],{},"An SSH key is RSA in PEM:",[170,1194,1195],{},"ssh-keygen -t rsa -m PEM",". Keys in OpenSSH's\nown format (",[170,1198,1199],{},"BEGIN OPENSSH PRIVATE KEY",", what ",[170,1202,1203],{},"ssh-keygen"," writes by\ndefault), ECDSA and Ed25519 keys are not read, and a server whose only host\nkey is Ed25519 cannot be reached. Convert an RSA key with\n",[170,1206,1207],{},"ssh-keygen -p -m PEM -f key",[225,1209,1211],{"href":1210},"\u002Fdocs\u002Fmodules\u002Fcreating-a-module#network-requests","network requests",[153,1213,1215],{"id":1214},"configs","Configs",[161,1217,1218,1235,1250,1281],{},[164,1219,1220,1223,1224,1227,1228,1230,1231,1234],{},[167,1221,1222],{},"The build reads the shape from the source,"," and refuses, with the place\nand the fix: an empty list without a type, a defaults variable without a\ndeclared type, a list of lists of lists or of objects, a ",[170,1225,1226],{},"Map"," of lists or\nobjects, a union that is not of names (",[170,1229,238],{},"), a generic\ninterface or one that ",[170,1232,1233],{},"extends"," another, a field named with a string, a\ntype that contains itself.",[164,1236,1237,1249],{},[167,1238,1239,1240,1242,1243,1245,1246,455],{},"A ",[170,1241,1226],{},"'s keys have no ",[170,1244,206],{}," and no ",[170,1247,1248],{},"["," such a key cannot be read or\nwritten.",[164,1251,1252,1255,1256,196,1259,1262,1263,1265,1266,1269,1270,305,1273,1276,1277,1280],{},[167,1253,1254],{},"YAML is the part configs use."," Not read: anchors and aliases (",[170,1257,1258],{},"&",[170,1260,1261],{},"*","),\ntags (",[170,1264,641],{},"), complex keys (",[170,1267,1268],{},"?","), directives, several documents, a plain value\nthat goes on for several lines (quote it, or use ",[170,1271,1272],{},"|",[170,1274,1275],{},">","), tabs in\nindentation, a key written twice, a key inside ",[170,1278,1279],{},"[ ]",". Each is an error with\nthe file, line and column, and the file reads as empty.",[164,1282,1283,1286,1287,1290,1291,251,1294,1296],{},[167,1284,1285],{},"Saving"," writes a YAML list written ",[170,1288,1289],{},"[a, b]"," one item per line, and drops\na comment after a value on its line and comments inside ",[170,1292,1293],{},"{ }",[170,1295,1279],{},".\nComments on lines of their own and blank lines are kept.",[153,1298,116],{"id":1299},"shared-modules",[146,1301,1302,1303,206],{},"The details are on ",[225,1304,1305],{"href":117},"shared modules",[161,1307,1308,1335],{},[164,1309,1310,571,1313,1315,1316,1319,1320,1323,1324,1326,1327,1330,1331,1334],{},[167,1311,1312],{},"What cannot cross between plugins does not build:",[170,1314,1226],{},", a ",[170,1317,1318],{},"Set",", a\n",[170,1321,1322],{},"Record"," with keys of any string, a generic class, a class from the standard library, a type the module does\nnot export, a computed default, a generic or ",[170,1325,524],{}," function, a rest\nparameter, an exported variable (",[170,1328,1329],{},"export let count",") - an object of a\nclass of the module's own (",[170,1332,1333],{},"export const counter = new Counter()",") does\ncross.",[164,1336,1337,235,1340,1342],{},[167,1338,1339],{},"An array or object field of a shared object reads as a copy:",[170,1341,1013],{}," on\nit changes the copy. Use the module's method, or assign the whole field.",[153,1344,1346,1347,1350],{"id":1345},"modules-and-the-amxts-command","Modules and the ",[170,1348,1349],{},"amxts"," command",[161,1352,1353,1371,1399,1411],{},[164,1354,1355,1358,1359,1362,1363,1366,1367,1370],{},[167,1356,1357],{},"A module gives one name",": itself as a namespace (",[170,1360,1361],{},"imports: [{ from, as }]",")\nor one of its exports (",[170,1364,1365],{},"imports: [{ from, name }]",") - not a list of its\nfunctions or types; ",[170,1368,1369],{},"menus.Menu"," is a type of the namespace.",[164,1372,1373,1389,1390,196,1393,1396,1397,206],{},[167,1374,1375,1376,196,1379,196,1382,251,1385,1388],{},"A module's ",[170,1377,1378],{},"meta",[170,1380,1381],{},"requires",[170,1383,1384],{},"defaults",[170,1386,1387],{},"imports"," are literals:"," the build\nreads them without running the module. Besides ",[170,1391,1392],{},"setup",[170,1394,1395],{},"defineModule"," has\nno lifecycle hooks: listen to server events inside ",[170,1398,1392],{},[164,1400,1401,1406,1407,1410],{},[167,1402,1403,1404,364],{},"Tests run with ",[170,1405,219],{}," which is ",[170,1408,1409],{},"bun test","; other test runners\nare not supported.",[164,1412,1413,1416,1417,1420,1421,206],{},[167,1414,1415],{},"A native the fake server does not answer stops the test"," with its name;\nanswer it with ",[170,1418,1419],{},"server.defineNative(name, native)"," in the test, or in a\nmodule's ",[225,1422,1424],{"href":1423},"\u002Fdocs\u002Ftesting#a-modules-test-kit","test kit",[153,1426,1428],{"id":1427},"the-editor","The editor",[161,1430,1431,1441,1454],{},[164,1432,1433,1440],{},[167,1434,1435,1436,1439],{},"The build and ",[170,1437,1438],{},"amxts typecheck"," use TypeScript 5,"," the one the core\ninstalls; the editor works with TypeScript 5.9, 6 and 7.",[164,1442,1443,1446,1447,1449,1450,1453],{},[167,1444,1445],{},"A field the editor accepts may be missing in the build:"," the editor\nsees the fields every file of the plugins folder adds to ",[170,1448,1045],{},", the\nbuild only those of the files the plugin imports. Add the ",[170,1451,1452],{},"import"," of the\nfile that declares it.",[164,1455,1456,1459,1460,229],{},[167,1457,1458],{},"Live help in menu files is for VS Code only,"," through the amxts\nextension (",[225,1461,1463],{"href":1462},"\u002Fmodules\u002Fmenu-core#editor-support","menus",[153,1465,1467],{"id":1466},"the-server","The server",[161,1469,1470],{},[164,1471,1472,1478,1479,1482,1483,229],{},[167,1473,1239,1474,1477],{},[170,1475,1476],{},".ts"," the server compiles holds the server"," for the second or two the\ncompile takes: in the middle of a round the game freezes. On a server\npeople play on, deploy ",[170,1480,1481],{},".aot"," files built in a project\n(",[225,1484,1486],{"href":1485},"\u002Fdocs\u002Fgetting-started\u002Finstall#written-on-the-server","installing on a server",{"title":1488,"searchDepth":1489,"depth":1490,"links":1491},"",2,3,[1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1505,1506],{"id":155,"depth":1489,"text":156},{"id":550,"depth":1489,"text":551},{"id":645,"depth":1489,"text":54},{"id":702,"depth":1489,"text":703},{"id":919,"depth":1489,"text":68},{"id":1049,"depth":1489,"text":76},{"id":1073,"depth":1489,"text":98},{"id":1095,"depth":1489,"text":106},{"id":1184,"depth":1489,"text":1185},{"id":1214,"depth":1489,"text":1215},{"id":1299,"depth":1489,"text":116},{"id":1345,"depth":1489,"text":1504},"Modules and the amxts command",{"id":1427,"depth":1489,"text":1428},{"id":1466,"depth":1489,"text":1467},"md",{},true,{"title":31,"description":148},"7b0i6mc6ithES5JEO66x7JGmU8ew3QDNnxzXlcU3MOM",[1513,1515],{"title":27,"path":28,"stem":29,"description":1514,"children":-1},"ghcr.io\u002Famxts\u002Fserver is a Docker image of a Linux Counter-Strike 1.6\nserver that runs amxts: HLDS with ReHLDS, ReGameDLL, Metamod-R, AMX Mod X 1.10\nand ReAPI, the amxts module and its compiler. Your project is mounted into\nit, and the server runs your plugins with your configs and files - on\nWindows, macOS or Linux, with nothing to install but Docker.",{"title":42,"path":43,"stem":44,"description":1516,"children":-1},"A plugin is one .ts file in the project's plugins folder. It does its work\nat the top level of the file: it names itself, adds commands and listens to\nevents. What it uses from the core - plugin, server, Player, print -\nneeds no import line (auto-imports).",null,1791273256351]