Заблаговременное планирование функций и улучшений
После долгого перерыва у меня появилась возможность вернуться к кодовой базе Осколков Онлайн и начать работать над некоторыми функциями.
Одной из первых вещей, которые я заметил, была зависимость нашего Lua-скрипта от стандартной функции Math.rand(), которая, учитывая ее зависящее от платформы поведение, мне показалась подозрительной для качественной генерации псевдослучайных чисел в будущем.
Будучи убежденным в том, что случайные числа являются кровью любой хорошей игры-симулятора (особенно ролевых игр), я создал небольшой проект, чтобы улучшения и иметь достижимую победу.
Кубок игральных костей
Идея была проста: взять старый предмет из Ultima Online (Cup and Dice) и реализовать такое же поведение игрового процесса в Shards.
Cup of Dice должен быть единым предметом, который бросает два кубика вместе и выдает значения на каждом кубике, а также общую сумму броска. Отлично подходит для игры в кости!
Решения, Решения
Имея это в виду, вот как шел мыслительный процесс:
- Не было объекта генератора случайных чисел, посвященного игровой составляющей сервера. Я бы создал такой, который можно было бы использовать глобально и который был бы безопасен для потоков (чтобы один серверный процесс не пытался создать его экземпляр одновременно с другим).
- Этот новый синглтон «Rand» должен иметь заменяемый генератор псевдослучайных чисел (PRNG). Другими словами, я бы создал набор интерфейсов, которые стояли бы между кодом Lua и кодом Rand, чтобы, если я позже изменил PRNG на Mersenne Twister или реализацию WELL512, больше ничего во всей кодовой базе не пришлось бы менять. Для меня важна уверенность в будущем.
- Должен быть статический класс «Dice», чтобы простая команда, такая как
Roll(1,6)
, выводила случайный бросок одной шестигранной кости (1d6). - Кости должны поддерживать два основных использования:
Roll()
, при котором по умолчанию будет бросок 1d6, илиRoll(numDice, numSides)
, при котором бросается определенное количество кубиков с определенным количеством граней и суммируется результат. - Функция
Roll()
должна иметь разумные ограничения, чтобы кто-то не мог бросить 1 000 000 игральных костей с 1 000 000 граней и переполнить максимальное значение целого числа (~ 2,6 миллиарда для положительных чисел). Я выбрал кепку из 100 игральных костей, бросающих 1000 сторон. - У меня не было никакого арта для чашки с игральными костями, поэтому мне пришлось использовать временный объект — в итоге это была обеденная тарелка, так как я не мог быстро найти объект чашки.
- Кажется, в Lua нет метода заставить неподвижные объекты говорить, поэтому я попросил пользователя, выполняющего действие, говорить за кости.
Тарелка невидимых костей
Некоторые выводы:
- В тексте должно быть больше пользовательских сообщений, таких как комментарии Snake Eyes для двойных и Craps.
- Разговор через объект игрока не отличается от случаев в Ultima Online, но UO использовала альтернативные цвета для текста и обычно окружала текст специальными символами, чтобы отличать его от Речи и Эмоций.
В следующий раз мы обсудим реальный код Lua для игры в кости и улучшение изображения.