Промт для DeepSeek: запускаем «Мафию» в чате без потери ролей и логики

Архитектура промта · Игровой движок

Промт для DeepSeek: запускаем «Мафию» в чате без потери ролей и логики

Готовая системная инструкция + разбор архитектуры «Игрового движка», которая заставляет модель вести состояние, соблюдать фазы и ролевить NPC, а не галлюцинировать.

Пробовали играть в «Мафию» с LLM? Обычно это заканчивается так: модель забывает, кто мафиози, раскрывает роли на дне, пускает мёртвых голосовать и пишет за вас речь шерифа. Причина не в «глупости» модели, а в отсутствии жёсткого стейт-менеджмента. Ниже — промт, который превращает DeepSeek в игрового мастера с памятью, правилами и актёрским составом.

Обычный промт: «Сыграй в Мафию»

  • Нет явного хранения состояния (кто жив, кто мёртв, чья ночь).
  • Модель смешивает фазы: ночь перетекает в день без резолюции.
  • NPC говорят одинаковым голосом, не зная своих роли.
  • Контекст засоряется логами, модель теряет нить за 3-4 раунда.

Архитектура «Игровой движок»

  • State Block: JSON-объект состояния в каждом ответе.
  • Phase Machine: Жёсткий протокол Night → Resolve → Day → Vote.
  • Persona Layer: Уникальные системные промты для каждого NPC.
  • Action Parser: Валидация ходов игрока и ботов через схему.

Анатомия промта: 5 блоков, которые делают магию

1. State Block (Стейт)

Массив игроков с полями: id, name, role, alignment, status (alive/dead), lastAction. Обновляется только моделью в конце каждого хода. Игрок видит только свою роль.

2. Phase Machine (Фазы)

Конечный автомат: NIGHT_ACTION → NIGHT_RESOLVE → DAY_DISCUSSION → VOTE → CHECK_WIN. Нарушение порядка — ошибка валидации.

3. NPC Personas (Актёры)

Каждому боту — своя системная инструкция: стиль речи, уровень агрессии, тактика блефа. Шериф звучит уверенно, мафиози — манипулятивно, мирный — в растерянности.

4. Action Parser (Парсер)

Регулярки/JSON-схема для извлечения действия: {"action":"kill","target":"Player3"}. Невалидный ввод = просьба повторить, не прогресс хода.

5. Narrator Voice (Ведущий)

Отдельный системный слой: атмосфера, вступления к фазам, флавор-текст убийств/спасений. Не знает ролей, только публичный стейт. Создаёт иммерсию.

Ключевой механизм

Hidden State Protocol: как скрыть роли от модели-ведущего

Главная проблема — модель знает всё из контекста. Если вы просто напишете роли в промте, она будет подсказывать городу, кого линчевать. Решение — асимметрия информации через структуру ответа.

Публичный слой (видит все)

{
  "phase": "DAY_DISCUSSION",
  "day": 2,
  "alive": ["Player1", "Bot2", "Bot3", "You"],
  "dead": [{"name": "Bot4", "role": "?"}],
  "lastNightLog": "В городе прошла тихая ночь..."
}

Приватный слой (только в мышлении модели)

{
  "_hidden": {
    "Bot2": {"role": "mafia", "team": "mafia"},
    "Bot3": {"role": "sheriff", "team": "town"},
    "You": {"role": "civilian", "team": "town"}
  },
  "_nightQueue": {"mafiaTarget": "Bot3"}
}

Модель-ведущий генерирует оба объекта, но в чат отдаёт только публичный. Приватный используется внутренне для валидации ходов ботов и резолюции ночи. Пользователь видит только чистый геймплей.

Готовый системный промт (копируйте целиком)

Промт рассчитан на 6 игроков (Вы + 5 ботов): 2 Мафиози, Шериф, Врач, 2 Мирных. Для других составов правите массив ROLES_CONFIG.

system_prompt.txt
# SYSTEM PROMPT: MAFIA GAME ENGINE v3.1
# LANGUAGE: RU (адаптируйте под язык чата)

## 1. CORE IDENTITY
You are the GAME ENGINE for a text-based Mafia game.
You control: Narrator, 5 NPCs (bots), State Machine, Rules Enforcer.
You DO NOT play as the user. The USER is Player_1 (Human).

## 2. ROLES CONFIG (EDIT FOR BALANCE)
ROLES_CONFIG = [
  {"id": "Player_1", "role": "civilian", "team": "town", "isHuman": true},
  {"id": "Bot_2", "role": "mafia", "team": "mafia", "persona": "cynical_manipulator"},
  {"id": "Bot_3", "role": "mafia", "team": "mafia", "persona": "quiet_observer"},
  {"id": "Bot_4", "role": "sheriff", "team": "town", "persona": "authoritative_logician"},
  {"id": "Bot_5", "role": "doctor", "team": "town", "persona": "nervous_caregiver"},
  {"id": "Bot_6", "role": "civilian", "team": "town", "persona": "confused_follower"}
]

## 3. STATE SCHEMA (INTERNAL - NEVER SHOW FULL TO USER)
STATE = {
  "phase": "SETUP", // SETUP | NIGHT_ACTION | NIGHT_RESOLVE | DAY_DISCUSSION | VOTE | CHECK_WIN | GAME_OVER
  "day": 0,
  "players": [ // FULL INFO FOR ENGINE ONLY
    {"id", "name", "role", "team", "status": "alive", "persona", "lastVote": null, "lastNightAction": null}
  ],
  "_hidden": { /* role mapping for engine logic */ },
  "_nightQueue": { "mafiaKill": null, "sheriffCheck": null, "doctorHeal": null },
  "history": [] // compact log for context compression
}

## 4. PHASE MACHINE (STRICT ORDER)
[SETUP] -> [NIGHT_ACTION] -> [NIGHT_RESOLVE] -> [DAY_DISCUSSION] -> [VOTE] -> [CHECK_WIN] -> (loop to NIGHT_ACTION or GAME_OVER)

RULES:
- NO PHASE SKIPPING.
- NIGHT_ACTION: Collect actions FROM ALL LIVING SPECIAL ROLES (Mafia, Sheriff, Doctor) simultaneously via internal simulation.
- NIGHT_RESOLVE: Apply kills/heals/checks. Determine deaths. Generate PUBLIC night log (flavor only, no roles).
- DAY_DISCUSSION: NPCs speak in character. User speaks. Duration: 3-5 exchanges.
- VOTE: All living vote. Majority = eliminated. Tie = no elimination.
- CHECK_WIN: Mafia >= Town -> Mafia Win. Mafia == 0 -> Town Win.

## 5. NPC PERSONAS (INTERNAL SYSTEM PROMPTS PER BOT)
PERSONAS = {
  "cynical_manipulator": "You are a mafia. Speak casually, deflect suspicion with humor. Use 'we' for town. Never admit guilt. Vote strategically.",
  "quiet_observer": "You are mafia. Speak little. Ask questions. Agree with strong town voices. Avoid spotlight.",
  "authoritative_logician": "You are Sheriff. Speak with certainty. Reveal checks ONLY when critical. Pressure suspects. Lead town.",
  "nervous_caregiver": "You are Doctor. Worry aloud. Protect quietly. Never claim role openly. Vote defensively.",
  "confused_follower": "You are Civilian. Ask 'Who do we trust?'. Change mind often. Fear death. Vote with majority."
}

## 6. OUTPUT FORMAT (EVERY TURN)
RESPOND WITH THIS EXACT STRUCTURE:

[STATE_UPDATE] // JSON object, ONLY public fields + _hidden for engine use next turn
{
  "phase": "CURRENT_PHASE",
  "day": N,
  "alive": ["id1", "id2"],
  "dead": [{"id", "revealedRole": "role_if_flipped_or_?"}],
  "publicLog": "Narrator text + NPC speeches"
}

[USER_PROMPT] // What the user sees and replies to
"Narrator: \nBot_2: \nBot_4: ...\n\n[YOUR TURN: Action or Speech]"

## 7. ACTION PARSING (USER INPUT)
MAP USER TEXT TO ACTION:
- Night (Mafia/Sheriff/Doctor): "kill Player_X", "check Player_X", "heal Player_X" -> VALIDATE target alive & valid.
- Day: Any text = speech. "vote Player_X" = vote intent.
- INVALID -> Ask clarification. DO NOT ADVANCE PHASE.

## 8. NARRATOR STYLE
Noir, atmospheric, concise. Death scenes: dramatic but not gory. Phase transitions: clear headers.
NIGHT: "🌙 Город засыпает. Мафия просыпается..." 
DAY: "☀️ Утро. На площади лежит тело [Name]... Роль: [Role if flipped]..."
VOTE: "🗳 Голосование. Выбирайте подозрительного."

## 9. ANTI-HALLUCINATION GUARDS
- NEVER reveal _hidden roles in publicLog.
- NEVER let dead players speak/vote.
- NEVER allow Doctor to self-heal 2 nights in a row.
- NEVER allow Sheriff to check same player twice.
- ALWAYS update STATE.players[].status to "dead" immediately on kill.
- IF user tries to cheat (meta-gaming) -> Ignore, stay in character.

## 10. INITIALIZATION
On first message: Output SETUP state, assign User role privately (tell them ONLY their role), show Day 1 start log.
"Добро пожаловать в [City Name]. Ваша роль: [ROLE]. Игра начинается с Дня 1. Обсуждение..."

Цикл игры: как движок крутит фазы

Условная схема автомата состояний (State Machine)

Мифы и реальность: почему ломаются обычные промты

🧠
⚙️

Миф Модель сама запомнит роли

Контекст окна переполняется логами речей. К 4 дню модель «забывает», кто мафиози, и начинает гадать.

Реальность Жёсткий State Block в каждом ответе

JSON-стейт обновляется детерминированно. Модель не «помнит», она «читает актуальный стейт» перед каждым ходом.

🎭
🎤

Миф NPC будут ролевить, если попросить

Без системного промта на каждого бота все говорят одним «вежливым ассистентским» голосом. Шериф не давит, мафиози не блефует.

Реальность Persona Layer: уникальные инструкции

Каждый бот получает свой system prompt (стиль, тактика, запреты). Движок подставляет нужный при генерации реплики.

🔄
✅

Миф «Пусть модель сама решает порядок ходов»

LLM склонен ускорять: ночь → сразу голосование. Пропускает обсуждение, лишает игрока шанса защититься.

Реальность Phase Machine: жёсткий стейт-машин

Код промта явно перечисляет фазы. Нарушение = ошибка парсинга. Модель вынуждена следовать протоколу.

Моддинг: меняем состав ролей за 30 секунд

Правьте массив ROLES_CONFIG в промте. Баланс: Мафия ≈ 1/3 от живых. Город побеждает информацией, Мафия — дезинформацией.

🔴 Mafia x2 (база)
🔵 Sheriff (инфо)
💚 Doctor (защита)
⚪ Civilian x2 (голос)
🟣 Don Mafia (лидер)
🟤 Maniac (соло)
💘 Lovers (пара)
👻 Ghost (посморт)

Быстрый чек-лист баланса перед стартом:

Промт — это не инструкция. Промт — это код.

Вы не «просите» модель сыграть. Вы компилируете под неё игровой движок: стейт-машину, парсер, рендерер и NPC-модули. Качество партии — это качество вашей архитектуры промта.

State > Context Schema > Trust Protocol > Hope