В общем так. Кое-то похерил мою игру Death Masters. Ладно, шучу, не похерил, сервер работает, но доступ к нему пока нет, бэкапы никак оттуда не достать. Я пересмотрел то, как делать бэкапы для игроков (Mario, ПодОпытный, крепитесь, надеюсь, весь прогресс восстановится). Теперь я из тех админов, кто делает бэкапы ещё на 2 удалённых сервера в другие дата-центры)
Посему я написал небольшую игру на 3д движке. Основа - отель Троди из будущего, который использовали под дата-центр. Очень удобно использовать старинное здание под дата центр. Одно плохо - пожары :)
В общем, приятной игры. Лучший опыт будет при игре на большом мониторе и в наушниках. На телефоне тоже можно, главное в настройках подправить чувствительность курсоров.
Всем привет! С момента прошлого поста прошло прилично времени. Я не забросил проект, руки не опустил и всё ещё продолжаю пилить-пиить-пилить :).
Сразу дисклеймер: 5000 онлайна — это синтетические боты. Не живые игроки. Но это честные боты, которые подключаются по реальным WebSocket-сокетам, перемещаются по геодате 25 зон острова, собирают лут, применяют скиллы, пишут в чат и нагружают Spatial Grid сервера точно так же, как живые люди.
Городская площадь Деревни поющей стали: толпа ботов у фонтана и NPC, живой чат и стабильные 50 FPS при 5001 онлайне
1. С чего всё началось:
Cамый главный вопрос - сколько людей сервер потянет до того, как сгорит процессор). На 100–300 игроках всё летает. На 1000 - начинаются первые проблемы. Но хотелось проверить планку в 3000-5000 одновременных подключений (CCU) на скромном сервере (2 vCPU, 2 ГБ RAM на базе Яндекс Облака).
Я попросил ИИ написать генератор нагрузки на Node.js и запустил его со своего домашнего компьютера прямо в боевой сервер.
План был простой: заспавнить 3000 сокетов батчами по 20 штук и посмотреть на тик ядра.
Где-то на отметке в 2200–2400 ботов дома внезапно наглухо лёг интернет. Браузер перестал открывать страницы, а в консоли посыпались тайм-ауты сокетов.
Сначала я подумал, что лёг VPS. Захожу с мобильного интернета - сервер живой, тик 0.5 мс, всё спокойно. А домашний роутер просто завис.
Причина оказалась банальной: Обычные домашние роутеры и Wi-Fi-коробочки от провайдеров не рассчитаны на то, что с одной машины в квартире откроется 3000 одновременных TCP/WebSocket соединений. На роутере кончилась таблица NAT-трансляций (SNAT порты), память забилась, и он просто ушел в глубокий нокдаун.
Стало ясно: стресс-тестировать тысячи сокетов с домашнего ПК больше нельзя.
2. Переезд на распределенный кластер GitHub Actions
Чтобы не вешать домашнюю сеть и не арендовать отдельную пачку серверов только ради тестов, пришла идея: использовать раннеры GitHub Actions Matrix.
Восточный полигон: боты распределены по полям, на счетчике 5001 онлайн, рендер 7.6 мс, сеть 0.8 мс
Но тут возникла вторая засада. Если запустить один раннер Ubuntu в GitHub Actions на 5000 сокетов, он упирается в лимит Azure NAT Gateway - для одной виртуальной машины выделяется всего около 2048 эфемерных портов на внешний IP. Всё, что выше, начинает отваливаться с ETIMEDOUT и ECONNRESET.
Решение - матричный запуск:
Раннер #1 (Runner 1): 1700 ботов (смещение ID от 0 до 1699, часть ботов в городе, часть в полях);
Раннер #2 (Runner 2): 1700 ботов (смещение ID от 1700 до 3399);
Раннер #3 (Runner 3): 1600 ботов (смещение ID от 3400 до 4999);
Четвертый агрегатор: собирает метрики, перцентили RTT и формирует итоговый отчет.
Каждый раннер запускается на изолированной виртуальной машине со своим независимым публичным IP-адресом. Проблема с исчерпанием портов исчезла.
3. «Запустил... и нагрузил ровно 49 ботов»
Казалось бы, всё готово. Жму кнопку запуска в GitHub Actions, захожу в игру и вижу: Онлайн: 49.
Запрашивали 5000, а зашло 49. В консолях раннеров - сотни ошибок: Connect error: Unexpected server response: 429
Полез в логи разбираться:
Раннер 1 подключил ровно 16 ботов.
Раннер 2 подключил ровно 16 ботов.
Раннер 3 подключил ровно 16 ботов.
$16 \times 3 = 48$ ботов + я в клиенте = ровно 49.
Оказалось, сработала защита от DoS-атак! В сетевом транспорте стоял лимит: не более 16 активных сокетов с одного внешнего IP-адреса. Для реальных игроков это имело смысл (хотя даже для CGNAT мобильных операторов 16 маловато), но для нагрузочных раннеров это стало железобетонной стеной. Сервер честно отвечал: HTTP 429 Too Many Requests.
Мы с ИИ добавили авторизованный заголовок x-stress-key, подняли базовый порог для игроков до 64, передеплоили ядро на VPS и перезапустили тест.
4. Итог: 5001 онлайн в реальном времени
После фикса все три раннера залетели на сервер на полной скорости.
Холмы Астарда: боты фармят автоматонов и бешеных кофемашин
Вот реальные цифры из консоли и игрового оверлея:
Запрошено ботов: 5000
Успешно подключено: 5000 из 5000 (100%)
Ошибок рукопожатия: 0
Онлайн в игре: 5001 CCU (5000 ботов + 1 GM персонаж)
FPS клиента в браузере: 50–59 FPS (WebGL Three.js)
Время тика игрового сервера: 1.0 мс (EMA: 0.3 мс при норме тика в 100 мс / 10 Hz)
Event Loop Lag Node.js: 11.88 мс (полное отсутствие блокировок главного потока)
Обработано входящих пакетов: свыше 4.7 млн пакетов за тестовую сессию
Трафик: благодаря дельта-сжатию AOI сервер отфильтровал 61.5% лишних обновлений координат
Что позволило серверу не умереть под 5000 сокетами:
uWebSockets.js (C++ Zero-GC транспорт): забыли про стандартный ws из npm для 5000 сокетов на 2GB RAM. Нативный C++ транспорт держит соединения без давления на сборщик мусора V8.
C++ SIMD (AVX2) для расчёта дистанций и коллизий: модуль project_steam_native.node считает AOI и радиусы агро мобов векторными инструкциями процессора за микросекунды.
Worker Threads для сохранения в базу: вся работа с диском и состоянием игроков вынесена на отдельный поток vCPU, поэтому запись профилей никак не задерживает тик игры.
Проект жив, пилится дальше. Впереди ещё огромная гора работы.
Спасибо всем, кто следит и поддерживает! На бумаге все выглядит шикарно, как будет в реальной жизни? Время покажет))
В апреле 2023 года мы запустили необычный для нас проект - ремонтный сервис нового формата. Первого клиента нашли только в начале лета, но уже с первого проекта удалось достичь запланированной прибыли. Расскажу, как мы создали современную компанию для поколения "новых денег", которые не готовы к тому, что прораб будет класть половину стоимости ремонта себе в карман, а сроки растягиваются без ограничений и почему это оказалось прибыльным бизнесом.
Как всё начиналось
Конец 2022 года. Я работал менеджером проектов в крупной IT-компании, мой друг Антон - тимлидом в другой известной технологической компании, а Дима занимал позицию backend-разработчика в третьей. У всех стабильные зарплаты, интересные проекты - жизнь шла своим чередом, пока Антон не решил купить квартиру в новостройке.
После долгих поисков он остановился на 85-метровой квартире в ЖК около метро Саларьево - современный комплекс с подземным паркингом и зелёным двором. Как типичный программист, к поиску ремонтников он подошёл педантично: изучил десятки предложений, провёл собеседования с кандидатами. В итоге выбрал бригаду с Авито с "15-летним опытом работы".
Денис (это я:) - один из создателей сервиса
За время ремонта у Антона мы с Димой часто приезжали к нему - помочь, посоветовать, и просто поржать над очередными косяками строителей. У нас обоих за плечами был серьёзный опыт управления командами, внедрения процессов, автоматизации и контроля качества. И знаете что? Нам казалось, что главное в ремонтном бизнесе - это грамотный менеджмент и организация процессов. И на самом деле, все примерно так и есть.
День когда мы решились
Если честно, мысли о собственной ремонтной компании появились у нас задолго до этого случая. В IT-тусовке часто шутят, что в России есть три верных пути: вебкам, айти и стройка. И мы, насмотревшись на хаос в ремонтной сфере, не раз обсуждали возможность открытия своей “фирмы”.
Мы выделили основные проблемы, которые должны были исправить с помощью своего сервиса
Первое - это постоянно растущие сметы и "задранная стоимость" на работы. Ну вы серьезно? Почему для меня ремонт в квартире должен чем-то отличаться от заказа носков на Вайлдберриз? Почему-то там нет такого, что цена носков может вырасти в 2 раза за время доставки. А тут начальная смета в 1 миллион превратилась почти в 1,7! И каждый раз это "ой, тут стены кривые", "ой, а тут придется докупить", "ой, а это мы не учли".
Второе - это бесконечно растущие сроки. Это еще хуже. Как люди с опытом в менеджменте, мы прекрасно знали, что растущие сроки – это всегда раздолбайство управления и ленивые рабочие. Но тут было чуть посложнее, об этом чуть позже. У Антона обещали сделать за 4 месяца, а в итоге растянули на 8.
Третье - хитрые прорабы. Это вообще отдельная история. Когда прораб говорит "давайте я сам закуплю материалы, у меня скидки", знайте - он накинет сверху процентов 30-40. А еще есть "срочные работы", которые почему-то не были учтены в смете. И конечно, вечная классика - экономия на материалах: заказываешь одно, а привозят что-то попроще, но по той же цене.
Целевая аудитория
А параллельно с этим мы определили нашу целевую аудиторию. Чтобы выделиться на конкурентном рынке, мы решили ориентироваться на молодых IT-специалистов и представителей “современных” профессий, живущих в Москве в возрасте 30-40 лет. Тех, кто покупает квартиру в новостройке и привыкших к хорошему сервису. Кто не готов, что его будут водить за нос и разводить на деньги.
Что с ценой?
При этом очень важно было держать цены НИЖЕ, чем у других компаний, иначе на рынке просто не выжить. В премиум сегмент нужен "пропуск" в виде большого количества работ для определенного типа клиентов, поэтому нам было понятно, что "брать" много - пока что, непозволительно. Но мы нашли способ: автоматизация процессов, прямые поставки материалов, четкое планирование работ и никаких скрытых накруток. Но несбыточной мечтой это покажется только обывателю: на самом деле сервис и правда должен быть таким, вообще любой.
История первого заказа летом 2023 года
А теперь самое интересное - наш первый заказ. Это была отдельная эпопея. Начало лета 2023, звонок от потенциального клиента.
Первый клиент оказался прямо "в яблочко" - тоже айтишник (пришедший из первой контекстной рекламы в яндексе запущенной на 20 тыс.), работал в крупной компании, купил двушку в панельке 80-х годов. Причем достаточно убитую - стены местами с дырками, старый паркет, трубы помнящие еще Горбачева... Но нам, если честно, даже повезло что первый объект был не новостройкой. На старом фонде учиться легче - там хотя бы есть на что посмотреть, в отличие от новостроек, где все "сюрпризы" спрятаны в голых стенах.
Дырка в стене была ДО демонтажа. Клиент купил квартиру с "убитым" ремонтом подешевле, в надежде сэкономить
Как мы мастеров искали
Начали с поиска бригады. Вот тут был первый холодный душ - оказалось, что найти классных специалистов без своей наработанной базы очень сложно. Мастера хорошего уровня либо уже при деле, либо просят космос. А те, кто сразу соглашается - ну, вы понимаете. За две недели провели больше 10 собеседований (назовем их так😊). Причем процесс собеседования мы сразу сделали "как в айти" - тестовые задания, проверка портфолио, разбор технологий работы. Бригадиры были в шоке - некоторые прямо уходили с собеседований, когда мы начинали распрашивать про технологии укладки плитки и показывали фотографии косяков с объектов с форумов.
В итоге нашли бригаду - два брата, которые до этого работали в крупной ремонтной компании, но ушли потому что устали от "серых" схем – по отношению К НИМ ЖЕ. В основном - задержки з/п и прорабы.
В том же санузле, но уже после демонтажных и некоторых черновых работ. Братья очень помогли нам с первым ремонтом, кроме этого, они дали нам контакты проверенных рабочих, которые впоследствии делали ремонт вместе с ними
Купили первый комплект инструмента - это отдельная история на 100 тысяч рублей. Ещё сразу купили свою тепловую пушку - это из необычного. Большинство компаний привлекают "потолочников" на субподряд. Мы захотели сразу начать формировать свой инструментарий для будущих сотрудников. Зато потом эта закупка очень помогла - не зависели от того, что принесет с собой бригада. Позже, когда начали расширяться купили свою штукатурную станцию. Это, на удивление, было самой выгодной покупкой.
Первые сложности
Начали ремонт. И тут поехало... Первый сюрприз - когда начали снимать старую штукатурку, оказалось что стены буквально рассыпались. Плюс под старым линолеумом в коридоре нашли деревянный пол с насыпью под ним.
Тут был первый серьезный разговор с заказчиком. Объяснили ситуацию, показали все фотки, рассказали что сколько будет стоит в соответствии с прайс-листом. Тут очень помогло то, что мы сразу взяли за правило - фотографировать вообще все. Каждый этап, каждый слой, каждую трубу.
С материалами тоже было весело. Первый месяц я лично объездил все крупные строительные магазины в радиусе 30 км. Искал поставщиков, договаривался о скидках. Помню, как чуть не купили партию плитки по "супер-выгодной" цене, а потом выяснилось что это условно "второй сорт" - брак, который продают через "серые" схемы.
Cделали систему закупок: (Первый заказ полностью сделан из материалов, купленных в Петровиче и на маркетплейсах). Бригада присылает список - мы проверяем цены у 3-4 поставщиков и заказываем где дешевле.
Мы сразу внедрили систему ежедневных фото-отчетов и еженедельных созвонов. Плюс сделали чат в телеграме, куда скидывали все чеки, все накладные, все фотки. Такая прозрачность очень помогла - клиент видел, что мы не химичим с ценами и не пытаемся на нем нажиться.
В итоге сделали.
Братья советовали нам недостающих специалистов по ходу ремонта и постепенно, укладываясь в срок мы сдавали клиенту новый и новый этап. Честно, это было не так сложно как казалось в начале, но нужно понимать, что на самом деле, проблем по ходу ремонта и мелких трудностей было ОЧЕНЬ много, просто мы как люди привыкшие, понимали что сейчас это и есть наша работа , за которую нам платит клиент - взять на себя все заботы по ремонту. Но серьезных форс-мажоров не возникало, максимум понервничали, когда внесли предоплату потолочникам, которых нашли по объявлению, после чего они явно начали задерживать сроки, но в итоге, все обошлось. Нам и до этого было ясно, что чем быстрее мы соберем свой , хотя бы, небольшой штат, тем лучше и выгоднее. Но для этого надо быть уверенным в постоянном потоке заказов, что мы на тот момент, не могли себе позволить.
Главное - мы поняли как надо и как не надо. Все закупки только через нас. Все договоренности - только в письменном виде.
По деньгам первый проект получился условно в ноль - не считая наших вложений в инструмент и рекламу. Но мы получили бесценный опыт, наработали связи с поставщиками (если это можно назвать так пафосно) и главное - поняли, что наша модель рабочая, хотя на тот момент не были в этом до конца уверены. Наши сомнения развеяло лето 2023 года.
1/5
Наша первая работа, которую нам помогли закончить "братья", советуя недостающих мастеров на каждый этап работ. Цена работ для заказчика вышла 750 000 рублей. Летом 2023 года, за аналогичный объём работ авитовские бригады просили до миллиона(!)
Сайт и маркетинг или как мы общаемся с клиентами ещё до первого звонка
Кстати, про сайт. Первую версию мы сделали за пару вечеров на Тильде - максимально простую: фотки, цены, контакты. Знаете что? Он у нас до сих пор такой – но с значительно изменённым UI/UX. Я иногда ловлю себя на мысли - вот мы же, можем сделать что-то крутое, с личным кабинетом, онлайн-сметами... Но потом смотрю вордстат, статистику и думаю - а зачем? Клиенты находят нас, звонят, все работает. Иногда лучшее решение - самое простое.
1/2
На главной странице "в лоб" о том кто мы, наши конкурентные преимущества, специализация и примеры работ
1/2
Сразу "ярко" заявляем о действующих скидках. Кроме этого, простым текстом пытаемся общаться с клиентом и убедить его в нашем сервисе, пока что, не общаясь с ним лично - конверсия в лиды увеличилась значительно, но важно, чтобы все предложения были реальны
А вот ворд стат. За последний месяц нас искали 680 раз не считая статистики переходов по прямой ссылке. Доказательство того, что дорогой сайт не нужен. Наш стоит 6 000 рублей в год, а сделан за 20 часов
Примеры лучших работ как маркетинговый инструмент
1/4
Оставляли подобные фото с примерами работ и вотермаркой в отзывах к жилым комплексам. Отличный маркетинговый инструмент - сразу определяем нужную ЦА и бесплатно заявляем о себе. Точно знаем, что минимум один клиент был из отзывов яндекс - поэтому работает
Как мы масштабировались и разбирались в проблемах ремонта
Теперь про то, как мы начали разбираться в проблемах ремонта и потихоньку расти. Знаете, за этот год мы много думали - почему вообще ремонтные компании задерживают сроки и не могут сделать работу по первоначальной цене? И нашли несколько интересных моментов.
Первое - сроки. Тут даже копать глубоко не пришлось - сам рынок сформирован так, что клиенты просто привыкли к задержкам. "А, ну это ремонт, тут всегда так" - классическая фраза. Благо тут нам помог опыт организации процессов из айти. Четкие спринты, ежедневные отчеты, календарный план. Работает как часы, если не филонить.
Второе - вечно растущая цена. Вот это было сложнее. В новостройках еще можно точно посчитать, а во вторичке... Но благодаря наработкам этот вопрос стал гораздо яснее. При правильно организации процессов, непредвиденные работы лучше оплатить из своих средств, чем терять клиента. Только так и делается сервис.
Третье - больная тема - воровство на материалах. Тут мы конкретно закрутили гайки. Завели строгий учет, до последнего мешка штукатурки. Прорабам сразу сказали - любая жалоба от клиента на нечестность - это конец сотрудничества. Знаете что самое смешное? Когда начали работать честно, оказалось что маржа все равно хорошая. Просто многие привыкли что надо обязательно накручивать еще и еще.
Неприятные особенности прозрачного сервиса
Большинство компаний, которые начинают работать честно, быстро сдуваются. Потому что сам потребитель привык к плохому сервису. Приходишь к клиенту, говоришь "мы все сделаем четко по смете и в срок", а он смотрит с недоверием - "да ладно, так не бывает". Сейчас в 2024-м ситуация получше, но рынок все еще очень консервативный.
Продвижение или как мы брали “Новую Москву”
Наш любимый Прокшино в Новой Москве - в 2024 году, это самый перспективный район в котором покупатели - наши потенциальные клиенты
Расти начали потихоньку. Сначала сделали специальные цены для новой Москвы - там как раз много новостроек, где мы хорошо научились работать. Потом пошли заказы по рекомендациям. Когда я говорю “пошли” заказы нужно понимать, что это 1-3 заказа в месяц стабильно, что на самом деле, тогда казалось не мало. С рекламой экспериментировали забавно - оставляли визитки в подъездах (да, просто старые добрые визитки!), ставили рекламные ящики у офисов продаж в дни выдачи ключей.
Был случай, когда на одном ЖК поставили такую стойку, а через неделю риелтор оттуда сам позвонил и предложил взять себе процент, если клиент пойдет к нам.
Сейчас берем 2-5 заказов в месяц, (летом было 5 в месяц, если разделить). Большинство клиентов приходят по рекомендациям. Штат за год работы постепенно собрали свой. Трудоустроено 14 сотрудников. Если их не хватало (как летом), привлекали мастеров с которым уже работали раньше, по договору ГПХ. Просили всех регистрировать самозанятость или ИП – это было тяжело, но зато честно платим налоги по Доходы – расходы.
Как устроен процесс
Знаете, что самое сложное в ремонтном бизнесе? Нет, не поиск клиентов и не работа с материалами. Самое сложное - это выстроить систему, которая будет удовлетворять запросы клиента и при этом позволит компании зарабатывать. Мы долго думали над этим и придумали несколько интересных решений.
Начнем с оплаты. Если посмотреть на московский рынок, там забавная система - вроде бы без предоплаты, но это только за первый, самый дешевый этап. А потом - бац, и клиент должен внести 50% от всей суммы. И попробуй не внеси - бригада уйдет на другой объект. Мы сделали иначе: разбили весь ремонт на этапы (их получилось 12 для капитального ремонта), и берем предоплату только за текущий этап. То есть клиент всегда понимает, за что именно платит, и может контролировать процесс.
С договорами тоже интересно получилось. Сначала делали один стандартный, а потом поняли - люди разные, запросы разные. Сейчас у нас три варианта: просто на работы (для тех, кто сам хочет закупать материалы), на работы плюс материалы (самый популярный), и полный пакет с дизайн-проектом. Кстати, про дизайн - мы не держим штатных дизайнеров, работаем с фрилансерами. Так получается и дешевле для клиента, и качество выше - каждый дизайнер специализируется на своем стиле.
Первый образец договора, который ставили на сайт
Расчёт стоимости
Расчет стоимости работ - отдельная история. Когда начинали, было очень сложно. На рынке нет четких цен - один мастер берет 3 тысячи за квадрат стяжки, другой - тысячу, третий вообще говорит "ну давайте посмотрим по факту". Сначала работали по среднему прайсу, но часто уходили в минус по отдельным этапам - то бригада дороже встанет, то материала больше уйдет. Сейчас, когда появились постоянные сотрудники, стало проще - мы точно знаем их расценки и можем давать фиксированную цену.
Материалы
Выяснилось, что в крупных магазинах часто дешевле в сравнении с рынками стройматериалов, особенно если ловить акции. Плюс появились маркетплейсы - там вообще красота по ценам. И главное - полная прозрачность, клиент сам видит все позиции. Если находим материал дешевле - возвращаем разницу. Был случай, когда на керамограните сэкономили клиенту почти 30 тысяч - просто потому что, нашли ту же плитку в другом магазине по акции.
Как работаем сейчас
Сейчас берем 2-5 заказов в месяц, зависит от сезона и сложности объектов.
Процесс обкатан до мелочей: сначала выезд на замер, потом предварительная смета. Если клиента все устраивает - детальный расчет и договор. Дальше начинается самое интересное - согласование материалов, закупки, работа.
Особенности продвижения и подводные камни
С продвижением интересно получилось. Сначала, как все, полезли на Авито. И знаете что? Не зашло. Там своя специфическая аудитория и конкретно у нас, с Авито “ не пошло”.
Свежий пример страницы с авито в категории "Ремонт квартир". Как клиенты определяются с подрядчиком среди тысяч однотипных объявлений - хороший маркетинговый вопрос, который мы решаем, после чего полноценно "зайдём" на авито
Пробовали контекстную рекламу яндекс - тоже так себе результат. Клики дорогие, конверсия низкая. Зато отлично зашла таргетированная реклама в Instagram* (*запрещен в РФ) и реклама в районных пабликах ВКонтакте. Особенно в группах новостроек в ТГ - там как раз наша целевая аудитория.
Но главный канал - сарафанное радио. Причем работает оно интересно. Всегда знаешь , от кого пришли заказчики и проще выстраивать коммуникацию. Есть клиент - он доволен, рассказал коллегам - и понеслось. За три месяца получили еще два заказа от сотрудников той же компании. Выходит такой “корпоративный ремонт”)))
Были, конечно, и провалы в продвижении. Пытались работать с риелторами - предлагали им комиссию за клиентов. Не пошло - у них свои схемы, свои бригады. Пробовали давать рекламу в лифтах, входных группах - тоже мимо, ни одного обращения, но тут скорее из-за того что эта реклама буквально на день.
ИТОГ
Сейчас мы существуем уже чуть больше года и в целом смотрим на ремонтный рынок не так, как раньше. За это время мы сделали несколько важных заметок для себя:
Оказывается, большинство проблем в ремонте - это не технические сложности, а банальная организация процессов. Когда все четко спланировано и каждый знает что делать - даже самый сложный ремонт идет как по маслу.
Мы поняли, почему многие компании "химичат" с ценами и сроками - просто потому что не умеют нормально считать и планировать. Когда все процессы выстроены правильно, можно работать честно и все равно оставаться в плюсе.
Самое сложное - это не найти клиентов или научиться делать ремонт. Самое сложное - это переломить привычку рынка работать "по-серому". И заказчики, и исполнители настолько привыкли к непрозрачным схемам, что честный подход вызывает удивление.
Мы до сих пор учимся. Каждый объект - это новый опыт и новые вызовы (особенно по части коммуникаций с клиентами). Но главное - мы видим, что наша модель работает и пока что, нам удается держать ценник немного ниже рыночного, за счёт того что до сих пор не имеем в найме маркетологов, IT, отдела продаж и менеджеров по продажам. Стараемся нанимать именно рабочих, все остальное можно отдать на аутсорс.
Уважаемые пикабушники, были рады составить для вас эту статью! С любовью, СК Комната
3D-репродукция «Ночного дозора» Рембрандта (1642), которая открывается в браузере — на компьютере или телефоне. Всё началось с подарка на день рождения другу, который давно мечтал о «Ночном дозоре» в 3D.
24 человека и собака с картины, ворота с аркой, лестница и щит. Камера стоит в ракурсе картины, а у каждой фигуры свой свет на лице — так Рембрандт выхватывает лица из темноты.
Следующие кадры — снимки экрана живой веб-сцены, а не рендеры.
1/3
Это сцена, а не картинка: роту можно обойти и рассмотреть с любой стороны, даже сверху.
Сцена работает на телефоне. Нажмите на фигуру — откроется карточка: имя, годы жизни, биография и источники. Отождествления — по Дудоку ван Хелу («Rijksmuseum Bulletin», 2009).
1/2
На щите над аркой имена стрелков заменены строкой из «Мёртвых душ» Гоголя, опубликованных в 1842 году — через двести лет после картины. Я тоже есть в сцене: скромненько стою возле Рембрандта и проверяю ту же надпись на картуше со свитка. Планирую разработать шрифт в стиле голландского курсива для лучшего соответствия этой надписи.
Кое-чего у Рембрандта нет. В толпе стоят мои друзья — с их разрешения. У ступеней сидят мои собаки Тотошка и Чип. А ещё есть «Амстердамская кавалерия»: три спаниеля, на одном из которых восседает кот, — оммаж «Бременским музыкантам» братьев Гримм и «Каштанке» Чехова.
Детализации фигур хватает, чтобы напечатать их на 3D-принтере как большие статуэтки (по частям) или как миниатюры в упрощенном виде. Капитана (геометрия) и лейтенанта (с текстурой) можно скачать с GitHub.
1/2
Чтобы сцена Blender на 6 ГБ поместилась в веб-страницу, каждая фигура упрощена примерно до 200 000 треугольников, текстуры сжаты, а свет пересобран для браузера. Заметки, скрипты и замеры лежат на GitHub — включая то, что здесь стандартная практика.
В середине 90-х и начале 2000-х у многих из нас дома стояли пузатые ЭЛТ-мониторы с Windows 95/98 или голым MS-DOS. И среди сотен игр были те самые особенные шедевры, музыка из которых въедалась в память навсегда:
Xixit (1995) — медитативная головоломка, чей глубокий, меланхоличный и невероятно атмосферный саундтрек затягивал так, что игру не хотелось выключать часами.
Mine Bombers 3.1 (1995) — финский хит, за которым мы с друзьями устраивали ожесточенные баталии на одной клавиатуре. Взрывы динамита в темных шахтах гремели под бешеный, зажигательный драйв трекерных мелодий.
А чуть позже — музыка из кейгенов и кряктро от культовых демогрупп (Razor 1911, Fairlight, Paradox), где авторы умудрялись упаковывать полноценные симфонии в файлы размером 20–50 килобайт!
Это была трекерная музыка (MOD, XM, IT, S3M). В ней не было записанного аудио: файл содержал крошечные кусочки сэмплов и таблицу шестнадцатеричных нот, которые компьютер синтезировал в реальном времени.
Я сам с юности увлекался написанием таких треков в FastTracker II и долгие годы мечтал о пет-проекте: сделать настоящий веб-плеер трекерной музыки, который играл бы эти хиты прямо в браузере с живым звуком и аутентичной атмосферой демосцены.
Я frontend-разработчик, поэтому большую часть времени работаю с веб-интерфейсами. Но давно хотелось сделать не просто технический прототип, а законченный игровой проект, который можно открыть в браузере и дать поиграть другим людям.
С Three.js я познакомился во время разработки 2D/3D-редактора. Тогда мне стало интересно, получится ли применить полученные знания не только для редакторов и интерфейсов, но и для полноценной игры. Поэтому я решил попробовать сделать собственный игровой проект.
Так появилась Taproom 8 — небольшая 3D-игра с элементами хоррора и механикой поиска аномалий.
Игра отдаёт дань уважения играм Exit 8 и серии Backrooms.
Сначала игрок попадает в обычную комнату. Это нулевой цикл — в нём нет аномалий. Нужно осмотреть помещение и запомнить его состояние: где стоит мебель, какие предметы присутствуют или отсутствуют.
Затем начинаются следующие циклы. Комната выглядит почти так же, но в ней появляется изменение.
Задача игрока — заметить отличие и выбрать правильную дверь:
«Есть аномалия»;
«Аномалий нет».
Если выбор правильный, игрок переходит дальше. Если ошибся, прохождение возвращается к началу.
Почему именно такой формат
В качестве визуального направления я выбрал мрачную low-poly графику с эффектом старых игр для PlayStation. Хотелось получить не реалистичный бар, а немного странное место, которое вызывает дискомфорт.
PS1-эффект я не стал делать только через готовый фильтр поверх экрана. Сцена сначала рисуется в уменьшенном разрешении, текстуры используют nearest-фильтрацию, а позиции вершин привязываются к виртуальной пиксельной сетке.
Что такое Three.js
Three.js — это JavaScript-библиотека для работы с 3D-графикой в браузере. Она использует WebGL и предоставляет базовые инструменты для создания сцен, камер, геометрии, материалов, текстур, освещения и загрузки 3D-моделей.
Важно, что Three.js — не игровой движок в привычном смысле. В ней нет готового редактора уровней, полноценной физики, системы персонажей, диалогов, сохранений и других игровых подсистем, которые обычно ассоциируются с Unity или Unreal Engine.
По сути, это набор инструментов для отображения 3D-графики и работы с ней. Поэтому в Taproom 8 мне пришлось самостоятельно собрать многие части игры: игровой цикл, загрузку уровня, управление игроком и камерой, столкновения, двери, систему раундов и аномалий, звук, интерфейс и интеграцию с Яндекс Играми.
Именно поэтому проект оказался для меня интересным: я не просто подключал готовые игровые механики, а собирал игровой слой поверх библиотеки, с которой раньше познакомился во время разработки 2D/3D-редактора.
Как устроена разработка
Стек получился немного необычным для игры:
Vue 3 — меню, настройки и интерфейс;
TypeScript — игровая логика и типы;
Three.js — 3D-сцена, камера, модели и взаимодействия;
Vite — сборка проекта;
Pinia — состояние интерфейса;
vue-i18n — русский и английский языки;
Vitest — тестирование игровой логики.
Vue здесь не управляет каждым объектом в 3D-сцене. Я разделил приложение на два слоя.
Игровой движок отвечает за сцену, игрока, камеру, столкновения, двери, звук и раунды. Vue отвечает за экраны, HUD, меню, настройки и мобильные контролы.
Между ними используется типизированная шина событий. Например, UI не должен знать, как именно Three.js открывает дверь. Он отправляет событие «выбрать дверь», а игровой координатор уже решает, что делать с этим действием.
Такой подход оказался полезен, когда количество систем начало расти: меню, загрузка, звук, пауза и сам игровой цикл не превратились в один огромный компонент.
Аномалии сделаны как отдельная система
Одной из главных задач было сделать так, чтобы добавление новых аномалий не требовало переписывать половину игры.
Сцена загружается из GLB-файла. Внутри неё есть специальные группы объектов, которые движок сканирует при загрузке. По имени объекта и суффиксу сложности он понимает, что с ним можно сделать.
Дальше система сама собирает пулы аномалий и распределяет их по уровням. В начале вероятность простых изменений выше, затем постепенно увеличивается доля средних и сложных вариантов.
Технически аномалия применяется только на время текущего цикла. После ответа игрока состояние объекта восстанавливается, а перед следующим раундом активируется новая аномалия.
Звук и управление
В игре есть фоновая музыка, звуки меню, открывания дверей, шагов и окружения. Для некоторых источников используется пространственное позиционирование, чтобы звук зависел от положения игрока в комнате.
Самый неприятный этап — публикация
До этого проекта мне казалось, что самая сложная часть — сделать саму механику. На практике после появления рабочей игры начался второй большой этап: адаптация под платформу.
Первая версия Taproom 8 не прошла модерацию. После этого пришлось отдельно пройтись по описанию игры, локализации, экрану загрузки, обработке пауз, рекламным переходам, мобильному управлению и общему поведению приложения при сворачивании.
Интеграция с платформой включает уведомление о готовности игры, управление игровым состоянием при паузе, полноэкранную и rewarded-рекламу, а также задел под внутриигровые покупки.
Игра должна корректно переживать не только обычный игровой цикл, но и вкладку браузера, потерю фокуса, рекламный экран и возвращение игрока обратно.
После доработок игру удалось опубликовать. Этот этап показал, что релиз браузерной игры состоит не только из сцены и игровой механики. Необходимо учитывать окружение платформы, её ограничения и различные сценарии поведения пользователя.
Что получилось в итоге
На текущей версии в репозитории есть отдельный 3D-движок, UI на Vue, загрузка GLB-модели и текстур, PS1-рендеринг, мобильное управление, звук, локализация, интеграция с платформой и система аномалий.
Я понимаю, что это не большая коммерческая игра и не попытка конкурировать с полноценными хоррорами. Это компактный самостоятельный проект, на котором хотелось пройти весь путь: от идеи и сцены до работающего релиза в браузере.
Главным результатом для меня стал опыт создания полноценного игрового проекта поверх Three.js: с собственной архитектурой, игровым циклом, системой аномалий, интерфейсом, звуком, оптимизацией и публикацией.
Привет, Пикабу. Я разработчик ГИГАХРУЩ / GIGAH|RUSH и хочу показать текущий браузерный билд, а заодно собрать нормальный фидбек по первым минутам.
Это survival horror / ARPG shooter про вылазки внутри безграничной бетонной структуры. Игрок начинает в относительно жилой зоне, собирает еду, воду, патроны, бинты, документы и оружие, выбирает повод выйти наружу, а потом пытается вернуться с добычей, информацией и последствиями.
Мне хотелось уйти от формата "сгенерировали коридор, убили врагов, вышли в меню". Поэтому игра строится вокруг вылазок и систем, которые давят друг на друга. Есть фракции, торговцы, NPC с A-Life, рынки, слухи, квесты, контракты, монстры, ручные и процедурные этажи, браузерные сохранения и САМОСБОР.
NPC не просто стоят декором. Они могут торговать, спать, драться, прятаться, вступать в конфликты и умереть навсегда. Фракции помнят поступки игрока. Рынки меняют цены. В комнатах остаются следы боев и пустые контейнеры. Если где-то умер человек, система не обязана тихо заменить его новым.
Отдельная механика - САМОСБОР. Это не катсцена, а событие, которое ломает нормальную прогулку: двери герметизируются, туман идет по щелям, монстры становятся активнее, а привычный маршрут перестает быть надежным. Иногда правильное решение - не геройствовать, а бросить часть плана и искать выход.
Сейчас в билде уже есть:
- подготовка перед вылазкой;
- бой, торговля, инвентарь и квесты;
- фракции, репутация и A-Life NPC;
- ручные и процедурные этажи;
- САМОСБОР-события;
- карта, слухи, контракты и браузерные сохранения;
- запуск прямо в браузере без установки.
Делается на TypeScript/Vite, WebGL/canvas и процедурных ассетах. Без Unity/Godot, без импортированных UI-фреймворков и без ассет-паков: текстуры, спрайты и звук генерируются внутри проекта.