Чуть больше, чем пол года назад, я уже писал статью о выпуске альфа версии инструмента DeckBuilder для игры Tabletop Simulator (TTS) и вот уже сейчас я готов представить первую версию приложения, в котором реализован полный цикл: от создания и описания карт, до замены локальных изображений ссылками файлового хранилища. В данной статье я бы хотел поделиться изменениями, которые произошли с момента написания предыдущей статьи.

Ссылка на предыдущую статью

Я не буду повторяться и описывать технические детали из прошлой статьи, но если вам интересно как выглядит json формат файла для TTS с описанием каждого поля, какой формат изображений ожидает TTS, то предлагаю ознакомиться с первой статьей. Но вкратце расскажу для чего же это приложение было написано. Все дело в том, что для человека при создании колоды карт удобно оперировать отдельными картами, а TTS же для быстродействия работает с большими изображениями, на которых карты размещаются по сетке. Так же, для того чтобы колода появилась в самой игре, нам нужно сгенерировать json в определенном формате. Именно этим и занимается DeckBuilder - дружит пользователя с игрой TTS. Преимущество DeckBuilder перед всеми подобными инструментами - это возможность заранее указать название, описание и lua переменные для каждой карты единожды и затем импортировать их в TTS, когда остальные инструменты позволяют только генерировать большое изображение с размещением карт на сетке.

Итак, что же произошло с момента выпуска последней статьи.

  • После начала тестирования на различных машинах оказалось, что Windows на все go приложения реагирует как на вирус. В деталях описание есть в этой статье. Последние тесты показали, что Windows исправили такое поведение своего брандмауэра и новые пользователи не будут получать уведомления о возможном вирусе.

  • Добавлена возможность загружать файлы с локального диска, а не только по ссылке.

  • Если у вас запущена игра TTS, то после создания объекты будут автоматически появляться на столе. Вам больше не нужно руками перетаскивать json файлы.

  • Из последнего была добавлена возможность через интерфейс приложения заменить в json файле пути до локальных файлов на URL.


Самое важное техническое изменение с момента написания прошлой статьи - это автоматическая загрузка сгенерированных карт. Рассмотрим как это работает. При запуске стола TTS открывает два порта. Первый это 39998, он нужен для внешних редакторов кода, через него общаются плагины для Atom и VSCode, при попытке открыть скрипт объекта TTS пишет весь скрипт в сокет и ждет прочитает ли кто-нибудь это сообщение.

Так же есть второй порт 39999, на нем TTS слушает сообщения и принимает команды, вот он нам в данном случае и нужен. На вход TTS ожидает json, и определенный тип сообщения, их существует несколько видов, но нам требуется только один вид, рассмотрим его, он называет Execute Lua Code и выглядит следующим образом.

{
    "messageID": 3,
    "guid":"-1",
    "script":"print(\"Hello, World\")"
}

messageID 3, говорит о типе сообщения Execute Lua Code. guid говорит для какого объекта нужно исполнить этот код, нам нужно исполнить глобально, поэтому из примера на официальном сайте указываем -1. В поле script указываем сам lua скрипт, который нужно исполнить.

У нас в DeckBuilder генерируется json объекта, а в TTS есть lua метод spawnObjectJSON, который позволяет ввести объект в игру из его json описания. Изначально у меня была идея отправлять полный json сгенерированного объекта в теле функции spawnObjectJSON, но при таком большом запросе TTS зависал на секунд 5-10 прежде чем объект появлялся на столе. Поэтому пришлось придумывать как решить этот вопрос иначе.

Тогда я решил поступить следующим образом. Завести в приложении новый endpoint, по запросу на который будет отдаваться только что сгенерированный json, а в самом TTS я буду делать вызов к этой API, а уже ответ помещать в метод spawnObjectJSON. И это помогло: объекты стали появляться мгновенно вне зависимости от их размеров. В lua коде это выглядит следующим образом.

WebRequest.get("http://127.0.0.1:5000/api/tts/data", function(request)
	if request.is_error then
		return
	end
	spawnObjectJSON({
		json = request.text
	})
end)

Теперь каждый раз, после завершения генерации, DeckBuilder пытается подключиться к 39999 TCP сокету, и если удается, то я скидываю туда json с указанным lua выше в поле script.


На этом все. Скачать приложение под все платформы можно тут:

https://github.com/HardDie/DeckBuilder/releases

Так же я записал видео гайд, по всем шагам и показал как закинуть это все в TTS:

https://www.youtube.com/watch?v=r0-4mW8gX1w

Сами исходники можно найти тут:

https://github.com/HardDie/DeckBuilder - Backend (golang)

https://github.com/lmm1ng/DeckBuilderGUI - Frontend (vue3)

Комментарии (0)