Документация по созданию модов для визуальной новеллы «Бесконечное Лето». Справочник терминов, примеры кода и ресурсы игры в одном месте.
pdm install
Copy-Item .env.example .env
pdm run dev # http://127.0.0.1:8000# Сборка и запуск контейнеров
docker compose up --build
# Приложение будет доступно по адресу http://localhost:8005
# TIP: не смотря на то что в main.py порт 8000, в контейнере есть еще nginx который проксирует запрос, а внешний порт у контейнера 8005Docker Compose настраивает два контейнера:
- web: Python-приложение на порту 8000 (внутренний)
- nginx: Reverse proxy на порту 8005 (внешний)
Контент хранится в Docker volume es-doc-content и автоматически обновляется при запуске контейнера из репозитория es-doc-assets.
Обновление контента:
# Перезапустите контейнеры для автоматического git pull
docker-compose restart web
# Или для ручного обновления (внутри контейнера)
docker-compose exec web bash -c "cd /app/content && git pull"Настройка репозитория контента:
Измените переменные окружения в docker-compose.yml:
environment:
- ASSETS_REPO=https://github.com/sovue/es-doc-assets.git
- ASSETS_BRANCH=mainРазработка с локальными ассетами:
- Клонируйте репозиторий ассетов:
git clone https://github.com/sovue/es-doc-assets.git - В
docker-compose.ymlзакомментируйте volume:# - es-doc-content:/app/content - Раскомментируйте строку для локальных ассетов:
volumes: - ../es-doc-assets:/app/content
- Перезапустите контейнеры:
docker compose up --build
После каждого push в main репозитория es-doc GitHub Actions сначала
запускает проверки, затем подключается к серверу по SSH. На сервере workflow
обновляет Git-копию до origin/main и выполняет
docker compose --env-file .env.production -f compose.production.yaml up -d --build --wait.
Pull request запускает только проверки. GHCR и GitHub Releases не используются.
Ассеты из es-doc-assets/main попадают в образ во время сборки; отдельный push
в репозиторий ассетов деплой не запускает.
На сервере нужны Git, Docker Engine с Compose Plugin и Git-копия приложения.
Один раз клонируйте репозиторий под пользователем деплоя, например в
/opt/es-doc (у пользователя должны быть права на запись в этот каталог и
доступ к Docker):
git clone https://github.com/sovue/es-doc.git /opt/es-doc
cd /opt/es-doc
cp .env.production.example .env.production
chmod 600 .env.productionУкажите адрес сайта и внешний порт в .env.production. Файл исключён из Git,
поэтому обновление исходников его не затронет. Если каталог остался от старого
деплоя и не содержит .git, сохраните .env.production и замените каталог
на Git-копию приложения.
В GitHub создайте окружение production и добавьте следующие secrets:
DEPLOY_HOST,DEPLOY_USER,DEPLOY_PATH;DEPLOY_SSH_KEY— приватный ключ отдельного пользователя деплоя;DEPLOY_KNOWN_HOSTS— заранее проверенная записьknown_hostsдля сервера.
DEPLOY_PATH должен указывать на Git-копию приложения, например /opt/es-doc.
Чтобы деплой происходил сразу после успешных проверок, в настройках окружения
production не должно быть правила обязательного ручного одобрения. Если такое
правило включено, GitHub приостановит деплой до одобрения.
Workflow ждёт успешного health check контейнеров и при ошибке показывает последние строки логов. Параллельные деплои блокируются настройкой GitHub Actions. Автоматического отката в этой простой схеме нет.
Локальный docker-compose.yml остаётся workflow разработки; production
использует отдельный compose.production.yaml без bind-mount исходников.
Локальный .env содержит только параметры этой установки: путь к репозиторию
ассетов (ES_DOC_ASSETS_PATH), путь к кэшу (ES_DOC_CACHE_PATH) и флаг
отладки (ES_DOC_DEBUG=1). Файл .env игнорируется Git; шаблон находится в
.env.example. Старый локальный config.yaml с assets-path и cache-path
тоже поддерживается для плавного перехода.
Серверная конфигурация хранится в es-doc-assets/config.yaml вместе с
контентом. Там находятся баннеры, тексты ошибок, площадки поддержки и другие
настройки, которые должны быть одинаковыми у всех экземпляров сайта.
Каждый ключ в разделе banners становится именем Markdown-блока: ключ notice
включает синтаксис :::notice, а удаление ключа отключает этот блок. Можно
переопределить только нужные поля:
banners:
stub:
title: Эта статья — заготовка.
text: Скоро здесь будет новая статья, мы уже работаем над этим.
icon: attention
tone: attentiontitle — обычный текст, text — Markdown. Приписка автора в статье заменяет
стандартный text. Иконка выбирается из встроенных SVG-иконок: info, tip,
attention, warning, danger, wip, outdated. Цветовые типы tone:
info, tip, attention, warning, danger; цвета берутся из палитры текущей
темы.
Для встроенных stub, wip и outdated пропущенные поля используют значения
по умолчанию из app/utils/config.py; новый ключ должен содержать все четыре
поля. После изменения серверного конфига перезапустите сервер.
Вставьте аудиофайл отдельной строкой: укажите его адрес, а после | —
название, которое увидит читатель:
::audio /resource/audio/theme.ogg | Тема лагеряКнопка использует общий плеер сайта; без JavaScript остаётся встроенный браузерный аудиоплеер. Название необязательно: если его нет, используется имя файла.
Основные ссылки главной страницы редактируются в home_notices.yaml в корне
репозитория es-doc-assets (рядом с materials.yaml и specialists.yaml).
Шаблон главной получает объявления из этого файла; изменения подхватываются
без перезапуска сервера. Порядок записей — порядок объявлений и обхода
клавишей Tab. Первое объявление оформляется как большая афиша на широком экране.
notices:
- title: Как создать свой мод
url: /docs/first_steps
description: Первые шаги для переноса истории в код
category: Создание модаtitle и url обязательны. description и category — необязательный
обычный текст. Допустимы пути от корня сайта и полные HTTP(S)-адреса.
Неполные записи и небезопасные URL пропускаются с предупреждением в журнале.
При ошибке синтаксиса YAML сохраняется предыдущий список. Чтобы скрыть доску,
задайте notices: [] или удалите файл. Все объявления — обычные ссылки,
которые открываются без JavaScript.
Страница /specialists объединяет художников, нейрохудожников, композиторов,
кодеров и сценаристов. Все участники, включая художников,
хранятся в specialists.yaml в корне репозитория ассетов.
В specialists находятся отдельные списки artists, ai-artists, coders,
composers и writers. В записи укажите name, необязательный status
(open, closed, unknown), контакты в links и примеры в works.
Один автор может присутствовать в нескольких списках: это независимые профили
со своими работами, контактами и статусом. На вкладке «Все» у каждого профиля
показана категория. По умолчанию сначала идут открытые заказы, затем неизвестный
статус и закрытые; внутри каждого статуса — по алфавиту.
Необязательные preview (изображение) и description (обычный текст) задаются
для каждого профиля отдельно. Без превью или при ошибке его загрузки карточка
показывает первую букву имени в той же области 3:2. Карточки в одном ряду
имеют одинаковую высоту. Без описания блок не занимает места.
preview не выбирается из примеров работ и не добавляется в них автоматически.
logo задаёт необязательный аватар. Без него или при ошибке загрузки в том же
круглом месте показывается первая буква имени.
Для tg и telegram можно указать "@PerpetuaPetua" — он превратится в
https://t.me/PerpetuaPetua. Также поддерживаются веб-ссылки, tg://resolve?domain=…
и tg://user?id=… с числовым ID. Если в tg://user?id=… указан username,
он преобразуется в ссылку https://t.me/….
Каждый пример содержит type, title и url или file:
artists,ai-artists—art;composers—track, до двух прямых аудиофайлов;coders—mod,project;writers—mod,fanfic.
Локальные файлы хранятся в specialists/ репозитория ассетов. Относительные
пути в url, file, preview и logo отсчитываются от этой папки.
Например, url: teromioset/preview.jpg открывается по
/specialists/res/teromioset/preview.jpg. Это работает и для аудио, архивов
проектов и документов; выход за пределы папки запрещён. Также поддерживаются
http(s)-ссылки и ссылки от корня сайта. Формат и примеры записей описаны
в specialists.yaml. Изменения этого файла подхватываются без перезапуска.
Старый формат списка с categories поддерживается для совместимости:
при загрузке он разделяется на профили с типами работ своей категории.