dnd5-scripts/generate_encounter/surprise_rolls_and_reaction.md
2026-06-17 22:32:48 +03:00

92 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Для интеграции механик **Surprise Roll** и **Reaction** из ACKS2 в ваш скрипт на Python, необходимо внести следующие изменения:
### 1. Как реализовать Surprise Roll (1d6)
Вместо автоматической проверки Скрытности против Пассивного Восприятия (D&D 5e), внедрите логику матрицы:
* **Параметры:** На входе функции теперь нужны два булевых флага для каждой стороны: `has_foreknowledge` (знали ли о присутствии заранее) и `has_los` (видят ли противника в момент начала).
* **Матрица:** Создайте словарь или цепочку `if-elif`, которая возвращает одно из состояний: `No Surprise`, `Roll Surprise (+1/0/-1)` или `No Encounter`.
* **Модификаторы:**
* Создайте аргумент `situational_modifiers` (целое число).
* **Классовые/Расовые:** Если в группе есть «Следопыт» (аналог Explorer), добавляйте +1 к его броску.
* **Скрытность:** Если одна сторона использует скрытность (Hiding/Sneaking), она накладывает штраф **-2** на бросок сюрприза оппонента.
* **Логика:** Бросок `1d6 + бонусы - штрафы`. Если результат `<= 2`, персонаж пропускает первый раунд (Surprised).
### 2. Как реализовать Reaction Roll (2d6)
Эта механика заменяет мгновенную инициативу в неочевидных ситуациях:
* **Бросок:** `2d6 + Харизма лидера (Face)`.
* **Модификатор Face:** Выбирайте персонажа с наивысшей Харизмой. Добавьте его модификатор к броску.
* **Ситуативные модификаторы:** Введите параметр `reaction_mod`. Например, если игроки достали оружие, добавьте `-2` (к враждебности), если предложили золото (взятка) — согласно таблице ACKS2 (+1/+2/+3 в зависимости от суммы).
* **Результат:** Верните текстовое описание (Hostile, Neutral, Friendly и т.д.), которое определит поведение монстров до начала боя.
### 3. Учет ситуативных модификаторов
Чтобы они подавались «явно для конкретного столкновения», расширьте структуру `EncounterRequest`.
Вместо того чтобы высчитывать их внутри скрипта, передавайте их как:
* `surprise_mod_bonus`: (например, +1 за бдительность).
* `surprise_mod_penalty`: (например, -2, если враги — затаившиеся варвары).
* `reaction_situational_mod`: (например, -4, если игроки осквернили алтарь этого племени ранее).
### Пример структуры данных для функции:
Вместо простого `level` и `environment`, объект `req` должен принимать:
```python
{
"environment": "underdark",
"level": 5,
"foreknowledge_party": True,
"foreknowledge_monsters": False,
"los_party": True,
"los_monsters": True,
"surprise_penalty": -2, # За скрытность монстров
"reaction_bonus": 2 # Модификатор Харизмы "лица" группы
}
```
Это позволит скрипту не просто выкидывать монстра, а сразу генерировать контекст: «Вы заметили их первыми (Surprise Roll монстров с -2), они настроены Неуверенно (Reaction: 7)».
---
Для внедрения механик из ACKS II (Внезапность и Реакция) в ваш генератор случайных встреч, нам потребуется расширить логику обработки каждого запроса. Поскольку генератор возвращает Markdown-текст, результаты проверок на внезапность и реакцию отлично впишутся как дополнительные пункты в описание каждой сгенерированной встречи.
Чтобы учесть ситуативные модификаторы, вам нужно расширить словарь запроса (тот, что сейчас принимает только биом и уровень). Ситуативные данные должны передаваться из того места, где формируется запрос к скрипту.
Вот как это можно архитектурно выстроить и какие варианты реализации существуют.
### Как передавать ситуативные модификаторы
В параметры запроса (в словарь) необходимо добавить опциональный блок контекста. Например, ключ `context`, внутри которого могут быть:
1. **Для Внезапности:** логические флаги (да/нет) для `party_foreknowledge`, `party_los`, `monster_foreknowledge`, `monster_los`. Также сюда можно передавать численные модификаторы: `party_surprise_mod` (например, если в группе есть варвар или исследователь) и `monster_surprise_mod` (чтобы учесть скрытность монстров).
2. **Для Реакции:** численное значение `face_cha_modifier` (модификатор Харизмы «лица» группы) и логический флаг `auto_hostile` (на случай, если группа выбила дверь или монстр — неразумный голодный хищник, где бросок реакции по правилам ACKS не нужен).
### Вариант 1: Жесткая симуляция (Передача полного контекста)
Этот вариант предполагает, что мастер или интерфейс тула точно знают, при каких обстоятельствах происходит встреча, и передают все параметры в скрипт.
* **Механика Внезапности:** Скрипт анализирует флаги предзнания (Foreknowledge) и видимости (LOS) для обеих сторон. На основе вашей матрицы из ACKS скрипт определяет результат (Кто не застигнут врасплох, а кому нужно бросать кубик). Если требуется бросок, скрипт кидает 1d6, применяет переданные штрафы/бонусы (от скрытности, классов или освещения) и выдает финальный статус: «Внимательны» или «Застигнуты врасплох». Также скрипт может вывести статус возможности уклонения (evasion).
* **Механика Реакции:** Скрипт проверяет флаг `auto_hostile`. Если он активен (например, стычка с нежитью), скрипт сразу пишет «Настроение: Враждебное (Атакуют)». Если нет, скрипт бросает 2d6, прибавляет переданный модификатор Харизмы группы (и бонусы за взятки, если они переданы в контексте), а затем сравнивает результат со шкалой от 2 до 12, выводя отношение от «Враждебного» до «Дружелюбного».
**Плюсы:** Максимальная точность по правилам ACKS.
**Минусы:** Требует передачи большого количества данных в каждом запросе.
### Вариант 2: Генеративная симуляция (Рандомизация контекста)
Поскольку это генератор *случайных* встреч, контекст часто неизвестен до момента броска. В этом подходе скрипт сам придумывает обстоятельства встречи.
* **Внезапность:** Скрипт случайным образом определяет, кто кого заметил первым. Например, можно привязать это к биому (в лесу шанс заметить друг друга ниже, чем на равнине). Скрипт сам бросает 1d6 за монстров и игроков, генерируя текст вроде: *"Группа заметила монстров издалека, монстры застигнуты врасплох (бросок 1d6: 2)"*.
* **Реакция:** Скрипт автоматически бросает 2d6. В Markdown-отчет выводится базовая реакция монстров *до* влияния Харизмы игроков. Вы можете написать: *"Базовая реакция: 7 (Нейтрально). Мастер, прибавьте модификатор Харизмы лидера для итогового результата"*.
**Плюсы:** Скрипт работает автономно, генерируя готовые мини-сценки, не требуя сложной настройки от пользователя.
**Минусы:** Мастеру придется на лету адаптировать сгенерированный скриптом контекст под текущую игру.
### Вариант 3: Гибридный подход (Рекомендуемый)
Скрипт проверяет параметры запроса. Если пользователь не передал конкретных модификаторов и контекстов, применяются значения по умолчанию или легкий рандом.
**Логика работы скрипта будет такой:**
1. Генерируется сам монстр/встреча (базовая часть вашего скрипта).
2. Скрипт смотрит в запрос. Есть ли там флаги ситуаций?
3. Если флагов скрытности и видимости нет, скрипт предполагает «Стандартную встречу встречными курсами» (у обеих сторон есть Line of Sight, ни у кого нет Foreknowledge). Бросается 1d6 за обе группы и выводится результат Внезапности.
4. Высчитывается бросок Реакции 2d6. Если в запросе передано `face_cha_modifier`, он плюсуется на этапе скрипта, и выводится финальный текст (например, «Итог: 10 — Индифферентны»). Если не передано, выводится «Сырой бросок реакции: 8, измените в зависимости от модификаторов партии».
5. К описанию встречи в Markdown добавляются две новые строки: **Состояние перед боем (Внезапность)** и **Первичная реакция**.
**Для реализации без изменения архитектуры базы данных монстров:**
Всю математику и броски кубиков (1d6 и 2d6) нужно вынести в отдельные вспомогательные функции внутри вашего Python-файла. Эти функции будут принимать словарь с любыми ситуативными модификаторами, обрабатывать матрицу исходов (как серию if/else условий на основе флагов) и возвращать отформатированные строки, которые затем будут приклеиваться к переменной `res` перед добавлением в общий список результатов.
---
комментарий к Вариант 3: Гибридный подход (Рекомендуемый), который я выбираю
Ок, реализуй, только учти ##Tool Generator (правила формирования тула), также промпт генерации энкаунтера дополни. также, важно, чтобы агент по возможности не спрашивал доп контекста, а исходил из имеющейся информации. возможно, надо подавать на вход три модификатора, для монстров surprise и для партии surprise, и модификатор для взаимодействия реакции, каждый модификатор -с словарь пар строковое значение причина модификатора - целочисленное число, все модификаторы суммируются и дают результат итоговый. что скажешь? также, для броска, для результата при выводе с обработкой промпта и результата скрипта должна агентом прикладыватьться простые таблицы, предварителньо будет сказано, какие модификаторы использованы, какой реузльтата, и елси гм использует другие модификаторы, тот вот уже итоговое значение, его поменяешь , и вот тебе таблицы, что понять, что будет после изменения. Что скажешь?