Метод извлечения лора ПЧК / Extraction Method¶
Источник: raw/*.srt — автоматические русские субтитры YouTube (DownSub), 87 файлов.
Промежуточный слой: clean/*.txt — субтитры без таймкодов/индексов, склеенные в абзацы с маркером [ЧЧ:ММ:СС] в начале каждого абзаца (≈12 реплик).
Принципы¶
- Цитата важнее пересказа. Везде, где возможно, приводится дословная цитата с таймкодом:
> «текст» — [00:12:34]. - Исправляются только ошибки распознавания речи и грамматика. Смысл, лексика и порядок слов сохраняются. Если исправление меняет смысл — оригинал приводится в скобках:
Вёрджинвальд (в субтитрах: «Верджин вальд», «Вёрджинвальд»). - При сомнении — сохранять и помечать. Ничего не выбрасывается. Маркеры:
?— неуверенное распознавание имени/термина[СЛУХ]— неточная расшифровка, вариант реконструкции[МЕТА]— реплика игроков/ведущего вне игры (шутка, обсуждение правил), но с лорным содержанием[ПРОТИВОРЕЧИЕ]— конфликт с данными другого выпуска[НЕЯСНО]— смысл фрагмента не восстановлен- Имена собственные приводятся в наиболее частом написании; все встреченные варианты перечисляются в
lore/index/naming.md. - Разделение внутриигрового и внеигрового. Реплики ведущего (Мастера) как нарратив — лор; шутки актёров — помечаются
[МЕТА], но сохраняются, если содержат лорный факт.
Структура файла выпуска (lore/episodes/PCHK_NN.md)¶
# ПЧК #NN — «Название»
Метаданные: video_id, участники, длительность
## Состав партии (игрок → персонаж)
## Синопсис по сценам (с таймкодами)
## Персонажи игроков (PC)
## NPC
## Локации
## Предметы и артефакты
## Способности, заклинания, механики
## Карты / броски / игровые сущности
## Загадки, головоломки, испытания
## Фракции, организации, религии
## Существа и бестиарий
## Лорные факты о мире
## Цитаты
## Неясное и помеченное
Пустые разделы удаляются. Разделы Q&A-выпусков — см. lore/qa/.
Сводные индексы (lore/index/)¶
characters.md, npcs.md, locations.md, items.md, abilities.md, bestiary.md,
factions.md, puzzles.md, timeline.md, naming.md, cosmology.md
— собираются после обработки всех выпусков, каждая запись со ссылкой на выпуск и таймкод.
Порядок обработки¶
- Пилот: выпуски 01, 02, 03 и 50, 51, 52 — проверка методики.
- Остальные выпуски 04–49 по порядку.
- Хроники Леониса Парфия (01–09, 10–20), OST.
- Q&A-подкасты (16–50).
- Сборка сводных индексов.
Сопоставление имён — только после ручной проверки¶
Автоматика сама решений не принимает. Каждая привязка живёт в своём проверенном вручную словаре, и сборка читает только их:
| Словарь | Что связывает |
|---|---|
lore/marked/formy/*.md |
словоформа в тексте → понятие (по полному совпадению) |
lore/marked/slovar.md, колонка «На экране» |
надпись на кадре → понятие; можно сузить до выпуска: ДВАРФ@PCHK_45 |
lore/marked/kadry.md |
какой кадр показывать наверху страницы |
lore/marked/fandom_stati.md |
статья фан-вики → понятие |
lore/marked/fandom_kartinki.md |
картинка дампа → понятие, и колонка «Выпуск» для галереи |
Ранний контур с tools/candidates.py и lore/matching.md удалён: его
53 проверенные привязки перенесены в slovar.md.
Проверяются три вида решений:
| Что | Чем опасна ошибка |
|---|---|
| Псевдонимы — «Ангелин» и «Ангелин Колосажатель» одно лицо | две страницы вместо одной или слияние разных героев |
| Поиск по части имени — искать ли «Балан» отдельно от «Дан Балан» | страница набирает чужие цитаты: «Укус ≠ обращение» ловил каждое «укус» |
| Имена с экрана — «ПОЛИАС» на карточке это Пэлиас | чужой портрет в карточке: «КАРГА» приписывалась мечу «Кара Гелиоса» |
Полное имя сущности ищется всегда и в проверке не нуждается.
Размеченные ленты выпусков (lore/marked/)¶
Разбор в lore/episodes/ написан для человека: сущности из него выводятся.
Размеченная лента — обратный порядок: сущности в ней объявлены.
Один файл на выпуск сводит расшифровку и разбор кадров на общую ось времени.
Речь идёт абзацами с тайм-кодом, кадры — отдельными строками со знаком ▸,
у каждой указан вид события, распознанный текст и имя файла кадра. Понятия
в речи и в надписях помечены явно: Имя либо как сказано.
Порядок работы:
- Внести решение в
lore/marked/slovar.md: каноническое имя, тип и — если имя видно на кадре — надпись с экрана. Формы речи там больше не задаются: их держат таблицыformy/. tools/markup.py PCHK_NN— собрать ленту (без аргументов — все выпуски).
Словарь — хранилище ручных решений: принятое однажды не пересматривается, при следующем прогоне добавляются только новые строки.
Побочная польза: понятия из словаря, ни разу не встретившиеся в расшифровке, выписываются в комментарий в конце шапки. Это сигнал — либо форма поиска задана неверно, либо факт в разборе не подтверждается речью и пришёл откуда-то ещё.
Таблицы форм — единственный источник сопоставления¶
Отсечения окончаний больше нет нигде в сборке. Каждая словоформа выписана
целиком в lore/marked/formy/ (по файлу на тип понятия) и вручную привязана
к понятию; сопоставление идёт по полному совпадению. Прочерк вместо имени
означает «это не упоминание».
Почему так: основа «Антошк» после отсечения окончания превращается в «Анто» и находит «Антон» — два разных персонажа склеиваются в одного. Никакая проверка отдельного выпуска этого не ловит, если имена стоят в разных местах корпуса.
У каждой формы указана область действия — файлы, где её проверили. Одно и то же слово в разных выпусках значит разное («Барон» — и Ворон Барон, и барон Эдвард), поэтому решение не переносится автоматически: новый выпуск добавляет свои строки осознанно.
tools/formtable.py пересобрать таблицы из расставленной разметки
tools/remark.py снять разметку и поставить заново строго по таблицам
Отсечения окончаний не осталось нигде в сборке: markcand.py, _legacy_stem.py,
candidates.py, approved.py, collide.py и режим markup.py --check удалены.
Нечёткое сравнение живёт только в imgcat.Matcher(guess=True) — режим сбора
кандидатов, из сборки недостижимый: без проверенного словаря матчер бросает
исключение.
Разметка рукописных разборов¶
tools/remark.py расставляет те же ссылки прямо в разборах. Разбор писал
человек, портить его нельзя, поэтому скрипт проверяет себя: если снять со свежего
файла все ссылки, должен получиться исходный текст буква в букву — иначе файл
не записывается. Заголовки не размечаются: по ним разбирается структура файла.
Наследование словаря¶
Подкаст берёт словарь своего выпуска, хроника — всего отрезка корпуса, а своды и слои источников (телеграм, фан-вики) — все принятые решения сразу. Это не новое угадывание: каждое решение уже проверено на своём выпуске.
Как называется статья¶
Заголовок — то, как имя написано: на карточке броска, на листе персонажа, в статье фан-вики. Не самая полная форма, произнесённая один раз при знакомстве. «Альбом в феврале» прозвучало дважды и нигде не написано, а на карточках стоит «АЛЬБО» и статья сообщества называется так же — значит, статья называется Альбо, а полная форма остаётся в строке «Также» и в разборе.
Проверка простая: если имя понятия ни разу не встречается в написанных
источниках, а короткая форма стоит на карточках — заголовок надо менять.
Переименование делает tools/renameents.py (SCREEN_NAME): оно переписывает
и словарь, и все проставленные ссылки.
Один тип на понятие¶
Персонаж, сыгранный игроком, остаётся Персонаж и там, где он появляется как
NPC. Иначе на одно имя выйдет две статьи. Расхождения ищет и правит
tools/normtypes.py.
Слой фан-вики¶
Сторонний дамп не редактируется. tools/markwiki.py собирает из него
производный lore/marked/fandom.md: заголовки, инфобоксы и вступления статей
с той же разметкой. Заголовки, которых нет в словаре корпуса, остаются
неразмеченными и перечислены в конце файла отдельным списком.
Сверка имени по независимым источникам (tools/crosscheck.py)¶
Расшифровка — это услышанное, а не написанное, и одного её голоса мало. Имя проверяется сразу по пяти источникам:
Источники строго по старшинству:
| Источник | Что это | |
|---|---|---|
| 1 | кадры | надпись на экране: карта мира, лист персонажа, карточка броска — написано авторами шоу |
| 2 | фан-вики | статьи сообщества, заголовки, имена файлов картинок — написано рукой, но это пересказ |
| 3 | lore/tg/ |
официальный канал и разборы участников |
| 4 | clean2/ |
Whisper large-v3 — услышано |
| 5 | raw/*.srt |
субтитры DownSub — самый ненадёжный источник, берётся в расчёт, только если все остальные молчат совсем |
Услышанное не спорит с написанным. «Соливуха» из расшифровки проигрывает надписи СОЛЕВУХА на карте мира из #28: безударные гласные распознаются плохо, а на карте имя написано.
Кадр с картой мира (#28, PCHK_28_part1/img/007_00204.jpg) — отдельно ценный
источник: это список топонимов в авторском написании.
Точечный прогон. Если написанных источников нет, а расшифровка сомнительна,
надо вырезать ffmpeg'ом полминуты вокруг спорного места и распознать отдельным
файлом на GPU-машине (/workspace/spot.py, beam 5 и 10). На коротком куске без
окружающего контекста Whisper ошибается заметно реже: «Морелло» из общего
прогона на вырезке оказалось «Мариеллой», а «Роберт» из DownSub — «Рупертом»
на обоих значениях beam.
uv run --python 3.11 python tools/crosscheck.py Голиаф глиаф
Осторожно с перекрытием: если одно написание — начало другого («Милош Клыков» внутри «Милош Клыкович»), счётчики складываются друг в друга, и сравнивать их нельзя. Такие пары проверяются по контексту, а не по числам.