{
  "version": "1.0",
  "language": "Quick code",
  "keywords": [
    "if",
    "then",
    "elseif",
    "else",
    "end",
    "and",
    "or",
    "not",
    "true",
    "false",
    "nil",
    "null",
    "local",
    "in",
    "while",
    "do",
    "for",
    "repeat",
    "until",
    "break",
    "continue",
    "self",
    "player",
    "other",
    "function",
    "return"
  ],
  "groups": [
    {
      "title": "Messages & screen",
      "kind": "game",
      "items": [
        {
          "name": "popup",
          "signature": "popup(text)",
          "help": "popup(text) → a short message on screen",
          "returns": "a short message on screen"
        },
        {
          "name": "banner",
          "signature": "banner(text)",
          "help": "banner(text) → a big announcement in the middle of the screen (\"Boss fight!\"); {names} show values",
          "returns": "a big announcement in the middle of the screen (\"Boss fight!\"); {names} show values"
        },
        {
          "name": "hud_text",
          "signature": "hud_text(name, text, corner = \"top_right\")",
          "help": "hud_text(name, text, corner = \"top_right\") → text on screen that updates itself: \"Score: {score}\" ({name} = a variable, counter, item or timer)",
          "returns": "text on screen that updates itself: \"Score: {score}\" ({name} = a variable, counter, item or timer)"
        },
        {
          "name": "hud_clear",
          "signature": "hud_clear(name)",
          "help": "hud_clear(name) → removes an on-screen text",
          "returns": "removes an on-screen text"
        },
        {
          "name": "hud_bar",
          "signature": "hud_bar(name, value, max, corner = \"top_left\", color = \"hp\")",
          "help": "hud_bar(name, value, max, corner = \"top_left\", color = \"hp\") → a bar on screen (health, boss, progress); hud_clear(name) hides it",
          "returns": "a bar on screen (health, boss, progress); hud_clear(name) hides it"
        },
        {
          "name": "show_hud",
          "signature": "show_hud(name)",
          "help": "show_hud(name) → shows one of your HUDs (HUDs panel), e.g. show_hud(\"Boss bar\")",
          "returns": "shows one of your HUDs (HUDs panel), e.g. show_hud(\"Boss bar\")"
        },
        {
          "name": "hide_hud",
          "signature": "hide_hud(name)",
          "help": "hide_hud(name) → hides a HUD",
          "returns": "hides a HUD"
        },
        {
          "name": "toggle_hud",
          "signature": "toggle_hud(name)",
          "help": "toggle_hud(name) → shows a hidden HUD, hides a shown one",
          "returns": "shows a hidden HUD, hides a shown one"
        },
        {
          "name": "hud_shown",
          "signature": "hud_shown(name)",
          "help": "hud_shown(name) → true while that HUD is showing",
          "returns": "true while that HUD is showing"
        },
        {
          "name": "choice",
          "signature": "choice(question, options)",
          "help": "choice(question, options) → shows the choices and waits; gives the one picked (its text)",
          "returns": "shows the choices and waits; gives the one picked (its text)"
        },
        {
          "name": "screen_effect",
          "signature": "screen_effect(\"flash\", seconds = 0.5, strength = 1, color = \"white\")",
          "help": "screen_effect(\"flash\", seconds = 0.5, strength = 1, color = \"white\") → flash / blur / split / black_white / wobble for a moment",
          "returns": "flash / blur / split / black_white / wobble for a moment"
        },
        {
          "name": "shake",
          "signature": "shake(strength = 0.15, seconds = 0.4)",
          "help": "shake(strength = 0.15, seconds = 0.4) → shakes the screen",
          "returns": "shakes the screen"
        },
        {
          "name": "camera_look",
          "signature": "camera_look(object, seconds = 2)",
          "help": "camera_look(object, seconds = 2) → the camera looks at an object (or player) for a while",
          "returns": "the camera looks at an object (or player) for a while"
        },
        {
          "name": "print",
          "signature": "print(text)",
          "help": "print(text) → prints to the editor's Output (Play mode)",
          "returns": "prints to the editor's Output (Play mode)"
        }
      ]
    },
    {
      "title": "Waiting & timing",
      "kind": "game",
      "items": [
        {
          "name": "wait",
          "signature": "wait(seconds)",
          "help": "wait(seconds) → pause this code (the game keeps going)",
          "returns": "pause this code (the game keeps going)"
        },
        {
          "name": "dt",
          "signature": "dt()",
          "help": "dt() → seconds since the last frame: x += speed * dt() moves at the same speed on every computer",
          "returns": "seconds since the last frame: x += speed * dt() moves at the same speed on every computer"
        },
        {
          "name": "time",
          "signature": "time()",
          "help": "time() → seconds since the level started (game time; it stops while the game is paused)",
          "returns": "seconds since the level started (game time; it stops while the game is paused)"
        },
        {
          "name": "frame",
          "signature": "frame()",
          "help": "frame() → how many frames since the level started",
          "returns": "how many frames since the level started"
        },
        {
          "name": "hour",
          "signature": "hour()",
          "help": "hour() → the time of day, 0 to 24 (with a day & night cycle)",
          "returns": "the time of day, 0 to 24 (with a day & night cycle)"
        },
        {
          "name": "set_hour",
          "signature": "set_hour(h)",
          "help": "set_hour(h) → jump to that time of day (e.g. 20.5 = half past eight in the evening)",
          "returns": "jump to that time of day (e.g. 20.5 = half past eight in the evening)"
        },
        {
          "name": "is_night",
          "signature": "is_night()",
          "help": "is_night() → true after dusk and before dawn",
          "returns": "true after dusk and before dawn"
        },
        {
          "name": "day",
          "signature": "day()",
          "help": "day() → which day it is (1 at the start; +1 each midnight)",
          "returns": "which day it is (1 at the start; +1 each midnight)"
        },
        {
          "name": "start_timer",
          "signature": "start_timer(name, seconds, when_done = \"nothing\", show = true)",
          "help": "start_timer(name, seconds, when_done = \"nothing\", show = true) → a countdown (show = false keeps it off screen, for your own HUD); when_done: \"lose\", \"win\"",
          "returns": "a countdown (show = false keeps it off screen, for your own HUD); when_done: \"lose\", \"win\""
        },
        {
          "name": "stop_timer",
          "signature": "stop_timer(name)",
          "help": "stop_timer(name)",
          "returns": ""
        },
        {
          "name": "time_left",
          "signature": "time_left(timer)",
          "help": "time_left(timer) → seconds left on a timer (0 = not running)",
          "returns": "seconds left on a timer (0 = not running)"
        }
      ]
    },
    {
      "title": "Running code at the same time",
      "kind": "game",
      "items": [
        {
          "name": "run_async",
          "signature": "run_async(fn, …)",
          "help": "run_async(fn, …) → runs a function alongside this code (both carry on); gives a task",
          "returns": "runs a function alongside this code (both carry on); gives a task"
        },
        {
          "name": "every",
          "signature": "every(seconds, fn)",
          "help": "every(seconds, fn) → calls fn every few seconds until cancelled; gives a task",
          "returns": "calls fn every few seconds until cancelled; gives a task"
        },
        {
          "name": "after",
          "signature": "after(seconds, fn)",
          "help": "after(seconds, fn) → calls fn once, later; gives a task",
          "returns": "calls fn once, later; gives a task"
        },
        {
          "name": "cancel",
          "signature": "cancel(task)",
          "help": "cancel(task) → stops a task from run_async, every or after",
          "returns": "stops a task from run_async, every or after"
        },
        {
          "name": "task_running",
          "signature": "task_running(task)",
          "help": "task_running(task) → true while that task hasn't finished or been cancelled",
          "returns": "true while that task hasn't finished or been cancelled"
        }
      ]
    },
    {
      "title": "Messages & events",
      "kind": "game",
      "items": [
        {
          "name": "send",
          "signature": "send(message, data = nil)",
          "help": "send(message, data = nil) → every on_message(message, …) handler and \"Message received\" event runs (data goes along)",
          "returns": "every on_message(message, …) handler and \"Message received\" event runs (data goes along)"
        },
        {
          "name": "on_message",
          "signature": "on_message(message, fn)",
          "help": "on_message(message, fn) → calls fn(data) whenever send(message, data) happens",
          "returns": "calls fn(data) whenever send(message, data) happens"
        },
        {
          "name": "on",
          "signature": "on(event, fn)",
          "help": "on(event, fn) → calls fn when this object's event happens: \"touched\", \"bumped\", \"used\", \"destroyed\", \"hurt\"",
          "returns": "calls fn when this object's event happens: \"touched\", \"bumped\", \"used\", \"destroyed\", \"hurt\""
        },
        {
          "name": "event_data",
          "signature": "event_data()",
          "help": "event_data() → what came with the event or run_script(id, data) that started this script",
          "returns": "what came with the event or run_script(id, data) that started this script"
        },
        {
          "name": "run_script",
          "signature": "run_script(id, data = nil)",
          "help": "run_script(id, data = nil) → runs that script's \"Called\" events; their code reads data with event_data()",
          "returns": "runs that script's \"Called\" events; their code reads data with event_data()"
        },
        {
          "name": "player_event",
          "signature": "player_event(name)",
          "help": "player_event(name) → runs your own player event (Player controls: an Event set to \"My own player event\")",
          "returns": "runs your own player event (Player controls: an Event set to \"My own player event\")"
        }
      ]
    },
    {
      "title": "Items & money",
      "kind": "game",
      "items": [
        {
          "name": "has",
          "signature": "has(item)",
          "help": "has(item) → how many the player has (\"* key\" = any key)",
          "returns": "how many the player has (\"* key\" = any key)"
        },
        {
          "name": "give",
          "signature": "give(item, count = 1)",
          "help": "give(item, count = 1)",
          "returns": ""
        },
        {
          "name": "take",
          "signature": "take(item, count = 1)",
          "help": "take(item, count = 1)",
          "returns": ""
        },
        {
          "name": "use_item",
          "signature": "use_item(item)",
          "help": "use_item(item) → uses an item (potion…) like the inventory does",
          "returns": "uses an item (potion…) like the inventory does"
        },
        {
          "name": "equipped",
          "signature": "equipped(slot)",
          "help": "equipped(slot) → the item equipped as \"weapon\" or \"armor\" (\"\" if none)",
          "returns": "the item equipped as \"weapon\" or \"armor\" (\"\" if none)"
        },
        {
          "name": "money_count",
          "signature": "money_count()",
          "help": "money_count() → how much money the player has",
          "returns": "how much money the player has"
        },
        {
          "name": "held",
          "signature": "held()",
          "help": "held() → the item in the player's hand (the selected skillbar slot; \"\" if empty)",
          "returns": "the item in the player's hand (the selected skillbar slot; \"\" if empty)"
        },
        {
          "name": "select_slot",
          "signature": "select_slot(n)",
          "help": "select_slot(n) → picks skillbar slot n (1–8), like pressing that key",
          "returns": "picks skillbar slot n (1–8), like pressing that key"
        },
        {
          "name": "put_on_bar",
          "signature": "put_on_bar(item, n)",
          "help": "put_on_bar(item, n) → puts an item the player has in skillbar slot n",
          "returns": "puts an item the player has in skillbar slot n"
        }
      ]
    },
    {
      "title": "Switches, counters & quests",
      "kind": "game",
      "items": [
        {
          "name": "switch_on",
          "signature": "switch_on(name)",
          "help": "switch_on(name) → true / false",
          "returns": "true / false"
        },
        {
          "name": "set_switch",
          "signature": "set_switch(name, on = true)",
          "help": "set_switch(name, on = true)",
          "returns": ""
        },
        {
          "name": "counter",
          "signature": "counter(name)",
          "help": "counter(name) → number",
          "returns": "number"
        },
        {
          "name": "add",
          "signature": "add(counter, amount = 1)",
          "help": "add(counter, amount = 1)",
          "returns": ""
        },
        {
          "name": "start_quest",
          "signature": "start_quest(id, goal text)",
          "help": "start_quest(id, goal text)",
          "returns": ""
        },
        {
          "name": "complete_quest",
          "signature": "complete_quest(id)",
          "help": "complete_quest(id)",
          "returns": ""
        },
        {
          "name": "quest_active",
          "signature": "quest_active(id)",
          "help": "quest_active(id) → true / false",
          "returns": "true / false"
        },
        {
          "name": "quest_done",
          "signature": "quest_done(id)",
          "help": "quest_done(id) → true / false",
          "returns": "true / false"
        },
        {
          "name": "objective",
          "signature": "objective()",
          "help": "objective() → the current objective's text (this level's Goal, or the game's list)",
          "returns": "the current objective's text (this level's Goal, or the game's list)"
        },
        {
          "name": "objective_done",
          "signature": "objective_done(text = \"\")",
          "help": "objective_done(text = \"\") → finishes the current objective (only if its text matches, when given)",
          "returns": "finishes the current objective (only if its text matches, when given)"
        }
      ]
    },
    {
      "title": "Levels & worlds",
      "kind": "game",
      "items": [
        {
          "name": "level_complete",
          "signature": "level_complete(name = \"\")",
          "help": "level_complete(name = \"\") → true once that level's Goal is done (\"\" = this level): level_complete(\"Cave\")",
          "returns": "true once that level's Goal is done (\"\" = this level): level_complete(\"Cave\")"
        },
        {
          "name": "world_complete",
          "signature": "world_complete(name = \"\")",
          "help": "world_complete(name = \"\") → true once that world (a group of levels) is complete (\"\" = this world): world_complete(\"Grass Land\")",
          "returns": "true once that world (a group of levels) is complete (\"\" = this world): world_complete(\"Grass Land\")"
        },
        {
          "name": "completed_level",
          "signature": "completed_level()",
          "help": "completed_level() → the name of the level whose goal was done last (\"\" = none yet); for the event \"A level's goal is complete\"",
          "returns": "the name of the level whose goal was done last (\"\" = none yet); for the event \"A level's goal is complete\""
        },
        {
          "name": "completed_world",
          "signature": "completed_world()",
          "help": "completed_world() → the name of the world completed last (\"\" = none yet); for the event \"A world is complete\"",
          "returns": "the name of the world completed last (\"\" = none yet); for the event \"A world is complete\""
        },
        {
          "name": "in_zone",
          "signature": "in_zone(name)",
          "help": "in_zone(name) → true while the player is in that zone (Level view ▸ Zone tool): in_zone(\"Forest\")",
          "returns": "true while the player is in that zone (Level view ▸ Zone tool): in_zone(\"Forest\")"
        },
        {
          "name": "win",
          "signature": "win()",
          "help": "win() → the player wins",
          "returns": "the player wins"
        },
        {
          "name": "lose",
          "signature": "lose()",
          "help": "lose() → the player loses (the lose screen)",
          "returns": "the player loses (the lose screen)"
        },
        {
          "name": "lives_left",
          "signature": "lives_left()",
          "help": "lives_left() → lives left (-1 = unlimited)",
          "returns": "lives left (-1 = unlimited)"
        },
        {
          "name": "best_score",
          "signature": "best_score()",
          "help": "best_score() → the best score so far (Game Settings ▸ Lives & score)",
          "returns": "the best score so far (Game Settings ▸ Lives & score)"
        },
        {
          "name": "save_game",
          "signature": "save_game()",
          "help": "save_game() → saves the game (the autosave slot; Continue loads it)",
          "returns": "saves the game (the autosave slot; Continue loads it)"
        },
        {
          "name": "checkpoint",
          "signature": "checkpoint()",
          "help": "checkpoint() → the player comes back here after falling or being defeated",
          "returns": "the player comes back here after falling or being defeated"
        }
      ]
    },
    {
      "title": "Objects & finding things",
      "kind": "game",
      "items": [
        {
          "name": "object",
          "signature": "object(name)",
          "help": "object(name) → the object with that Script name in this level",
          "returns": "the object with that Script name in this level"
        },
        {
          "name": "objects",
          "signature": "objects(tag)",
          "help": "objects(tag) → every object whose model has that tag (a list)",
          "returns": "every object whose model has that tag (a list)"
        },
        {
          "name": "spawn",
          "signature": "spawn(what, x, level, z, count = 1)",
          "help": "spawn(what, x, level, z, count = 1) → a new copy of a prefab or model (by name); no position = next to this object. Gives the new object",
          "returns": "a new copy of a prefab or model (by name); no position = next to this object. Gives the new object"
        },
        {
          "name": "remove_self",
          "signature": "remove_self()",
          "help": "remove_self() → removes the object this script is on",
          "returns": "removes the object this script is on"
        },
        {
          "name": "nearest",
          "signature": "nearest(tag, from = self)",
          "help": "nearest(tag, from = self) → the closest object with that tag (\"any\" = any object), or nil",
          "returns": "the closest object with that tag (\"any\" = any object), or nil"
        },
        {
          "name": "objects_near",
          "signature": "objects_near(where, radius, tag = \"any\")",
          "help": "objects_near(where, radius, tag = \"any\") → the objects within radius tiles of a position or object, nearest first",
          "returns": "the objects within radius tiles of a position or object, nearest first"
        },
        {
          "name": "line_of_sight",
          "signature": "line_of_sight(a, b)",
          "help": "line_of_sight(a, b) → true if nothing solid is between two objects or positions",
          "returns": "true if nothing solid is between two objects or positions"
        },
        {
          "name": "raycast",
          "signature": "raycast(from, direction, distance = 20)",
          "help": "raycast(from, direction, distance = 20) → what a line hits first: {object =, position =, tile =}, or nil",
          "returns": "what a line hits first: {object =, position =, tile =}, or nil"
        },
        {
          "name": "tile_at",
          "signature": "tile_at(x, level, z)",
          "help": "tile_at(x, level, z) → the model name of the ground tile there (\"\" if empty)",
          "returns": "the model name of the ground tile there (\"\" if empty)"
        },
        {
          "name": "set_tile",
          "signature": "set_tile(x, level, z, model)",
          "help": "set_tile(x, level, z, model) → puts a ground tile there (by model name)",
          "returns": "puts a ground tile there (by model name)"
        },
        {
          "name": "clear_tile",
          "signature": "clear_tile(x, level, z)",
          "help": "clear_tile(x, level, z) → removes the ground tile there",
          "returns": "removes the ground tile there"
        },
        {
          "name": "path_to",
          "signature": "path_to(from, to)",
          "help": "path_to(from, to) → a walkable path as a list of tile vectors (empty if there's no way)",
          "returns": "a walkable path as a list of tile vectors (empty if there's no way)"
        }
      ]
    },
    {
      "title": "The player",
      "kind": "game",
      "items": [
        {
          "name": "hp",
          "signature": "hp()",
          "help": "hp() → the player's health",
          "returns": "the player's health"
        },
        {
          "name": "heal",
          "signature": "heal(hp)",
          "help": "heal(hp)",
          "returns": ""
        },
        {
          "name": "hurt",
          "signature": "hurt(hp)",
          "help": "hurt(hp)",
          "returns": ""
        },
        {
          "name": "launch",
          "signature": "launch(direction = \"forward\", speed = 12)",
          "help": "launch(direction = \"forward\", speed = 12) → pushes the player: \"forward\" (a dash), \"up\", \"up_forward\", \"back\", \"left\", \"right\"",
          "returns": "pushes the player: \"forward\" (a dash), \"up\", \"up_forward\", \"back\", \"left\", \"right\""
        },
        {
          "name": "player_move",
          "signature": "player_move(what, value, how = \"set\")",
          "help": "player_move(what, value, how = \"set\") → walk_speed, run_speed, jump_height or gravity; how: \"set\", \"add\", \"times\", \"reset\"",
          "returns": "walk_speed, run_speed, jump_height or gravity; how: \"set\", \"add\", \"times\", \"reset\""
        },
        {
          "name": "allow",
          "signature": "allow(move, on = true)",
          "help": "allow(move, on = true) → lets the player jump, run, attack, climb or swim (false stops it)",
          "returns": "lets the player jump, run, attack, climb or swim (false stops it)"
        },
        {
          "name": "freeze",
          "signature": "freeze(on = true)",
          "help": "freeze(on = true) → stops the player's controls (a cutscene); freeze(false) gives them back",
          "returns": "stops the player's controls (a cutscene); freeze(false) gives them back"
        },
        {
          "name": "player_model",
          "signature": "player_model(name)",
          "help": "player_model(name) → the player wears another model (\"\" = the usual one)",
          "returns": "the player wears another model (\"\" = the usual one)"
        },
        {
          "name": "player_state",
          "signature": "player_state()",
          "help": "player_state() → what the player is doing: idle, walk, run, jump, fall, climb, swim",
          "returns": "what the player is doing: idle, walk, run, jump, fall, climb, swim"
        }
      ]
    },
    {
      "title": "Input",
      "kind": "game",
      "items": [
        {
          "name": "key_down",
          "signature": "key_down(key)",
          "help": "key_down(key) → true while that key (or mouse button) is held: key_down(\"Q\"), key_down(\"Space\"), key_down(\"Mouse Right\") (key_pressed: once per press)",
          "returns": "true while that key (or mouse button) is held: key_down(\"Q\"), key_down(\"Space\"), key_down(\"Mouse Right\") (key_pressed: once per press)"
        },
        {
          "name": "key_pressed",
          "signature": "key_pressed(key)",
          "help": "key_pressed(key) → true once when that key goes down, then false until it's let go and pressed again: in a loop, if key_pressed(\"E\") then … end runs once per press",
          "returns": "true once when that key goes down, then false until it's let go and pressed again: in a loop, if key_pressed(\"E\") then … end runs once per press"
        },
        {
          "name": "key_released",
          "signature": "key_released(key)",
          "help": "key_released(key) → true once when that key is let go",
          "returns": "true once when that key is let go"
        },
        {
          "name": "mouse_x",
          "signature": "mouse_x()",
          "help": "mouse_x() → the mouse's x on the screen (pixels from the left)",
          "returns": "the mouse's x on the screen (pixels from the left)"
        },
        {
          "name": "mouse_y",
          "signature": "mouse_y()",
          "help": "mouse_y() → the mouse's y on the screen (pixels from the top)",
          "returns": "the mouse's y on the screen (pixels from the top)"
        },
        {
          "name": "mouse_tile",
          "signature": "mouse_tile()",
          "help": "mouse_tile() → the tile under the mouse as a vector (x, level, z), or nil over the sky",
          "returns": "the tile under the mouse as a vector (x, level, z), or nil over the sky"
        },
        {
          "name": "pad_down",
          "signature": "pad_down(button)",
          "help": "pad_down(button) → true while a gamepad button is held: \"A\", \"B\", \"X\", \"Y\", \"LB\", \"RB\", \"Start\", \"Up\"…",
          "returns": "true while a gamepad button is held: \"A\", \"B\", \"X\", \"Y\", \"LB\", \"RB\", \"Start\", \"Up\"…"
        },
        {
          "name": "pad_pressed",
          "signature": "pad_pressed(button)",
          "help": "pad_pressed(button) → true once when a gamepad button goes down",
          "returns": "true once when a gamepad button goes down"
        },
        {
          "name": "pad_axis",
          "signature": "pad_axis(stick)",
          "help": "pad_axis(stick) → -1…1: \"left_x\", \"left_y\", \"right_x\", \"right_y\", \"lt\", \"rt\"",
          "returns": "-1…1: \"left_x\", \"left_y\", \"right_x\", \"right_y\", \"lt\", \"rt\""
        },
        {
          "name": "action_down",
          "signature": "action_down(action)",
          "help": "action_down(action) → true while a control is held, whatever key the player set for it: \"jump\", \"interact\", \"attack\", \"run\", \"forward\", \"back\", \"left\", \"right\"",
          "returns": "true while a control is held, whatever key the player set for it: \"jump\", \"interact\", \"attack\", \"run\", \"forward\", \"back\", \"left\", \"right\""
        },
        {
          "name": "action_pressed",
          "signature": "action_pressed(action)",
          "help": "action_pressed(action) → true once when that control is pressed",
          "returns": "true once when that control is pressed"
        }
      ]
    },
    {
      "title": "Sound & effects",
      "kind": "game",
      "items": [
        {
          "name": "play",
          "signature": "play(sound, volume = 1)",
          "help": "play(sound, volume = 1) → a sound (built-in name like \"door\", or your sound's name or id)",
          "returns": "a sound (built-in name like \"door\", or your sound's name or id)"
        },
        {
          "name": "play_at",
          "signature": "play_at(sound, where, volume = 1)",
          "help": "play_at(sound, where, volume = 1) → a sound at an object or position (quieter far away)",
          "returns": "a sound at an object or position (quieter far away)"
        },
        {
          "name": "stop_sound",
          "signature": "stop_sound(sound = \"\")",
          "help": "stop_sound(sound = \"\") → stops that sound, or every sound playing",
          "returns": "stops that sound, or every sound playing"
        },
        {
          "name": "volume",
          "signature": "volume(kind, level)",
          "help": "volume(kind, level) → \"music\", \"sound\" or \"all\" at 0…1",
          "returns": "\"music\", \"sound\" or \"all\" at 0…1"
        },
        {
          "name": "music",
          "signature": "music(id)",
          "help": "music(id) → change the music (\"\" = the level's)",
          "returns": "change the music (\"\" = the level's)"
        },
        {
          "name": "music_fade",
          "signature": "music_fade(id, seconds = 2)",
          "help": "music_fade(id, seconds = 2) → fades into other music (\"\" = the level's)",
          "returns": "fades into other music (\"\" = the level's)"
        },
        {
          "name": "particles",
          "signature": "particles(effect, size = 1)",
          "help": "particles(effect, size = 1) → plays a particle effect once here (built-in name like \"explosion\", or your effect's name)",
          "returns": "plays a particle effect once here (built-in name like \"explosion\", or your effect's name)"
        }
      ]
    },
    {
      "title": "Chance",
      "kind": "game",
      "items": [
        {
          "name": "chance",
          "signature": "chance(percent)",
          "help": "chance(percent) → true that often",
          "returns": "true that often"
        },
        {
          "name": "rand",
          "signature": "rand(low, high)",
          "help": "rand(low, high) → a whole number between them",
          "returns": "a whole number between them"
        }
      ]
    },
    {
      "title": "Data & debugging",
      "kind": "game",
      "items": [
        {
          "name": "data",
          "signature": "data(name)",
          "help": "data(name) → a Data table (Data tab) as a table of rows: data(\"Enemies\")[\"Goblin\"].hp",
          "returns": "a Data table (Data tab) as a table of rows: data(\"Enemies\")[\"Goblin\"].hp"
        },
        {
          "name": "watch",
          "signature": "watch(name, value)",
          "help": "watch(name, value) → shows a value live in the debug overlay (F3) and the editor's Watch list while playing",
          "returns": "shows a value live in the debug overlay (F3) and the editor's Watch list while playing"
        }
      ]
    },
    {
      "title": "Object commands",
      "kind": "object",
      "items": [
        {
          "name": "move",
          "signature": "obj.move(dx, dy, dz, seconds = 1, wait = true, ease = \"smooth\")",
          "help": "move(dx, dy, dz, seconds = 1, wait = true, ease = \"smooth\") → glide by tiles (x, levels, z); ease: smooth, linear, in, out, bounce, elastic, back",
          "returns": "glide by tiles (x, levels, z); ease: smooth, linear, in, out, bounce, elastic, back"
        },
        {
          "name": "move_to",
          "signature": "obj.move_to(x, y, z, seconds = 1, wait = true)",
          "help": "move_to(x, y, z, seconds = 1, wait = true) → glide to a tile (x, level, z)",
          "returns": "glide to a tile (x, level, z)"
        },
        {
          "name": "go_home",
          "signature": "obj.go_home(seconds = 1, wait = true)",
          "help": "go_home(seconds = 1, wait = true) → glide back to where it was placed",
          "returns": "glide back to where it was placed"
        },
        {
          "name": "turn",
          "signature": "obj.turn(degrees, seconds = 0.5, wait = true)",
          "help": "turn(degrees, seconds = 0.5, wait = true) → turn around (+ = left)",
          "returns": "turn around (+ = left)"
        },
        {
          "name": "particles",
          "signature": "obj.particles(effect, size = 1)",
          "help": "particles(effect, size = 1) → plays a particle effect once on it",
          "returns": "plays a particle effect once on it"
        },
        {
          "name": "play",
          "signature": "obj.play(animation, keep = false)",
          "help": "play(animation, keep = false) → plays a part animation (attack, wave…) once, or keeps playing it",
          "returns": "plays a part animation (attack, wave…) once, or keeps playing it"
        },
        {
          "name": "hide",
          "signature": "obj.hide()",
          "help": "hide() → invisible and walk-through",
          "returns": "invisible and walk-through"
        },
        {
          "name": "show",
          "signature": "obj.show()",
          "help": "show() → back again",
          "returns": "back again"
        },
        {
          "name": "show_hud",
          "signature": "obj.show_hud()",
          "help": "show_hud() → shows its Attached HUD (nameplate, health bar…)",
          "returns": "shows its Attached HUD (nameplate, health bar…)"
        },
        {
          "name": "hide_hud",
          "signature": "obj.hide_hud()",
          "help": "hide_hud() → hides its Attached HUD",
          "returns": "hides its Attached HUD"
        },
        {
          "name": "remove",
          "signature": "obj.remove()",
          "help": "remove() → gone for the rest of the game",
          "returns": "gone for the rest of the game"
        },
        {
          "name": "distance",
          "signature": "obj.distance(other)",
          "help": "distance(other) → tiles between them (other: an object or player)",
          "returns": "tiles between them (other: an object or player)"
        },
        {
          "name": "touching",
          "signature": "obj.touching(what)",
          "help": "touching(what) → true if touching it: an object, player, or a tag like \"enemy\"",
          "returns": "true if touching it: an object, player, or a tag like \"enemy\""
        },
        {
          "name": "can_move",
          "signature": "obj.can_move(dx, dy, dz)",
          "help": "can_move(dx, dy, dz) → true if that move wouldn't run into anything solid",
          "returns": "true if that move wouldn't run into anything solid"
        },
        {
          "name": "attach",
          "signature": "obj.attach(model, point = \"Right hand\")",
          "help": "attach(model, point = \"Right hand\") → shows a model (by name) on an attachment point: player.attach(\"Sword\"), self.attach(\"Party hat\", \"Head\")",
          "returns": "shows a model (by name) on an attachment point: player.attach(\"Sword\"), self.attach(\"Party hat\", \"Head\")"
        },
        {
          "name": "detach",
          "signature": "obj.detach(point = \"Right hand\")",
          "help": "detach(point = \"Right hand\") → takes off what's on that attachment point",
          "returns": "takes off what's on that attachment point"
        },
        {
          "name": "teleport",
          "signature": "obj.teleport(x, y, z)",
          "help": "teleport(x, y, z) → jumps there at once (a vector works too): player.teleport(4, 0, 9)",
          "returns": "jumps there at once (a vector works too): player.teleport(4, 0, 9)"
        },
        {
          "name": "look_at",
          "signature": "obj.look_at(target, seconds = 0.3, wait = true)",
          "help": "look_at(target, seconds = 0.3, wait = true) → turns to face an object, the player or a position",
          "returns": "turns to face an object, the player or a position"
        },
        {
          "name": "face",
          "signature": "obj.face(degrees, seconds = 0.3, wait = true)",
          "help": "face(degrees, seconds = 0.3, wait = true) → turns to a direction (0 = -Z, 90 = -X…)",
          "returns": "turns to a direction (0 = -Z, 90 = -X…)"
        },
        {
          "name": "tween",
          "signature": "obj.tween(what, to, seconds = 1, ease = \"smooth\", wait = true)",
          "help": "tween(what, to, seconds = 1, ease = \"smooth\", wait = true) → glides x, y, z, turn or scale to a value with easing: \"linear\", \"smooth\", \"in\", \"out\", \"bounce\", \"elastic\", \"back\"",
          "returns": "glides x, y, z, turn or scale to a value with easing: \"linear\", \"smooth\", \"in\", \"out\", \"bounce\", \"elastic\", \"back\""
        },
        {
          "name": "set_scale",
          "signature": "obj.set_scale(size, seconds = 0)",
          "help": "set_scale(size, seconds = 0) → grows or shrinks it (1 = normal)",
          "returns": "grows or shrinks it (1 = normal)"
        },
        {
          "name": "tint",
          "signature": "obj.tint(color, seconds = 0)",
          "help": "tint(color, seconds = 0) → colours it (\"red\", \"#ff8800\"; \"\" = its own colours)",
          "returns": "colours it (\"red\", \"#ff8800\"; \"\" = its own colours)"
        },
        {
          "name": "follow",
          "signature": "obj.follow(target, speed = 3, keep = 1.5)",
          "help": "follow(target, speed = 3, keep = 1.5) → keeps walking after an object or the player (stop() ends it)",
          "returns": "keeps walking after an object or the player (stop() ends it)"
        },
        {
          "name": "flee",
          "signature": "obj.flee(target, speed = 3)",
          "help": "flee(target, speed = 3) → keeps walking away from it",
          "returns": "keeps walking away from it"
        },
        {
          "name": "stop",
          "signature": "obj.stop()",
          "help": "stop() → stops follow / flee / a glide",
          "returns": "stops follow / flee / a glide"
        },
        {
          "name": "hurt",
          "signature": "obj.hurt(amount)",
          "help": "hurt(amount) → takes health from it (objects with Health; the player too)",
          "returns": "takes health from it (objects with Health; the player too)"
        },
        {
          "name": "heal",
          "signature": "obj.heal(amount)",
          "help": "heal(amount) → gives health back",
          "returns": "gives health back"
        },
        {
          "name": "has_tag",
          "signature": "obj.has_tag(tag)",
          "help": "has_tag(tag) → true if its model has that tag",
          "returns": "true if its model has that tag"
        },
        {
          "name": "say",
          "signature": "obj.say(text, seconds = 2.5)",
          "help": "say(text, seconds = 2.5) → a speech bubble over it",
          "returns": "a speech bubble over it"
        }
      ]
    },
    {
      "title": "Object fields",
      "kind": "field",
      "items": [
        {
          "name": "x",
          "signature": "obj.x",
          "help": "x → tile X (fractions while moving)",
          "returns": "tile X (fractions while moving)"
        },
        {
          "name": "y",
          "signature": "obj.y",
          "help": "y → height level",
          "returns": "height level"
        },
        {
          "name": "z",
          "signature": "obj.z",
          "help": "z → tile Z",
          "returns": "tile Z"
        },
        {
          "name": "name",
          "signature": "obj.name",
          "help": "name → its Script name (\"\" if none)",
          "returns": "its Script name (\"\" if none)"
        },
        {
          "name": "exists",
          "signature": "obj.exists",
          "help": "exists → false if it was removed or not found",
          "returns": "false if it was removed or not found"
        },
        {
          "name": "position",
          "signature": "obj.position",
          "help": "position → where it is, as a vector",
          "returns": "where it is, as a vector"
        },
        {
          "name": "hp",
          "signature": "obj.hp",
          "help": "hp → its health (objects with Health, or the player); nil if it has none",
          "returns": "its health (objects with Health, or the player); nil if it has none"
        },
        {
          "name": "max_hp",
          "signature": "obj.max_hp",
          "help": "max_hp → its full health",
          "returns": "its full health"
        },
        {
          "name": "model",
          "signature": "obj.model",
          "help": "model → the name of its model",
          "returns": "the name of its model"
        },
        {
          "name": "tags",
          "signature": "obj.tags",
          "help": "tags → its model's tags (a list)",
          "returns": "its model's tags (a list)"
        },
        {
          "name": "hidden",
          "signature": "obj.hidden",
          "help": "hidden → true while hidden",
          "returns": "true while hidden"
        },
        {
          "name": "turn",
          "signature": "obj.turn",
          "help": "turn → which way it faces, in degrees",
          "returns": "which way it faces, in degrees"
        }
      ]
    },
    {
      "title": "Maths",
      "kind": "language",
      "items": [
        {
          "name": "abs",
          "signature": "abs(x)",
          "help": "abs(x) → x without its sign",
          "returns": "x without its sign"
        },
        {
          "name": "min",
          "signature": "min(a, b, …)",
          "help": "min(a, b, …) → the smallest",
          "returns": "the smallest"
        },
        {
          "name": "max",
          "signature": "max(a, b, …)",
          "help": "max(a, b, …) → the biggest",
          "returns": "the biggest"
        },
        {
          "name": "round",
          "signature": "round(x, step = 1)",
          "help": "round(x, step = 1) → nearest whole number (or nearest step: round(x, 0.5))",
          "returns": "nearest whole number (or nearest step: round(x, 0.5))"
        },
        {
          "name": "floor",
          "signature": "floor(x)",
          "help": "floor(x) → down to a whole number",
          "returns": "down to a whole number"
        },
        {
          "name": "ceil",
          "signature": "ceil(x)",
          "help": "ceil(x) → up to a whole number",
          "returns": "up to a whole number"
        },
        {
          "name": "clamp",
          "signature": "clamp(x, low, high)",
          "help": "clamp(x, low, high) → x kept between low and high",
          "returns": "x kept between low and high"
        },
        {
          "name": "wrap",
          "signature": "wrap(x, low, high)",
          "help": "wrap(x, low, high) → x wrapped around inside low…high (wrap(370, 0, 360) = 10)",
          "returns": "x wrapped around inside low…high (wrap(370, 0, 360) = 10)"
        },
        {
          "name": "sign",
          "signature": "sign(x)",
          "help": "sign(x) → -1, 0 or 1",
          "returns": "-1, 0 or 1"
        },
        {
          "name": "sqrt",
          "signature": "sqrt(x)",
          "help": "sqrt(x) → square root",
          "returns": "square root"
        },
        {
          "name": "pow",
          "signature": "pow(x, y)",
          "help": "pow(x, y) → x to the power y (same as x ^ y)",
          "returns": "x to the power y (same as x ^ y)"
        },
        {
          "name": "exp",
          "signature": "exp(x)",
          "help": "exp(x)",
          "returns": ""
        },
        {
          "name": "log",
          "signature": "log(x)",
          "help": "log(x) → natural log",
          "returns": "natural log"
        },
        {
          "name": "lerp",
          "signature": "lerp(a, b, t)",
          "help": "lerp(a, b, t) → part way from a to b (t = 0…1); works on vectors too",
          "returns": "part way from a to b (t = 0…1); works on vectors too"
        },
        {
          "name": "smoothstep",
          "signature": "smoothstep(low, high, x)",
          "help": "smoothstep(low, high, x) → 0…1, easing in and out",
          "returns": "0…1, easing in and out"
        },
        {
          "name": "sin",
          "signature": "sin(degrees)",
          "help": "sin(degrees)",
          "returns": ""
        },
        {
          "name": "cos",
          "signature": "cos(degrees)",
          "help": "cos(degrees)",
          "returns": ""
        },
        {
          "name": "tan",
          "signature": "tan(degrees)",
          "help": "tan(degrees)",
          "returns": ""
        },
        {
          "name": "asin",
          "signature": "asin(x)",
          "help": "asin(x) → degrees",
          "returns": "degrees"
        },
        {
          "name": "acos",
          "signature": "acos(x)",
          "help": "acos(x) → degrees",
          "returns": "degrees"
        },
        {
          "name": "atan",
          "signature": "atan(x)",
          "help": "atan(x) → degrees",
          "returns": "degrees"
        },
        {
          "name": "atan2",
          "signature": "atan2(y, x)",
          "help": "atan2(y, x) → the angle in degrees to the point (x, y)",
          "returns": "the angle in degrees to the point (x, y)"
        },
        {
          "name": "int",
          "signature": "int(x)",
          "help": "int(x) → whole number (drops the fraction); int(\"42\") reads text",
          "returns": "whole number (drops the fraction); int(\"42\") reads text"
        },
        {
          "name": "float",
          "signature": "float(x)",
          "help": "float(x) → a number with a fraction; float(\"2.5\") reads text",
          "returns": "a number with a fraction; float(\"2.5\") reads text"
        },
        {
          "name": "num",
          "signature": "num(text)",
          "help": "num(text) → the number in a text (nil if there isn't one)",
          "returns": "the number in a text (nil if there isn't one)"
        }
      ]
    },
    {
      "title": "Random",
      "kind": "language",
      "items": [
        {
          "name": "random",
          "signature": "random(low = 0, high = 1)",
          "help": "random(low = 0, high = 1) → a random number between them (with a fraction)",
          "returns": "a random number between them (with a fraction)"
        },
        {
          "name": "randf",
          "signature": "randf()",
          "help": "randf() → a random number 0…1",
          "returns": "a random number 0…1"
        },
        {
          "name": "randi_range",
          "signature": "randi_range(low, high)",
          "help": "randi_range(low, high) → a random whole number",
          "returns": "a random whole number"
        },
        {
          "name": "random_pick",
          "signature": "random_pick(list)",
          "help": "random_pick(list) → one item at random (nil for an empty list)",
          "returns": "one item at random (nil for an empty list)"
        },
        {
          "name": "shuffle",
          "signature": "shuffle(list)",
          "help": "shuffle(list) → mixes the list up (in place)",
          "returns": "mixes the list up (in place)"
        },
        {
          "name": "seed",
          "signature": "seed(n)",
          "help": "seed(n) → makes random numbers repeat the same way each run",
          "returns": "makes random numbers repeat the same way each run"
        },
        {
          "name": "noise",
          "signature": "noise(x, y = 0, z = 0)",
          "help": "noise(x, y = 0, z = 0) → smooth random -1…1 that changes gently with x, y, z (terrain, wobble)",
          "returns": "smooth random -1…1 that changes gently with x, y, z (terrain, wobble)"
        }
      ]
    },
    {
      "title": "Vectors",
      "kind": "language",
      "items": [
        {
          "name": "vec",
          "signature": "vec(x, y, z)",
          "help": "vec(x, y, z) → a vector (a position or a direction): v.x, v + w, v * 2",
          "returns": "a vector (a position or a direction): v.x, v + w, v * 2"
        },
        {
          "name": "pos",
          "signature": "pos(obj)",
          "help": "pos(obj) → an object's position as a vector",
          "returns": "an object's position as a vector"
        },
        {
          "name": "length",
          "signature": "length(v)",
          "help": "length(v) → how long a vector is",
          "returns": "how long a vector is"
        },
        {
          "name": "normalize",
          "signature": "normalize(v)",
          "help": "normalize(v) → the same direction, length 1",
          "returns": "the same direction, length 1"
        },
        {
          "name": "distance",
          "signature": "distance(a, b)",
          "help": "distance(a, b) → between two vectors, or two objects (tiles)",
          "returns": "between two vectors, or two objects (tiles)"
        },
        {
          "name": "dot",
          "signature": "dot(a, b)",
          "help": "dot(a, b) → how much two directions agree",
          "returns": "how much two directions agree"
        },
        {
          "name": "cross",
          "signature": "cross(a, b)",
          "help": "cross(a, b) → the direction at right angles to both",
          "returns": "the direction at right angles to both"
        },
        {
          "name": "angle_to",
          "signature": "angle_to(from, to)",
          "help": "angle_to(from, to) → the turn in degrees from one position to face another (on the ground)",
          "returns": "the turn in degrees from one position to face another (on the ground)"
        }
      ]
    },
    {
      "title": "Text",
      "kind": "language",
      "items": [
        {
          "name": "str",
          "signature": "str(x)",
          "help": "str(x) → x as text",
          "returns": "x as text"
        },
        {
          "name": "len",
          "signature": "len(x)",
          "help": "len(x) → length of a text, list or table (same as #x)",
          "returns": "length of a text, list or table (same as #x)"
        },
        {
          "name": "upper",
          "signature": "upper(text)",
          "help": "upper(text)",
          "returns": ""
        },
        {
          "name": "lower",
          "signature": "lower(text)",
          "help": "lower(text)",
          "returns": ""
        },
        {
          "name": "sub",
          "signature": "sub(text, start, count = to the end)",
          "help": "sub(text, start, count = to the end) → part of a text (start at 0)",
          "returns": "part of a text (start at 0)"
        },
        {
          "name": "find",
          "signature": "find(text, part)",
          "help": "find(text, part) → where part starts in text (-1 if it isn't there)",
          "returns": "where part starts in text (-1 if it isn't there)"
        },
        {
          "name": "contains",
          "signature": "contains(text or list, part)",
          "help": "contains(text or list, part) → true if it's in there",
          "returns": "true if it's in there"
        },
        {
          "name": "split",
          "signature": "split(text, separator = \" \")",
          "help": "split(text, separator = \" \") → a list of the pieces",
          "returns": "a list of the pieces"
        },
        {
          "name": "replace",
          "signature": "replace(text, old, new)",
          "help": "replace(text, old, new) → every old changed to new",
          "returns": "every old changed to new"
        },
        {
          "name": "trim",
          "signature": "trim(text)",
          "help": "trim(text) → without spaces at the ends",
          "returns": "without spaces at the ends"
        },
        {
          "name": "starts_with",
          "signature": "starts_with(text, part)",
          "help": "starts_with(text, part)",
          "returns": ""
        },
        {
          "name": "ends_with",
          "signature": "ends_with(text, part)",
          "help": "ends_with(text, part)",
          "returns": ""
        },
        {
          "name": "format",
          "signature": "format(\"{0} has {1} hp\", name, hp)",
          "help": "format(\"{0} has {1} hp\", name, hp) → fills in the {n} slots",
          "returns": "fills in the {n} slots"
        },
        {
          "name": "join",
          "signature": "join(list, separator = \", \")",
          "help": "join(list, separator = \", \") → the items as one text",
          "returns": "the items as one text"
        },
        {
          "name": "rep",
          "signature": "rep(text, n)",
          "help": "rep(text, n) → the text n times",
          "returns": "the text n times"
        },
        {
          "name": "char",
          "signature": "char(code)",
          "help": "char(code) → the letter with that code",
          "returns": "the letter with that code"
        },
        {
          "name": "type",
          "signature": "type(x)",
          "help": "type(x) → \"number\", \"text\", \"bool\", \"nil\", \"list\", \"table\", \"vector\", \"function\" or \"object\"",
          "returns": "\"number\", \"text\", \"bool\", \"nil\", \"list\", \"table\", \"vector\", \"function\" or \"object\""
        }
      ]
    },
    {
      "title": "Lists & tables",
      "kind": "language",
      "items": [
        {
          "name": "list",
          "signature": "list(a, b, …)",
          "help": "list(a, b, …) → a list of the values",
          "returns": "a list of the values"
        },
        {
          "name": "push",
          "signature": "push(list, value)",
          "help": "push(list, value) → adds to the end (also list:push(value))",
          "returns": "adds to the end (also list:push(value))"
        },
        {
          "name": "pop",
          "signature": "pop(list)",
          "help": "pop(list) → takes the last item off and gives it",
          "returns": "takes the last item off and gives it"
        },
        {
          "name": "insert",
          "signature": "insert(list, index, value)",
          "help": "insert(list, index, value) → puts a value in at index",
          "returns": "puts a value in at index"
        },
        {
          "name": "remove",
          "signature": "remove(list, value)",
          "help": "remove(list, value) → takes the first matching value out; remove(table, key)",
          "returns": "takes the first matching value out; remove(table, key)"
        },
        {
          "name": "remove_at",
          "signature": "remove_at(list, index)",
          "help": "remove_at(list, index) → takes the item at index out and gives it",
          "returns": "takes the item at index out and gives it"
        },
        {
          "name": "index_of",
          "signature": "index_of(list, value)",
          "help": "index_of(list, value) → where it is (-1 if not there)",
          "returns": "where it is (-1 if not there)"
        },
        {
          "name": "sort",
          "signature": "sort(list, compare = nil)",
          "help": "sort(list, compare = nil) → sorts the list in place (compare(a, b) → true if a goes first)",
          "returns": "sorts the list in place (compare(a, b) → true if a goes first)"
        },
        {
          "name": "reverse",
          "signature": "reverse(list)",
          "help": "reverse(list) → turns the list around (in place)",
          "returns": "turns the list around (in place)"
        },
        {
          "name": "slice",
          "signature": "slice(list, from, to = end)",
          "help": "slice(list, from, to = end) → a new list of items from … up to (not including) to",
          "returns": "a new list of items from … up to (not including) to"
        },
        {
          "name": "copy",
          "signature": "copy(list or table)",
          "help": "copy(list or table) → a separate copy (deep)",
          "returns": "a separate copy (deep)"
        },
        {
          "name": "keys",
          "signature": "keys(table)",
          "help": "keys(table) → its keys as a list",
          "returns": "its keys as a list"
        },
        {
          "name": "values",
          "signature": "values(table)",
          "help": "values(table) → its values as a list",
          "returns": "its values as a list"
        },
        {
          "name": "has_key",
          "signature": "has_key(table, key)",
          "help": "has_key(table, key) → true if the table has that key",
          "returns": "true if the table has that key"
        },
        {
          "name": "range",
          "signature": "range(from, to, step = 1)",
          "help": "range(from, to, step = 1) → a list of numbers from … up to and including to",
          "returns": "a list of numbers from … up to and including to"
        },
        {
          "name": "map",
          "signature": "map(list, fn)",
          "help": "map(list, fn) → a new list of fn(item) for each item",
          "returns": "a new list of fn(item) for each item"
        },
        {
          "name": "filter",
          "signature": "filter(list, fn)",
          "help": "filter(list, fn) → a new list of the items where fn(item) is true",
          "returns": "a new list of the items where fn(item) is true"
        },
        {
          "name": "sum",
          "signature": "sum(list)",
          "help": "sum(list) → all the numbers added up",
          "returns": "all the numbers added up"
        }
      ]
    },
    {
      "title": "Waiting",
      "kind": "language",
      "items": [
        {
          "name": "wait_until",
          "signature": "wait_until(fn, timeout = 0)",
          "help": "wait_until(fn, timeout = 0) → waits until fn() is true (checks every frame); gives false if timeout seconds pass first",
          "returns": "waits until fn() is true (checks every frame); gives false if timeout seconds pass first"
        }
      ]
    },
    {
      "title": "Checks & debugging",
      "kind": "language",
      "items": [
        {
          "name": "assert",
          "signature": "assert(condition, message = \"assert failed\")",
          "help": "assert(condition, message = \"assert failed\") → stops the code with the message when condition is false",
          "returns": "stops the code with the message when condition is false"
        },
        {
          "name": "error",
          "signature": "error(message)",
          "help": "error(message) → stops the code with that message",
          "returns": "stops the code with that message"
        },
        {
          "name": "pcall",
          "signature": "pcall(fn, …)",
          "help": "pcall(fn, …) → runs fn and catches its error: gives [true, result] or [false, message]",
          "returns": "runs fn and catches its error: gives [true, result] or [false, message]"
        },
        {
          "name": "warn",
          "signature": "warn(message)",
          "help": "warn(message) → a warning in the Output panel (the code goes on)",
          "returns": "a warning in the Output panel (the code goes on)"
        },
        {
          "name": "breakpoint",
          "signature": "breakpoint()",
          "help": "breakpoint() → pauses the game here and shows this code's values (F5 continue, F10 next line)",
          "returns": "pauses the game here and shows this code's values (F5 continue, F10 next line)"
        }
      ]
    },
    {
      "title": "Libraries",
      "kind": "language",
      "items": [
        {
          "name": "require",
          "signature": "require(\"Utils\")",
          "help": "require(\"Utils\") → the functions of the script named Utils (a library), as a table",
          "returns": "the functions of the script named Utils (a library), as a table"
        }
      ]
    }
  ]
}
