Архитектура игры «Березовка»: C4 и критические пути
Окружение, схемы C4 до компонентов и четыре критических пути: запуск, кадр, шаг сюжета и подстройка под слабую машину.
Берёзовка — заснеженная деревня в браузере: открытый мир около километра, сюжет, «Жигули», рыбалка. Без сервера и без сборки: одна страница и пять модулей. Ниже: окружение, схемы C4 до компонентов и четыре пути, на которых всё держится.
C4: контекст и контейнеры
Уровень 1. Система и её окружение
Своего сервера у игры нет: всё работает из статических файлов, прогресс лежит в браузере.
Уровень 2. Контейнеры
Страница владеет циклом и состоянием; модули получают всё нужное через переданный объект ctx и своих глобальных данных не заводят.
C4 уровня 3: компоненты
Показаны контейнеры, где есть что разбирать: страница и четыре модуля плюс загрузка ассетов. Звук (sound.js) устроен просто: makeSound(env) получает снимок состояния игры и сам решает, что играть.
Страница
Сюжет задаёт номер этапа; от него зависит, какие предметы видны и куда указывает стрелка задания.
Цикл ограничивает шаг по времени 0,05 с, чтобы после паузы ничего не «прыгнуло».
Сохранение пишется при смене этапа и каждые 15 секунд.
Свет и вид
Небо, окружающий свет и туман берутся из одних и тех же панорам, поэтому все модели стоят в одном свете.
Днём и в пасмурь это панорамы Poly Haven, ночью своя картинка.
Затенение углов само выключается, если средний кадр дольше 33 мс.
Движение
Чистая логика не зависит от three.js: человека и машину можно прогнать в тесте без экрана.
Скорость растёт с конечным ускорением, поворот идёт дугой.
Темп шага считается как скорость, делённая на длину шага клипа: ноги не скользят.
Машина: четыре пружины, крен, лёд, ручник; разгон 0–100 за около 18 с.
Расстановка и масштаб
Все расстановки считаются от одного зерна случайных чисел: мир каждый раз получается одинаковым.
Дом разворачивается к ближайшей дороге, двор получает забор и колею.
Размер модели сверяется с реальным: если выходит из допустимой полосы, ставится целевой.
Дальний лес режется на плитки и скрывается целиком, пока игрок далеко.
Загрузка ассетов
Модели лежат в .js-файлах как текст: так игра грузится с любого статического хостинга.
Загрузчик показывает группы ресурсов и помечает ту, где что-то не загрузилось.
Звуки подгружаются отдельно, пока файла нет, играет синтез.
Четыре критических пути
1. Запуск игры
Меню появляется, только когда загружено и собрано всё; кнопка «Продолжить» видна, если есть сохранение.
2. Один кадр
Если игра в меню, цикл только крутит камеру вокруг деревни; в загрузке ничего не делает.
3. Шаг сюжета
Игра ведёт игрока по цепочке из 13 этапов; финал запускается колоколом на 12-м.
4. Слабая машина
Игра снижает качество сама: на сенсорных экранах без постобработки, на медленных видеокартах без затенения углов.
Правила, на которых всё держится
Один источник света. Небо, окружение и туман берутся из одних панорам.
Модуль не заводит глобальных данных. Всё приходит через ctx из страницы.
Чистая логика отдельно от экрана. Движение проверяется без three.js.
Каждое измеримое свойство имеет проверку. Игра печатает в консоль строки GATE … OK или FAIL: размеры зданий, скорость шага, скольжение ног, разгон машины, яркость кадра.
Мир детерминирован. Расстановка идёт от фиксированного зерна.
Слабые места
Где
Что не так
Страница-монолит
Цикл, сюжет, столкновения, интерфейс и сборка мира лежат в одном файле на полторы тысячи строк.
Сюжет в коде
Реплики и этапы зашиты в функции talk; новую главу не добавить без правки страницы.
Вес загрузки
Около 33 МБ при первом запуске: модели в base64 и библиотека с внешнего CDN.
Нет сервера
Сохранение живёт только в одном браузере и пропадает при очистке данных сайта.
Телефоны
Есть джойстик, но игра рассчитана на компьютер; на сенсорных экранах нет постобработки.