# 19 — Движок и языковая модель ## Из чего это сделано Три вещи, и порядок между ними важен: | Что | Где | Зачем | |---|---|---| | **инструменты** | `tile2d_editor --tool ...` | обратная связь: во что превращается содержимое | | **скиллы** | `.claude/commands/*.md` | правила этого движка, которые нельзя вывести из кода | | **терминал** | панель снизу в редакторе, клавиша `` ` `` | место, где всё это встречается | Инструменты — главное. Терминал без них был бы просто консолью в чужом окне. ## Почему именно инструменты, а не «API редактора» Содержимое проекта уже текст: комнаты, каталог сущностей и манифест лежат в git и правятся руками. Значит, править их умеет кто угодно, включая модель, — открыл файл, изменил, сохранил. Никакого особого интерфейса для этого не нужно. Чего у модели нет — **последствий**. Собралась ли комната в этаж, достижима ли точка спавна от входа, выбрал ли этаж бюджет опасности, во что превращается набор на двадцать четвёртом этаже: на эти вопросы нельзя ответить, глядя на текст комнаты. Их знает только генератор. Поэтому инструменты — это замкнутая петля: **правка делается файлами, а последствия читаются командой**. И всё выводится текстом, включая карту собранного этажа, — по той же причине, по которой ассеты проверяются через `sf ascii`, а не глазами по PNG: картинку нельзя ни продиффать, ни процитировать в отчёте, ни сравнить с такой же картинкой другого сида. ``` tile2d_editor --tool map 3 42 --project hollow 20 ###.o.......#######.........#########.###.###### 21 ###..##.##..#######..##.##..####...........##### 22 ##....@....................................##### 23 ##.....#...............#.........###.......##### # стена . пол @ старт > спуск < эвакуация m тварь o обстановка $ лут ``` Полный список — `--tool help`. Код возврата 1 означает «не выполнено или найдена поломка», поэтому на инструменты можно вешать хуки и скрипты, а не читать вывод глазами. ![инструменты в терминале редактора](editor-terminal-tools.png) ## Терминал ![терминал редактора](editor-terminal.png) Клавиша `` ` `` открывает панель снизу. Команды выполняются в **корне репозитория**: работают не только над содержимым — рядом код движка, документация и git. Каталог с бинарниками добавлен в `PATH`, поэтому `tile2d_editor --tool validate` пишется без путей. Строка ввода работает в трёх режимах, Tab переключает: | режим | что делает с введённой строкой | |---|---| | `shell$` | выполняет как команду | | `claude>` | `claude -p "..."` | | `codex>` | `codex exec "..."` | Одно поле, а не три — потому что работа выглядит как чередование: спросил, посмотрел, проверил инструментом, снова спросил. Открытый в редакторе проект уходит детям переменной окружения `TILE2D_PROJECT`. Поэтому `--tool validate` без ключей проверяет именно его — и то же самое видит агент, запущенный отсюда. Дописывать `--project` в чужие команды строковой подстановкой было бы способом однажды подставить его не туда. ### Чего терминал НЕ делает Он не эмулятор терминала. Полный VT100 — альтернативный экран, адресация курсора, рамки из псевдографики — нужен ровно одному сорту программ: интерактивным TUI, и `claude` без ключей именно такой. Строчный вывод здесь не упрощение, а выбор в пользу того, как с моделью работают из редактора на самом деле: `claude -p` и `codex exec` печатают обычный текст, инструменты печатают таблицы и карты, git и cmake — тоже текст. Эмулятор не нужен ни одному из них. Полный интерактивный CLI открывается кнопкой `EXTERNAL` (или `F12`) во внешнем окне, в том же рабочем каталоге. Так у каждого способа остаётся то, в чём он хорош, и ни один не притворяется другим. Шрифт панели — Consolas с кириллицей, а не встроенный шрифт raylib. Правило «тексты на экране латиницей» здесь не нарушается: оно про ИГРУ, где текст пишет разработчик. В терминал текст приходит извне, и выбора языка нет. ## Скиллы `.claude/commands/`: `/tile2d` — работа над проектом вообще, `/room` — сделать или починить комнату, `/floor` — править кривую сложности. В них записано то, чего нет в коде и что модель иначе узнаёт слишком поздно: - **не отчитываться об успехе без прохода `--tool validate`.** Комната, которая безупречно читается в диффе, может запечатать карман от собственной двери — в этом репозитории так случилось дважды (`storage`, потом `maw`); - **id сущностей — граница игры, а не движка.** Движок поставит любой id из каталога проекта; `squad_proto` превращает в тварь только те, что перечислены в `src/sim/spawn_catalog.cpp`; - глубину нельзя делать труднее множителями HP — это не страшнее, это дольше; - приёмка меряется в песочнице и проект не подключает. ## Проверки ```bash tile2d_editor --tool validate --project descent # код 0 tile2d_editor --tool validate --project hollow # код 0 tile2d_editor --tool map 6 1 --project descent # карта этажа текстом tile2d_editor --term "tile2d_editor --tool floor 8 42" # то же изнутри редактора ``` Ключ `--term "<команда>"` открывает редактор сразу с выполненной командой. Он нужен не только для картинок в документации: так редактор открывают «с делом» — открыл, и уже видно, что не сходится. ## Чего ещё нет - **Инструментов на запись.** Всё, что здесь есть, только читает и считает; правит модель сами файлы. Это осознанно: запись через инструмент означала бы второй способ менять комнату, и рано или поздно они разошлись бы. - **MCP-сервера.** Инструменты доступны как команды, а не как протокол. Для `claude` и `codex` этого достаточно; для редакторов, которые умеют только MCP, понадобится обёртка. - **Своей истории диалога.** Каждый вызов `claude -p` независим; терминал хранит историю КОМАНД, но не контекст разговора. Длинную работу ведут во внешнем интерактивном CLI. - **Правки текущей комнаты из терминала.** Модель работает с файлами на диске, а редактор держит рабочую копию в памяти: после правки файла нажмите `RELOAD`.