Tabletop Simulator Guide

How to redeem '3rd Echelon' map - [DEPRECATED; GAMESPOT REMOVED THE PAGE] for Tom Clancy's Splinter Cell: Conviction

Обучение Lua – Руководство для начинающих по написанию скриптов

Overview

Изучайте основы как работает LuaЭто первое руководство в этой серии.

Введение

Это руководство предназначено для тех, у кого ограниченный опыт работы с LUA. Мы рассмотрим основы того, как оформлять код, строительные блоки для Вас, чтобы создавать более сложный код и предоставим некоторые примеры. Руководство написано так, чтобы сразу применять его на практике. Поэтому Вам следует открыть Tabletop Simulator и Ваш редактор LUA, чтобы следовать дальше.

Это первое руководство в этой серии. Второй – это Изучение Lua Подробнее. Третий представляет собой набор полезных функций под названием Learning Lua Functions.

Перед первым нажатием клавиши

Во-первых, я бы настоятельно рекомендовал установить Atom, если вы собираетесь делать скрипты в Tabletop Simulator. Он знает, какие функции можно использовать и будет импортировать/экспортировать код в/из TTS.
Инструкции по установке и настройке Atom[berserk-games.com]

Затем Вы должны добавить в закладках Knowledge Base[berserk-games.com]. Вы будете часто ссылаться на этот сайт, как только начнете писать свои скрипты. Здесь Вы найдете специальные функции в Tabletop Simulator и как они работают. Вы чаще всего будете использовать страницы API и Object, по крайней мере, на моем опыте.

Подготовка

Когда Вы сохраняете свои скрипты в Tabletop, он будет использовать Ваше последнее сохранение, а затем загрузит в него скрипты. Поэтому для любого скрипта, который Вы намереваетесь написать, Вам нужно будет сделать следующее:

  • Подготовьте стол так, как Вы этого хотите.
  • Сохраните стол.
  • Загрузите стол.

Для этого упражнения возьмите пустой стол и создайте два объекта (я использовал квадратный блок и прямоугольный блок), а также красную шашку.

Не забудьте сохранить/загрузить, а затем открыть скрипт в Atom или перейти в Host>Scripting в Tabletop Simulator, чтобы начать.

1) Global.lua

Global.lua – это скрипт, который является частью файла сохранения. Именно здесь мы будем работать над большей частью этого руководства. При новом сохранении он всегда начинается с некоторого текста, сохраненного в редакторе. Просто удалите его, мы его не будем использовать.

Также можно писать скрипты и прикреплять их к объектам вместо Global. Таким образом, если Вы сохраните объект, то сохраниться и его LUA скрипт. Вы можете выполнять большинство функций с использованием скрипты Global или объекта, но мы будем работать в Global.

2) Функции

Функции[berserk-games.com] – участок кода, который вызывается. Некоторые из них встроены в систему (например, onload()), а другие могут быть созданы пользователем. Каждая функция начинается со словом function и заканчивается словом end.

Часто используемая функция, встроенная в Tabletop Simulator – onload(). Эта функция запускается каждый раз при загрузке скрипта (например, если нажата кнопка Отменить(Undo) / Повторить(Redo), а также во время загрузки сохранений).
Замечу, что все переменные вне функций также инициализируются всякий раз при загрузке скрипта.
Итак, давайте начнем с его использования, чтобы запустить функцию, которую мы создадим. Функции должны начинаться с строчной буквы и не содержать пробелов. Мы будем использовать exampleFunction.

function onload() exampleFunction() end

Теперь наш скрипт, когда он загружается, попытается запустить функцию с именем exampleFunction. Но мы еще не писали! Итак, теперь мы создадим нашу собственную функцию сразу после завершения функции onload.

function exampleFunction() print(‘Hello, World.’) end

Команда print() также является функцией. Но вместо запуска секции кода в LUA она активирует уже встроенный в Tabletop Simulator для получения желаемого эффекта. В данном случае печатает сообщение хосту игры в чате.

Сообщение является строкой и всегда окружено кавычками, чтобы указать это. Строка представляет собой последовательность символов. (Пример: “Это строка” или ‘Это так!’). Когда Вы сохраняете и загружаете свой скрипт, теперь он должен печатать “Hello, World” в чат.

Extra Credit: Когда Вы создаете свою собственную функцию, Вы также можете передавать переменные вместе с ней для их использования функцией. Другой способ написать наше начальное упражнение:

function onload() exampleFunction(‘Hello, World.’) end function exampleFunction(passedString) print(passedString) end

Мы создали переменную для представления строки (passString), а затем напечатали то, что содержалось в этой переменной.

3) Объекты

Objects[berserk-games.com] – физические объекты, которые существуют на столе. В нашем случае объектами являются два блока и шашка (какую ужасную игру мы делаем). Используя скрипты, мы можем манипулировать объектами, перемещать их, добавлять к ним кнопки или выполнять другие различные действия. Мы запускаем наш Global.lua заново. Удалите весь текст.

Идентификаторы GUID

Чтобы повлиять и на объект, сначала мы должны идентифицировать его в LUA. Существует несколько способов сделать это, например, идентифицировать элементы, которые подбираются или отпускаются игроками, находить объекты в скриптовых зонах и многое другое. Мы будем идентифицировать эти объекты по их GUID.

GUID – это уникальный идентификатор, который имеет каждый сгенерированный элемент в игре. Даже два одинаковых элемента будут иметь разные GUID. Чтобы найти GUID объекта, щелкните по нему правой кнопкой мыши и перейдите к Scripting. Если Вы нажмете на GUID, он скопирует его в буфер обмена. GUID всегда является строкой, поэтому не забывайте, что строки всегда в кавычках. Давайте создадим несколько переменных с идентификаторами GUID наших объектов. ОБРАТИТЕ ВНИМАНИЕ: Ваши идентификаторы GUID будут отличаться от моих.

object1_GUID = ‘195868’ object2_GUID = ‘333365’ checker_GUID = ‘7dc60d’

Определение объектов

Затем, создадим переменные для представления наших объектов. Используем функцию onLoad(), чтобы создание происходило при загрузке скрипта. Все эти имена переменных, которых мы делали, должны начинаться со строчной буквы и не содержать пробелов, но, кроме этого, Вы можете свободно сами составлять имена переменных. Используйте такие имена, чтобы было понятно, что объект из себя представляет. Я буду использовать object1, object2 и checker для представления моих Объектов. Функция, которую мы будем использовать для идентификации, будет getObjectFromGUID(строка). Мы помещаем GUID в место для строки.

function onload() object1 = getObjectFromGUID(object1_GUID) object2 = getObjectFromGUID(object2_GUID) checker = getObjectFromGUID(checker_GUID) end

Манипулирование объектами

Теперь нам нужно каким-то образом манипулировать этими объектами. Мы дадим им имена. В onload() после определения наших объектов мы будем использовать функцию setName(string). Обратите внимание, что setName, как и другие функции объекта, должна быть привязана к объекту. В противном случае скрипт не поймет, имя какого объекта мы хотим изменить. Строкой в setName будет то, что мы установили для имени.

object1.setName(‘Object1’) object2.setName(‘Object2’) checker.setName(‘That Stupid Checker’)

Extra Credit: Вам может быть интересно узнать, почему мы не поместили GUID объекта непосредственно в getObject(Например: object1 = getObjectFromGUID(‘195868’)). Мы могли бы, и это сработало бы. Этот пример должен был показать Вам, что иногда удобнее устанавливать переменную на раннем этапе, поэтому вы можете ссылаться на нее позже. Таким образом, если эта переменная должна измениться (новый GUID), Вам не нужно пытаться ее отслеживать, чтобы исправить ее во всем коде.

Если бы вы хотели, то нет причин, по которым вы не могли бы написать для шашки это, так:

function onload() getObjectFromGUID(‘7dc60d’).setName(‘That Stupid Checker’) end

Причина, по которой я не одобряю это ученикам является частично эстетическим выбором, и частично для ясности чтения кода. Вы хотите, чтобы кому-то было легко понять Ваш код, и как только вы начнете делать что-то более сложное, чем изменение имени Объекта, может становиться ОЧЕНЬ трудно понять, что происходит. Это улучшает восприятие кода при внесений правок в будущем.

4) Кнопки

Хотя есть много способов активировать функции, кнопки — это весьма удобный способ активировать разделы кода по выбору игрока. Все кнопки должны быть прикреплены к объекту и создаются с использованием параметров. Объект, к которому мы хотим присоединить нашу кнопку – это наша шашка, и эти параметры находятся на странице “Objects” в Knowledge Base. Многие являются необязательными, здесь они для справки.

  • click_function = Строка –Имя вызываемой функции.
  • function_owner = Объект –Объект или Global, где находится функция.
  • label = Строка –Название на кнопке.
  • position = Таблица –Координаты X, Y и Z, для которых отображается кнопка, от центра объекта, к которому он присоединен.
  • rotation = Таблица –Поворот по осям X, Y и Z в градусах относительно объекта, к которому он привязан.
  • width = Число –Ширина кнопки по отношению к масштабу объекта.
  • height = Число –Высота кнопка по отношению к масштабу объекта.
  • font_size = Число –Размер шрифта на кнопке относительно масштаба ее объекта.
  • scale = Число –Масштаб кнопки по отношении к ее объекту.

Таблицы

Таблицы в LUA – это динамический гетерогенный ассоциативный массив, то есть множество пар (ключ-значение). Вы можете хранить все что угодно внутри таблицы и ссылаться на нее позже в таблице по имени или по номеру индекса (в LUA нумерация индексов в таблице начинаются с 1). Все таблицы обозначаются фигурными скобками {}. Мы создадим таблицу прямо под тем, где мы установили наши GUID, а затем заполнили ее записями для использования с функцией createButton(table). Название, которое мы выбираем для нашей таблицы это button_parameters.

button_parameters = {} button_parameters.click_function = ‘buttonClicked’ button_parameters.function_owner = nil button_parameters.label = ‘Press Me’ button_parameters.position = {0,0.8,0} button_parameters.rotation = {0,0,0} button_parameters.width = 500 button_parameters.height = 500 button_parameters.font_size = 100

Теперь мы имеем параметры, то есть таблицу со значениями. Используем функцию объекта, чтобы создать кнопку на шашке. Запишите это внутри функции onload().

checker.createButton(button_parameters)

Проверьте свою работу

Сохраните и примените свой код. Теперь у Вас должна быть кнопка, которая парит на несколько дюймов выше Вашей шашкой. Если вы не видите ее и не получили сообщение об ошибке, попробуйте перевернуть свою шашку. Она может быть перевернута, так что кнопка скрывается внутри стола! Если вы перевернули шашку, то не забудьте перезаписать сохранение с правильно установленной шашкой.

Добавить функцию кнопки

Теперь нам нужно добавить функцию кнопки в наш код. Чтобы проверить функцию, мы напечатаем себе сообщение. Мы добавим эту пользовательскую функцию в конец нашего скрипта.

function buttonClicked() print(‘Learning is fun. Sort of.’) –Обучение – это весело. Вроде. end

После загрузки нашего скрипта нажатие кнопки должно печатать наше сообщение один раз для каждого щелчка.

Повторно нажимайте его, потому что, конечно, вы это сделаете.

EXTRA CREDIT: Когда вы создаете таблицы, есть несколько способов сделать это[link]. Способ, используемый здесь, заключался в том, чтобы обеспечить визуальную ясность. Однако такой способ создания параметров кнопки, как этот, занимает не мало места, если у Вас будет много кнопок. Я предпочитаю создавать свои таблицы таким образом, чтобы экономить место, но не выходить за правых край. Используя наш пример, я бы создал таблицу параметров следующим образом:

button_parameters = { click_function=’buttonClicked’, function_owner=nil, label=’Press Me’, position={0,0.8,0}, rotation={0,0,0}, width=500, height=500, font_size=100 }

EXTRA CREDIT: Это идеальный момент для начала игры с разными вещами, которые вы можете делать с объектами. Перейдите на страницу «Объект» в Knowledge Base и попробуйте материал. Двигайте объекты, заставляйте их переключаться на позиции, менять их цвета, что бы вы ни думали.

EXTRA CREDIT: Кроме того, при каждом нажатии кнопки функция click_function запускается с двумя параметрами. Первая – это ссылка на объект, в частности ссылка на объект, к которому привязана кнопка. Второй – это цвет (например, “Blue” – синий) в строчном формате цвета игрока, который нажал на кнопку.

5) Логические утверждение

Логические утверждения[www.lua.org] обычно называются условиями. Они используются, чтобы сообщить Вашему коду, что вы хотите, чтобы он делал в данной ситуации. Когда инструкция активирована (например, нажатием кнопки), логика, содержащаяся в ее утверждении, активируется только в том случае, если данное условие истинно. Они всегда оформляются как:

if CONDITION then –Активируется если условие было истинно end

Вы также можете добавить к нему “else”, так что если утверждение ложно, вместо этого происходит что-то ДРУГОЕ (else). Обратите внимание, что я добавил комментарии, используя два минуса подряд. Компилятор игнорирует что-либо на линии после –.

if CONDITION then –Активируется если условие было истинно else –Активируется если условие было ложно end

То, что вы размещаете в области, которую я обозначил CONDITION (условие) в этих примерах, называется условными операторами или операторами отношениями.[www.tutorialspoint.com] Используя их, вы можете сравнивать много вещей друг с другом. Они производят так называемое булевское (boolian) значение (переменное значение, которое является либо true – истина, либо false – ложь).

Наши первые логические утверждения

Мы попробуем несколько из них. Удалите текущее содержимое в Вашей функции buttonClicked(). Теперь введите в эту функцию следующие утверждения:

if 5 > 6 then print(“5 is greater than 6”) –5 больше, чем 6 end if 6 > 5 then print(‘6 is greater than 5’) –6 больше, чем 5 end if 5 == 0 then print(“Five is equal to ZERO?!”) –Пять равно НУЛЮ?! else print(“No, five isn’t equal to zero.”) –Нет, пять не равно нулю. end

Эти строки выполнится, как кнопка будет нажата. Вы увидите, что напечатались только те сообщения, находящихся в ИСТИННЫХ утверждениях. Кроме того, поскольку 5==0 является ложным утверждением, он активировал print(), расположенны в “else” части логики.

Сравнение переменных

Еще раз удалите все скрипты внутри функции buttonClicked(). Мы собираемся создать новую переменную, а затем изменить ее. Новая переменная будет булевского типа. Булевские значения могут быть только true, false. Булевские значения всегда записываются маленькими буквами. Во-первых, мы создадим нашу переменную под нашим идентификатором GUID объектов и шашки.

trueOrFalse = true

Затем, в buttonClicked, мы установим некоторую логику, чтобы проверить, истинно ли значение trueOrFalse. Если оно истинно, то будет печатать, что это Истина, и переключит его на Ложь. Если кнопка снова нажата, будет печатать, что это Ложь, и переключит значение на Истина.

if trueOrFalse then print(‘trueOrFalse was true.’) –trueOrFalse была истина. trueOrFalse = false else print(‘trueOrFalse was false.’) –trueOrFalse была ложна. trueOrFalse = true end

Мы могли бы также написать это так “if trueOrFalse == true then”, но это необязательно. Помните, что оператору IF нужно передать булевское значение. И так как trueOrFalse уже является одним из таких, мы можем отпустить “== true”.

6) Циклы

Цикл – это секция кода, которая могут запускаться несколько раз. Это один из более сложных элементов, которые Вы будете использовать в LUA. Они часто идут со таблицами, позволяя запускать код для каждой записи в таблице.

Числовые Циклы For

В числовом цикле for[www.lua.org] используется число-счётчик, которое изменяется при каждой итерации (прогон цикла). Для работы с циклом используются 2 или 3 числа и уникальное имя переменной (я буду использовать “i”, что означает индекс). Отсчёт идёт с первого числа и заканчивается вторым числом, третье число указывает шаг отчёта (если шаг отсчёта равен 1, то его можно не писать). Каждое число разделяется запятой. Замените этим код в вашей функции buttonClicked и попробуйте. Индекс, будет равен 1 в первом прогоне, затем он увеличится на 1 и будет равен 2 и снова запустится и продолжит делать это, пока не достигнет 10.

for i=1, 10 do print(i) end print(‘Loop Finished’)

Какой вывод будет после нажатия на кнопку:

Generic Циклы For

Generic цикл for[www.lua.org] проходит по записям в таблице. Например, в созданную нами таблицу button_parameter мы установили в цикле две переменные: одну для индекса и одну для значения. Используя цикл просмотрим записи таблицы. Для каждой записи в таблице индекс равен имени переменной (Например: position, width и т.д.), а значение, равное значениям, которые мы дали каждой записи. Добавьте это после вашего текущего цикла for в buttonClicked.

for i, v in pairs(button_parameters) do print(i) end

Какой вывод будет после нажатия на кнопку:

Это ещё один тип – ipairs. Pairs нужны для таблиц без числовых ключей, а ipairs нужны для таблицы с последовательными числовыми ключами (массивы). ipairs идет по порядку, когда pairs может идти в любом порядке.

Break
Break[www.lua.org] завершит цикл for, как только он будет выполнен. Например, если Вы добавили в свой числовой цикл for, сразу после его функции печати строка “if i==3 then break end”, она закончит цикл после того, как напечатала 1, 2, 3.

7) Скрипты за пределами Global

Чтобы написать скрипт непосредственно в объект, щелкните на него правой кнопкой мыши, перейдите в Scripting и выберите Lua Editor (если Вы используете Atom, это откроет для него окно в Atom).

Когда вы пишете код здесь, это похоже на global. За исключением случаев, когда Вам нужно ссылаться на объект, частью которого является скрипт, вы просто пишете “self”. Чтобы создать кнопку на себе, вы должны использовать self.createButton(table_of_paramiters).

Завершение

Надеюсь, что это введение в LUA помогло Вам лучше понять некоторые основные механики написания скриптов.

Помните, что в Knowledge Base есть информация обо всех функциях, которые входят в состав Tabletop Simulator. Это и базовая практика с if, else, then и for позволит Вам выполнить большинство всего, что Вы хотите. Удачи.

Оригинал: [link]

SteamSolo.com