Модули, rock-пакеты и приложения
Чтобы сделать игровую логику доступной другим разработчикам и Lua-приложениям, поместим её в Lua-модуль.
Модуль (в Lua модуль называется «rock») — это необязательная библиотека, расширяющая функциональность Tarantool. Таким образом, можно установить нашу логику как модуль в Tarantool и использовать её из любого приложения или модуля Tarantool. Как и приложения, модули в Tarantool могут быть написаны на Lua (rocks), C или C++.
Модули полезны в двух отношениях:
- более удобного управления кодом (повторное использование, упаковка, версионирование); и
- «горячей» перезагрузки кода без перезапуска экземпляра Tarantool.
Технически, модуль — это файл с исходным кодом, который экспортирует
свои функции через API. Например, вот Lua-модуль с именем
mymodule.lua, который экспортирует одну функцию с именем myfun:
local exports = {}exports.myfun = function(input_string)print('Hello', input_string)endreturn exports
Чтобы вызвать функцию myfun() — из другого модуля, из Lua-приложения
или из самого Tarantool, — нужно сохранить этот модуль как файл, затем
загрузить его с помощью директивы require() и вызвать экспортированную
функцию.
Например, вот Lua-приложение, которое использует функцию myfun() из
модуля mymodule.lua:
-- loading the modulelocal mymodule = require('mymodule')-- calling myfun() from within test() functionlocal test = function()mymodule.myfun()end
Здесь важно помнить, что директива require() берёт пути загрузки
Lua-модулей из переменной package.path. Это строка с
разделителями-точками с запятой, где вопросительный знак используется
для подстановки имени модуля. По умолчанию эта переменная содержит
системные пути Lua и рабочий каталог. Но если модули помещены в
определённый каталог (например, scripts/), необходимо добавить этот
каталог в package.path перед любыми вызовами require():
package.path = 'scripts/?.lua;' .. package.path
Для нашего микросервиса простым и удобным решением будет поместить все
методы в Lua-модуль (например, pokemon.lua) и написать Lua-приложение
(например, game.lua), которое инициализирует игровое окружение и
запускает игровой цикл.
Теперь перейдём к деталям реализации. В нашей игре нужны три сущности:
- карта (map) — массив покемонов с координатами точек возрождения; в этой версии игры пусть локация представляет собой прямоугольник, заданный двумя точками — верхней левой и нижней правой;
- игрок (player)— имеет ID, имя и координаты точки местоположения игрока;
- покемон (pokemon) — имеет те же поля, что и игрок, плюс статус (активен/неактивен, то есть присутствует на карте или нет) и вероятность поимки (ну, дадим нашим покемонам шанс сбежать :-) )
Эти сущности будут храниться как кортежи в спейсах Tarantool. Но чтобы предоставить наше серверное приложение как микросервис, рекомендуется отправлять и получать данные в универсальном формате JSON, используя Tarantool как хранилище документов.