Интерактивная игра-пазл по Honkai: Star Rail на Next.js и Bun. Игрок выбирает профиль, сложность или режим испытания, собирает мозаику drag-and-drop механикой, а результаты endurance-режима попадают в таблицу лидеров.
- Drag-and-drop сборка пазла на
@dnd-kit. - Три обычные сложности:
easy,medium,hard. - Challenge/Endurance режим: бесконечные раунды, таймер, очки, бонусы времени и leaderboard.
- Infinity режим: свободная бесконечная игра без таймера, очков и статистики.
- Leaderboards: классические таблицы по сложностям и рейтинговая таблица Challenge-режима.
- Live-обновление лидербордов через Server-Sent Events.
- Админ-панель со статистикой, настройками режимов и быстрым запуском Challenge/Infinity игр.
- Адаптивный portrait layout для мобильных экранов.
- Модалка правил с каруселью и изображениями из
src/assets/help. - Автоподготовка игровых изображений: контуры, нарезанные фрагменты и цветовые палитры досок.
- SQLite-хранилище через
bun:sqlite. - Docker-сборки для local/development/production окружений.
- CI/CD публикует Docker image, standalone zip build и GitHub Release/Pre-release.
Установка зависимостей:
bun installЗапуск dev-сервера:
bun devПриложение будет доступно на http://localhost:3000.
Production build:
bun run buildStandalone build в папку build без Docker:
bun run build:exportЗапуск production-сервера:
bun run startbun dev # predev + Next dev server через Bun/Turbopack
bun run build # prebuild + production build через Bun/Turbopack
bun run build:export # build + экспорт standalone runtime в ./build
bun run start # Next production server
bun run lint # ESLintПеред dev и build автоматически запускается:
bun run scripts/prepareBoardImages.tsЭтот скрипт:
- генерирует
public/palettes.jsonдля фона игрового экрана; - генерирует
public/profiles.jsonсо связями профилей и досок; - генерирует
public/boards.jsonсо списком доступных досок; - создаёт контурные версии досок в
public/boards/outline; - нарезает доски на фрагменты в
public/pieces; - нарезает контуры в
public/pieces/outline.
sharp используется только в scripts pipeline, а не в runtime-коде Next.
Если Docker не нужен, можно собрать такой же runtime-артефакт, какой используется в runner stage Dockerfile:
bun run build:exportКоманда создаёт директорию:
build
В неё попадают:
- standalone-сервер из
.next/standalone; - статические Next-ассеты из
.next/static; - публичные runtime-файлы из
public, кроме оригинальных изображенийpublic/boards; - директория
build/dataдля SQLite-файла.
Запуск из корня проекта:
bun build/server.jsПо умолчанию приложение использует data/puzzle.sqlite относительно текущей рабочей директории. Чтобы хранить базу внутри exported build:
DATABASE_PATH=build/data/puzzle.sqlite bun build/server.jsПорт и hostname можно переопределить стандартными переменными standalone Next-сервера:
PORT=3000 HOSTNAME=0.0.0.0 bun build/server.jsЕсли запускать из самой папки build, путь к базе можно упростить:
cd build
DATABASE_PATH=data/puzzle.sqlite bun server.jsНа экране старта доступны обычные сложности:
easy
medium
hard
Дополнительные режимы:
challenge- endurance-режим с таймером, очками, бонусами времени, milestone-бонусами и возрастающей сложностью.infinity- свободная бесконечная игра без таймера, очков и записи в статистику.
Доступность challenge и infinity управляется из админских настроек. Если режим выключен, он не показывается игрокам на экране выбора сложности.
На главном экране отображаются:
Классика- табы по сложностямeasy,medium,hard; сортировка по лучшему времени.Испытание- рейтинг endurance-игр по очкам, количеству раундов и времени.
Данные лидербордов отдаются через:
GET /api/leaderboards
Endpoint работает как SSE stream (text/event-stream), отправляет актуальный snapshot, keepalive-сообщения и обновления при изменении результатов или настроек endurance-режима.
Админские страницы:
/admin/stats
/admin/settings
/admin/stats показывает:
- ключевые метрики по играм;
- распределение по статусам, сложностям и режимам;
- дневную динамику;
- статистику по профилям, доскам и endurance-раундам;
- последние игры.
/admin/settings позволяет:
- включать и выключать Challenge/Endurance режим;
- включать и выключать Infinity режим;
- настраивать стартовое время, бонусы времени, milestone-бонусы;
- настраивать базовые очки и target time по сложностям.
В админском layout есть быстрый запуск Challenge и Infinity игр с выбором профиля.
Игровые доски лежат в:
public/boards
Поддерживаемые форматы досок:
jpg, jpeg, png, webp
Подсказки для модалки правил лежат в:
src/assets/help/help-1.png
src/assets/help/help-2.png
src/assets/help/help-3.png
Сгенерированные директории не коммитятся:
public/boards/outline
public/pieces
public/boards.json
public/palettes.json хранит готовые палитры для досок и используется приложением при рендере игрового фона.
public/profiles.json хранит сгенерированные связи профилей и досок.
public/boards.json хранит список досок для runtime, чтобы standalone-билду не нужны были оригинальные изображения из public/boards.
Приложение использует SQLite через bun:sqlite.
По умолчанию база создаётся здесь:
data/puzzle.sqlite
Путь можно переопределить переменной окружения:
DATABASE_PATH=/app/data/puzzle.sqliteБаза инициализируется автоматически при старте приложения. Используется WAL-режим, поэтому рядом могут появляться служебные файлы:
puzzle.sqlite-wal
puzzle.sqlite-shm
Основные таблицы:
games- игровые сессии, статус, таймеры, сохранённое состояние пазла.game_rounds- раунды endurance-режима и начисленные очки.app_settings- настройки Challenge/Endurance и Infinity режимов.
Поле gameMode различает:
classic
endurance
infinity
В проекте используется общий Dockerfile:
docker/Dockerfile
Compose-файлы:
docker/compose.local.yml
docker/compose.development.yml
docker/compose.production.yml
Dockerfile упаковывает уже готовый exported runtime из директории build и не запускает Next build внутри образа.
Локальная проверка Docker-образа:
bun run build:export
docker compose -f docker/compose.local.yml up --buildDevelopment deploy:
docker compose -f docker/compose.development.yml up -dProduction deploy:
docker compose -f docker/compose.production.yml up -ddevelopment и production compose-файлы рассчитаны на внешний Traefik network traefik и Watchtower.
GitHub Actions workflow Build and Release запускается при push в ветки:
dev
prod
и при push любого git tag.
Workflow состоит из четырёх jobs:
prepare- вычисляет Docker-теги, имя zip-файла и параметры релиза.build- выполняетbun run build:export, пакует директориюbuildв zip и сохраняет artifact.docker-image- скачивает zip artifact, распаковываетbuildи публикует Docker image в GHCR.release- создаёт GitHub Release или Pre-release и прикрепляет zip build.
build является единственным build-шагом для runtime-артефакта. Docker image и zip build используют одну и ту же директорию build.
Docker image публикуется в GHCR:
ghcr.io/<owner>/<repo>/hsr-puzzle
Для веток используются теги:
dev-latest
dev-YYYYMMDD-HHMMSS
prod-latest
prod-YYYYMMDD-HHMMSS
Для tag build используется сам tag как Docker tag. Если tag указывает на commit из prod, дополнительно обновляется prod-latest; иначе используется pre-latest.
Zip build называется так:
hsr-puzzle-<ref>-<short-sha>.zip
Внутри zip находится exported standalone build из директории:
build
Release-логика:
- push в
devилиprodсоздаёт GitHub Pre-release с Docker tags и zip build; - push git tag создаёт Pre-release, если tag не относится к
prod; - push git tag на commit из
prodсоздаёт полноценный GitHub Release.
Автоматические pre-release tags имеют префикс:
prerelease-
Workflow игнорирует такие tag events, чтобы не запускать повторный release pipeline от собственного служебного тега.
src/
├── actions/ # Server actions
├── app/ # Next.js App Router
├── assets/ # Шрифты, профили, loading/help изображения
├── components/ # UI и игровые компоненты
├── contexts/ # Глобальный UI context
├── dal/ # Слой доступа к данным
├── db/ # SQLite подключение и schema migrations
├── hooks/ # React hooks
├── screens/ # Экранные композиции
└── utils/ # Игровые и общие утилиты
scripts/
├── prepareBoardImages.ts
├── exportStandaloneBuild.ts
├── extractBoardPalette.ts
├── convertToOutline.ts
└── sliceImageBySize.ts
docker/
├── Dockerfile
├── compose.local.yml
├── compose.development.yml
└── compose.production.yml
- Next.js 16
- React 19
- Bun
- SQLite через
bun:sqlite @dnd-kit@tanstack/react-formreact-modalreact-iconsrechartssharpдля подготовки изображений- CSS Modules
- Docker / Docker Compose