Создание карточных игр и колод
Создание колоды в tts достаточно простое. Карта состоит из трех частей:
- Лицевая сторона – передняя часть карты
- Рубашка – задняя часть карты
- Изображение, появляющиеся на скрытых картах – в руке у других игроков.
Каждая колода может состоять максимум из 69 различных карт. Если вам нужна игра, где более 69 карт в колоде, нужно будет создать несколько колод и сложить их вместе.
Задняя часть (рубашка) должна содержать в себе отдельно изображение формата *jpg
Лицо карты – это лист из 69 карт в 7 рядов и 10 колонок в одном изображении, также формата *jpg. Если в вашей колоде менее 69 карт, оставшиеся позиции для карт следует оставить пустыми и добавить на 70ю позицию изображение для скрытых карт. Для того, чтобы сделать уникальные рубашки карт, расположите их так же на листе, в том же порядке, что и на листе для лицевой стороны карты. Схема расположения карт на листе ниже:
Добавление в игру
Чтобы загрузить вашу колоду в игру, нажмите на chest -> custom object -> custom deck. Во всплывшем окне вам нужно будет ввести URL адреса ваших изображений, предварительно загруженных на какой-либо сервис хранения изображений (например imgur или photobucket).
Если же изображения хранятся на ПК то вы можете использовать локальный адрес файла (“`file: /// C:/адрес_вашего_изображения/изображение.jpg”) Но, если вы будете загружать файлы с локальной машины, то они, скорее всего будут недоступны другим игрокам, так что желательно размещать их где-нибудь в сети.
1. Lua TTS

Предполагается, что ты УЖЕ знаешь язык программирования Lua. Но если нет, то и ладно. Всё равно я люблю разжёвывать всё до блевоты. В любом случае советую почитать (хотя бы полистать?) книжку "Programming in Lua".
Для тех, кто не умеет искать, подсказываю. Наберите в гугле:
Программирование на языке LUA 2014 PDF RUS rutracker
Здесь же речь пойдёт о том, как Луа встроен в Tabletop Simulator, как с ним жить и как юзать. Конечно, если ты знаком с английским, то можешь сразу проследовать к официальной документации[berserk-games.com] , а эту статью закрыть и забыть.
Оглавление для этой серии статейУрок 1. Скприты Lua для TTS
Урок 2. Инструменты
Урок 3. Раскраска API для Notepad++
Урок 4. Отложенные задачи во времени
Урок 5. Колоды и карты
Прежде, чем начать.
. Нужно понять, каким местом скрипт сохраняется в игру. В общем, скрипт можно применить лишь к ЗАГРУЖЕННОЙ (из сейва) игре. Таким образом, прежде чем начать программировать, нужно загрузить игру. А для этого, в свою очередь, нужно её сохранить.
Круто, да? Теперь ты готов. Но я хочу, чтобы ты прочувствовал этот момент. Так что мы разберем некоторые казусы.
Предположим, ты применил скрипт к текущей игре. Затем ты кое-что изменил и сохранил игру под другим именем (чтобы не портить хороший сейв). И теперь ты хочешь изменить скрипт. Ты его меняешь и применяешь к текущей игре, наивно думая, что всё ок. Но — сюрприз! Скрипт применяется к предыдущему сейву, и он тут же загружается. Круто, да? Нет, совсем не круто. Фишка в том, что последним был загружен предыдущий сейв, а текущий сейв ни разу не загружался, поэтому скрипт применяется именно к последнему загруженному. Так что все изменения после сохранения теряются. Кстати, старый скрипт тоже теряется, затирается новым.
Следующий казус в том, что когда ты применяешь скрипт, то он сохраняется в предыдущий (загруженный) сейв, но прочие изменения теряются! Предположим, ты изменил стол, передвинул элементы, создал новые, потом написал скрипт и нажал злосчастную кнопку "SAVE&PLAY". В результате игра сохраняет скрипт в сейв и сразу загружает его, при этом теряется всё остальное, что ты сделал. Потом ты привыкнешь, и это даже будет удобно.
Ещё одно маленькое замечание. Скрипты должны быть включены в опциях игры. Вообще по умолчанию они и так включены. Так что не знаю, каким чудом они у тебя отключились, но упомянуть об этой детали было нужно, а то мало ли. Обычно из-за таких вот мелочей и появляются комменты типы "ничего не работает! хелп!".
Последний совет. Пиши скрипты в другом редакторе типа Notepad++, а потом просто копируй в игру. Так надёжней (и привычней для бывалых программеров).
Ну, теперь ты вроде точно готов. Можно начинать.
Пишем простецкий скрипт
Ну, ты понял, это "Hello World". Выглядит он так:
print("Hello World") Жми на кнопку "Scripting". Слева будут непонятные кнопки, справа рабочая область для написания скрипта, а сверху кнопка "SAVE&PLAY" (Сохранить и перезапустить). Скопируй туда наш свежий скрипт и жми кнопку. Старый текст можешь удалить или оставить. Ну, сделал?
Теперь возрадуйся — скрипт сработал! 🙂 Об успешной загрузке тебя известило зелёное сообщение "Loading complete." посреди экрана. Если в скрипте есть синтаксическая ошибка, то он просто не сработает, а сообщение об ошибке выведется красным цветом на экран. Также многие сообщения дублируются в лог — это наше средство отладки и обратной связи, чтобы знать, что там вообще происходит в скрипте и правильно ли он работает.
Где этот лог? Внизу слева есть окошко с чатом и логом. Если ты случайно нажал F11 и убрал весь интерфейс нафиг, то нажми ещё раз — и он включится, и ты увидишь чат\лог внизу. Вкладка "Game" — это и есть лог событий. Именно здесь появляется различная информация по игре. Также сюда будет писать твой скрипт о том, что он делает. На картинке справа ты видишь мой лог после волшебной кнопки SAVE&LOAD: 1) Игра пишет, что сохраняет скрипт в сейв. Он у меня называется "test_script", без палева. 2) Инфа о сейве и о том, что он изменился. 3) Это отработал наш скрипт — и в лог попала наша строка "Hellow World". 4) Игра ещё раз напоминает, что все прочие изменения улетели в трубу.
В будущем ты будешь писать скрипты так, чтобы они сообщали о своей работе через функцию print. К сожалению, это чуть ли ни единственный способ отлаживать скрипты в Tabletop Simulator, так что морально готовься общаться со скриптом через это окошко.
Глобальное пространство и Global
К слову, здесь уже начинаются трудности, так что лентяев прошу откланяться, до свидания.
Мы привыкли, что глобальное пространство — то место, где хранятся все глобальные переменные. Ещё его называют _G. Здесь оно тоже есть. Наш скрипт выполняется именно в глобальном пространстве, куда игра положила для нас все нужные функции. Там же игра будет искать специальные наши функции, которые будет вызывать при некоторых событиях (если найдёт).
Но разрабы пошли дальше — они решили создать отдельное глобальное пространство для каждого объекта в игре. Вот это поворот! А чё такого? Тормоза будут лишь при создании/инициализации объекта, ну ещё массовая проверка обработчиков событий, а в остальном это просто несколько отдельных скриптов.
Давай-ка сначала пощупаем, а потому уже покумекаем. Создай обычный блок на столе и снова сохрани игру. Вообще можно любой объект, не важно. Правой кнопкой — вызываем редактор Луа. Как видишь, теперь у нас два скрипта! Сразу напишем print(2) и перезапустим. Ну, сделал?
Теперь у нас в логе две записи — Hellow world из главного скрипта и "2" из второго скрипта.
Вся трагедия в том, что у каждого скрипта своё глобальное пространство _G, и они никак не пересекаются. Если в одном написать x=5, то в другом по-прежнему будет x==nil.
В большинстве случаев нам нужно, чтобы скрипты умели общаться. Конечно, это не всегда так остро нужно, но для серьёзных вещей — маст хэв. Ещё есть вариант сделать один большой глобальный скрипт, а к отдельным объектам скрипты не добавлять. Но всё же это не очень удобно. Раз уж есть такая фича, то надо юзать её по-полной. Кстати, если ты не собираешься публиковаться и беспокоишься о том, чтобы игроки (твои гости) не стырили скрипты, то лучше делать именно один глобальный скрипт (потому что любой игрок может добавить любой объект себе в библиотеку вместе с прикреплённым к нему скриптом, артом, модельками и т.д.).
В общем, разработчики решили проблему оригинальным способом (через одно место). Они просто предоставили интерфейс для "общения" между разными скриптами. Он заключается в том, что данные тупо копируются. Если речь идёт о таблице, то она тоже копируется целиком со всеми вложенностями. Ссылка на таблицу не передаётся, таблица именно копируется. И если таблицу нужно изменить, то шаги следующие: 1) копируем таблицу через API 2) меняем один или несколько элементов 3) копируем таблицу обратно поверх старой, меняется даже её адрес. Вот такие пироги с котятами!
Каждый скрипт в игре (вместе со своим глобальным пространством имён) соответствует одному объекту. Доступ к этому объекту из скрипта возможен посредством ключевого слова "self". Причем, это не локальная переменная функции-обработчика, а глобальная переменная, доступная отовсюду и в любое время, даже с самой первой строчки скрипта.
Сразу после создания объект не инициализирован. На это нужно некоторое время. Хотя "извне" доступны некоторые его свойства. Как только объект полностью инициализирован, в этот момент происходит проверка наличия скрипта — на данном этапе это просто строка с текстом программы на языке Луа. Если скрипт есть, то он компилируется и сразу же выполняется. Именно поэтому переменная self, как и другие функции, доступна с самого начала.
Однако для глобального скрипта нет соответствующего объекта. Вместо этого разработчики придумали переменную Global (типа userdata, кто бы сомневался). Через эту переменную любой другой скрипт может получить доступ к пространству имён глобального скрипта через вызовы Global:getVar(), Global:setVar(), Global:getTable(), Global:setTable().
Не путай Global (главный объект игры) и "глобал" как глобальное пространство имён отдельно взятого скрипта (_G). Ещё именем "Global" называется сам глобальный скрипт в списке скриптов и переименовать нельзя (хотя в целом разумно).
GetObjectFromGUID
Мда, что-то мы резко начали. Надо поубавить обороты. Вернёмся к азам и простым примерам. Давай-ка перекрасим наш красный куб в жёлтый цвет. Писать будем только в глобальный скрипт, остальное по желанию в другое время.
Чтобы узнать guid СВОЕГО куба, кликни правой кнопкой по нему — и в пункте "Scripting" он будет указан, его можно скопировать в буфер обмена. Дело в том, что я создал свой куб, а ты — свой, и у нас разные guid. Вот если бы я сохранил игру и переслал тебе свой сейв, тогда было бы одинаково, а так тебе приходится самому выяснять.
function onload() local cub = getObjectFromGUID(‘ca018a’) —> заменить на свой cub:setColorTint <1,1,0>—rgb end Ого! Куб перекрасился в жёлтый. Сам!! Конечно, можно перекрасить его руками, но это не интересно.
Здесь ты применил функцию getObjectFromGUID, которая принимает на вход GUID (строку), а на выход даёт объект типа userdata, с которым можно взаимодействовать. Например, уже здесь мы можем получить доступ к пространству имён кубика — cub:getVar(), cub:getTable() и т.д. Можно использовать функции изменения позиции, цвета, поворота, ускорения, размера, менять имя, подсветку и всё, что доступно через официальный API игры. Документация есть на официальном сайте, мы к ней ещё вернёмся.
setColorTint — функция изменения цвета. Она есть у всех объектов. И почти для всех работает, но присутствует вообще у всех. На вход она принимает таблицу с цветами RGB (красный-R, зелёный-G, синий-B). Ты же прочёл ту книгу, которую я советовал в начале? Молодец. Тогда ты уже знаешь, что если функция принимает лишь один аргумент и это таблица, то круглые скобки не нужны (для красоты). Но для пущей понятности и привычности можно написать и так:
local color = <1,1,0>cub:setColorTint(color)
Цикл игры и функция Update
А слабó перекрашивать куб каждую секунду то в красный, то в жёлтый? Ну, мы же не лыком шиты, это-то как раз легко:
—При создании нового объекта, ему присваивается новый GUID. local CUBE_GUID = ‘ca018a’ —Идентификатор нашего куба. local cube —Будущая ссылка на объект. —Функция вызывается после загрузки игры и всех объектов. function onload() cube = getObjectFromGUID(CUBE_GUID) —Получаем ссылку на объект. end local COL_RED = <1,0,0>—Красный. local COL_YELLOW = <1,1,0>—Жёлтый. local last_time = 0 —Время перекрашивания. local is_color_red = true —Красный ли куб? —Функция вызывается каждый тик. Потом оптимизируем, а сейчас лень. function update() local time_now = os.clock() if (time_now — last_time < 1) then —Прошло меньше 1 секунды. return —Завершаем работу функции. end local color = is_color_red and COL_YELLOW or COL_RED —Новый цвет cube:setColorTint(color) —Применяем цвет к нашему кубику. is_color_red = not is_color_red —Цвет поменялся. last_time = time_now —Запоминаем время изменения. end
Сразу учись программировать красиво. Без красоты нет понимания! Нужны отступы[ru.wikipedia.org] , комментарии "для тупых" (да, именно такие я пишу для себя), правильное именование имён, функций[ru.wikipedia.org] и т.д.
Погоди-ка, ты всё ещё не умеешь программировать на Луа? Если так, то вынужден огорчить, — дальше без основ уже никак. Начинается креатив, создание чего-то нового, а не просто копипаст. Так что, пожалуйста, прочти ТУ САМУЮ книгу. И на этом моменте я перестаю напоминать тебе об этом. Будем считать, что ты уже профи.
Итак, здесь есть два ключевых места — это функция onload и функция update. Это как бы "точки входа", потому что эти функции вызывает игра. Они обязаны быть в глобальном пространстве, так что не вздумай поставить перед ними слово "local", иначе они сразу станут невидимыми для игры и просто не сработают никогда.
ОптимизацияА вот переменные, константы и вспомогательные функции можно смело делать локальными. Это "невидимое" локальное пространство на самом деле работает чуть шустрее, чем глобальное. Хотя в целом это экономия на спичках, конечно же.
Переменную cube мы теперь выносим на уровень выше, чтобы она была доступна в обеих функциях. В onload она инициализируется, а в update — используется.
Цвета COL_RED и COL_YELLOW мы тоже делаем отдельными переменными, убивая сразу двух зайцев. Во-первых, так банально красивее — безликие цифры и скобки сразу приобретают смысл. Во-вторых, создание таблицы — дорогое удовольствие в Луа, и лучше сделать это единожды, а затем просто использовать ссылку на таблицу.
Также на заметку — старайся делать степень вложенности как можно меньше. Чем меньше, тем красивее и понятней.
updateО, это самая коварная функция, и её желательно не использовать. Но если надо, то нужно свести вычисления к минимуму. Это сейчас всё тип-топ, а когда у тебя будет сотня-другая объектов на столе, начнутся тормоза. Ведь функция вызывается каждый тик.
Тик — условная единица времени в игре, обычно равная одному кадру. Как ты знаешь, хороший FPS имеет значение не ниже 60. А это значит, что на каждый тик приходится 16мс (миллисекунд). За это время нужно вычислить все скрипты и отрендерить новый кадр в Tabletop Simulator. И проблема в том, что мы не знаем, сколько времени занимает рендеринг. Более того, он тоже зависит от количества объектов и детализации моделек. А ещё время зависит от мощности компа.
Поэтому, в идеале не следует использовать эту функцию вообще! Иначе её нужно оптимизировать максимально. Хорошо, если работу скрипта можно "размазать" по нескольким тикам. Иначе остаётся лишь маленький хитрый приём:
local my_counter = 0 function update() my_counter = my_counter + 1 if my_counter < 50 then return —Пропуск 50 тиков. end my_counter = 0 —Сброс счётчика тиков. —Далее основная работа функции. end Это не полноценная разгрузка. Но так хотя бы при перегрузе лаг будет лишь каждые 50 кадров, подёргивание будет наблюдаться сносное, да и то только у хоста.
Конечно, тебе ещё далеко до такого перегруза. Но сразу бери на заметку, что архитектуру программы лучше сразу продумывать хорошо, а не переделывать по 100 раз. К слову, перегруза и проседания FPS на слабых компах можно добиться вообще без скриптов.
Сохранение и загрузка данных скрипта
Шутки кончились. Это уже серьёзно. Работает это так: при сохранении игра ищет функцию onSave, и если находит, то вызывает и требует с неё строку для сохранения в файл игры. А при загрузке из сейва игра передаёт эту строку (если она есть) в функцию onload. Вот так относительно просто можно сохранять и загружать данные. Благо разработчики предусмотрительно оставили нам доступ к библиотеке JSON, чтобы запаковать в строку любую таблицу. Правда, там не должно быть ссылок на функции, userdata и прочие непотребства (было бы странно, если бы адреса удачно сохранялись и потом загружались).
local SAVED = <> Сразу рекомендую сделать специальную таблицу и назвать её, например, SAVED, — и туда уже заносить то, что нужно сохранить. Здесь возможны два подхода: 1) постоянно обновлять данные в таблице SAVED, либо 2) формировать таблицу SAVED заново при каждом сохранении. Всё зависит от того, что чаще. Автосохранения происходят примерно раз в минуту. А вообще в целом без разницы, какой подход применить. Но решать тебе.
Здесь я просто оставлю готовую шпору для копипаста. Лишнее нужно удалить.
local SAVED = < Red = < name = 'Красный игрок', player_cube = 'ca018a', >, Blue = < name = 'Синий игрок', player_cube = 'f6626f', >, Green = < name = 'Зелёный игрок', player_cube = '74f5ae', >, > —Функция восполняет недостающие поля в только что загруженном сейве. —Ориентируется по базовому сейву, так что много перебирать не придётся. —Она полезна, когда добавляются новые поля в скрипт, а в старом сейве их нет. local function FixSave(basic,tbl) for k,v in pairs(basic) do if type(tbl[k])
= type(v) then if v
= nil then —допустимо "false", например. print("Wrong type [",tostring(k),"]: ",type(tbl[k]),’, ‘, type(v)) tbl[k] = v —Как правило, это замена nil на таблицу (но не наоборот!) end elseif type(v) == "table" then —типы равные, так что второе тоже таблица. FixSave(v,tbl[k]) —Рекурсия end end end local function InitGame() —Здесь инициализируем игру. cube = getObjectFromGUID(CUBE_GUID) —Например, таким образом. end —Срабатывает при загрузке и сигнализирует о начале работы скрипта. function onload(save_state) —Облом случается в начале игры и при Ctrl+Z на начало игры. if save_state == nil or save_state == » then InitGame() —Сейва нет. Но return end local BASIC_SAVE = SAVED —Сохраняем ссылку на изначальную структуру сейва. SAVED = JSON.decode(save_state) FixSave(BASIC_SAVE, SAVED) —Вытаскиваем нужные временные данные. last_time = SAVED.last_time —Далее всё как обычно. InitGame() end function onSave() —Подготавливаем SAVED. Дописываем туда нужные данные. SAVED.last_time = last_time —Потом просто возвращаем строку. return JSON.encode(SAVED) end
Документация и API
Что ж, основные тонкие моменты мы прошли. Всё остальное — дело техники, опыта, терпения и желания, а ещё не повредит базовое знание английского языка.
Важные странички в официальной документации всего две:
1) Базовый API[berserk-games.com]
Здесь перечислены функции API, доступные из глобального пространства игры. Также здесь перечислены некоторые обработчики событий (их не много, к сожалению).
Например, ты можешь отслеживать момент, когда один объект касается другого, создав специальную функцию onCollisionEnter, которая будет вызвана в этот самый момент. Почитай описания функций, там всё более-менее очевидно. Если в описании сказано "this Object", то пользоваться функцией можно только в скрипте, привязанном к объекту, иначе можно также и в глобальном скрипте.
Однако ты не можешь, например, отслеживать изменение положение объекта или внезапный переворот карты. Для таких невозможных вещей приходится использовать функцию update — и в цикле проверять нужные свойства нужных объектов.
2) API объекта (Object)[berserk-games.com]
Здесь перечислены свойства и функции практически каждого объекта в игре. Их очень много, но всё же не достаточно. Специализированные объекты имеют дополнительные несколько функций, которые описаны отдельно.
Вот и всё. Имея эти две ссылки открытыми в отдельных вкладках браузера, а также зная язык Луа, можешь создавать вполне реальные скрипты почти на любой твой каприз. Дальше начинается чистый креатив и в полной мере проявляется твоё искусство владения навыком программирования (т.е. умения писать простой, понятный, красивый и оптимизированный код, чтобы самому же в нём быстро ориентироваться, поддерживать, развивать и совершенствовать по необходимости).
Из бумаги на экран монитора, или как я создал пошаговую стратегию за 2 дня
и вместо того чтобы отдыхать и лежать на диванчике, часами сидел за редактором Tabletop Simulator.
Началось все в вечер пятницы. В обычной посиделке по дискорду, вдруг решили вспомнить старые времена. И зашла речь об одной нашей старой игре про захват земель и войны. Ностальгировали бы мы и дальше, но в голове я подумал: «Что мне мешает портировать эту игру в Tabletop Simulator? Думаю выйдет что-то стоющее.» И сказал об этом. Мою идею сразу же одобрили и сказали что это очень хорошая идея — не нужно рисовать карту на клетчатом листочке, мучатся с цветными карандашами и все будут у себя дома перед монитором.
Ещё идею подталкивало то, что это будет просто порт игры с бумаги на экраны и ничего нового придумывать не надо. Как же я ошибался.
Самое первое над чем я начал думать это была карта. Самая главная и необходимая часть игры ведь именно на ней будут происходить войны, союзы или колонизации. Брать идею с обычным клеточным листочком или клетками я не стал потому, что это было бы очень сложно отмечать как захваченная земля игрока. И я сделал вот что:
Форма гексагона идеально подходила для стыкования между собой и выглядела немного круче чем обычные квадратики. Сделав карту из слоя гексагонов и поместив их на поле, я сделал тайл в такой же форме и как пустышку для верхней и нижней стороны взял челика из Habitica. Идея с такой формой карты и такой формой тайла мне быстро понравилась и следующее что я должен был сделать — карта.
Поскольку я тогда не знал где делать такого рода карты для игр, я запустил у себя на компьютере RPG MAKER MV и сделал простую карту. Но потом я понял что эта карта состоит из квадратов, а не из гексов (дальше я буду называть их так чтобы все время не писать гексагон). Выключив программу я пошел в интернет на поиск того что мне было нужно и спустя 5 минут был найден довольно интересный сайт под названием
Этот сайт как я понял предназначался для ДнД партий и вымышленных миров, но даже так он мне очень сильно помог. После 10 минут осваивания редактора и создания карты у меня получилось такая картина:
Посмотрев на неё ещё раз, я подумал что на ней слишком мало пространства и земель и поэтому после этого я решил немного её обработать в Paint.NET:
После редактирования карта мне понравилась и решено было добавить её в игру как первую:
Также при добавлении карты я уменьшил размер тайлов чтобы они подходили для карты и стыковались между собой, добавил цвета для них в количестве 4 штук, а также листки для записывания данных о своей стране.
После всего этого я решил перейти на вопрос о воинах, зданиях и т.д.
Я сначала решил просто добавить солдат и здания из обычных фигурок из Tabletop Simulator, но потом я передумал и друг предложил взять миплов из Каркассона:
В итоге я взял пару миплов воинов, пару зданий и свинью как обозначение фермы. Также как и с тайликами миплы были уменьшены до таких размеров чтобы они могли стоять на землях и не выходить за границы гекса.
Все здания и войны были помещены в бесконечные мешочки, чтобы их можно было брать в неограниченном количестве. Были поставлены ценники, названия и цвет.
После всего что я сделал я решил показать игру друзьям. Но после первой партии которая прошла всего лишь за 10 минут, мне сказали что карта слишком маленькая и мало континентов для развития. Мы вышли из звонка и была придумана гениальная идея: сделать 4 таких же по размеру карты, и соединить их в одну большую.
Конечно на карте видны швы и сопли между соединениями, но думаю это не будет влиять на процесс самой игры. Закинул эту карту в игру, в самой игре увеличил стол, увеличил поле и все тайлики.
Также поскольку стало больше места, я решил добавить ещё место для двоих игроков: черный цвет и фиолетовый.
Маленькая фича которая была придумана — маленький флажок на котором нужно написать название своей столицы. Добавил счетчики доходов, силы войск, денег и количества земель:
И после последней партии в моей игре которая была на днях выяснилось — слишком долго. Но это было легко исправить. Мы просто приняли что теперь за ход можно захватить три земли и проблема была решена.
Сражения происходили очень просто — у каждого войска есть своя сила например: 30, 23, 5 и т.д. У кого больше цифры тот и победил в сражении. Разница которая была остается и может идти дальше. Здания приносят монеты и прочее.
Игра была создана за два дня и была сыграна два раза. Думаю будем чаще собираться по вечерам и играть в неё. Этот опыт производства игры я думаю, запомнится надолго. Есть предложение опубликовать это дело в мастерскую, но это уже вы решайте.
Update v3.9 New Configuration Menu & addition of the Deck Builder!
If you haven’t noticed yet, the launcher is now gone when you start up Tabletop Simulator. That’s because there is a new configuration menu in-game. So you no longer need to exit to make any changes. Additionally, we have now included Andrew’s Deck Builder into Tabletop Simulator to make creating your decks that much easier.
And just in time, we have the latest Tutorial Video featuring Custom Content. If you want to learn how to use the Deck Builder, then please watch this video as it will take you through the steps.
It will be a few weeks before we get our next update out as it will be our big 4.0 update and like all of these “special” updates, we want to make it a good one. Thanks for your patience and enjoy!
- Launcher has been removed from the game.
- You can now change your keybinds and graphics settings in game.
- Settings menu has been renamed to configuration and has been given an overhaul.
- You can now modify individual graphics settings instead of just using the preset values.
- You can now reset controls, graphics, and game settings to default separately.
- New graphics settings (VSync, Texture Size, Post AA, MSAA, Shadow Quality, Anisotropic, Cap FPS).
- New anti-aliasing support called Post AA (SMAA post processing version).
- You can now see the SteamID of blocked players.
- Chat is now rebindable in the controls menu.

- We reached out to Andrew Mazar the creator of the very popular Deck Builder.
- His Deck Builder is now bundled in the games root and modding folder.
- Deck Builder allows you to easily create & modify custom decks.

- You can now save multiple selected objects as one chest item.
- Spawning saved objects will produce the same sound as spawning other objects from the chest.
- Saved object will now snap to the grid when spawned.
- Custom backgrounds can now be loaded from a save with the expand arrow without resetting the board.
- Improved object naming when expanding a save to see custom objects inside.
- Delete and expand save buttons now only appear when mousing over a save/workshop file.
- Reduced scrolling stutter on Saves and Workshop files.

- Doubled the resolution of the paintingtool (still blocky, but better).
- Optimized the network traffic when rewinding through time with something drawn on the table.
- Added back in randomized backgrounds when the game is started.
- Rewind/fastforward messages are now sent to everyone on the server.
- Improved the texture quality on custom assets using a slight negative mipmap bias.
- Optimized card search to work with more cards (will optimize more in the future).
- Added new Workshop Tags (Backgrounds and templates).
- Fixed loading one custom background to another not updating the background.
- Fixed issues loading large file sized saved objects when promoted.
- Fixed weird turn bugs that would break entire game for the host.
- Fixed problems with long rules sections not being properly transferred.
- Fixed certain custom decks not showing up when expanding a save.
- Fixed being unable to create a save if there were no saves created already.
- Fixed custom backgrounds being horizontally inverted.
- Fixed custom physics materials reverting to default incorrectly.
- Fixed being able to delete the create save button.
- Fixed the pointer selection menu not displaying the pointers properly.
- Fixed the RPG figurines missing their stands.
- Fixed the RPG figurines not properly displaying in the chest.
Stay up to date on our development by following us on Twitter and Facebook!
Update v3.8 New Backgrounds, Semi-lock, & Improvements
We have some exciting additions for you this week! New backgrounds have been added, BUT you can also now add your own custom backgrounds too! Additionally, we added Semi-Lock, which will enable you to play without worrying about accidentally knocking pieces over. Hope you enjoy these new features in addition to the overall fixes and improvements as well.

- 4 new backgrounds been added: Cathedral, Downtown, Regal, and Sunset.
- You can now import your own custom backgrounds (Lighting is not affected by custom backgrounds, only the skybox).
- Custom background images should be hdri panorama images >4000×2000.
- Choose the backgrounds’ lighting you would like first then choose Custom.
- Semi-Lock causes objects that have come to rest to be semi-locked in place (can still be picked up but ignores physics).
- This means you can’t accidentally knock over objects without direct manipulation with Semi-Lock enabled.
- Semi-Lock can be found in the Host Options menu.

- Loading save files will be much faster after the first load (Workshop and Normal Save).
- More error checking to avoid one bad save breaking the ability to load other saves.
- Optimized GUI scrolling for Workshop and Save Files.
- Custom objects and decks will no longer fly all over the place when loaded up fresh.
- Added a spinning loading icon for the server browser so you know when it is fetching servers.
- Added red private text header when in the private notepad.
- Fixed an issue where custom objects were loading up the wrong texture.
- Fixed the back of the quarter being rotated incorrectly.
- Fixed flip/rotate on certain objects that would cause them to fall through the table.
- Fixed issues uploading or updating to the Steam Workshop when nothing would happen when submitted.
- Fixed typing + or – in a text box would also scale selected objects.
- Fixed custom model importer type selection not working properly.
- Fixed multiple command lines breaking the Workshop downloading.
- Fixed some missing radio button not being converted from checkboxes.
- Fixed hover highlighting working over GUI when holding down your mouse button.
Stay up to date on our development by following us on Twitter and Facebook!
Update v3.7 Flick tool added & additional improvements and fixes
**Note** This update was released on January 5th, but due to issues with our web host, we weren’t able to get this posted right away.
We don’t normally do Monday updates (in fact, this is our first!), but due to the DDoS issues we had earlier, we worked really hard to get a new server up so we can get the server browser back online. Thank you very much for your patience during the downtime as that was completely out of our control.
Since we had to do a hotfix so you can access the new master server, this is an update of what we’ve been working on so far since after the holidays. The flick tool was a much requested feature, so hope you enjoy that new addition.
We hope you all had a wonderful holiday season and let’s all enjoy the new year – 2015!

- New hand mode Flick has been added to the pointer selection menu on the left side of the screen.
- Flick can used to launch objects using a ‘pull back and release’ motion.
- Flick works on all selected objects or on an individual object that you click and drag on.
- Can use ‘CTRL + LMB’ to select multiple objects or in Hand mode use box selection then swap to Flick.
- Flick is great for pool, block stacking, and other games that require dexterity to play.
- Cards will not begin to overlap until there are more than 5 cards in your hand.
- This will make it easier to read the text on card if you do not want to use ALT to zoom.

- Greatly optimized networking traffic when modifying/manipulating multiple objects.
- Custom objects use 30% less cpu resources (model, figurine, deck, and board).
- Lift height and rotation snap has been moved up next to the top bar to avoid clipping issues with lower resolutions.
- Box selection will no longer select objects that are hidden in fog of war.
- Recreated the hand icon for the hand mode selection menu.
- Fixed adding or removing a password from your game not updating for people joining through Steam friends.
- Fixed tables being able to be placed insides of bags by throwing it at the legs (lol).
- Fixed voice chat microphone icons not appearing for all players.
- Fixed the sharing violation error when overwriting certain saves (Hopefully).
- Fixed sharing is caring achievement not working retroactively (must be subscribed to your mod).
- Fixed default video quality settings back to medium.
- Fixed grab + lower while not in hand mode picking up objects.
- Fixed some line tool bugs when hovering over GUI elements while measuring.
Stay up to date on our development by following us on Twitterand Facebook!
Last chance to get Tabletop Simulator at 40% off!
Today has been an awesome day! We found out we were chosen as a daily deal on Steam and Tabletop Simulator was offered to you all for 40% off! This discount price will end on December 23rd at 10am PST, so get it while you can!
Because of all your support, we made it to the #1 spot in Early Access games and the #4 spot out of all the top sellers! We never thought we’d see that, so thank you very much!

And finally to top this day off, our all time peak users at one time shot up to 1, 644! Two days ago, we were so happy to reach our peak of 614, but you guys more than doubled it!

Thank you again everyone! We hope you all have a wonderful holiday season. See you next year!
Update v3.6 Steam Holiday Sale, New Pencil & Eraser Pointers, & much more!

Happy holidays everyone! This will be our final update to Tabletop Simulator for 2014, so we hope you all have a wonderful holiday season with your family and loved ones, and we’ll see you all in 2015!
Until then, Tabletop Simulator is on sale for 33% off during the Steam Holiday Sale through January 2nd at 10am PST and we’ve got a brand spanking new “serious” trailer up on the store page and on YouTube.
- New pencil and eraser models when being in those pointer modes.
- Pencil model helps with drawing due to its static and accurate point.
- Helps to remind you that you aren’t in hand mode and cannot grab objects.
- Fixed some alignments/accuracy issues when drawing in the air not on the table.

- You can now rewind time by using ‘CTRL’ + ‘Z’.
- Fast-forward can be done by using ‘CTRL’ + ‘SHIFT’ + ‘Z’.
- As always you can still control this by using the arrows on the top right.
- Added a chat message to let you know when you are rewinding/fast-forwarding.
- Improved voice chat to reduce the annoying voice stuttering that occurred.
- Custom Model now supports multiple separate objects/meshes; you no longer must merge your meshes.
- Option to hide player pointers in the hidden areas has been added to the right click menu.
- Improved and fixed graphics quality settings to be more in line with their names.
- Steam Cloud now also syncs saved Chest objects.
- Other people’s pointers will no longer clip through your ALT zoom on cards.
- Load complete messages will only appear for custom content taking at least a half a second to load to avoid chat spam.
- Animated RPG figurines will now save what state they were in when saving and loading (dead or mode).

- Fixed many issues with conflicting deck ids on merged decks loading from the chest.
- Fixed loading the same deck multiple times from the chest causing strange stuff to happen.
- Fixed some issues loading multiple old saves in row with custom cards.
- Fixed stack loading bug where the chips would end up being blocks instead of chips.
- Fixed some RPG figurine errors on affecting clients.
- Fixed some card bugs in the Cardbots decks.
- Fixed black go bowls giving white pieces.
- Fixed some settings not properly resetting on the settings menu.
- Fixed pointer bug where it would improperly display the player’s pointer as white when first spawned.
Discuss this post on our forums.
Stay up to date on our development by following us on Twitter and Facebook!
Update v3.5 Custom stacking objects, Workshop Improvements, & much more!
Stacking custom objects was a much requested feature and now we have it! Stack your custom objects just like the poker chips do! Promoted players can now spawn saved objects, and you can also now subscribe to the workshop and have it download without restarting the game! And of course there are a lot of other great improvements as well.
We were also chosen as one of the top 100 games for Indie of the Year at IndieDB, so please vote for us to make the top 10!
If you missed it, our latest tutorial series video is now live. This one is all about the RPG Kit. Check it out!
- Choosing type ‘Chip’ from the custom model importer will allow your custom objects to stack just like the poker chips do.
- Create your own stacking currency or something new altogether.
- Custom colliders will not work with the new stacking type.
- Checkers can now also be stacked to make your Kings even more noticeable.
- Improved the spawn position when removing an object from a stack.

- Promoted players can now spawn objects from their saved chest.
- Anyone on a server can now save objects to their chest for future use.
- NAT punchthrough is how the game establishes connection behind peoples’ routers without having to port forward.
- You can now toggle between automatic, enable, or disable NAT punchthrough when hosting a server.
- Most people should be fine with automatic, but if you are having trouble hosting try /testconnection in game, port forwarding 11155, and change NAT settings.
- Automatic works by checking and seeing if you have a public address, if you do not then NAT is enabled.

- Blocked players are now saved to the BlockList.json in ‘Documents/My Games/Tabletop Simulator’.
- Blocked players will no longer reset when you reset your settings.
- Human readable list thanks to the json format.
- You no longer must restart the game after subscribing to a mod on the Workshop, it will download while it’s running.
- Workshop Game list will automatically repopulate with new subscribed mods if open when subscribing.
- Added an Open Workshop button in the Workshop Game List that opens the Workshop in the overlay.
- Overall object physics improvements when adding and removing objects (stacks, bags, decks, etc).
- Grid snapping will work at low lift height, but not when lowering an object with ‘T’.
- Number key actions like rotate dice or RPG kit animations now work with the numpad as well as the normal number keys.
- Optimized bag saving to reduce autosave stutter with many bags.
- Boards from the chest can be drag and dropped spawning at that location like other objects.
- Added error check to custom model mesh generation.
- Slightly improved the stop card search animation.
- Fixed issue shaking an object would cause it to rotate incorrectly for clients.
- Fixed the achievement “Speed Machine”.
- Fixed gravity getting stuck on zero gravity.
- Fixed Steam Cloud to work with the new Json save format.
- Fixed the smooshed description field when right clicking on a deck.
- Fixed boards being spawned from the chest menu not showing up for other players.
- Fixed sideways property being lost when resetting a deck.
- Fixed search stack being visible on transparent tables.
- Fixed collision issues with camera.
- Fixed some stack objects properties that weren’t being transferred properly.
- Fixed mesh download bar cleanup.
- Fixed removing chips from a scaled stack causing it to fall over.
Stay up to date on our development by following us on Twitter and Facebook!
Discuss this post on our forums.
Vote for Tabletop Simulator as Indie of the Year!
We didn’t think it was possible in such short notice, but we did it! We made the top 100 in the Indie of the Year at IndieDB! But it’s not over yet! For the next 9 days you can vote for us for the top spot. Help us get to the top 10 by spreading the word and voting for us here.
When you go to our page, click the red “Vote for this Game” button and it will bring you to another page where you have to choose between others in our category. Click the “Vote” button next to Tabletop Simulator and you’ll be all set!
Thank you again so much everyone for making this all possible!
Discuss this post on our forums.
Update v3.4 is now live – Achievements are here!
As a lot of you have noticed, we have added achievements to Tabletop Simulator. Hope you enjoy earning them! Good luck! If you have any good suggestions for more achievements, post on our forums and we may just add it! In addition, we’ve got some new goodies like toggling rotation snapping, height control, and overall general improvements.
Be sure to check out our Tutorial Series to help you along your Tabletop Simulator journey!

- Steam achievements have been added to the game.
- You can check out the full list on Steam.
- Playtime achievements unfortunately do not retroactively work.
- Workshop upload achievement does retroactively work if you are subscribed to your own mods.
- You can now toggle between 15°, 30°, 45°, 60°, and 90°rotation snapping (default 15°).
- The UI button on the left side has an angle when pressed it will cycle through the degrees.
- Use 60° for your hex objects, 45° for cards, and 15° for very precise control, etc.
- This will help you more quickly orientate your objects for each system.

- You can now control the default holding height of your objects.
- The UI button on the left side has a man lifting a bar, click on that and move the slider.
- You can use this in combination with ‘R’ to lift objects very high.
- Searching a face up deck will return face up when searching is stopped.
- Searching no longer grabs any loose cards that are in the area of the search.
- Tooltips will no longer clip off the edge of the screen.
- Tooltips have been added to the UI elements on the left side of the screen.
- Tooltips will now resize to fit the content of whatever text is supplied.
- Can use BBcode in the object name to give the text some flair.
- Reduced the shininess of all cards, especially on the Field background.
- Bags in old saves will default to brown instead of grey/white.
- Updated some miscellaneous UI icons.
- Fixed dominoes not having sounds on the “cardboard” surface.
- Fixed the bugged out table issue, when the table cannot be reset after flipping (for real this time!).
- Fixed bug with normal textures not being imported correctly.
- Fixed bug with normal textures being accidently deleted when removing similar objects.
- Fixed being able to unsubscribe from a Workshop mod when deleting.
Discuss this post on our forums!
Stay up to date on our development by following us on Twitter and Facebook!
Tabletop Simulator Tutorial Series: Part 3 Hosting & Connecting
Part 3 of our new Tutorial Series for Tabletop Simulator is now live! This tutorial gives you a more advanced look at the various controls in Tabletop Simulator.
Check it out!
Fall Steam Sale – 33% off! Update v3.3 is now live!
Happy Thanksgiving! For Update v3.3, Tabletop Simulator is 33% off in the Steam Fall Sale until Dec 2 at 10am PST! The double 3’s must be a sign!
Wednesday isn’t usually our update day, but we decided to get one out for you early before the Thanksgiving weekend began, so enjoy! This update focuses on a rebuilt save format, making it much easier overall and giving users more control over them. This also means that you can now properly save custom decks to your chest!
Remember to check out our Wiki for additional help. If you are registered on our forums, you are welcome to add anything related to Tabletop Simulator to help your fellow community members.
- New Json save format, a human readable format that will allow more control over objects.
- Optimized the save code to avoid any stutter when saving.
- Json is very expandable without having to worry about breaking old version save files.
- Old saves will still work just fine, all new saves will be Json.
- Json will allow modders to create save generators with external tools.
- Modify the scaling of an object in each axis independently in the save file.

- Can now modify the physics properties of object by modifying the Json save files.
- There are two classes – the Rigidbody (mass, drag, etc) and physics material (friction, bounciness, etc).
- You can read up on how to modify these properties on our Wiki page.
- Overall stability improvements for loading and saving custom decks.
- One broken download for cards will not mess up the rest of the cards downloaded.
- You can see the progress of custom cards because they will visually update during the download.
- Merged decks saved to the chest will now properly load.
- You can now load decks from a save file using the expand arrow (some older saves will not work).
- Custom Decks now cleanup on RAM much better when they are deleted individually.

- Color tinting bags is now working, this should help organize your saves.
- Improved the spawn position when pulling a card from a deck of cards.
- Grid settings now reset when the table resets.
- Better URL cleanup for custom content with automatic url whitespace trimming, might help with RAM usage in certain scenarios.
- Empty server names will now default to “?”.
- Improved object network syncing, when FPS is low and ping is high.
- Reduced other players pointer smoothing, so the positions are more accurate.
- Download status being wrong when loading directly from one save to another.
- Fixed flip table bug not allowing the table to respawn or load another game.
- Fixed floating deck bug when loading locked decks.
- Fixed notification arrow sound distance.
- Cards taken from a deck now inherit the deck’s grid setting.
Discuss this post on our forums!
Stay up to date on our development by following us on Twitter and Facebook!