├── .gitattributes ├── .github └── workflows │ └── mkdocs.yml ├── .gitignore ├── Pipfile ├── Pipfile.lock ├── README.md ├── build.bat ├── deploy.bat ├── docs ├── CNAME ├── atom.md ├── backgrounds.md ├── base.md ├── behavior │ ├── assetbundle.md │ ├── book.md │ ├── browser.md │ ├── clock.md │ ├── container.md │ ├── counter.md │ ├── layoutzone.md │ ├── rpgfigurine.md │ └── texttool.md ├── built-in-object.md ├── color.md ├── components │ ├── component.md │ ├── examples.md │ ├── gameobject.md │ ├── introduction.md │ └── material.md ├── css │ ├── i_icons.css │ ├── player_color_table.css │ ├── table.css │ ├── theme.css │ └── type_icons.css ├── custom-game-objects.md ├── events.md ├── externaleditorapi.md ├── grid.md ├── hands.md ├── img │ ├── Icon-Dice.png │ ├── TSIcon.png │ ├── atom │ │ ├── autocomplete.png │ │ ├── install.png │ │ ├── logo.png │ │ ├── pipes.PNG │ │ ├── sap1.png │ │ ├── sap2.png │ │ ├── setup.PNG │ │ └── syntax.png │ ├── intro.gif │ ├── overview1.png │ ├── overview2.png │ ├── pawn.png │ └── pawn_outlined.png ├── index.md ├── info.md ├── intro.md ├── json.md ├── lighting.md ├── lua-in-tabletop-simulator.md ├── musicplayer.md ├── notes.md ├── object.md ├── overview.md ├── physics.md ├── player │ ├── colors.md │ ├── instance.md │ └── manager.md ├── systemconsole.md ├── tables.md ├── time.md ├── timer.md ├── turns.md ├── types.md ├── ui.md ├── ui │ ├── attributes.md │ ├── basicelements.md │ ├── defaults.md │ ├── image_inprogress │ ├── inputelements.md │ ├── introUI.md │ └── layoutgrouping.md ├── vector.md ├── vr.md ├── wait.md └── webrequest │ ├── instance.md │ └── manager.md ├── mkdocs.yml ├── process_anchors.py ├── serve.bat ├── serve.py └── theme ├── icons └── i.svg ├── main.html └── partials ├── footer.html └── nav.html /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/workflows/mkdocs.yml: -------------------------------------------------------------------------------- 1 | name: Github Pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-18.04 11 | steps: 12 | - uses: actions/checkout@v2 13 | 14 | - name: Setup Python 15 | uses: actions/setup-python@v1 16 | with: 17 | python-version: '3.6' 18 | architecture: 'x64' 19 | 20 | - name: Install pipenv 21 | run: | 22 | pip install pipenv 23 | 24 | - name: Cache dependencies 25 | id: cache-dependencies 26 | uses: actions/cache@v1 27 | with: 28 | path: ~/.local/share/virtualenvs 29 | key: ${{ runner.os }}-pipenv-${{ hashFiles('**/Pipfile.lock') }} 30 | 31 | - name: Install dependencies 32 | if: steps.cache-dependencies.outputs.cache-hit != 'true' 33 | run: pipenv install 34 | 35 | - run: pipenv run mkdocs build 36 | 37 | - name: Deploy 38 | uses: peaceiris/actions-gh-pages@v3 39 | with: 40 | github_token: ${{ secrets.GITHUB_TOKEN }} 41 | publish_dir: ./site 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | site/ 2 | mkdocs/ -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.python.org/simple" 3 | verify_ssl = true 4 | name = "Tabletop Simulator API" 5 | 6 | [packages] 7 | mkdocs = "~=1.1.2" 8 | mkdocs-material = "~= 7.0.6" 9 | mkdocs-material-extensions = "~= 1.0.1" 10 | pymdown-extensions = "~= 8.1.1" 11 | pymdown-toc-ext = "~= 1.3" 12 | 13 | [requires] 14 | python_version = "3.6" 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tabletop Simulator API 2 | 3 | This is the source of the api documentation in Tabletop Simulator. It uses a modified version of [Material-Design](https://github.com/squidfunk/mkdocs-material) for MkDocs. 4 | 5 | ## How it Works 6 | 7 | The `.md` files in the `/docs` folder are written in Markdown, which is an easy-to-use markup language to add formatting to text. Additionally, some custom CSS is used, as well as a handful of custom images. When making changes, it is possible to live-preview them as you go if you have set up the local files for mkdocs + material design. 8 | 9 | Alternatively, you can make modifications to individual pages then submit them for review. The developers will always be the ones to build and publish the site anyway, all you will do is modify the contents of this Git. 10 | 11 | ## Contributing 12 | 13 | The API website is built using [MkDocs](https://www.mkdocs.org/) and several related extensions. 14 | 15 | Pull requests are welcome, however in order to preview your changes, you must follow the instructions below: 16 | 17 | ### Prerequisites 18 | 19 | You will need to ensure Python `3.6` is installed on your system. 20 | 21 | If your system doesn't have it installed, you can either [download directly](https://www.python.org/downloads/release/python-366/) or install from a Python version manager such as [pyenv](https://github.com/pyenv/pyenv). 22 | 23 | We utilise Pipenv and a `Pipfile` to ensure builds are consistent. If you don't already have Pipenv installed, please follow the official [pipenv install instructions](https://pipenv.readthedocs.io/en/latest/install/#installing-pipenv) for you platform. 24 | 25 | ### Installing Dependencies 26 | 27 | Once've you installed the prerequisites, you must initialize your environment. From command line, this is done with: 28 | 29 | ``` 30 | pipenv install 31 | ``` 32 | 33 | You can then "activate" this environment with: 34 | 35 | ``` 36 | pipenv shell 37 | ``` 38 | 39 | ### Previewing 40 | 41 | Once your Pipenv environment is activated, you can simply execute: 42 | 43 | ``` 44 | mkdocs serve 45 | ``` 46 | 47 | Then open your browser and navigate to `http://localhost:8000` in order to view your changes. 48 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | mkdocs build 2 | -------------------------------------------------------------------------------- /deploy.bat: -------------------------------------------------------------------------------- 1 | mkdocs gh-deploy || @echo: & @echo Did you remember to `pipenv shell` first? 2 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | api.tabletopsimulator.com -------------------------------------------------------------------------------- /docs/atom.md: -------------------------------------------------------------------------------- 1 | 2 |  3 | 4 | Atom is a free, open source, and cross-platform text editor created by [GitHub](http://www.github.com/): 5 | 6 | !!!note "" 7 | Atom is a text editor that's modern, approachable, yet hackable to the core - a tool you can customize to do anything but also use productively without ever touching a config file. 8 | 9 | We created an official plugin for the Atom text editor to make writing Lua scripts for Tabletop Simulator super easy and fun! 10 | 11 | This page provides a basic overview of how to install and use the plugin; if you would like a more in-depth explanation of its features and how to install/use it then please see its documentation: 12 | 13 | * [Atom Plugin Documentation Home](https://github.com/Berserk-Games/atom-tabletopsimulator-lua/wiki) 14 | * [Installation Instructions](https://github.com/Berserk-Games/atom-tabletopsimulator-lua/wiki/Installation) 15 | * [Features](https://github.com/Berserk-Games/atom-tabletopsimulator-lua/wiki/Features) 16 | * [Commands](https://github.com/Berserk-Games/atom-tabletopsimulator-lua/wiki/Commands) 17 | * [Settings](https://github.com/Berserk-Games/atom-tabletopsimulator-lua/wiki/Settings) 18 | 19 | Our official plugin introduces syntax highlighting, code autocompletion for the Tabletop Simulator Lua API, and functions to interact with the game. The in-game editor will continue to exist for quick access to scripts, but development on it will cease to continue. 20 | 21 | Prefer another text editor? Take look at our [External Editor API](https://api.tabletopsimulator.com/externaleditorapi/) to make your own plugin. 22 | 23 | --- 24 | 25 | ## Features 26 | 27 | This is only a summarized list of features Atom offers. Check out a more complete documentation on the plugin specifically in the [plugin wiki](https://github.com/Knils/atom-tabletopsimulator-lua/wiki). 28 | 29 | ### Syntax Highlighting 30 | All standard Lua syntax is highlighted in multiple colors to help with readability. 31 | 32 |  33 | 34 | ### Code Autocompletion 35 | The entire Tabletop Simulator Lua Scripting API (with the exception of the Player class) has been added to the native Atom autocomplete system. Easily see all of the member variables and functions available to you with their parameters, return type, short description, and a link directly to our Knowledge Base with more information for that variable or function. Functions belonging to the Lua standard library classes such as math, coroutine, or os link directly to the official Lua documentation. 36 | 37 |  38 | 39 | ### Tabletop Simulator Integration 40 | The Atom plugin can directly connect to a running instance of Tabletop Simulator to get all of the existing Lua scripts on Objects and to call Save & Play. Both functions can be called directly from the Packages menu or the right click contextual menu. TTS must be running with the game loaded for these functions to work. 41 | 42 | Command | Action Taken 43 | --------|-------- 44 | Get Lua Scripts |
Downloads all existing scripts in a loaded Tabletop Simulator game with Atom. You will need to call Get Lua Scripts every time you change to a different game in TTS.
**Shortcut:** ++Ctrl+Shift+L++
45 | Save & Play |Saves all Lua files in Atom, uploads them to a loaded Tabletop Simulator game, and reloads the current game (same as Save & Play in the in-game editor).
**Shortcut:** ++Ctrl+Shift+S++
46 | 47 |  48 |  49 | 50 | Every time you start up Atom, the cached local `*.ttslua` files are deleted. 51 | 52 | --- 53 | 54 | ## Installing Atom 55 | Download and install Atom [from the official website](https://atom.io/). 56 | 57 | ### Installing the Official Plugin 58 | 1. Click on File -> Settings 59 | 2. Select the Install tab in Settings 60 | 3. Type in tabletopsimulator-lua into the search field and press the ++Enter++ key or click the Packages button 61 | 4. Click the blue Install button for the tabletopsimulator-lua package 62 | 63 |  64 | 65 | ### Updating the Official Plugin 66 | 67 | The plugin will automatically check for updates when Atom is started. If a new update is found, it will update itself. 68 | 69 | You will have to manually restart Atom for the new version of the plugin to be loaded. 70 | 71 | --- 72 | 73 | ## Atom Console 74 | 75 | ### Print, Log and Error Messages 76 | 77 | All [print(...)](base.md#print), [log(...)](base.md#log) and error messages are sent to Atom's console. This is 78 | particularly helpful as you're able to copy text from here. 79 | 80 | #### Shortcut {: #atom-console-shortcut } 81 | 82 | **Windows/Linux:** ++Ctrl+Alt+I++ 83 | 84 | **macOS:** ++Cmd+Opt+I++ 85 | 86 | --- 87 | 88 | ## User Customization 89 | 90 | ### Tab Width 91 | By default, Tabletop Simulator scripts use a tab width of four spaces. You are not required to adhere to this spacing. By default, Atom has a tab width of two spaces. To optionally make Atom default to a tab width of four spaces: 92 | 93 | 1. Click on File -> Settings 94 | 2. Select the Editor tab in Settings 95 | 3. Scroll down to Tab Length 96 | 4. Set the Tab Length to 4 97 | 98 |  99 | 100 | ### Tables as Pipe Operators 101 | To enable tabs showing up as pipe operators "|" as an indent guide: 102 | 103 | 1. Click on File -> Settings 104 | 2. Select the Editor tab in Settings 105 | 3. Scroll down to Show Indent Guide 106 | 4. Check Show Indent Guide 107 | 108 |  109 | 110 | -------------------------------------------------------------------------------- /docs/backgrounds.md: -------------------------------------------------------------------------------- 1 | `Backgrounds` is a global which provides the ability to interact with the background. 2 | 3 | > Example Usage:`#!lua Backgrounds.getBackground()`. 4 | 5 | ## Function Summary 6 | 7 | Function Name | Description | Return | 8 | -- | -- | -- | --: 9 | getBackground() | Returns the current background name. | [](types.md) | 10 | getCustomURL() | Returns the image URL of the current custom background, or `nil` if the current background is not custom. | [](types.md) | 11 | setBackground([](types.md) name) | Replaces the current background with the background matching the specified `name`. | [](types.md) | 12 | setCustomURL([](types.md) url) | Replaces the current background with a custom background loaded from the specified `url`. | [](types.md) | 13 | 14 | --- 15 | -------------------------------------------------------------------------------- /docs/behavior/assetbundle.md: -------------------------------------------------------------------------------- 1 | The AssetBundle behavior is present on Objects that were created from a 2 | [custom AssetBundle](https://kb.tabletopsimulator.com/custom-content/custom-assetbundle/). 3 | 4 | ## Function Summary 5 | 6 | Function Name | Description | Return | 7 | -- | -- | -- | -- 8 | getLoopingEffectIndex() {: #getloopingeffectindex data-toc-label="" data-toc-child-of="function-details" } | [](../types.md) | Index of the currently looping effect. Indexes starts at 0. | 9 | getLoopingEffects() | [](../types.md) | Returns a Table with the keys "index" and "name" for each looping effect. | [:i:](#getloopingeffects) 10 | getTriggerEffects() | [](../types.md) | Returns a Table with the keys "index" and "name" for each trigger effect. | [:i:](#gettriggereffects) 11 | playLoopingEffect([](../types.md) index) {: #playloopingeffect data-toc-label="playLoopingEffect(...)" data-toc-child-of="function-details" } | [](../types.md) | Starts playing a looping effect. Indexes starts at 0. | 12 | playTriggerEffect([](../types.md) index) {: #playtriggereffect data-toc-label="playTriggerEffect(...)" data-toc-child-of="function-details" } | [](../types.md) | Starts playing a trigger effect. Indexes starts at 0. | 13 | 14 | --- 15 | 16 | ## Function Details {: data-toc-sort } 17 | 18 | ### getLoopingEffects() 19 | 20 | [](../types.md) Returns a Table with the keys "index" and "name" for each looping effect. 21 | 22 | ``` Lua 23 | -- Example usage 24 | effectTable = self.AssetBundle.getLoopingEffects() 25 | ``` 26 | ``` Lua 27 | -- Example returned table 28 | { 29 | {index=0, name="Effect Name 1"}, 30 | {index=1, name="Effect Name 2"}, 31 | } 32 | ``` 33 | 34 | --- 35 | 36 | ### getTriggerEffects() 37 | 38 | [](../types.md) Returns a Table with the keys "index" and "name" for each trigger effect. 39 | 40 | ``` Lua 41 | -- Example usage 42 | effectTable = self.AssetBundle.getTriggerEffects() 43 | ``` 44 | ``` Lua 45 | -- Example returned table 46 | { 47 | {index=0, name="Effect Name 1"}, 48 | {index=1, name="Effect Name 2"}, 49 | } 50 | ``` 51 | -------------------------------------------------------------------------------- /docs/behavior/book.md: -------------------------------------------------------------------------------- 1 | The Book behavior is present on Custom PDF Objects. The Book behaviour allows you to manipulate the displayed PDF. 2 | 3 | ## Member Variables 4 | 5 | Variable | Type | Description 6 | -- | -- | :-- 7 | page_offset {: #page_offset } | [](../types.md) | The page numbers displayed in the Custom PDF UI are offset by this amount. 8 | 9 | !!! info 10 | For example, if `page_offset` were set to 10, the first page in the UI would be 11, rather than 1. Negative numbers are accepted, and useful if a rule book contains a front cover, index etc. within the PDF file. 11 | 12 | ## Function Summary 13 | 14 | Function Name | Return | Description | 15 | -- | -- | -- | -- 16 | clearHighlight() {: #clearhighlight data-toc-label="clearHighlight()" data-toc-child-of="function-details" } | [](../types.md) | Clears the current highlight. 17 | getPage([](../types.md) offsetPageNumbering) | [](../types.md) | Gets the current page of the PDF. | [:i:](#getpage) 18 | setHighlight([](../types.md) x1, [](../types.md) y1, [](../types.md) x2, [](../types.md) y2) | [](../types.md) | Set highlight box on current page.| [:i:](#sethighlight) 19 | setPage([](../types.md) page, [](../types.md) offsetPageNumbering) | [](../types.md) | Set current page.| [:i:](#setpage) 20 | 21 | --- 22 | 23 | ## Function Details {: data-toc-sort } 24 | 25 | #### getPage(...) 26 | 27 | [](../types.md) Gets the current page of the PDF. 28 | 29 | !!! info "getPage(offsetPageNumbering)" 30 | * [](../types.md) **offsetPageNumbering**: Indicates whether or not [page_offset](#page_offset) should be applied to the page number returned. 31 | * {>>Optional, defaults to `false`.<<} 32 | --- 33 | 34 | #### setHighlight(...) 35 | 36 | [](../types.md) Draws a highlight rectangle on the popout mode of the PDF at the given coordinates. Coordinates (0,0) are the lower left corner of the PDF, while coordinates (1,1) are the upper right corner. 37 | 38 | !!! info "setHighlight(x1, y1, x2, y2)" 39 | * [](../types.md) **x1**: x coordinate of the rectangle's left side. 40 | * [](../types.md) **y1**: y coordinate of the rectangle's bottom side. 41 | * [](../types.md) **x2**: x coordinate of the rectangle's right side. 42 | * [](../types.md) **y2**: y coordinate of the rectangle's top side. 43 | 44 | !!!example 45 | Highlight the upper right quarter of a PDF. 46 | ```lua 47 | object.Book.setHighlight(0.5, 0.5, 1, 1) 48 | ``` 49 | 50 | --- 51 | 52 | #### setPage(...) 53 | 54 | [](../types.md) Sets the current page of the PDF. Returns true if the page was succesfully set, false if the page number was invalid. 55 | 56 | !!! info "setPage(page, offsetPageNumbering)" 57 | * [](../types.md) **page**: The new page number. 58 | * [](../types.md) **offsetPageNumbering**: Indicates whether or not [page_offset](#page_offset) should be applied to the page number set. 59 | * {>>Optional, defaults to `false`.<<} 60 | -------------------------------------------------------------------------------- /docs/behavior/browser.md: -------------------------------------------------------------------------------- 1 | The Browser behavior is present on the Tablet Object. 2 | 3 | !!!example 4 | Instruct a Tablet Object to load the Tabletop Simulator homepage. 5 | ```lua 6 | object.Browser.url = "https://tabletopsimulator.com" 7 | ``` 8 | 9 | ## Member Variables 10 | 11 | Variable | Type | Description 12 | -- | -- | -- 13 | url {: #url } | [](../types.md) | URL which currently wants to display. 14 | pixel_width {: #pixel_width } | [](../types.md) | The pixel width the browser is virtually rendering to. 15 | -------------------------------------------------------------------------------- /docs/behavior/clock.md: -------------------------------------------------------------------------------- 1 | The Clock behavior is present on the Digital Clock object. 2 | 3 | ## Clock Modes 4 | 5 | * **Current Time**: Displays the current time of the host. 6 | * **Stopwatch**: Displays a running count up. 7 | * **Timer**: Displays a countdown and beeps once complete. 8 | 9 | ## Member Variables 10 | 11 | Variable | Type | Description 12 | -- | -- | :-- 13 | paused {: #paused } | [](../types.md) | If the clock timer is paused. 14 | 15 | --- 16 | 17 | ## Function Summary 18 | 19 | Function Name | Return | Description | 20 | -- | -- | -- | --: 21 | getValue() {: #getvalue data-toc-label="getValue()" data-toc-child-of="function-details" } | [](../types.md) | Current time in stopwatch or timer mode. Clock mode returns 0. This function acts the same as [Object's getValue()](../object.md#getvalue). 22 | pauseStart() {: #pausestart data-toc-label="pauseStart()" data-toc-child-of="function-details" } | [](../types.md) | Pauses/resumes a Clock in stopwatch or timer mode. 23 | setValue([](../types.md) seconds) | [](../types.md) | Switches clock to timer and sets countdown time. This function acts the same as [Object's setValue()](../object.md#setvalue). | [:i:](#setvalue) 24 | showCurrentTime() {: #showcurrenttime data-toc-label="showCurrentTime()" data-toc-child-of="function-details" } | [](../types.md) | Switches clock to display current time. It will clear any stopwatch or timer. 25 | startStopwatch() {: #startstopwatch data-toc-label="startStopwatch()" data-toc-child-of="function-details" } | [](../types.md) | Switches clock to stopwatch, setting time to 0. It will reset time if already in stopwatch mode. 26 | 27 | --- 28 | 29 | ## Function Details {: data-toc-sort } 30 | 31 | ### setValue(...) 32 | 33 | [](../types.md) Set the timer to display a number of seconds. This function acts the same as [Object's setValue()](../object.md#setvalue). If the Clock is not in timer mode, it will be switched. If it is in timer mode, it will be paused and the remaining time will be changed. This will not start the countdown on its own. 34 | 35 | 36 | !!!info "setValue(seconds)" 37 | * [](../types.md) **seconds**: How many seconds will be counted down. 38 | 39 | ``` Lua 40 | self.Clock.setValue(30) 41 | ``` 42 | -------------------------------------------------------------------------------- /docs/behavior/container.md: -------------------------------------------------------------------------------- 1 | The Container behavior is present on Container objects such as Bags, Stacks and Decks. 2 | 3 | --- 4 | 5 | ## Function Summary 6 | 7 | Function Name | Return | Description | 8 | -- | -- | -- | --: 9 | search([](../types.md) player, [](../types.md) max_card) | Activate search window for player, optionally limited to top N cards | [](../types.md) | [:i:](#search) 10 | 11 | --- 12 | 13 | ## Function Details {: data-toc-sort } 14 | 15 | ### search(...) 16 | 17 | [](../types.md) Show the Search window for the container to `player`. If you specify `max_cards` then the search will be limited to that many cards from the top of the deck. 18 | 19 | 20 | !!!info "search(player, max_cards)" 21 | * [](../types.md) **player**: The player to show the Search window to. 22 | * [](../types.md) **max_cards**: Optional maximum number of cards to show. 23 | 24 | ``` Lua 25 | deck.Container.search(Player.Blue, 3) 26 | ``` 27 | -------------------------------------------------------------------------------- /docs/behavior/counter.md: -------------------------------------------------------------------------------- 1 | The Counter behavior is present on the Counter object. 2 | 3 | ## Functions {: data-toc-sort } 4 | 5 | Function Name | Return | Description 6 | -- | -- | -- 7 | clear() {: #clear data-toc-label="clear()" data-toc-child-of="functions" } | [](../types.md) | Resets Counter to 0. 8 | decrement() {: #decrement data-toc-label="decrement()" data-toc-child-of="functions" } | [](../types.md) | Reduces Counter's value by 1. 9 | getValue() {: #getvalue data-toc-label="getValue()" data-toc-child-of="functions" } | [](../types.md) | Returns Counter's current value. This function behaves the same as [Object's getValue()](../object.md#getvalue). 10 | increment() {: #increment data-toc-label="increment()" data-toc-child-of="functions" } | [](../types.md) | Increases Counter's value by 1. 11 | setValue() {: #setvalue data-toc-label="setValue()" data-toc-child-of="functions" } | [](../types.md) | Sets the current value of the Counter. This function behaves the same as [Object's setValue()](../object.md#setvalue). 12 | 13 | !!!example 14 | Increment a counter's value. 15 | ```lua 16 | object.Counter.increment() 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/behavior/layoutzone.md: -------------------------------------------------------------------------------- 1 | The LayoutZone behavior is present on [Layout Zones](https://kb.tabletopsimulator.com/game-tools/zone-tools/#layout-zone). 2 | 3 | ## Functions {: data-toc-sort } 4 | 5 | Function Name | Return | Description 6 | -- | -- | -- 7 | getOptions() {: #getoptions data-toc-label="getOptions()" data-toc-child-of="functions" } | [](../types.md) | Returns the layout zones [options](#options). 8 | layout() {: #layout data-toc-label="layout()" data-toc-child-of="functions" } | [](../types.md) | Causes the layout zone to (re)layout. 9 | setOptions([](../types.md) options) {: #setoptions data-toc-label="setOptions(...)" data-toc-child-of="functions" } | [](../types.md) | Sets the layout zone's [options](#options). If an option is not included in the table, then the zone's value for that option will remain unchanged. 10 | 11 | !!!example 12 | Log a layout zone's options. 13 | ```lua 14 | log(zone.LayoutZone.getOptions()) 15 | ``` 16 | 17 | ## Options 18 | 19 | Layout zone option tables may contain the following properties. 20 | 21 | Name | Type | Description 22 | -- | -- | -- 23 | allow_swapping {: #allow_swapping } | [](../types.md) | When moving an object from one full group to another, the object you drop on will be moved to the original group. 24 | alternate_direction {: #alternate_direction } | [](../types.md) | Objects added to a group will be aligned up or right, different from the preceding object in the group. Used, for example, in trick-taking games to make counting easier. 25 | cards_per_deck {: #cards_per_deck } | [](../types.md) | Sets the size of decks made by the layout zone when it combines newly added cards. 26 | combine_into_decks {: #combine_into_decks } | [](../types.md) | Whether cards added to the zone should be combined into decks. You may specify the number of cards per deck. 27 | direction {: #direction } | [](../types.md) | The directions the groups in the zone expand into. This will determine the origin corner. 28 | horizontal_group_padding {: #horizontal_group_padding } | [](../types.md) | How much horizontal space is inserted between groups. 29 | horizontal_spread {: #horizontal_spread } | [](../types.md) | How far each object in a group is moved horizontally from the previous object. 30 | instant_refill {: #instant_refill } | [](../types.md) | When enabled, if ever a group is picked up or removed the rest of the layout will trigger to fill in the gap 31 | manual_only {: #manual_only } | [](../types.md) | The zone will not automatically lay out objects: it must be triggered manually. 32 | max_objects_per_group {: #max_objects_per_group } | [](../types.md) | Each group in the zone may not contain more than this number of objects. 33 | max_objects_per_new_group {: #max_objects_per_new_group } | [](../types.md) | When new objects are added to a zone, they will be gathered into groups of this many objects. 34 | meld_direction {: #meld_direction } | [](../types.md) | The direction the objects within a group will expand into. 35 | meld_reverse_sort {: #meld_reverse_sort } | [](../types.md) | When enabled the sort order inside a group is reversed 36 | meld_sort {: #meld_sort } | [](../types.md) | How groups are sorted internally. 37 | meld_sort_existing {: #meld_sort_existing } | [](../types.md) | When enabled all groups will be sorted when laid out, rather than only newly added groups. 38 | new_object_facing {: #new_object_facing } | [](../types.md) | Determines whether newly added objects are turned face-up or face-down. 39 | randomize {: #randomize } | [](../types.md) | Objects will be randomized whenever they are laid out 40 | split_added_decks {: #split_added_decks } | [](../types.md) | Decks added to the zone will be split into their individual cards. 41 | sticky_cards {: #sticky_cards } | [](../types.md) | When picked up, cards above the grabbed card will also be lifted. 42 | trigger_for_face_down {: #trigger_for_face_down } | [](../types.md) | Face-Down objects dropped on zone will be laid out. 43 | trigger_for_face_up {: #trigger_for_face_up } | [](../types.md) | Face-Up objects dropped on zone will be laid out. 44 | trigger_for_non_cards {: #trigger_for_non_cards } | [](../types.md) | Non-card objects dropped on zone will be laid out 45 | vertical_group_padding {: #vertical_group_padding } | [](../types.md) | How much vertical space is inserted between groups. 46 | vertical_spread {: #vertical_spread } | [](../types.md) | How far each object in a group is moved vertically from the previous object. 47 | -------------------------------------------------------------------------------- /docs/behavior/rpgfigurine.md: -------------------------------------------------------------------------------- 1 | The RPGFigurine behavior is present on Objects that are figurines with built-in animations i.e. RPG Kit objects. 2 | 3 | ## Callback Members 4 | 5 | These are `RPGFigurine` member variable which can be assigned a function that will be executed in response to an even 6 | occurring. 7 | 8 | Member Name | Description | 9 | -- | -- | -- 10 | onAttack([](../types.md) hitObjects) | Executed when an attack is performed by the RPGFigurine Object. | [:i:](#onattack) 11 | onHit([](../types.md) attacker) | Executed when the RPGFigurine Object is attacked. | [:i:](#onattack) 12 | 13 | ## Functions {: data-toc-sort } 14 | 15 | Function Name | Return | Description 16 | -- | -- | -- 17 | attack() {: #attack data-toc-label="attack()" data-toc-child-of="functions" } | [](../types.md) | Plays a random attack animation. 18 | changeMode() {: #changemode data-toc-label="changeMode()" data-toc-child-of="functions" } | [](../types.md) | Changes the figurine's current mode. What the mode represents is based on the figurine. 19 | die() {: #die data-toc-label="die()" data-toc-child-of="functions" } | [](../types.md) | Plays the death animation or causes it to return to life. 20 | 21 | !!!example 22 | Make an RPG figurine attack. 23 | ```lua 24 | object.RPGFigurine.attack() 25 | ``` 26 | --- 27 | 28 | ## Callback Member Details 29 | 30 | ### onAttack(...) 31 | 32 | Executed when an attack is performed by the RPGFigurine Object. 33 | 34 | An attack is triggered via the context menu or by pressing the appropriate number key. If another RPGFigurine is within 35 | its attack arc, then [onHit](#onhit) will be executed on the other figurine. 36 | 37 | !!!info "onAttack(hitObjects)" 38 | * [](../types.md) **hitObjects**: A table of RPGFigurine Objects within the reach of the attack. 39 | 40 | !!!example 41 | Assign an `onAttack` callback that prints the name of each object attacked. 42 | ```lua 43 | function object.RPGFigurine.onAttack(hitObjects) 44 | for _, v in ipairs(hitObjects) do 45 | print(v.getName() .. " was hit!") 46 | end 47 | end 48 | ``` 49 | 50 | --- 51 | 52 | 53 | ### onHit(...) 54 | 55 | Executed when the RPGFigurine Object is hit by another attacking RPGFigure Object. 56 | 57 | An attack is triggered via the context menu or by pressing the appropriate number key. If this RPGFigurine Object is 58 | within the attack radius of an attacker, this function will be executed. 59 | 60 | !!!info "onHit(attacker)" 61 | * [](../types.md) **attacker**: The RPGFigurine Object performing the attack. 62 | 63 | !!!example 64 | Assign an `onHit` callback that prints the name of the object that performed the attack. 65 | ```lua 66 | function object.RPGFigurine.onHit(attacker) 67 | print(attacker.getName() .. " attacked the Cyclops!") 68 | end 69 | ``` 70 | -------------------------------------------------------------------------------- /docs/behavior/texttool.md: -------------------------------------------------------------------------------- 1 | The TextTool behavior is present on 3DText objects i.e those created with the 2 | [text tool](https://kb.tabletopsimulator.com/game-tools/text-tool/). 3 | 4 | ## Functions {: data-toc-sort } 5 | 6 | Function Name | Return | Description 7 | -- | -- | -- 8 | getFontColor() {: #getfontcolor data-toc-label="getFontColor()" data-toc-child-of="functions" } | [](../types.md#color) | Returns Table of font Color. 9 | getFontSize() {: #getfontsize data-toc-label="getFontSize()" data-toc-child-of="functions" } | [](../types.md) | Returns Int of the font size. 10 | getValue() {: #getvalue data-toc-label="getValue()" data-toc-child-of="functions" } | [](../types.md) | Returns the current text. Behaves the same as Object's [getValue()](../object.md#getvalue). 11 | setFontColor([](../types.md#color) font_color) {: #setfontcolor data-toc-label="setFontColor(...)" data-toc-child-of="functions" } | [](../types.md) | Sets font Color. 12 | setFontSize([](../types.md) font_size) {: #setfontsize data-toc-label="setFontSize(...)" data-toc-child-of="functions" } | [](../types.md) | Sets font size. 13 | setValue([](../types.md) text) {: #setvalue data-toc-label="setValue(...)" data-toc-child-of="functions" } | [](../types.md) | Sets the current text. Behaves the same as Object's [setValue(...)](../object.md#setvalue). 14 | -------------------------------------------------------------------------------- /docs/components/component.md: -------------------------------------------------------------------------------- 1 | !!!danger 2 | Component APIs are an advanced feature. An **understanding of how Unity works is required** to utilize them. 3 | 4 | ## Member Variables 5 | 6 | Name | Type | Description | Return 7 | -- | -- | -- | -- 8 | game_object {: #game_object } | [GameObject](gameobject.md) | The GameObject the Component composes. 9 | name {: #name } | [](../types.md) | The name of the Component. 10 | 11 | ## Functions {: data-toc-sort } 12 | 13 | Name | Return | Description 14 | -- | -- | -- 15 | get([](../types.md) name) {: #get data-toc-label="get(...)" data-toc-child-of="functions" } | [](../types.md) | Obtains the value of a given Variable on a Component. 16 | getVars() {: #getvars data-toc-label="getVars()" data-toc-child-of="functions" } | [](../types.md) | Returns a table mapping Var names ([](../types.md)) to their type, which is also represented as a [](../types.md). 17 | set([](../types.md) name, [](../types.md) value) {: #set data-toc-label="set(...)" data-toc-child-of="functions" } | [](../types.md) | Sets the Var of the specified `name` to the provided `value`. 18 | 19 | -------------------------------------------------------------------------------- /docs/components/examples.md: -------------------------------------------------------------------------------- 1 | !!!danger 2 | Component APIs are an advanced feature. An **understanding of how Unity works is required** to utilize them. 3 | 4 | These examples are complete scripts which can be placed on a regular Red Block. 5 | 6 | !!!example 7 | Disable shadow receiving for an object. 8 | 9 | ```lua 10 | function onLoad() 11 | -- Get the MeshRenderer of the block's GameObject 12 | local meshRenderer = self.getComponent("MeshRenderer") 13 | -- Disable its ability to have a shadow cast onto it by another Object 14 | meshRenderer.set("receiveShadows", false) 15 | end 16 | ``` 17 | 18 | !!!example 19 | Disable an object's (box) collider. This will typically result in the object falling through the table. 20 | 21 | ```lua 22 | function onLoad() 23 | -- Get the BoxCollider Component of the block's GameObject 24 | local boxCollider = self.getComponent("BoxCollider") 25 | -- Disable the BoxCollider Component 26 | boxCollider.set("enabled", false) 27 | end 28 | ``` 29 | 30 | !!!example 31 | Disable audio for an object. The object will no longer make sound e.g. when picked up from or dropped on the table. 32 | Other objects may continue to make sound when colliding with this object. 33 | 34 | ```lua 35 | function onLoad() 36 | -- Get the AudioSource Component of the block's GameObject 37 | local blockComp = self.getComponent("AudioSource") 38 | -- Mute it 39 | blockComp.set("mute", true) 40 | end 41 | ``` 42 | -------------------------------------------------------------------------------- /docs/components/gameobject.md: -------------------------------------------------------------------------------- 1 | !!!danger 2 | Component APIs are an advanced feature. An **understanding of how Unity works is required** to utilize them. 3 | 4 | ## Member Variables 5 | 6 | Name | Type | Description 7 | -- | -- | -- 8 | name {: #name } | [](../types.md) | The name of the GameObject. 9 | 10 | ## Functions {: data-toc-sort } 11 | 12 | Name | Return | Description 13 | -- | -- | -- 14 | getChild([](../types.md) name) {: #getchild data-toc-label="getChild(...)" data-toc-child-of="functions" } | [GameObject](gameobject.md) | Returns a child GameObject matching the specified `name`. 15 | getChildren() {: #getchildren data-toc-label="getChildren()" data-toc-child-of="functions" } | [](../types.md) | Returns the list of children GameObjects. 16 | getComponent([](../types.md) name) {: #getcomponent data-toc-label="getComponent(...)" data-toc-child-of="functions" } | [Component](component.md) | Returns a Component matching the specified `name` from the GameObject's list of Components. 17 | getComponentInChildren([](../types.md) name) {: #getcomponentinchildren data-toc-label="getComponentInChildren(...)" data-toc-child-of="functions" } | [Component](component.md) | Returns a Component matching the specified `name`. Found by searching the Components of the GameObject and its [children](#getchildren) recursively (depth first). 18 | getComponents([](../types.md) name) {: #getcomponents data-toc-label="getComponents(...)" data-toc-child-of="functions" } | [](../types.md) | Returns the GameObject's list of Components. `name` is optional, when specified only Components with specified `name` will be included. 19 | getComponentsInChildren([](../types.md) name) {: #getcomponentsinchildren data-toc-label="getComponentsInChildren(...)" data-toc-child-of="functions" } | [](../types.md) | Returns a list of Components found by searching the GameObject and its [children](#getchildren) recursively (depth first). `name` is optional, when specified only Components with specified `name` will be included. 20 | getMaterials() {: #getmaterials data-toc-label="getMaterials()" data-toc-child-of="functions" } | [](../types.md) | Returns the GameObject's list of Materials. 21 | getMaterialsInChildren() {: #getmaterialsinchildren data-toc-label="getMaterialsInChildren()" data-toc-child-of="functions" } | [](../types.md) | Returns a list of Materials found by searching the GameObject and its [children](#getchildren) recursively (depth first). 22 | -------------------------------------------------------------------------------- /docs/components/introduction.md: -------------------------------------------------------------------------------- 1 | !!!danger 2 | Component APIs are an advanced feature. An **understanding of how Unity works is required** to utilize them. 3 | 4 | A Component is a collection of functions and variables that allow you to control object behavior. 5 | 6 | Components are a [Unity concept](https://docs.unity3d.com/Manual/Components.html), they're the building blocks that 7 | Tabletop Simulator objects are composed of. 8 | 9 | ## GameObjects 10 | 11 | Every object in Tabletop Simulator is a [GameObject](gameobject.md). When a game is created, GameObjects are loaded, 12 | initialized and _some_ of these top-level GameObjects are then exposed via Tabletop Simulator's Lua scripting APIs 13 | as regular [Objects](../object.md), each with their own scripting contexts. 14 | 15 | Some Lua-exposed Objects are made-up of hierarchy of children GameObjects. The Component APIs allow to access and 16 | interact with these children GameObjects (which you'd otherwise be unable to control). 17 | 18 | ## Components 19 | 20 | GameObjects are themselves made up of [Components](component.md). A typical GameObject would contain a Collider, 21 | Transform, Mesh etc. These Components describe the GameObject's behavior and visual representation. 22 | 23 | !!!tip 24 | In addition to built-in Objects, the Component APIs provide access the GameObjects and Components that exist in 25 | AssetBundles. This means that when creating an AssetBundle, you may attach all manner of components (lights, sounds 26 | etc.) and you'll be able to control them via these APIs. 27 | 28 | ## Vars 29 | 30 | Each Component has **Vars**. These are variables which you can modify to change how that Component affects the 31 | GameObject it composes. 32 | 33 | ## Materials 34 | 35 | GameObjects with Renderer components typically also have attached [Materials](material.md), which govern the appearance of the object. 36 | -------------------------------------------------------------------------------- /docs/components/material.md: -------------------------------------------------------------------------------- 1 | The Material of a Renderer [component](component.md) is the primary method of controlling that object's appearance. 2 | 3 | ## Member Variables 4 | 5 | Name | Type | Description | Return 6 | -- | -- | -- | -- 7 | game_object {: #game_object } | [GameObject](gameobject.md) | The GameObject the Material is attached to. 8 | shader {: #shader } | [](../types.md) | The name of the Shader used by the Material. 9 | 10 | ## Functions {: data-toc-sort } 11 | 12 | Name | Return | Description 13 | -- | -- | -- 14 | get([](../types.md) name) {: #get data-toc-label="get(...)" data-toc-child-of="functions" } | [](../types.md) | Obtains the value of a given Variable on a Material. 15 | getVars() {: #getvars data-toc-label="getVars()" data-toc-child-of="functions" } | [](../types.md) | Returns a table mapping Var names ([](../types.md)) to their type, which is also represented as a [](../types.md). 16 | set([](../types.md) name, [](../types.md) value) {: #set data-toc-label="set(...)" data-toc-child-of="functions" } | [](../types.md) | Sets the Var of the specified `name` to the provided `value`. 17 | -------------------------------------------------------------------------------- /docs/css/i_icons.css: -------------------------------------------------------------------------------- 1 | /* Fixed size for icons in links in the last cell of tables i.e. (i) more info links. */ 2 | 3 | td:last-child > a > .twemoji { 4 | height: 22px; 5 | margin: -2px 0 0 0; 6 | } 7 | 8 | td:last-child > a > .twemoji > svg { 9 | width: 22px; 10 | height: 22px; 11 | max-width: 22px; 12 | max-height: 22px; 13 | } 14 | -------------------------------------------------------------------------------- /docs/css/player_color_table.css: -------------------------------------------------------------------------------- 1 | /*Formatting for Player Color page's table*/ 2 | 3 | table.playerColorTable { 4 | width: 100%; 5 | text-align: center; 6 | border-collapse: collapse; 7 | border-color: grey; 8 | border-spacing: 1px; 9 | border-radius: .1rem; 10 | box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12), 0 3px 1px -2px rgba(0,0,0,.2); 11 | } 12 | table.playerColorTable td { 13 | padding: 6px 2px; 14 | } 15 | table.playerColorTable tr:nth-child(even) { 16 | background: #E8E8E8; 17 | } 18 | table.playerColorTable thead th { 19 | font-size: 15px; 20 | font-weight: bold; 21 | color: #FFFFFF; 22 | background-color: rgba(0,0,0,.54); 23 | text-align: center; 24 | } 25 | table.playerColorTable td { 26 | vertical-align: middle; 27 | } 28 | table.playerColorTable th { 29 | padding: 16px 2px; 30 | } 31 | -------------------------------------------------------------------------------- /docs/css/table.css: -------------------------------------------------------------------------------- 1 | /*General table formatting of markdown-created tables*/ 2 | 3 | /*Table Striping*/ 4 | .md-typeset__table table tr:nth-child(even) { 5 | background-color: #f2f2f2; 6 | } 7 | 8 | /*Table padding*/ 9 | .md-typeset table:not([class]) td { 10 | padding: 4px 6px; 11 | vertical-align: middle; 12 | } 13 | .md-typeset table:not([class]) th { 14 | min-width: 0px; 15 | padding: 14px 6px; 16 | } 17 | 18 | /*Prevent break of function name in table*/ 19 | .md-typeset table th:first-child { 20 | white-space: nowrap; 21 | } 22 | 23 | /*Prevent break of function name in table*/ 24 | .md-typeset table td:first-child { 25 | font-family: 'Inconsolata', 'Monaco', 'Consolas', 'Courier New', 'Courier'; 26 | } 27 | 28 | 29 | /*Nowrap on first row of tables 30 | html body div.md-container table tr td:first-child { 31 | white-space: nowrap; 32 | }*/ 33 | -------------------------------------------------------------------------------- /docs/css/theme.css: -------------------------------------------------------------------------------- 1 | /*Disable top bar shdow fade-in*/ 2 | .md-header { 3 | box-shadow: 0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2); 4 | } 5 | 6 | /*Increase width/height of icon on top bar*/ 7 | .md-header__button.md-logo img, 8 | .md-header__button.md-logo svg { 9 | width: 42px; 10 | height: 42px; 11 | } 12 | 13 | .md-header__button.md-logo { 14 | margin: 0 0.2rem 0 0.2rem; 15 | padding: 0; 16 | } 17 | 18 | /* Override scrollbar colors */ 19 | [class$=__scrollwrap]:hover, 20 | .md-typeset pre > code:hover { 21 | scrollbar-color: #bb0c0d transparent; 22 | } 23 | 24 | /*background behind current selection in left bar*/ 25 | [data-md-color-primary=indigo] .md-nav__link--active, [data-md-color-primary=indigo] .md-nav__link:active { 26 | color: black; 27 | background-color: #d3d3d3; 28 | } 29 | 30 | /*Coloring of top bar*/ 31 | [data-md-color-primary=indigo] .md-header, [data-md-color-primary=indigo] .md-hero { 32 | background-color: #bb0c0d; 33 | } 34 | 35 | /*Header coloring and formatting*/ 36 | .md-typeset h1 { 37 | color: #000000; 38 | font-weight: 600; 39 | font-size: 1.6rem; 40 | text-transform: none; 41 | font-family: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; 42 | } 43 | .md-typeset h2{ 44 | color: #202020; 45 | font-weight: 500; 46 | font-size: 1.45rem; 47 | text-transform: none; 48 | font-family: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; 49 | } 50 | .md-typeset h3 { 51 | color: #404040; 52 | font-weight: 500; 53 | font-size: 1.3rem; 54 | text-transform: none; 55 | font-family: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; 56 | } 57 | .md-typeset h4 { 58 | color: #606060; 59 | font-weight: 400; 60 | font-size: 1.15rem; 61 | text-transform: none; 62 | font-family: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; 63 | } 64 | .md-typeset h5 { 65 | color: #808080; 66 | font-weight: 300; 67 | font-size: 1rem; 68 | text-transform: none; 69 | font-family: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; 70 | } 71 | .md-typeset h6 { 72 | color: #A0A0A0; 73 | font-weight: 200; 74 | font-size: 0.85rem; 75 | text-transform: none; 76 | font-family: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; 77 | } 78 | 79 | /*Coloring of permalink icon*/ 80 | [data-md-color-accent=indigo] .md-nav__link:focus, [data-md-color-accent=indigo] .md-nav__link:hover, [data-md-color-accent=indigo] .md-typeset .footnote li:hover .footnote-backref:hover, [data-md-color-accent=indigo] .md-typeset .footnote li:target .footnote-backref, [data-md-color-accent=indigo] .md-typeset .md-clipboard:active:before, [data-md-color-accent=indigo] .md-typeset .md-clipboard:hover:before, [data-md-color-accent=indigo] .md-typeset [id] .headerlink:focus, [data-md-color-accent=indigo] .md-typeset [id]:hover .headerlink:hover, [data-md-color-accent=indigo] .md-typeset [id]:target .headerlink { 81 | color: #8b090a; 82 | } 83 | 84 | /*Make edit button red, !important required*/ 85 | .md-content__icon { 86 | color: #bb0c0d !important; 87 | } 88 | 89 | /*prevent left/right scrollbar 90 | .md-typeset .admonition, .md-typeset details { 91 | overflow-x:hidden; 92 | } 93 | disabled due to lack of need currently, but works*/ 94 | 95 | /*Make lines across pages solid*/ 96 | .md-typeset hr { 97 | border-bottom: .05rem solid rgba(0,0,0,.26); 98 | } 99 | 100 | .custom-line { 101 | border:0; 102 | border-top:1px solid rgba(0, 0, 0, 0.1); 103 | border-bottom: 1px solid rgba(255, 255, 255, 0.3); 104 | } 105 | 106 | .custom-link { 107 | color:#f4641d; 108 | position:relative; 109 | left:0.625rem; 110 | } 111 | 112 | [data-toc-mock-searchable] { 113 | scroll-margin-top: 72px !important; 114 | } 115 | -------------------------------------------------------------------------------- /docs/css/type_icons.css: -------------------------------------------------------------------------------- 1 | /*General Icon Formatting, used by all tag type icons*/ 2 | .tag { 3 | font-family: 'Inconsolata', 'Monaco', 'Consolas', 'Courier New', 'Courier'; 4 | font-weight: normal; 5 | text-align: center; 6 | font-size: 0.5rem; 7 | display: inline; 8 | padding: 2px 4px; 9 | border-radius:5px; 10 | position: relative; 11 | margin: 0px 1px; 12 | bottom: 2px; 13 | 14 | word-break: normal; 15 | 16 | width: 50px; 17 | min_width: 50px; 18 | line-height: 0; 19 | } 20 | .tag:hover { 21 | opacity: 0.75; 22 | } 23 | 24 | /*General Return Formatting, used by all return type icons*/ 25 | .ret { 26 | font-family: 'Inconsolata', 'Monaco', 'Consolas', 'Courier New', 'Courier'; 27 | /*background-color:rgba(1, 0, 0, 0.2);*/ 28 | font-style: italic; 29 | text-align: center; 30 | font-size: 0.5rem; 31 | /*padding: 1px 4px; 32 | box-shadow: 2px 2px #696969; 33 | border-radius: 6px;*/ 34 | border-radius:5px; 35 | padding: 2px 4px; 36 | display: inline-block; 37 | 38 | position: relative; 39 | bottom: 1px; 40 | left: 1px; 41 | vertical-align:middle; 42 | 43 | width: 50px; 44 | /*Squeezes lines together vertically*/ 45 | line-height: 1; 46 | 47 | word-break: keep-all; 48 | } 49 | .ret:hover { 50 | opacity: 0.75; 51 | } 52 | .ret:before { 53 | content: "return\A"; 54 | } 55 | 56 | 57 | 58 | 59 | /*String*/ 60 | .str { 61 | color: #000000; 62 | background-color: #ACC39B; 63 | } 64 | .str:after { 65 | content: "string"; 66 | } 67 | 68 | /*Table*/ 69 | .tab { 70 | color: #000000; 71 | background-color: rgba(1, 0, 0, 0.2); 72 | } 73 | .tab:after { 74 | content: "table"; 75 | } 76 | 77 | /*Integer*/ 78 | .int { 79 | color: #000000; 80 | background-color: #D48E87; 81 | } 82 | .int:after { 83 | content: "int"; 84 | } 85 | 86 | /*Float*/ 87 | .flo { 88 | color: #000000; 89 | background-color: #D48E87; 90 | } 91 | .flo:after { 92 | content: "float"; 93 | } 94 | 95 | /*Nil*/ 96 | .nil { 97 | color: #ffffff; 98 | background-color: rgba(1, 0, 0, 0.6); 99 | } 100 | .nil:after { 101 | content: "nil"; 102 | } 103 | 104 | /*Bool*/ 105 | .boo { 106 | color: #000000; 107 | background-color: #BE9FAD; 108 | } 109 | .boo:after { 110 | content: "bool"; 111 | } 112 | 113 | /*Object*/ 114 | .obj { 115 | color: #000000; 116 | background-color: #b1bfe0; 117 | } 118 | .obj:after { 119 | content: "object"; 120 | } 121 | 122 | /*Self*/ 123 | .sel { 124 | color: #000000; 125 | background-color: #fa983a; 126 | } 127 | .sel:after { 128 | content: "self"; 129 | } 130 | 131 | /*Var*/ 132 | .var { 133 | color: #000000; 134 | background-color: #E0E270; 135 | } 136 | .var:after { 137 | content: "var"; 138 | } 139 | 140 | /*Vector*/ 141 | .vec { 142 | color: #000000; 143 | background-color: #f4d29a; 144 | } 145 | .vec:after { 146 | content: "vector"; 147 | } 148 | 149 | /*Color*/ 150 | .col { 151 | color: #000000; 152 | background-color: #e2bae0; 153 | } 154 | .col:after { 155 | content: "color"; 156 | } 157 | 158 | /*Player*/ 159 | .pla { 160 | color: #000000; 161 | background-color: #b5e1e5; 162 | } 163 | .pla:after { 164 | content: "player"; 165 | } 166 | 167 | /*Function*/ 168 | .fun { 169 | color: #FFFFFF; 170 | background-color: #DE4816; 171 | } 172 | .fun:after { 173 | content: "func"; 174 | } 175 | 176 | /*Deprecated*/ 177 | .deprecated { 178 | color: #FFFFFF; 179 | background-color: #000000; 180 | } 181 | .deprecated:after { 182 | content: "deprecated"; 183 | } 184 | 185 | 186 | 187 | 188 | /*XML stuff*/ 189 | 190 | /*xmlcolor*/ 191 | .xmlco { 192 | color: #000000; 193 | background-color: #B87FED; 194 | } 195 | .xmlco:after { 196 | content: "color"; 197 | } 198 | 199 | /*xmlcolorblock*/ 200 | .xmlcb { 201 | color: #000000; 202 | background-color: #ed7feb; 203 | } 204 | .xmlcb:after { 205 | content: "colorblock"; 206 | } 207 | -------------------------------------------------------------------------------- /docs/custom-game-objects.md: -------------------------------------------------------------------------------- 1 | You can spawn [custom Objects](https://kb.tabletopsimulator.com/custom-content/about-custom-objects/) and then provide the custom content for them after spawning them by calling [setCustomObject()](object.md#setcustomobject). {>>See setCustomObject for usage<<} 2 | 3 | You can also use setCustomObject along with [reload()](object.md#reload) to modify an existing custom Object. 4 | 5 | ##Custom AssetBundle 6 | 7 | * Custom_Assetbundle 8 | 9 | !!!info "Custom Parameters" 10 | * [](types.md) **parameters**: A Table of parameters which determine the properties of the Object. 11 | * [](types.md) **assetbundle**: The path/URL for the AssetBundle. 12 | * [](types.md) **assetbundle_secondary**: The path/URL for the secondary AssetBundle property. 13 | * {>>Optional, is not used by default.<<} 14 | * [](types.md) **type**: An Int representing the Object's type. 15 | * {>>Optional, defaults to 0.<<} 16 | * **0**: Generic 17 | * **1**: Figurine 18 | * **2**: Dice 19 | * **3**: Coin 20 | * **4**: Board 21 | * **5**: Chip 22 | * **6**: Bag 23 | * **7**: Infinite bag 24 | * [](types.md) **material**: An Int representing the Object's material. 25 | * {>>Optional, defaults to 0.<<} 26 | * **0**: Plastic 27 | * **1**: Wood 28 | * **2**: Metal 29 | * **3**: Cardboard 30 | 31 | ##Custom Board 32 | 33 | * Custom_Board 34 | 35 | !!!info "Custom Parameters" 36 | * [](types.md) **parameters**: A Table of parameters which determine the properties of the Object. 37 | * [](types.md) **image**: The path/URL for the board. 38 | 39 | ##Custom Card 40 | 41 | * CardCustom 42 | 43 | !!!info "Custom Parameters" 44 | * [](types.md) **parameters**: A Table of parameters which determine the properties of the Object. 45 | * [](types.md) **type**: The card shape. 46 | * {>>Optional, defaults to 0.<<} 47 | * **0**: Rectangle (Rounded) 48 | * **1**: Rectangle 49 | * **2**: Hex (Rounded) 50 | * **3**: Hex 51 | * **4**: Circle 52 | * [](types.md) **face**: The path/URL of the face image. 53 | * [](types.md) **back**: The path/URL of the back image. 54 | * [](types.md) **sideways**: If the card is horizontal, instead of vertical. 55 | * {>>Optional, defaults to false.<<} 56 | 57 | ##Custom Deck 58 | 59 | * DeckCustom 60 | 61 | !!!info "Custom Parameters" 62 | * [](types.md) **parameters**: A Table of parameters which determine the properties of the Object. 63 | * [](types.md) **face**: The path/URL of the face cardsheet. 64 | * [](types.md) **back**: The path/URL of the back cardsheet or card back. 65 | * [](types.md) **unique_back**: If each card has a unique card back (via a cardsheet). 66 | * {>>Optional, defaults to false.<<} 67 | * [](types.md) **width**: The number of columns on the cardsheet. 68 | * {>>Optional, defaults to 10.<<} 69 | * [](types.md) **height**: The number of rows on the cardsheet. 70 | * {>>Optional, defaults to 7.<<} 71 | * [](types.md) **number**: The number of cards on the cardsheet. 72 | * {>>Optional, defaults to 52.<<} 73 | * [](types.md) **sideways**: Whether the cards are horizontal, instead of vertical. 74 | * {>>Optional, defaults to false.<<} 75 | * [](types.md) **back_is_hidden**: Whether the card back should be used as the hidden image (instead of the last slot of the `face` image). 76 | * {>>Optional, defaults to false.<<} 77 | 78 | ##Custom Dice 79 | 80 | * Custom_Dice 81 | 82 | !!!info "Custom Parameters" 83 | * [](types.md) **parameters**: A Table of parameters which determine the properties of the Object. 84 | * [](types.md) **image**: The path/URL for the [custom die](https://kb.tabletopsimulator.com/custom-content/custom-dice/). 85 | * [](types.md) **type**: The type of die, which determines its number of sides. 86 | * {>>Optional, defaults to 1.<<} 87 | * **0**: 4-sided 88 | * **1**: 6-sided 89 | * **2**: 8-sided 90 | * **3**: 10-sided 91 | * **4**: 12-sided 92 | * **5**: 20-sided 93 | 94 | ##Custom Figurine 95 | 96 | * Figurine_Custom 97 | 98 | !!!info "Custom Parameters" 99 | * [](types.md) **parameters**: A Table of parameters which determine the properties of the Object. 100 | * [](types.md) **image**: The path/URL for the [custom figurine](https://kb.tabletopsimulator.com/custom-content/custom-figurine/). 101 | * [](types.md) **image_secondary**: The path/URL for the custom figurine's back. 102 | * {>>Optional, defaults to "image".<<} 103 | 104 | ##Custom Model 105 | 106 | * Custom_Model 107 | 108 | !!!info "Custom Parameters" 109 | * [](types.md) **parameters**: A Table of parameters which determine the properties of the Object. 110 | * [](types.md) **mesh**: The path/URL for the .obj mesh used on the [custom model](https://kb.tabletopsimulator.com/custom-content/custom-model/). 111 | * [](types.md) **diffuse**: The path/URL for the diffuse image. 112 | * [](types.md) **normal**: The path/URL for the normals image. 113 | * {>>Optional, is not used by default.<<} 114 | * [](types.md) **collider**: The path/URL for the collider mesh. 115 | * {>>Optional, defaults to a generic box collider.<<} 116 | * [](types.md) **convex**: Whether the object model is convex. 117 | * {>>Optional, defaults to false.<<} 118 | * [](types.md) **type**: An Int representing the Object's type. 119 | * {>>Optional, defaults to 0.<<} 120 | * **0**: Generic 121 | * **1**: Figurine 122 | * **2**: Dice 123 | * **3**: Coin 124 | * **4**: Board 125 | * **5**: Chip 126 | * **6**: Bag 127 | * **7**: Infinite bag 128 | * [](types.md) **material**: An Int representing the Object's material. 129 | * {>>Optional, defaults to 0.<<} 130 | * **0**: Plastic 131 | * **1**: Wood 132 | * **2**: Metal 133 | * **3**: Cardboard 134 | * [](types.md) **specular_intensity**: The specular intensity. 135 | * {>>Optional, defaults to 0.1.<<} 136 | * [](types.md) **specular_color**: The specular [Color](types.md#color). 137 | * {>>Optional, defaults to {r=1, g=1, b=1}.<<} 138 | * [](types.md) **specular_sharpness**: The specular sharpness. 139 | * {>>Optional, defaults to 3.<<} 140 | * [](types.md) **freshnel_strength**: The freshnel strength. 141 | * {>>Optional, defaults to 0.1.<<} 142 | * [](types.md) **cast_shadows**: Whether the Object casts shadows. 143 | * {>>Optional, defaults to true.<<} 144 | 145 | ##Custom Tile 146 | 147 | * Custom_Tile 148 | 149 | !!!info "Custom Parameters" 150 | * [](types.md) **parameters**: A Table of parameters which determine the properties of the Object. 151 | * [](types.md) **image**: The path/URL for the [custom tile](https://kb.tabletopsimulator.com/custom-content/custom-tile/) image. 152 | * [](types.md) **type**: Determines the shape of the tile. 153 | * {>>Optional, defaults to 0.<<} 154 | * **0**: Square/Rectangle 155 | * **1**: Hex 156 | * **2**: Circle 157 | * [](types.md) **image_bottom**: The path/URL for the bottom-side image. 158 | * {>>Optional, uses the top image by default.<<} 159 | * [](types.md) **thickness**: How thick the tile is. 160 | * {>>Optional, defaults to 0.5.<<} 161 | * [](types.md) **stackable**: Whether these tiles stack together into a pile. 162 | * {>>Optional, defaults to false.<<} 163 | 164 | ##Custom Token 165 | 166 | * Custom_Token 167 | 168 | !!!info "Custom Parameters" 169 | * [](types.md) **parameters**: A Table of parameters which determine the properties of the Object. 170 | * [](types.md) **image**: The path/URL for the [custom token](https://kb.tabletopsimulator.com/custom-content/custom-token/) image. 171 | * [](types.md) **thickness**: How thick the token is. 172 | * {>>Optional, defaults to 0.2.<<} 173 | * [](types.md) **merge_distance**: How accurately the token shape will trace image edge (in pixels). 174 | * {>>Optional, defaults to 15.<<} 175 | * [](types.md) **stackable**: Whether these tokens stack together into a pile. 176 | * {>>Optional, defaults to false.<<} 177 | -------------------------------------------------------------------------------- /docs/externaleditorapi.md: -------------------------------------------------------------------------------- 1 | This page describes how our [Official Atom Plugin](atom.md) API works so that you can write your own plugin for your text editor of choice if Atom does not suit your needs. 2 | 3 | Communication between the editor and TTS occurs via two localhost TCP connections: one where TTS listens for messages and one where the editor listens for messages. All communication messages are JSON. 4 | 5 | ##Atom as the Server 6 | 7 | The following are messages the editor plugin listens for and handles. 8 | 9 | !!!note "" 10 | Atom listens for incoming localhost TCP connections on port 39998. 11 | 12 | ###Pushing New Object 13 | 14 | When clicking on "Scripting Editor" in the right click contextual menu in TTS for an object that doesn't have a Lua Script yet, TTS will send a JSON message with an ID of 0 and data for the object. The Atom plugin will open a new tab for this Object. If TTS is unable to connect to an external editor, e.g. if Atom is not running, then TTS falls back to the in-game editor. 15 | 16 | ```JSON 17 | { 18 | "messageID": 0, 19 | "scriptStates": [ 20 | { 21 | "name": "Chess Pawn", 22 | "guid": "db3f06", 23 | "script": "" 24 | } 25 | ] 26 | } 27 | ``` 28 | 29 | ###Loading a New Game 30 | 31 | After loading a new game in TTS, TTS will send all the Lua scripts and UI XML from the new game to Atom. TTS sends a JSON message with an ID of 1 and an array of the Lua Scripts and UI XMLs. TTS also sends this message as a response to requests made by the editor, as described later under messages TTS listens for and handles. 32 | 33 | ```JSON 34 | { 35 | "messageID": 1, 36 | "scriptStates": [ 37 | { 38 | "name": "Global", 39 | "guid": "-1", 40 | "script": "...", 41 | "ui": "..." 42 | }, 43 | { 44 | "name": "BlackJack Dealer's Deck", 45 | "guid": "a0b2d5", 46 | "script": "..." 47 | }, 48 | ] 49 | } 50 | ``` 51 | 52 | Note that this message contains all objects in the TTS session that have Lua scripts or UI XML data. Any object not mentioned by this message does not have a Lua script or UI XML in TTS. 53 | 54 | ###Print/Debug Messages 55 | 56 | TTS sends all print() messages to Atom to be displayed in Atom's console (ctrl + alt + i). TTS sends a JSON message with an ID of 2 and the message. 57 | 58 | ```JSON 59 | { 60 | "messageID": 2, 61 | "message": "Hit player! White" 62 | } 63 | ``` 64 | 65 | 66 | ###Error Messages 67 | 68 | TTS sends all Lua error messages to Atom to be displayed in Atom's console *(ctrl + alt + i)*. TTS sends a JSON message with an ID of 3 and the error message. 69 | 70 | ```JSON 71 | { 72 | "messageID": 3, 73 | "error": "chunk_0:(36,4-8): unexpected symbol near 'deck'", 74 | "guid": "-1", 75 | "errorMessagePrefix": "Error in Global Script: " 76 | } 77 | ``` 78 | 79 | 80 | ###Custom messages 81 | 82 | A `messageID` of *4* is used to send a custom message from TTS to the attached editor. This is done in Lua by calling `sendExternalMessage` with the table of data you wish to send. It is up to the editor how it uses this information (usually this message is used when the editor itself has sent code to be executed by TTS, which will send something back. i.e. this is mainly of use for people developing editor plugins). 83 | 84 | ```JSON 85 | { 86 | "messageID": 4, 87 | "customMessage": {"foo": "Hello", "bar": "World"} 88 | } 89 | ``` 90 | 91 | 92 | 93 | ###Return messages 94 | 95 | When the editor sends Lua code to TTS using the `Execute Lua Code` message (detailed below), if that code returns a value it will be sent back to the editor using message ID *5*. 96 | 97 | ```JSON 98 | { 99 | "messageID": 5, 100 | "returnValue": true 101 | } 102 | ``` 103 | 104 | 105 | 106 | ###Game Saved 107 | 108 | Whenever the player saves the game in TTS, a save game notification is sent to any attached editor using message ID *6*. 109 | 110 | 111 | 112 | ###Object Created 113 | 114 | Whenever the player creates an object in TTS a notification is sent to any attached editor using message ID *7*. 115 | 116 | ```JSON 117 | { 118 | "messageID": 7, 119 | "guid": "abcdef" 120 | } 121 | ``` 122 | 123 | 124 | 125 | ##Tabletop Simulator as the Server 126 | 127 | The following describes messages that TTS listens for and handles. 128 | 129 | !!!note "" 130 | TTS listens for incoming localhost TCP connections on port 39999. 131 | 132 | 133 | ###Get Lua Scripts 134 | 135 | TTS listens for a JSON message with an ID of 0, and responds by sending a JSON message containing scripts and UI XML. 136 | 137 | ```JSON 138 | { 139 | "messageID": 0 140 | } 141 | ``` 142 | 143 | The response is not sent over the same connection as the original request, but rather is sent to a server listening on the localhost on port 39998. The response is a message sent by TTS with an ID of 1, and is the same as the message TTS sends when loading a new game. 144 | 145 | ###Save & Play 146 | 147 | TTS listens for a JSON message with an ID of 1 containing an array of the Lua Scripts and UI XML. 148 | 149 | ```JSON 150 | { 151 | "messageID": 1, 152 | "scriptStates": [ 153 | { 154 | "name": "Global", 155 | "guid": "-1", 156 | "script": "...", 157 | "ui": "..." 158 | }, 159 | { 160 | "name": "Block Rectangle", 161 | "guid": "a0b2d5", 162 | "script": "..." 163 | }, 164 | ] 165 | } 166 | ``` 167 | 168 | TTS updates the Lua scripts and UI XML for any objects listed in the message, and then reloads the save file, the same way it does when pressing "Save & Play" within the in-game editor. Objects not mentioned in the scriptStates array are not updated. 169 | 170 | Any objects mentioned have both their Lua script and their UI XML updated. If no value is set for either the "script" or "ui" key then the corresponding Lua script or UI XML is deleted. That means if you want to update a Lua script for an object without changing its UI XML, then the message must contain both the updated Lua script and the unchanged UI XML. 171 | 172 | After TTS reloads the game, it then also sends a message with an ID of 1 back to the editor, with content the same as the message TTS sends when loading a new game. 173 | 174 | ###Custom Message 175 | 176 | TTS listens for a JSON message with an ID of 2 containing a custom message to be forwarded to the [`onExternalMessage`](events.md#onexternalmessage) event handler in the currently loaded game. 177 | 178 | ```JSON 179 | { 180 | "messageID": 2, 181 | "customMessage": {...} 182 | } 183 | ``` 184 | 185 | The value of `customMessage` must be a table, and is passed as a parameter to the event handler. If this value is not a table then the event is not triggered. 186 | 187 | ###Execute Lua Code 188 | 189 | TTS listens for a JSON message with an ID of 3 containing an object guid and lua script to run. 190 | 191 | ```JSON 192 | { 193 | "messageID": 3, 194 | "guid":"-1", 195 | "script":"print(\"Hello, World\")" 196 | } 197 | ``` 198 | 199 | To execute Lua code for an object in the game that object must have an associated script in TTS. Otherwise the TTS scripting engine will fail with an error "function \[](intro.md#deprecated) _Use [playlist_index](#playlist_index)_.
Current index of the playlist. `-1` if no playlist audioclip is playing. | [](types.md) 10 | playlist_index {: #playlist_index } | Current index of the playlist. `-1` if no playlist audioclip is playing. | [](types.md) 11 | repeat_track {: #repeat_track } | If the current audioclip should be repeated. | [](types.md) 12 | shuffle {: #shuffle } | If the playlist should play shuffled. | [](types.md) 13 | 14 | ##Function Summary 15 | 16 | Functions that interact with the in-game music player. 17 | 18 | Function Name | Description | Return | 19 | -- | -- | -- | -- 20 | getCurrentAudioclip() | Gets the currently loaded audioclip. | [](types.md)| [:i:](#getcurrentaudioclip) 21 | getPlaylist() | Gets the current playlist. | [](types.md)| [:i:](#getplaylist) 22 | pause() | Pauses currently playing audioclip. Returns true if the music player is paused, otherwise returns false. | [](types.md)| [:i:](#pause) 23 | play() | Plays currently loaded audioclip. Returns true if the music player is playing, otherwise returns false. | [](types.md) | [:i:](#play) 24 | setCurrentAudioclip() | Sets the audioclip to be loaded. | [](types.md)| [:i:](#setcurrentaudioclip) 25 | setPlaylist() | Sets the current playlis 26 | skipBack() | Skips to the beginning of the audioclip or if the play time is less than 3 seconds to the previous audioclip in playlist if possible. Returns true if skip was successful, otherwise returns false. | [](types.md)| [:i:](#skipback) 27 | skipForward() | Skips to the next audioclip in playlist if possible. Returns true if skip was successful, otherwise returns false. | [](types.md)| [:i:](#skipforward) | [](types.md)| [:i:](#setplaylist) 28 | 29 | --- 30 | 31 | ##Function Details 32 | 33 | ####getCurrentAudioclip() 34 | 35 | [](types.md) Gets the currently loaded audioclip. 36 | 37 | !!!info "Returned table" 38 | * [](types.md) Table describing the current audioclip. 39 | * [](types.md) **url**: The URL of the current audioclip. 40 | * [](types.md) **title**: The title of the current audioclip. 41 | 42 | !!!example 43 | Print the title of the current audioclip. 44 | ``` Lua 45 | local clip = MusicPlayer.getCurrentAudioclip() 46 | print("Currently playing '" .. clip.title .. "'") 47 | ``` 48 | 49 | --- 50 | 51 | ####getPlaylist() 52 | 53 | [](types.md) Gets the current playlist. 54 | 55 | !!!info "Returned table" 56 | * [](types.md) Playlist table, consisting of zero or more audioclip sub-tables. 57 | * [](types.md) Sub-table describing each audioclip. 58 | * [](types.md) **url**: The URL of the current audioclip. 59 | * [](types.md) **title**: The title of the current audioclip. 60 | 61 | !!!example 62 | Print the track number and title of each audioclip making up the playlist. 63 | ``` Lua 64 | local playlist = MusicPlayer.getPlaylist() 65 | for i, clip in ipairs(playlist) do 66 | print(i .. " - " .. clip.title) 67 | end 68 | ``` 69 | 70 | --- 71 | 72 | ####pause() 73 | 74 | [](types.md) Pause the current audioclip. 75 | 76 | Returns `true` if the music player is/was paused, otherwise `false`. 77 | 78 | !!!example 79 | Pause the current track. 80 | ``` Lua 81 | MusicPlayer.pause() 82 | ``` 83 | 84 | --- 85 | 86 | ####play() 87 | 88 | [](types.md) Plays the current audioclip. 89 | 90 | Returns `true` if the music player is/was playing, otherwise `false`. 91 | 92 | !!!example 93 | Play the current track. 94 | ``` Lua 95 | MusicPlayer.play() 96 | ``` 97 | 98 | --- 99 | 100 | ####setCurrentAudioclip(...) 101 | 102 | [](types.md) .Sets/loads the specified audioclip. 103 | 104 | !!!info "setCurrentAudioclip(parameters)" 105 | * [](types.md) **parameters**: A table describing an audioclip. 106 | * [](types.md) **url**: The URL of the audioclip. 107 | * [](types.md) **title**: The title of the audioclip. 108 | 109 | !!!example 110 | Set the current track. 111 | ``` Lua 112 | MusicPlayer.setCurrentAudioclip({ 113 | url = "https://domain.example/path/to/clip.mp3", 114 | title = "Example" 115 | }) 116 | ``` 117 | 118 | --- 119 | 120 | ####setPlaylist(...) 121 | 122 | [](types.md) Sets the current playlist. 123 | 124 | !!!info "setPlaylist(parameters)" 125 | * [](types.md) **parameters**: A table containing zero or more audioclip sub-tables. 126 | * [](types.md) Sub-table describing each audioclip. 127 | * [](types.md) **parameters.url**: The URL of an audioclip. 128 | * [](types.md) **parameters.title**: The title of an audioclip. 129 | 130 | !!!example 131 | Set the current playlist to include three pieces of music. 132 | ``` Lua 133 | MusicPlayer.setCurrentAudioclip({ 134 | { 135 | url = "https://domain.example/path/to/clip.mp3", 136 | title = "Example" 137 | }, 138 | { 139 | url = "https://domain.example/path/to/clip2.mp3", 140 | title = "Example #2" 141 | }, 142 | { 143 | url = "https://domain.example/path/to/clip3.mp3", 144 | title = "Example #3" 145 | } 146 | }) 147 | ``` 148 | 149 | --- 150 | 151 | ####skipBack() 152 | 153 | [](types.md) Skips to the beginning of the audioclip or if the play time is less than 3 seconds to the previous audioclip in playlist if possible. 154 | 155 | Returns `true` if skip was successful, otherwise returns `false`. 156 | 157 | !!!example 158 | Skip backwards to either the beginning of the audioclip, or the prior audioclip in the playlist. 159 | ``` Lua 160 | MusicPlayer.skipBack() 161 | ``` 162 | 163 | --- 164 | 165 | ####skipForward() 166 | 167 | [](types.md) Skips to the next audioclip in the current playlist. If the current 168 | audioclip is the last of the playlist, loops around to the first audioclip in the playlist. 169 | 170 | 171 | Returns `true` if skip was successful, otherwise returns `false`. 172 | 173 | 174 | !!!example 175 | Skip to the next audioclip. 176 | ``` Lua 177 | MusicPlayer.skipForward() 178 | ``` 179 | 180 | --- 181 | -------------------------------------------------------------------------------- /docs/notes.md: -------------------------------------------------------------------------------- 1 | Notes, a static global class, allows access to the on-screen notes and the notebook. 2 | 3 | Example function call: `Notes.setNotes()` 4 | 5 | ##Function Summary 6 | 7 | ###Notebook Functions 8 | Functions that interact with the in-game notebook tabs. 9 | 10 | Function Name | Description | Return | 11 | -- | -- | -- | -- 12 | addNotebookTab([](types.md) parameters) | Adds a notebook tab, returning its index. | [](types.md) | [:i:](#addnotebooktab) 13 | editNotebookTab([](types.md) parameters) | Edit an existing Tab in the notebook. | [](types.md) | [:i:](#editnotebooktab) 14 | getNotebookTabs() | Returns Table containing data on all tabs in the notebook. | [](types.md) | [:i:](#getnotebooktabs) 15 | removeNotebookTab([](types.md) index) | Remove a notebook tab. | [](types.md) | [:i:](#removenotebooktab) 16 | 17 | ###Notes Functions 18 | Functions that interact with the on-screen notes (lower right corner of screen). 19 | 20 | Function Name | Description | Return | 21 | -- | -- | -- | -- 22 | getNotes() {: #getnotes data-toc-label="getNotes()" data-toc-child-of="notes-function-details" } | Returns the contents of the on-screen notes section. | [](types.md) | 23 | setNotes([](types.md) notes) | Replace the text in the notes window with the string. | [](types.md) | [:i:](#setnotes) 24 | 25 | --- 26 | 27 | 28 | ##Function Details 29 | 30 | 31 | ###Notebook Function Details 32 | 33 | ####addNotebookTab(...) 34 | 35 | [](types.md) Add a new notebook tab. If it failed to create a new tab, a -1 is returned instead. Indexes for notebook tabs begin at 0. 36 | 37 | !!!info "addNotebookTab(parameters)" 38 | * [](types.md) **parameters**: A Table containing spawning parameters. 39 | * [](types.md) **parameters.title**: Title for the new tab. 40 | * [](types.md) **parameters.body**: Text to place into the body of the new tab. 41 | * {>>Optional, defaults to an empty string<<} 42 | * [](types.md) **parameters.color**: [Player Color](player/instance.md) for the new tab's color. 43 | * {>>Optional, defaults to "Grey"<<} 44 | 45 | ``` Lua 46 | parameters = { 47 | title = "New Tab", 48 | body = "Body text example.", 49 | color = "Grey" 50 | } 51 | Notes.addNotebookTab(parameters) 52 | ``` 53 | 54 | --- 55 | 56 | 57 | ####editNotebookTab(...) 58 | 59 | [](types.md) Edit an existing Tab in the notebook. Indexes for notebook tabs begin at 0. 60 | 61 | !!!info "editNotebookTab(parameters)" 62 | * [](types.md) **parameters**: A Table containing instructions for the notebook edit. 63 | * [](types.md) **parameters.index**: Index number for the tab. 64 | * [](types.md) **parameters.title**: Title for the tab. 65 | * {>>Optional, defaults to the current title of the tab begin edited.<<} 66 | * [](types.md) **parameters.body**: Text for the body for the tab. 67 | * {>>Optional, defaults to the current body of the tab begin edited.<<} 68 | * [](types.md) **parameters.color**: [Player Color](player/colors.md) for who the tab belongs to. 69 | * {>>Optional, defaults to the current color of the tab begin edited.<<} 70 | 71 | ``` Lua 72 | params = { 73 | index = 5, 74 | title = "Edited Title", 75 | body = "This tab was edited via script.", 76 | color = "Grey" 77 | } 78 | Notes.editNotebookTab(params) 79 | ``` 80 | 81 | --- 82 | 83 | 84 | ####getNotebookTabs() 85 | 86 | [](types.md) Returns a Table containing data on all tabs in the notebook. Indexes for notebook tabs begin at 0. 87 | 88 | ``` Lua 89 | --Example Usage 90 | tabInfo = Notes.getNotebookTabs() 91 | ``` 92 | ``` Lua 93 | --Example Returned Table 94 | { 95 | {index=0, title="", body="", color="Grey"}, 96 | {index=1, title="", body="", color="Grey"}, 97 | {index=2, title="", body="", color="Grey"}, 98 | } 99 | ``` 100 | 101 | --- 102 | 103 | 104 | ####removeNotebookTab(...) 105 | 106 | [](types.md) Remove a notebook tab. Notebook tab indexes begin at 0. 107 | 108 | !!!info "removeNotebookTab(index)" 109 | * [](types.md) **index**: Index for the tab to remove. 110 | 111 | ``` Lua 112 | Notes.removeNotebookTab(0) 113 | ``` 114 | 115 | --- 116 | 117 | 118 | 119 | 120 | 121 | ###Notes Function Details {: data-toc-sort } 122 | 123 | 124 | ####setNotes(...) 125 | 126 | [](types.md) Replace the text in the notes window with the string. The notes is an area which displays text in the lower-right corner of the screen. 127 | 128 | !!!info "setNotes(notes)" 129 | * [](types.md) **notes**: What to place into the notes area. 130 | 131 | ``` Lua 132 | Notes.setNotes("This appears in the notes section") 133 | ``` 134 | 135 | --- 136 | -------------------------------------------------------------------------------- /docs/overview.md: -------------------------------------------------------------------------------- 1 | ## Available scripting methods 2 | 3 | ### In-Game Lua Editor 4 | You can access the in-game Lua Editor by clicking on **Scripting** on the top bar or by right clicking on an object, choosing Scripting, and then selecting Lua Editor from the contextual menu. In the Lua Editor, the tabs on the left of the editor let you switch between the Global and the Object scripts. Once your Lua code is written, you can use the *Save and Play* button to commit your changes to your save file and reload for quick iteration. *Save and Play* will only commit your script changes, any changes made that weren't scripting will be lost. 5 | 6 | The advantage of this method is it requires no additional setup. However it lacks many features included in some of the other options. 7 | 8 |  9 | 10 | 11 | ### Official Atom Plugin 12 | The preferred method of writing Lua scripts is using our Official Plugin for the Atom Text Editor. It has all of the functionality of the in-game editor plus line numbers, syntax highlighting, autocomplete, and a modern look. [Click here for setup instructions.](atom.md) 13 | 14 |  15 | 16 | 17 | ### External Editor API 18 | It is also possible to edit inside of other envionments which are not officially supported. Using the External Editor API it is possible to work in other enviornments (like Notepad++). 19 | 20 | !!! warning 21 | This method does not, by default, include many features that Atom provides, like auto-completion of Tabletop Simulator functions/class members. 22 | 23 | 24 | ###For further information 25 | * [Official Lua Website](http://www.lua.org/home.html) 26 | * [MoonSharp](http://www.moonsharp.org/) 27 | 28 | 29 | ##Example Mods 30 | * [BlackJack](http://steamcommunity.com/sharedfiles/filedetails/?id=620967608) 31 | * [Chess Clock](http://steamcommunity.com/sharedfiles/filedetails/?id=659350499) 32 | * [Roulette](http://steamcommunity.com/sharedfiles/filedetails/?id=659349425) 33 | * [Interactable](http://steamcommunity.com/sharedfiles/filedetails/?id=737574536) 34 | -------------------------------------------------------------------------------- /docs/physics.md: -------------------------------------------------------------------------------- 1 | Physics, a static global class, allows access to casts and gravity. Physics casts are a way to detect Objects. You call these functions like this: `Physics.getGravity()`. This class also allows you to access elements of the environment. 2 | 3 | For more information on physics casts in Unity, [refer to the Unity documentation](https://docs.unity3d.com/ScriptReference/Physics.html) under BoxCast/RayCast/SphereCast. 4 | 5 | 6 | 7 | ##Member Variable Summary 8 | 9 | ###Member Variables 10 | These are variables that affect elements of the environment. It allows you to both read and write values. 11 | 12 | Read example: `print(Physics.play_area)` Write Example = `Physics.play_area = 0.5` 13 | 14 | Variable | Description | Type 15 | -- | -- | :-- 16 | play_area {: #play_area } | The play area being used (ie. how far from middle you can get). Values from 0 - 1. Default is 0.5 | [](types.md) 17 | 18 | 19 | --- 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | ##Function Summary 29 | 30 | ###Functions 31 | 32 | Function Name {: #angular_drag } | Description | Return | 33 | -- | -- | -- | -- 34 | cast([](types.md) parameters) | Returns Table containing information on hit Objects. | [](types.md) | [:i:](#cast) 35 | getGravity() {: #getgravity data-toc-label="getGravity()" data-toc-child-of="function-details" } | Returns directional Vector of the direction gravity is pulling. | [](types.md#vector) | 36 | setGravity([](types.md#vector) direction) {: #setgravity data-toc-label="setGravity(...)" data-toc-child-of="function-details" } | Sets the direction gravity pulls. | [](types.md) 37 | 38 | 39 | 40 | 41 | 42 | 43 | --- 44 | 45 | 46 | ##Function Details {: data-toc-sort } 47 | 48 | ###cast(...) 49 | 50 | [](types.md) Returns Table containing information on hit Objects. There are three kinds of casts: 51 | 52 | Type | Description 53 | --- | --- 54 | Ray | A line. 55 | Box | A cube, rectangle, plane. 56 | Sphere | A round ball. You cannot make ovals. 57 | 58 | It draws the imaginary cast, then moves the rap/box/sphere along that path instantly. The debug Bool in the parameters allows you to see this shape, to aid in setup, but the visual is not instant (due to that making it pointless, if you can't see it). 59 | 60 | !!!Warning 61 | Physics casts are somewhat expensive. When running 30+ at once it will cause your game to stutter and/or crash. Do not overuse. 62 | 63 | !!!info "cast(parameters)" 64 | * [](types.md) **parameters**: A Table of parameters used to guide the function. 65 | * [](types.md#vector) **parameters.origin**: Position of the starting point. 66 | * {>>Optional, defaults to {x=0, y=0, z=0}.<<} 67 | * [](types.md#vector) **parameters.direction**: A direction for the cast to move in. 68 | * {>>Optional, but cast is motionless without a direction.<<} 69 | * [](types.md) **parameters.type**: The type of cast. {>>1 = Ray, 2 = Sphere, 3= Box<<} 70 | * {>>Optional, defaults to 1.<<} 71 | * [](types.md#vector) **parameters.size**: Size of the cast shape. Sphere/Box only. 72 | * {>>Optional, defaults to {x=0, y=0, z=0}.<<} 73 | * [](types.md#vector) **parameters.orientation**: Rotation of the cast shape. Box only. 74 | * {>>Optional, defaults to {x=0, y=0, z=0}.<<} 75 | * [](types.md) **parameters.max_distance**: How far the cast will travel. 76 | * {>>Optional, defaults to infinity. Won't move without direction.<<} 77 | * [](types.md) **parameters.debug**: If the cast is visualized for the user. 78 | * {>>Optional, defaults to false.<<} 79 | 80 | !!!info "Returned Table of Hit Objects" 81 | * [](types.md) **table**: A numerically indexed Table, one entry for each hit Object. Entries are in the order of being hit. 82 | * [](types.md#vector) **table.point**: Position the cast impacted the Object. 83 | * [](types.md#vector) **table.normal**: The surface normal of the impact point. 84 | * [](types.md) **table.distance**: Distance between cast origin and impact point. 85 | * [](types.md) **table.hit_object**: An Object reference to the Object hit by the cast. 86 | 87 | ``` Lua 88 | -- Example usage 89 | -- This function, when called, returns a table of hit data 90 | function findHitsInRadius(pos, radius) 91 | local radius = (radius or 1) 92 | local hitList = Physics.cast({ 93 | origin = pos, 94 | direction = {0,1,0}, 95 | type = 2, 96 | size = {radius,radius,radius}, 97 | max_distance = 0, 98 | debug = true, 99 | }) 100 | 101 | return hitList 102 | end 103 | ``` 104 | 105 | ``` Lua 106 | -- Example returned Table 107 | { 108 | { 109 | point = {x=0,y=0,z=0}, 110 | normal = {x=1,0,0}, 111 | distance = 4, 112 | hit_object = objectreference1, 113 | }, 114 | { 115 | point = {x=1,y=0,z=0}, 116 | normal = {x=2,0,0}, 117 | distance = 5, 118 | hit_object = objectreference2, 119 | }, 120 | } 121 | ``` 122 | -------------------------------------------------------------------------------- /docs/player/colors.md: -------------------------------------------------------------------------------- 1 | # Player Colors 2 | 3 | Each person able to interact with objects in-game is assigned a Player Color to represent them. This is chosen when a Player picks a seat color or is assigned one by the host. Many functions refer to these Players or their hand zones, and it does so via color names. All color names are strings and are case sensitive within functions. 4 | 5 | Each color also has an RGB value associated with it. For more information on the RGB Color standard, view the [Color section](../types.md#color). 6 | 7 |Color Name | 11 |Color Swatch | 12 |RGB | 13 |
---|---|---|
White | 18 |19 | | {1, 1, 1} | 20 |
Brown | 23 |24 | | {0.443, 0.231, 0.09} | 25 |
Red | 28 |29 | | {0.856, 0.1, 0.094} | 30 |
Orange | 33 |34 | | {0.956, 0.392, 0.113} | 35 |
Yellow | 38 |39 | | {0.905, 0.898, 0.172} | 40 |
Green | 43 |44 | | {0.192, 0.701, 0.168} | 45 |
Teal | 48 |49 | | {0.129, 0.694, 0.607} | 50 |
Blue | 53 |54 | | {0.118, 0.53, 1} | 55 |
Purple | 58 |59 | | {0.627, 0.125, 0.941} | 60 |
Pink | 63 |64 | | {0.96, 0.439, 0.807} | 65 |
Grey (spectator) |
68 | 69 | | {0.5, 0.5, 0.5} | 70 |
Black (GM/DM) |
73 | 74 | | {0.25, 0.25, 0.25} | 75 |
Prints "1", "2", "3", "4", "5", waiting 60 frames before each printed number.
115 |Note that the scheduled function, upon execution, will reschedule itself unless `count` has reached 5.
116 | ``` Lua 117 | local count = 1 118 | local function printAndReschedule() 119 | print(count) 120 | 121 | if count < 5 then 122 | count = count + 1 123 | Wait.frames(printAndReschedule, 60) 124 | end 125 | end 126 | 127 | Wait.frames(printAndReschedule, 60) 128 | ``` 129 | 130 | --- 131 | 132 | ###stop(...) 133 | 134 | [](types.md) Cancels a Wait-scheduled function. 135 | 136 | !!!info "stop(id)" 137 | * [](types.md) **id**: A wait ID (returned from `Wait` scheduling functions). 138 | 139 | !!!example 140 | Schedules two functions: one that says "Hello!", and one that says "Goodbye!". However, the latter is stopped before 141 | it has a chance to execute i.e. We'll see "Hello!" printed, but we _won't_ see "Goodbye!" 142 | ``` Lua 143 | Wait.time(function() print("Hello!") end, 1) 144 | local goodbyeId = Wait.time(function() print("Goodbye!") end, 2) 145 | Wait.stop(goodbyeId) 146 | ``` 147 | 148 | --- 149 | 150 | ###stopAll(...) 151 | 152 | Cancels all Wait-scheduled functions. 153 | 154 | !!!warning 155 | You should be extremely careful using this function. Generally you should cancel individual scheduled functions with 156 | [stop](#stop) instead. 157 | 158 | !!!example 159 | Schedules two functions: one that says "Hello!", and one that says "Goodbye!". However, _both_ are stopped before 160 | either has the chance to execute. 161 | ``` Lua 162 | Wait.time(function() print("Hello!") end, 1) 163 | Wait.time(function() print("Goodbye!") end, 2) 164 | Wait.stopAll() 165 | ``` 166 | 167 | --- 168 | 169 | ###time(...) 170 | 171 | [](types.md) Schedules a function to be executed after the specified amount of time 172 | (in seconds) has elapsed. 173 | 174 | The return value is a unique ID that may be used to [stop](#stop) the scheduled function before it runs. 175 | 176 | !!!info "time(toRunFunc, seconds, repetitions)" 177 | * [](types.md#function) **toRunFunc**: The function to be executed after the specified amount of time has elapsed. 178 | * [](types.md) **seconds**: The amount of time that must elapse before `toRunFunc` is executed. 179 | * [](types.md) **repetitions**: Number of times `toRunFunc` will be (re)scheduled. `-1` is infinite repetitions. 180 | * {>>Optional, defaults to `1`.<<} 181 | 182 | `repetitions` is optional and defaults to `1`. When `repetitions` is a positive number, `toRunFunc` will execute for the 183 | specified number of repetitions, with the specified time delay before and between each execution. When `repetitions` is 184 | `-1`, `toRunFunc` will be re-scheduled indefinitely (i.e. infinite repetitions). 185 | 186 | !!!example 187 | Prints "Hello!" after 1 second has elapsed. 188 | ``` Lua 189 | Wait.time( 190 | function() 191 | print("Hello!") 192 | end, 193 | 1 194 | ) 195 | ``` 196 | It's a matter of personal preference, but it's quite common to see the above compacted into one line, like: 197 | ``` Lua 198 | Wait.time(function() print("Hello!") end, 1) 199 | ``` 200 | 201 | !!!example 202 | Prints "1", "2", "3", "4", "5", waiting 1 second before each printed number. 203 | ``` Lua 204 | local count = 1 205 | Wait.time( 206 | function() 207 | print(count) 208 | count = count + 1 209 | end, 210 | 1, -- second delay 211 | 5 -- repetitions 212 | ) 213 | ``` 214 | 215 | --- 216 | -------------------------------------------------------------------------------- /docs/webrequest/instance.md: -------------------------------------------------------------------------------- 1 | # Web Request Instance 2 | 3 | Web request instances represent a singular in-progress, completed or failed web request. They are created via the [Web Request Manager](manager.md). 4 | 5 | ##Member Variables 6 | 7 | Variable | Description | Type 8 | -- | -- | :-- 9 | download_progress {: #download_progress } | Download percentage, represented as a number in the range 0-1. | [](../types.md) 10 | error {: #error } |Reason why the request failed to complete.
If the server responds with a [HTTP status code](#response_code) that represents a HTTP error (4xx/5xx), this is _not_ considered a request error.
| [](../types.md) 11 | is_error {: #is_error } | If the request failed due to an [error](#error). | [](../types.md) 12 | is_done {: #is_done } | If the request completed _or failed_. If the request failed, [is_error](#is_error) will be set. | [](../types.md) 13 | response_code {: #response_code } | Response [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status). | [](../types.md) 14 | text {: #text } | Response body. | [](../types.md) 15 | upload_progress {: #upload_progress } | Upload percentage, represented as a number from 0-1. | [](../types.md) 16 | url {: #url } | The request's target URL. If the request was redirected, this will still return the initial URL. | [](../types.md) 17 | 18 | ##Functions {: data-toc-sort } 19 | 20 | Function Name | Return | Description | 21 | -- | -- | -- | --: 22 | dispose() {: data-toc-child-of="functions" } | |**Web requests are automatically disposed of after a request completes/fails.**
You may call this method to _try_ abort a request and dispose of it early.
| 23 | getResponseHeader([](../types.md) name) {: data-toc-label="getResponseHeader(...)" data-toc-child-of="functions" } | [](../types.md) | Returns the value of the specified response header, or `nil` if no such header exists. | 24 | getResponseHeaders() {: data-toc-child-of="functions" } | [](../types.md) | Returns the table of response headers. Keys and values are both [](../types.md). | 25 | -------------------------------------------------------------------------------- /docs/webrequest/manager.md: -------------------------------------------------------------------------------- 1 | # Web Request Manager 2 | 3 | `WebRequest` is a static global class which allows you to send HTTP web request, from the game host's computer only. 4 | 5 | !!!note 6 | This is an advanced feature that allows you to send and receive data to/from web services. You could, for example, 7 | provide a companion web server for your game which has a persistent database. 8 | 9 | ##Function Summary 10 | 11 | Function Name | Return | Description | 12 | -- | -- | -- | --: 13 | custom([](../types.md) url, [](../types.md) method, [](../types.md) download, [](../types.md) data, [](../types.md) headers, [](../types.md#function) callback_function) | [Web Request Instance](instance.md) | Performs a HTTP request using the specified method, data and headers. | [:i:](#custom) 14 | delete([](../types.md) url, [](../types.md#function) callback_function) {: data-toc-label="delete(...)" data-toc-child-of="function-details" } | [Web Request Instance](instance.md) | Performs a HTTP DELETE request. | 15 | get([](../types.md) url, [](../types.md#function) callback_function) | [Web Request Instance](instance.md) | Performs a HTTP GET request. | [:i:](#get) 16 | head([](../types.md) url, [](../types.md#function) callback_function) {: data-toc-label="head(...)" data-toc-child-of="function-details" } | [Web Request Instance](instance.md) | Performs a HTTP HEAD request. | 17 | post([](../types.md) url, [](../types.md) form, [](../types.md#function) callback_function) | [Web Request Instance](instance.md) | Performs a HTTP POST request, sending the specified form. | [:i:](#post) 18 | put([](../types.md) url, [](../types.md) data, [](../types.md#function) callback_function) | [Web Request Instance](instance.md) | Performs a HTTP PUT request, sending the specified data. | [:i:](#put) 19 | 20 | --- 21 | 22 | ##Function Details {: data-toc-sort } 23 | 24 | ###custom(...) 25 | 26 | Performs a HTTP request using the specified method, data and headers. Returns a [Web Request Instance](instance.md). 27 | 28 | !!!info "custom(url, method, download, data, headers, callback_function)" 29 | * [](../types.md) **url**: The URL. 30 | * [](../types.md) **method**: The HTTP method. 31 | * [](../types.md) **download**: Whether you want to handle the response body. Must be `true` if you intend to read the response [text](instance.md#text). 32 | * [](../types.md) **data**: The request body. 33 | * [](../types.md) **headers**: Table of request headers. The table's keys and values must both be [](../types.md). 34 | * [](../types.md#function) **callback_function**: Called when the request completes (or fails). Passed the [Web Request Instance](instance.md). 35 | * {>>Optional, but you will be unable to handle the response (or errors) if unused.<<} 36 | 37 | !!!example 38 | We're going to make an (intentionally invalid) _attempt_ to use Github's APIs to create a Github issue. 39 | 40 | We'll include a JSON request body and some request headers. Once the request completes, we're going to inspect the 41 | response headers, decode the response, and finally print the reason why our request was denied by Github. 42 | ```lua 43 | local headers = { 44 | -- Github's APIs require an Authorization header 45 | Authorization = "token 5199831f4dd3b79e7c5b7e0ebe75d67aa66e79d4", 46 | -- We're sending a JSON body in the request 47 | ["Content-Type"] = "application/json", 48 | -- We're expecting a JSON body in the response 49 | Accept = "application/json", 50 | } 51 | 52 | -- Some JSON data (that represents a new Github issue). 53 | -- See: https://docs.github.com/en/rest/guides/getting-started-with-the-rest-api#creating-an-issue 54 | local data = { 55 | title = "New logo", 56 | body = "We should have one", 57 | labels = {"design"} 58 | } 59 | 60 | -- Encode the data as JSON, so we can send it in our request body. 61 | local body = JSON.encode(data) 62 | 63 | -- Our request is targeting the Berserk Games API docs Github repository's issues endpoint. 64 | local url = "https://api.github.com/repos/Berserk-Games/Tabletop-Simulator-API/issues" 65 | 66 | -- Perform the request 67 | WebRequest.custom(url, "POST", true, body, headers, function(request) 68 | -- Check if the request failed to complete e.g. if your Internet connection dropped out. 69 | if request.is_error then 70 | print("Request failed: " .. request.error) 71 | return 72 | end 73 | 74 | -- Check that Github responded with JSON 75 | local contentType = request.getResponseHeader("Content-Type") or "" 76 | if contentType ~= "application/json" and not contentType:match("^application/json;") then 77 | -- We're expecting a JSON response only, if we get something else we'll print an error 78 | print("Uh oh! Github sent us something we didn't expect.") 79 | print("Content-Type: " .. contentType) 80 | return 81 | end 82 | 83 | print("Request denied with status code: " .. request.response_code) 84 | 85 | -- Decode the JSON response body 86 | local responseData = JSON.decode(request.text) 87 | 88 | -- When Github denies a request, they include a "message" field in the JSON body to explain. Let's print it. 89 | print("Reason: " .. responseData.message) 90 | end) 91 | ``` 92 | 93 | --- 94 | 95 | ###get(...) 96 | 97 | Performs a HTTP GET request. Returns a [Web Request Instance](instance.md). 98 | 99 | !!!info "get(url, callback_function)" 100 | * [](../types.md) **url**: The URL. 101 | * [](../types.md#function) **callback_function**: Called when the request completes (or fails). Passed the [Web Request Instance](instance.md). 102 | * {>>Technically optional, but it makes no sense to send a GET request and not handle the response (or errors).<<} 103 | 104 | !!!example 105 | Broadcast the text returned from Github's "Zen API". If the request fails, log the error. 106 | ```lua 107 | WebRequest.get("https://api.github.com/zen", function(request) 108 | if request.is_error then 109 | log(request.error) 110 | else 111 | broadcastToAll(request.text) 112 | end 113 | end) 114 | ``` 115 | 116 | --- 117 | 118 | 119 | ###post(...) 120 | 121 | Performs a HTTP POST request, sending the specified data. Returns a [Web Request Instance](instance.md). 122 | 123 | The form will be sent as the body of the request (`Content-Type: application/x-www-form-urlencoded`). 124 | 125 | !!!info "post(url, form, callback_function)" 126 | * [](../types.md) **url**: The URL. 127 | * [](../types.md)/[](../types.md) **form**: The form to post. 128 | * [](../types.md#function) **callback_function**: Called when the request completes (or fails). Passed the [Web Request Instance](instance.md). 129 | * {>>Optional, but you will be unable to handle the response (or errors) if unused.<<} 130 | 131 | When `form` is provided as a [](../types.md) the data will be URL encoded for you. 132 | The table keys and values must both be [](../types.md). 133 | 134 | --- 135 | 136 | 137 | ###put(...) 138 | 139 | Performs a HTTP PUT request, sending the specified data. Returns a [Web Request Instance](instance.md). 140 | 141 | The data will be UTF-8 encoded and sent as binary data in the body of the request (`Content-Type: application/octet-stream`). 142 | 143 | !!!info "put(url, data, callback_function)" 144 | * [](../types.md) **url**: The URL. 145 | * [](../types.md) **data**: The request body. 146 | * [](../types.md#function) **callback_function**: Called when the request completes (or fails). Passed the [Web Request Instance](instance.md). 147 | * {>>Optional, but you will be unable to handle the response (or errors) if unused.<<} 148 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Tabletop Simulator API 2 | theme: 3 | custom_dir: 'theme' 4 | favicon: 'img/Icon-Dice.png' 5 | logo: 'img/TSIcon.png' 6 | name: 'material' 7 | palette: 8 | primary: 'indigo' 9 | accent: 'indigo' 10 | 11 | extra_css: 12 | - css/theme.css 13 | - css/table.css 14 | - css/type_icons.css 15 | - css/i_icons.css 16 | - css/player_color_table.css 17 | 18 | markdown_extensions: 19 | - admonition 20 | - attr_list 21 | - codehilite 22 | - meta 23 | - pymdownx.arithmatex 24 | - pymdownx.betterem: 25 | smart_enable: all 26 | - pymdownx.caret 27 | - pymdownx.critic 28 | - pymdownx.details 29 | - pymdownx.emoji: 30 | emoji_index: !!python/name:materialx.emoji.twemoji 31 | emoji_generator: !!python/name:materialx.emoji.to_svg 32 | options: 33 | custom_icons: 34 | - theme/icons 35 | - pymdownx.highlight 36 | - pymdownx.inlinehilite 37 | - pymdownx.keys: 38 | camel_case: true 39 | strict: true 40 | - pymdownx.mark 41 | - pymdownx.smartsymbols 42 | - pymdownx.superfences 43 | - pymdownx.tasklist: 44 | custom_checkbox: true 45 | - pymdownx.tilde 46 | - toc_ext: 47 | mkdocs_search_sections: true 48 | permalink: true 49 | 50 | repo_name: 'GitHub Source' 51 | repo_url: 'https://github.com/Berserk-Games/Tabletop-Simulator-API' 52 | 53 | 54 | extra: 55 | social: 56 | - icon: fontawesome/brands/reddit 57 | link: 'https://www.reddit.com/r/tabletopsimulator/' 58 | - icon: fontawesome/brands/twitter 59 | link: 'https://twitter.com/tabletopsim' 60 | - icon: fontawesome/brands/facebook 61 | link: 'https://www.facebook.com/tabletopsimulator' 62 | - icon: fontawesome/brands/youtube 63 | link: 'https://www.youtube.com/user/berserkgames' 64 | 65 | nav: 66 | - Getting Started: 67 | - Introduction: index.md 68 | - Overview: overview.md 69 | - Atom: atom.md 70 | - Lua in Tabletop Simulator: lua-in-tabletop-simulator.md 71 | - System Console: systemconsole.md 72 | - Virtual Reality: vr.md 73 | - External Editor API: externaleditorapi.md 74 | - Patch Notes: https://www.tabletopsimulator.com/news/patch-notes 75 | - Scripting API: 76 | - Introduction: intro.md 77 | - Types: types.md 78 | - Events: events.md 79 | - Base: base.md 80 | - Object: object.md 81 | - Object Behaviors: 82 | - AssetBundle: behavior/assetbundle.md 83 | - Book: behavior/book.md 84 | - Browser: behavior/browser.md 85 | - Clock: behavior/clock.md 86 | - Container: behavior/container.md 87 | - Counter: behavior/counter.md 88 | - LayoutZone: behavior/layoutzone.md 89 | - RPGFigurine: behavior/rpgfigurine.md 90 | - TextTool: behavior/texttool.md 91 | - Object Components: 92 | - Introduction: components/introduction.md 93 | - GameObject: components/gameobject.md 94 | - Component: components/component.md 95 | - Material: components/material.md 96 | - Examples: components/examples.md 97 | - Backgrounds: backgrounds.md 98 | - Color: color.md 99 | - Grid: grid.md 100 | - Hands: hands.md 101 | - Info: info.md 102 | - JSON: json.md 103 | - Lighting: lighting.md 104 | - Music Player: musicplayer.md 105 | - Notes: notes.md 106 | - Physics: physics.md 107 | - Player: 108 | - Colors: player/colors.md 109 | - Instance: player/instance.md 110 | - Manager: player/manager.md 111 | - Spawnable Objects: 112 | - Built-in: built-in-object.md 113 | - Custom: custom-game-objects.md 114 | - Tables: tables.md 115 | - Time: time.md 116 | - Timer: timer.md 117 | - Turns: turns.md 118 | - UI: ui.md 119 | - Vector: vector.md 120 | - Wait: wait.md 121 | - Web Request: 122 | - Instance: webrequest/instance.md 123 | - Manager: webrequest/manager.md 124 | - UI API: 125 | - Introduction: ui/introUI.md 126 | - Attributes: ui/attributes.md 127 | - Basic Elements: ui/basicelements.md 128 | - Input Elements: ui/inputelements.md 129 | - Layout/Grouping: ui/layoutgrouping.md 130 | - Defaults: ui/defaults.md 131 | -------------------------------------------------------------------------------- /process_anchors.py: -------------------------------------------------------------------------------- 1 | import glob, re 2 | 3 | def replace(matchobj): 4 | id = matchobj.group(1) 5 | return '%s' % (id.lower(), id) 6 | 7 | for filename in glob.glob("docs/*.md"): 8 | data = ''.join((x for x in open(filename))) 9 | data = re.sub('@([a-zA-Z_]+)', replace, data) 10 | out = open(filename, 'w') 11 | out.write(data) 12 | out.close() 13 | -------------------------------------------------------------------------------- /serve.bat: -------------------------------------------------------------------------------- 1 | @python serve.py %* 2 | -------------------------------------------------------------------------------- /serve.py: -------------------------------------------------------------------------------- 1 | import os, sys 2 | 3 | port = 8080 4 | if len(sys.argv) > 1: 5 | try: 6 | port = int(sys.argv[1]) 7 | except ValueError: 8 | print(f'USAGE: {os.path.basename(sys.argv[0])} [