Проект: dnd-time — внутриигровые часы, планировщик и менеджер событий для TTRPG  Публичный пост
8 июня 2026  51
dnd-time – внутриигровые часы, планировщик и менеджер событий для TTRPG
http://dnd-time.com

Предисловие

Год назад я потерял работу. Не буду вдаваться в подробности, скажу лишь, что это был очень сложный период принятия новой ситуации и поисков работы.
Но, как бы там ни было, оставалось одно – любовь к коду и возможность создавать свои миры, а еще я глубоко и бесповоротно влюбился в настольную TTRPG Dungeons and Dragons – это еще и классный способ социализации, знакомства с новыми людьми и здоровый способ сбросить стресс.

Если кто-то еще не знает, то Dungeons and Dragons – это настолка, где мир игры, его лор, персонажи, квесты создаются, планируются и симулируются "Гейм Мастером", а игроки берут на себя роль "приключенцев" – персонажей, которые волею судеб вынуждены отправиться в опасные приключения и спасать мир.

Пожалуй, лучшее определение того, что такое D&D, дала Deborah Ann в этом интервью:

...

Во время наших сессий я замечал, что часто возникает один и тот же вопрос: “а сколько сейчас времени”, “а сколько времени прошло с момента А”, или “а куда делись эти 3-4 часа, если прошло всего 15 минут (внутриигрового времени)”. И я подумал: "блин, а было бы классно, если было бы приложение..."; но его не было.

Хотите верьте, хотите нет, но однажды вечером, в полудреме, уже почти засыпая, я увидел картинку: большие часы на весь экран, и рядом крутится планета с облаками, и я подумал: "Блин, круто! Вот это оно! Можно просто и быстро запилить, и будет выглядеть эффектно". Такое маленькое приложение, но при этом уютное и удобное. Так и родилась идея проекта dnd-time.com

Человеческий мозг удивительная штука) Это рекламный щит на станции метро рядом с моим домом. Обнаружил его уже на 5-6 месяце работы над проектом). Не знаю, видел ли я его до этого, или это просто совпадение)
Человеческий мозг удивительная штука) Это рекламный щит на станции метро рядом с моим домом. Обнаружил его уже на 5-6 месяце работы над проектом). Не знаю, видел ли я его до этого, или это просто совпадение)

В чем суть проекта?

На данный момент dnd-time.com – это внутриигровые часы, а также планировщик и менеджер событий на временной линии для TTRPG (Table Top Role Playing Games) сессий. Вы можете создавать множество отдельных миров, каждый из которых – это таймлайн, где вы можете описать ключевые вехи, события и даже дни рождения ваших персонажей (если нужно), вы также можете планировать события для своих сессий наперед.

Планета еще является здоровенной кнопкой, жмякнув на которую, время встает на паузу
Планета еще является здоровенной кнопкой, жмякнув на которую, время встает на паузу

Прототип часов и планету я собрал быстро, буквально за вечер.
Но дальше – больше: мне хотелось добавить интерактивности и превратить это в арт-инсталляцию, родились идеи:

  • а давай запилим смену дня и ночи, и чтобы красивые градиенты меняли друг друга с течением времени
  • а давай сделаем интерактивное солнце, чтоб оно также показывало примерное положение солнца над горизонтом (если нижняя часть экрана – это горизонт)
  • а давай, чтобы облака, короче, создавались вокруг планеты с рандомным углом поворота, с рандомизируемой в диапазоне скоростью вращения, высотой и длительностью "жизни" и чтобы после "смерти" через рандомизируемое в диапазоне время создавалось новое облако.
  • а и давай еще сами облака нарисуем, потому что все, что нахожу, не подходит и не нравится
  • а давай сделаем, чтобы вариантов стрелок изменения часов было штук 6 и они, например, совались в интерфейс каждый раз по-разному
  • а давай сделаем, чтобы ночью появлялись звезды
  • а давай добавим музыку
  • а давай, чтобы можно было по звездам кликать и чтобы проигрывались звуки в тональности музыки
  • а давай, чтобы, когда на паузу поставил, все звуки замедлялись и анимации останавливались

... этому не было конца и края... НО МНЕ НРАВИЛОСЬ!

Какие могут быть юзкейсы?

Расскажу эпизод из моего личного опыта, когда я проводил игру для своих друзей. Мои игроки, разумеется, начали свой путь с таверны (даа, скукота, но это был мой первый опыт проведения игры, камон). Будучи новичками, они повели себя агрессивно, устроили акт вандализма, угрожали оружием тавернщику и посыльному, который дал им квест. К счастью, никто не пострадал (разве что портрет почившей жены тавернщика, проткнутый арбалетным болтом)! Я заранее предусмотрел такой исход событий и дал им переговорный камень, чтобы в случае чего они могли сообщить страже из ближайшего города.

Я понимал, что страже потребуется около часа времени, чтобы снарядиться, выдвинуться и прибыть на место происшествия. Я засек это время на часах 🙂
Мои игроки суммарно потратили еще примерно 30 минут игрового времени на то, чтобы исследовать таверну и ее окрестности, прежде чем выдвинуться дальше в путь. Стража прибыла слишком поздно, чтобы застать их врасплох, однако они решили подождать и устроить им засаду в самой таверне. Так и получилось – игроки были арестованы.

Как выглядит в дизайне. Можно создавать дорожки, двигать элементы, задавать им цвета, описание, длительность и т.д.
Как выглядит в дизайне. Можно создавать дорожки, двигать элементы, задавать им цвета, описание, длительность и т.д.

В моей истории у тавернщика также был бар и разные напитки, которые дают при умеренном употреблении полезные бафы длительностью до 1 часа, а при чрезмерном употреблении – неприятные дебафы, которые, в зависимости от дозы, увеличивали свою продолжительность и усиливали негативные эффекты.

Все это, как и многое другое, можно заводить и отслеживать на временной шкале.
А самое интересное, что это там на ней и останется, поэтому, когда вам понадобится вернуться в прошлое, чтобы вспомнить о каких-то событиях, вы всегда можете это сделать. Можно запланировать параллельные события или чем занимаются ваши NPC в других местах заранее. Или, например, ваша пати разделилась на 2 ветки, и в какой-то момент вам нужно “откатиться назад во времени” и продолжить за других игроков, при этом вы хотите видеть и знать, что, когда и в какое время закончит или начнет делать.

Если будете пользоваться приложением, присылайте ваши кейсы сюда: dm@dnd-time.com (заодно проверим, работает он или нет XD , мне будет интересно почитать, или пишите комментарии с идеями под этим постом.

Зачем нужно солнце?

Если вы посещали проект, то, возможно, заметили, что днем появляется солнце… которое вращается вокруг планеты? Если вы задавались вопросом, есть ли у этого какое-то практичное применение помимо красивого визуала, то вы не ошиблись: оно и правда есть.

Это все очень субъективно и всегда остается на усмотрение гейм-мастера, но, на мой взгляд, если в вашей пати нет персонажа с перком “keen mind” или какого-то соответствующего артефакта/заклинания, которое дает вам знать точное время, все, что вам остается, будучи героями в средневековом фэнтези-мире, – это ориентироваться по солнцу, его положению и цвету неба. Даа, я знаю, возможно, это кому-то покажется странным или притянутым за уши… но мне показалось это интересным.
Поэтому я постарался сделать так, чтобы положение солнца на экране, как и цвета неба, примерно соответствовали текущему времени суток, для того чтобы быть вдохновением для гейм-мастера.

Как это работает: представьте, что нижняя часть вашего экрана – это условный горизонт вашего мира. Утром солнце поднимается из-за горизонта, ближе к 12 часам солнце в зените, а вечером солнце уходит за горизонт. Так и здесь. Космос и планета – это скорее мое желание сделать это все частью чего-то целого и визуально приятного. У меня получилось? :)

Таким образом, вы можете описать игрокам цвет неба и примерное положение солнца (если они видят их), чтобы дать им намек или возможность бросить на survival или nature, чтобы понять приблизительный диапазон возможных значений.

У солнца есть пасхалка, возможно, вы ее найдете :)

Редактирование событий
Редактирование событий

Что еще планирую делать?

Планирую расширять проект и добавлять в него больше маленьких и больших полезных инструментов, которые будут синергировать друг с другом, а также улучшать сам таймлайн и его фичи, например:

  • поиск событий по датам
  • возможность создавать закладки на таймлайне и быстрое переключение между ними
  • возможность ускорять или замедлять течение времени
  • возможность масштабирования (zoom in и zoom out на временной линии)

Также я хочу создать:

  • систему оповещений – вы можете включить эту опцию, и вам будут приходить пуш-уведомления о событиях, которые начались или закончились.
  • планировщик и трекер погони: есть конец и начало гонки, можно создать несколько движущихся объектов, дать им скорость, возможность редактировать, менять скорость, возможность измерять расстояние между объектами. Лог погони, а также синергия событий с таймлайном.
  • денежный конвертер – быстрая конвертация одних монет в другие по заданному курсу, а также возможность разбить общую сумму денег на количество членов в пати
  • гербарий: энциклопедия растений с картинками и их описанием, по разным биомам, возможность поиска по тегам/фильтрам
  • торговец: возможность настройки и генерации торговца в зависимости от уровня вашей репутации, жадности торговца, контрабандности/редкости товара. Он будет показывать стоимость продажи и покупки, если указана базовая стоимость.
  • трекер инициативы и лог боя – возможность создать своих персонажей (связь с публичным SGI), выбирать действие и цель, например атаку или заклинание.
  • создание аудиосцен (как в https://tabletopaudio.com/ только круче :D )
  • сохранение состояния приложения через бэкенд

Что уже есть сейчас:

  • интерактивный UI, звуки, музыка, пасхалки, анимации, смена дня и ночи
  • создание, удаление и редактирование миров, у каждого своя временная линия, шкала и треки, каждый из которых редактируется, а состояние запоминается в local storage браузера. Данные обновляются и сохраняются каждую секунду течения времени.
  • возможность кастомизировать события – цвет, описание, продолжительность, драг-н-дроп
  • динамическое редактирование времени мира – можно задать день, месяц, год, часы, минуты и секунды. Есть возможность быстрой смены времени по заданным шаблонам

Технические особенности

Я постараюсь коротко, потому что, если буду подробно, то это растянется в бесконечное количество слов.

Итак, особенности, они же сложности:

  • я узнал, что, оказывается, есть browser life cycle и что вкладка проживает разные стадии жизни. И если уйти со вкладки, то она уйдет в спящий режим в целях экономии ресурсов, во время которого все таймауты и интервалы замедляются. Для часов это убийственное ограничение, т.к. ты как Гейм Мастер вынужден держать 100500 вкладок открытыми и ты не хочешь принудительно держать открытыми часы. Решение: есть несколько способов, как не давать вкладке уснуть, например можно обновлять title каждую минуту. Есть и другие, о них можете прочитать вот по ссылке выше.
  • я впервые попробовал поработать с audio API и побаловаться с разными аудиоэффектами. Оказывается, можно менять питч, делать cutoff-фильтры, заменять темп аудио и так далее. К сожалению, я не был силен в теме, а ИИ год назад был так себе, и насоветовал он мне херни – создавать аудиоконтекст на проигрывание каждого отдельного звука. Интуитивно я понимал, что контекст должен быть общим, но в тот момент у меня не было желания детально изучать тему, поэтому я забил болт и оставил как есть. Как результат, после всех моих идей со звездами – безумное количество ненужных листенеров и куча контекстов, которые создаются и умирают
  • Я разлюбил стек tailwind + shadcn. Один мудрец сказал однажды: "начиная работу с tailwind, вы начинаете проект с техническим долгом"; и был совершенно прав. Tailwind невозможно нормально читать – это каша из 2-3-4-5 строк классов в html, которая черт пойми что делает, а колонка справа, где можно было бы прочитать стили, просто заспамлена целой кучей непонятно чего. Да, это прикольно и приятно для создания быстрых прототипов, но как будто можно так же или не хуже, но без вот этого всего. С ростом приложения этим становится сложнее пользоваться и сложнее поддерживать. К тому же новая версия tailwind перестала поддерживать scss “за ненадобностью” 🤷‍♂️ Короче, переношу стили обратно в scss, ухожу постепенно от tailwind, использую его в основном как набор переменных. Смотрю на Mantine UI
  • Zustand и Jotai – оч популярные библиотеки, работающие по аналогии с recoil.js. Их проблема в том, что они сильно завязаны на react life cycle, и твоя бизнес-логика начинает жить в хуках или селекторах. Но бизнес-логика не должна зависеть от UI, и UI не должен диктовать условия, каким образом управлять бизнес-логикой, – такая система становится менее гибкой. Реакт – это просто UI-слой. Как альтернатива, можно поставить computed midleware, чтобы вычислять производные значения, подписавшись на поля в сторе, эдакий аналог "юзэффекта", однако библиотечка оказалась с багами, и пришлось ее локально пропатчить. Другая проблема, что твои слайсы с ростом приложения начинают становиться зависимыми друг от друга, влиять друг на друга, и всему этому не хватает какой-то прозрачности, чистоты и структуры. Команда разработчиков Zustand прямо говорит, что, когда появляются зависимости между слайсами, то иметь god-like стор – это ок. Судьба свела меня с разработчиком awai.js, на базе которого можно довольно легко построить свою декларативную систему стора и сообщений. Хочу попробовать как-нибудь позже.
  • Для таймлайна: драг-н-дроп/ресайз событий использовал https://www.npmjs.com/package/interactjs просто потому, что 2 в 1, понятный интерфейс и пример, который был под рукой. В других либах либо демки багованные были, либо не было ресайза, либо еще что-то. Возможно, я просто долбился в глаза.
  • Для событий я сделал виртуализацию https://tanstack.com/virtual/latest – т.е. рендерится только то, что попадает во вьюпорт + половина вьюпорта слева и справа, но не меньше 300px.
  • Проблемным местом было прикрутить интервальные деревья: я очень прям хотел иметь возможность быстро получать события в заданном диапазоне. Так, например, каждую секунду я смотрю, есть ли пересечения, чтобы пометить те события, которые попали в дельту и оказались "в прошлом". Эти события становятся чуть более прозрачными... 😁 Использовал вот эту библиотечку https://www.npmjs.com/package/@flatten-js/interval-tree обещают логарифмическую скорость поиска, что достаточно быстро. Заодно посмотрел курс по алгоритмам про самобалансирующиеся красно-черные деревья https://www.coursera.org/learn/algorithms-part1-ru/home/module/1 Так вот, проблема в том, что структура интервального дерева мутабельная. Ну т.е. вы не хотите заново пересоздавать все дерево, если вы добавили или удалили событие, правильно? Потому что их может быть тысячи. А реакт любит иммутабельность (сторы, стейты, вот это все). Как быть? Короче, оказывается, есть вот такая херня: https://react.dev/reference/react/useSyncExternalStore, можно сделать что-то вроде простейшего pub/sub – инкрементально увеличивать ревизию при изменениях и оповещать подписчиков, и это как-то более-менее с пердежом и скрипом работает.

С какими трудностями пришлось столкнуться?

Звезды! Короче, звезды сажают перформанс! Оказывается, рендерить ~300 объектов, рандомизированно анимировать их – это, блин, дорого. Изначально у каждой звезды был блюр-фильтр, чтобы создать ощущение глубины, словно некоторые звезды ближе / дальше. Однако это оказалось слишком дорого – прям экран ночью начинал подлагивать. Это не годится.
Я пытался использовать svg и webgl. Возможно, с текущим уровнем ИИ писать шейдеры на webgl будет проще, но спустя полтора месяца экспериментов я вконец задолбался и решил откатиться к более простой и базовой версии звезд.

Ну и, по сути, уровень моих знаний, который, как оказалось, вырос, и недостаток которого сказался на архитектурных решениях, о которых я говорил уже выше. Сейчас я бы многие вещи сделал иначе.

UI все еще остается для меня больным местом. Из-за динамической смены дня и ночи/градиентов нужно подобрать цвета таким образом, чтобы они одинаково хорошо смотрелись на темном и светлом фоне. Это проблема. Чтобы решить ее полностью, мне нужно поработать над "светлой" и "темной" темами, пока что это отложено.

Я не делал stress test, возможно, при работе с тысячами событий в дереве я обнаружу падение перформанса. В теории все должно быть ок, но пока потестить руки не доходили.

Сколько потратили и заработали? Есть идеи, как это можно монетизировать?

Я работал над проектом в течение года в свободное от работы время и не заработал ничего, и не знаю, заработаю ли вообще. :) Я просто хотел сделать что-то крутое и доступное. Приложение бесплатное и хранит данные в браузере. Единственная идея, как можно было бы это монетизировать, – это предложить возможность хранения данных и регистрации/аутентификации, а значит, синхронизации и восстановления состояния между устройствами через бэкенд. Думаю предложить подписочную модель за 2$ в месяц.

Какие планы на будущее?

Мне нужно поработать над SEO. Разделить приложение и посадочную страницу, постараться постучаться в комьюнити и показать аппку. На Реддите меня забанили просто за пост о том, что я такие комьюнити ищу (на самом же Реддите)... Апелляцию уже подал, но все пока очень долго.

Я хочу сделать обучающие скринкасты и оформить лендинг.

Набросок лендинга, а точнее нижней его части. Белый прямоугольник – это подложка под контент (может, уберу ее хз). Земля – это футер
Набросок лендинга, а точнее нижней его части. Белый прямоугольник – это подложка под контент (может, уберу ее хз). Земля – это футер

Нужно также оформить и завести соцсети, начать их вести.
Я думаю, я расчленю данную статью на куски и буду скармливать ее по кускам там.

В голове есть сценарий и идея для ролика на ютуб. Должно получиться забавно... но когда до этого руки дойдут, я хз.

Все это занимает уйму времени, мне, конечно, хотелось бы больше уделять времени приложению и фичам, я все же разработчик, а все эти SEO и SMM – это не мое.

А еще, работая год над приложением, я понял, что... я перестал играть в D&D... Как-то это контрпродуктивно получается, не находите? Все затевалось для того, чтобы сделать крутые инструменты и пробовать вести игры, а в итоге сама игра стала чем-то совсем далеким. В то же время, если я переключусь на свои D&D игры, то где брать время на проект?..

Нужны ли какие-то советы или помощь Клуба?

Афигеть как нужны! Любая помощь востребована, начиная просто от слов поддержки, заканчивая конкретной помощью по проекту.

Как я и говорил, большая сложность для меня – это маркетинг и SEO.
Буду исследовать эту область, строить семантическое ядро, пилить лендинг, оформлять соцсети.

Любые советы от людей, запускавших свои веб-приложения, будут в кассу. У меня это "первенец". Я двигаюсь исходя из common sense и тех пары часов после работы, что остаются.

Вы пользовались приложением и у вас есть фидбек?
Или, может быть, вы нашли баг?
Может, у вас есть идеи/предложения?
Вы знаете классные уютные D&D сообщества или интересных контент-мейкеров/блогеров/инфлюенсеров, к которым можно постучаться и попросить рассказать о проекте?
Может быть, вы SEO-специалист, маркетолог, SMM-щик или запускали свой патреон?
Круто! Напишите мне об этом тут или на почту dm@dnd-time.com или в телегу @maliyshock

...

Если хочется поддержать финансово и купить мне пиво, то вот мой пейпал – maliyshator+paypal@gmail.com, мне будет приятно, хотя и слов поддержки и так вполне достаточно. :)

Музыка

Музыка была написана одноклубчанином Лешей Козловым, за что ему огромное спасибо!
Вот его сайт, YouTube и SoundCloud.
А пересеклись мы с ним в Вастрик.Музыканты

Связанные посты
Откомментируйте первым 👇

😎

Автор поста открыл его для большого интернета, но комментирование и движухи доступны только участникам Клуба

Что вообще здесь происходит?


Войти  или  Вступить в Клуб