The Jerusalem Post‘Hager (Land),’ an epic story of Ethiopian immigrants, wins Best Israeli Film at Haifa festESPNWeek 5 Power Rankings: Miami moves up, Missouri and Pitt join the top 25PunchTwo dead, one missing as floods hit Spain cityDaily MaverickSOCIAL (IN)SECURITY: A Cape Town mother buys bread on credit to stretch her children’s grants, then spends payday settling the debtRTP Desporto12h30 Henrique Calisto quer saída digna para Cristiano RonaldoSky TG24Istat, la pressione fiscale aumenta al 43,5%. Cala il potere d'acquisto delle famiglieZDF heuteAktuelle Pressemitteilungen des ZDFObservador DesportoAs notícias das 13hGlobal NewsU.S. Coast Guard suspends search for missing Ontario air ambulanceStraits Times SportFrom jiu-jitsu fighter Noah Lim a lovely lesson: Grace after gritABC NewsSouth Korea blames North Korean mines for border blast injuries and demands apologyسكاي نيوز عربيةمقاعد من الركام.. رحلة غزاوي لإعالة أسرته ومساعدة الطلاب
The Daily Newsstand · Free, Always
Monday, October 5, 2026

Детектив на статике: как я собрал ARG с пятью шифрами без бэкенда, регистрации и бюджета

Translate

Привет, Хабр. Я соло разработчик: студия из одного человека и ИИ ассистента. У нас есть сайт tempapp.ru, и на нём живёт «дело № 031»: сезонный детектив в формате ARG (alternate reality game). Игрок находит спрятанную папку с делом, ловит голубя свидетеля, читает чужой дневник 1999 года, разгадывает цепочку шифров и в финале выясняет, что расследование было не совсем расследованием.

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

Задача и ограничения

Хотелось: многошаговую игру на 6 эпизодов, прогресс игрока между эпизодами, сезонный ритм (особые события по пятницам), воронку аналитики, и чтобы всё это переживало паузы: сезон должен быть проходим в любое время, без живого админа.

Ограничения: статика на Object Storage + CDN, один разработчик, телефоны у большинства игроков.

Проблема первая: синк прогресса без аккаунтов

Серверного состояния нет. Прогресс игрока хранится в localStorage хаба, но «спутники» расследования (отдельные страницы спутники с уликами) должны как то сообщить хабу: «игрок дошёл, засчитай этап». Можно было бы положиться на общий localStorage внутри одного домена, но это ломается сценарии вроде «спутник прошёл на телефоне, хаб открыл на десктопе» и вообще выглядит хрупко.

Решение: кодовые слова как явный протокол синхронизации. Спутник в финале своего эпизода выдаёт игроку слово. Игрок вносит его на хабе, хаб засчитывает улику. Слово это одновременно и механика, и часть сюжета: оно существует внутри мира игры, а не в интерфейсе.

Проверка на хабе выглядит примерно так:

function checkCode(word){  const w = (word || '').toLowerCase().trim();  if (w === 'клевета'){ /* улики 3-5, цель case031_kleveta_hub */ }  else if (w === 'протокол'){ /* улики 6-7, цель case031_protokol_hub */ }  else if (w === 'голубь'){ /* уже сработало раньше */ }  else { /* ложный след, цель case031_wrong_code */ }}

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

Проблема вторая: шифры, которые решает человек

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

Шаг

Шифр

Разгадка

1

Цезарь +3: «ЁСОЦДЯ»

ГОЛУБЬ (алфавит 33 буквы, с Ё)

2

Морзянка -.- .-.. . .-- . - .-

КЛЕВЕТА

3

Акростих из 8 записей дневника

ПРОТОКОЛ

4

Перестановка «УПШСОИ», ключ 1-7-0-9-1-9

ТИШИНА (ключ: дата газеты 17.09.1999)

5

Дверь из пяти слов

ОТДЕЛ

Морзянку голубь «стучит» сам: пульсы opacity на картинке, единица 170 мс. Ключ перестановки спрятан внутри лора: газета датирована 17.09.1999, и это реальная пятница (проверял по календарю, да). Каноническая дата исчезновения: ночь с четверга на пятницу. Игроки такое находят и ценят.

Проблема третья: сезонный ритм без сервера

События по расписанию обычно означают cron где то в облаке. Здесь расписание вычисляется на клиенте:

const d = new Date();const isSignal = d.getDay() === 5 && d.getHours() >= 19;

Пятница, 19:00: на хабе загорается «сигнал» у папки дела, на спутниках открываются особые фразы и скрытая запись дневника. Сезонный ритм без единого таймера на бэке. Да, время клиента можно подкрутить. Для сюжетной игры это приемлемая цена: мы не турнир с призовым фондом, а честность игрока с самим собой часть жанра.

Проблема четвёртая: мобильные игроки

На десктопе есть приятный секрет: тайп‑трап. Игрок просто печатает слово на клавиатуре в любом месте страницы, буфер последних 8 клавиш ловит его:

buf = (buf + e.key.toLowerCase()).slice(-8);

На телефоне клавиатуры нет, тайп‑трап мёртв. Решение: на спутниках живёт «полевая рация» (обычный input, стилизованный под рацию), а на хабе «полевой ввод кода». Тайп‑трап остался десктопным бонусом для внимательных, критический путь не зависит от него.

Аналитика без регистрации

Вся воронка собирается целями Яндекс.Метрики: case031_open, case031_ep1, case031_morse, case031_kleveta_hub, case031_friday9 и так далее. Каждый вызов обёрнут в try/catch, чтобы блокировщики не ломали игру:

function caseGoal(name){  try { ym(111******, 'reachGoal', name); } catch(e) {}}

Так я вижу, где игроки застревают, не зная о них ничего лишнего. Идеальная сделка: у игры нет персональных данных, у меня есть воронка.

Что в итоге

Три эпизода из шести уже живут, суммарно это примерно 80 КБ HTML и JS. Сезон дешевле месяца аренды самого слабого VPS. Главные выводы для себя:

  1. Кодовое слово как протокол синка: просто, надёжно, работает между устройствами и легко объясняется сюжетом.

  2. Расписание на клиенте: годится для всего, где подкрутка часов не рушит экономику.

  3. Шифр должен решаться карандашом. Если нужен CyberChef, порог входа уже слишком высокий.

  4. Метрика целями вместо аналитического бэкенда: ноль персональных данных, вся воронка на месте.

Сайт: https://tempapp.ru (папку дела найдёте, если осмотритесь). Сезон проходится в любое время, а сигнал, как положено, по пятницам после 19:00.

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

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.