Язык Системы
Язык, на котором мир говорит сам с собой. Игрок встречает его задолго до того, как понимает, что это язык: идентификаторами на узлах, текстом на монолите, командами в чужих руках.
Статус: принят каркас, грамматика и словарь не спроектированы. Проектирование — следующий заход.
Принято
| Решение | Суть |
|---|---|
| Это отдельный ЯЗЫК в локализации, наравне с EN и RU | нераскрытое имя — строка, отрендеренная на нём, а не отсутствие перевода. Проверка полноты ключей работает как обычно, «не раскрыто» не спутается с «забыли перевести» |
| Тип языка — команды, а не программа | декларативные приказы, никаких циклов и ветвлений. Мы не Zachtronics: игрок пришёл готовиться, а не отлаживать |
Словарь строится из наших РЕАЛЬНЫХ id (domain.name) | enc.goblin.03, relic.the_draugr. Мы пишем на этом языке год, просто не называли его языком. Иначе пришлось бы вести два словаря — декоративный и настоящий, — и они разошлись бы за месяц |
Префикс gm. — маркер привилегии, как sudo | чтение мира без префикса, изменение мира — с ним. Не на всех командах: префикс на всём становится невидимым за пять минут, а раскрыть в финале можно только то, что игрок замечал |
| Консоль игроку дадут нарративно, к финалу | будет ли она настоящим исполняемым инструментом — решаем потом, глубоко не закладываем |
| Консоль — это приз Чемпионата | «загадать любое желание» оказывается доступом к консоли. Выдаёт её турнир, правило мира, а не автор: автор ни на что не влияет. Условие — пройти на финальном возвышении. См. Meta §Финальная арка |
Система безмолвна (решение Макса 2026-07-29)
У Системы нет голоса. Она исполнитель — безмолвная машина. Голос имеет только автор.
Отсюда главное следствие: x-sys — это не речь Системы, а её вывод. Речь адресована кому-то, вывод
не адресован никому — он просто есть, и игрок читает его через плечо. Поэтому он и жуткий.
Почему это сильнее говорящей Системы. С говорящей можно спорить, её можно осмысленно ненавидеть, у неё есть воля — и она немедленно становится GLaDOS, то есть чужим приёмом. Процесс не спорит и не оправдывается. В финальном развороте «порядок = Система» злодея не оказывается вовсе: с процессом нельзя договориться, и это тяжелее, чем любой антагонист.
Всё, что звучит как речь — насмешки, комментарии, «ты ведь не заметишь разницы, так?» — принадлежит автору (Devices §Голос разработчика), который наблюдает за работой машины и комментирует.
Конфликт снят: слой «Две Силы» (говорящие божества) отменён 2026-07-29 — разбор в Closed Forks. Говорящий в игре ровно один.
Имена сущностей: АДРЕСА, а не слова (принято 2026-07-29)
Проблема, которую это решает (поставлена Максом). Если Система выводит enemy.goblin_archer, игрок
прочитает это мгновенно — тайны нет, расшифровывать нечего, и весь язык оказывается «английским в костюме
кода». Хуже того, тайна на английских корнях несправедлива к русскому игроку: он в неё даже не заходит.
Решение: сущности обозначаются адресами. И это не выдумка, а правда о машине — строковый
enemy.goblin_archer существует для разработчика, а внутри рантайма сущность есть индекс. Система
оперирует адресами, потому что она машина.
E.421.02.117
│ │ │ └── порядковый номер записи
│ │ └────── тип: редкость у предмета, ранг у врага (обычный / элита / босс)
│ └────────── 4 = фракция, 2 = вид, 1 = подвид (по одной цифре, позиция фиксирована)
└───────────── род: E враг, I предмет, R мементо
Короткая форма — E4.117 (род, фракция, номер). Это минимальный размер записи: на узле карты
двенадцать символов не влезут и не запомнятся, а узнаваемость там важнее точности. Полный адрес живёт в
консоли и логах. Так работает любой артикул: полная номенклатура в каталоге, короткий индекс на этикетке.
Следствие короткой формы: порядковый номер уникален ВНУТРИ ФРАКЦИИ, а не внутри подвида и типа. Иначе два разных врага получат один короткий адрес, и сокращение начнёт лгать.
Почему адреса, а не другие способы кодирования:
| Способ | Чем плох |
|---|---|
Согласные без гласных (gbln.archr) | держится на английских корнях — русский игрок отрезан, англоязычный угадывает за минуту |
Свой словарь корней (krath.vel) | лучшая расшифровка, но надо придумать и вести двести слов, и теряется связь с реальными данными |
Хеши без структуры (0x8F2A1C) | нечего расшифровывать: структуры нет, догадаться не о чем |
Адрес плюс подсказка-тег (E.421 [pack]) | ускоряет обучение, но крадёт открытие |
Главная ценность — игрок расшифровывает сам. Сначала E4.117 просто номер. Потом он замечает, что все
гоблины это 4xx — и это его личное открытие. Потом что соседние номера у похожих врагов. Механика
Chants of Sennaar: догадка из контекста, а не таблица в меню. Через десяток боёв он читает состав врага
прямо с машинного вывода:
> scan(E4.117)
E4.117 : 3 x E4.02, 1 x E4.09
Глаголы при этом остаются словами (принято ранее) — игрок понимает, что делает Система, но не знает, с кем. Это и страшнее, и учебнее.
Открытые имена — это перевод. «Трое и костёр» открывается за пять побед и заменяет адрес; сам адрес никуда не исчезает и остаётся тем, чем сущность является для Системы.
Требование: адрес ВЫЧИСЛЯЕТСЯ, а не пишется руками
Шесть уровней — шесть решений на каждую сущность. Стоит один раз указать неверный подвид, и адрес начнёт врать: игрок расшифрует систему, поверит ей и получит ложь — прямое нарушение правила «ни одно семя не лжёт».
Поэтому фракция, вид, подвид и тип обязаны быть закрытыми перечислениями в данных, а адрес — вычисляемым представлением. Тогда соврать невозможно: адрес не отдельная строка, в которой можно ошибиться, а отражение того, чем сущность является.
Три состояния имени
Имя сущности бывает в трёх ненормальных состояниях, и они обязаны выглядеть по-разному — иначе игрок не различит «ещё не открыл», «идёт загрузка» и «предмет сломан», и три приёма схлопнутся в невнятный шум.
| Состояние | Что показываем | Почему так |
|---|---|---|
| Имя не заслужено — энкаунтер до пяти побед | полный стабильный идентификатор: enc.goblin.03 | стабильность и есть суть: игрок запоминает и узнаёт при встрече |
| Ещё не прогрузилось — момент перехода на арену | id разрешается в имя на глазах: сначала ключ, потом проступает значение | буквально то, что делает движок — сначала ключ, потом строка из таблицы. Мы не изображаем загрузку, а показываем её |
| Поломано — сломанный предмет | имя повреждённое, а не отсутствующее: item.oaken_charm:corrupt | поломка иной природы, чем незнание: имя есть, оно битое. corrupt — наш настоящий служебный суффикс из сейв-системы, куда уезжает испорченный файл |
Разделитель поломанного состояния — двоеточие, не точка. Третий сегмент через точку уже занят действием в аудио-ключах (
effect.burn.apply,relic.cryomancer.cast), поэтомуitem.oaken_charm.corruptпрочиталось бы как аудио-событие «corrupt». Двоеточие свободно и читается как «состояние сущности».
Мелькание при загрузке — на грани восприятия (proposed скрайба). Если id показывается полностью и
разборчиво на каждой загрузке, приём стирается за час — та же болезнь, что у gm. на всех командах.
Кадр-два, чтобы игрок не был уверен, видел ли он что-то: это создаёт сомнение, а не информацию.
В коопе работает вдвойне — один заметил, другой нет, и получается то самое «ты видел?!».
Связь с показом: анимация перехода между аренами — Visual Direction трек 4 (SAO-переход), там же живёт «цифровая подмена арены».
Три дна префикса gm.
- Game Master — читается сразу и не вызывает вопросов: игра про гильдию и мастера.
- Guildmaster — рабочее имя мира (и проекта). Имя файла проекта оказалось именем мира.
- Титул самого игрока. Игрок — Гильдмастер. То есть команды всё это время подписаны его титулом, и в финале консоль не «дают», а возвращают.
Форма записи (черновая иллюстрация, не спека):
scan.roster(player) -> damage.arcane
gm.buff(army, resist.arcane, 40)
Грамматика (принято 2026-07-29)
Одна форма предложения: глагол снаружи, всё остальное — аргументы.
scan(player.roster)
apply(army, resist.arcane, 40)
copy(vessel.veteran_04)
Почему не buff.army(...). Точка у нас уже занята — она разделитель пространства имён
(relic.the_draugr, enc.goblin.03). Форма «глагол.объект» заставила бы точку значить две разные вещи, и
язык перестал бы быть однозначным. При выбранной форме точка всегда означает ровно одно.
gm. встаёт сюда без исключений: gm — это пространство привилегированных команд, ровно как
relic — пространство мементо. gm.apply(...) разбирается по тем же правилам, что relic.the_draugr.
scan(player.roster) > читает мир, префикс не нужен
gm.apply(army, resist.arcane, 40) > меняет мир
Отклонён естественный порядок слов (apply resist.arcane to army 40, как в Baba Is You): читается
легче для нетехнического игрока, но хуже ощущается машинным выводом — а x-sys обязан читаться как
вывод, не как речь.
Словарь: двадцать глаголов
Чтение свободно, изменение — только под gm.. Префикс появляется ровно тогда, когда мир меняется.
| Читают (без префикса) | Что делает |
|---|---|
scan | прочитать состояние сущности |
list | перечислить содержимое |
count | посчитать |
find | найти по признаку |
trace | проследить происхождение, историю записи |
Меняют (только под gm.) | Что делает |
|---|---|
set | задать значение поля |
apply · remove | наложить и снять эффект |
spawn · kill | создать и уничтожить сущность |
copy | скопировать — команда сцены с ветераном |
purge | удалить безвозвратно |
move | переместить |
bind · unbind | связать сущности |
lock · unlock | запретить и разрешить действие |
rename | переименовать |
grant · revoke | выдать и отобрать право |
revert | откатить к сохранённому состоянию — команда истинного финала |
stop | остановить процесс (вместо halt: понятнее обычному игроку — правка Макса) |
Границы: чего язык НЕ умеет
Важнее списка возможностей — именно границы делают систему правдоподобной.
- Нет условий и циклов. Приказ, а не программа.
- Нет создания понятий. Язык оперирует только существующими id и не может выдумать сущность, которой в мире нет. Система работает с тем, что есть.
- Нет обращения к прошлому. Изменить случившееся нельзя;
revertоткатывает к сохранённому состоянию. Это и есть «правим вперёд, не отменяем прожитое». playerможно ЧИТАТЬ, но нельзя изменять.scan(player.roster)работает;gm.set(player, …)не запрещено — оно невыразимо. Игрок не объект мира.
Граница №4 объясняет, почему работает сцена с ветераном. Система физически не может дотянуться до игрока — только до его данных. Поэтому она копирует «Сосуда», а не трогает того, кому «Сосуд» дорог. И поэтому единственное место, где эта смерть существует, — голова игрока: у языка нет средств туда попасть.
Как выглядит отказ
Система безмолвна, значит она не объясняется и не помогает. Никаких «возможно, вы имели в виду»:
> gm.set(player.mood, happy)
denied
Три формы отказа: denied · undefined: relic.foo · locked. Ни одного извинения и ни одной подсказки —
половина характера языка живёт здесь.
Что ещё предстоит прописать
Порядок значим: пункты 1–3 определяют язык, 4–7 определяют, будет ли он живым.
- Грамматика — одна форма предложения, максимум две. Всё остальное выражается словарём.
- Словарь глаголов — что вообще можно делать. Двадцать-тридцать, не больше.
- Пространство имён — уже есть (
domain.name), нужно зафиксировать как часть языка и запретить расхождения. - Границы: чего язык НЕ умеет. Важнее списка возможностей — именно границы делают систему правдоподобной.
- Как выглядит ошибка. Половина характера языка живёт в отказах.
- Диегетический источник знания — откуда персонажи узнали язык. Уже посеяно: монолит гоблинов, находка у торговца, консоль вражеского короля.
- Типографика и локаль — моноширинный, цвет, префиксы строк; код локали.
Уроки ресёрча (2026-07-29)
| Игра | Что взять |
|---|---|
| TIS-100 / EXAPUNKS (Zachtronics) | 13 инструкций. Малый набор нужен не ради сложности, а ради правдоподобия машины. Бедный словарь читается как настоящая система, богатый — как выдумка |
| Chants of Sennaar | ~30 слов на язык — и у языка есть грамматика. Ключевое отличие от Fez и Tunic, где был шифр (символ = буква или слог): шифр разгадывают за вечер, и он умирает, а язык живёт всю игру. Плюс блокнот с подтверждением догадки — без него расшифровка становится угадайкой |
| Else Heart.Break() | язык Sprak на основе BASIC, специально сделан менее строгим, чтобы новичок не пугался. Мануал лежит на десяти внутриигровых дискетах — документация как находка, а не пункт меню |
| Duskers | командная строка как весь интерфейс: автодополнение, история команд, цепочки через ;, алиасы-макросы. Их принцип «игра про стратегию, а не про ловкость» для нас обязателен — консоль без автодополнения нарушит столп «скилл в подготовке, а не в реакции» |
| Baba Is You | грамматика из трёх слов (СУЩЕСТВИТЕЛЬНОЕ IS СВОЙСТВО) несёт огромную глубину и читается без обучения |
Общий вывод ресёрча: шифр — не язык. Если бы x-sys просто подменял буквы, его расшифровали бы за
вечер и он перестал бы работать. Живым его делает грамматика — пусть даже из одной формы.
Открыто
- Подвиды и строковые id — конфликт, требующий вердикта. В адресе подвид есть отдельной цифрой
(
E.421…), а строковый id у нас один на роль (enemy.goblin_archer). Значит лесной и горный гоблин-лучник получат разные адреса при одном id — и обратное соответствие «адрес → запись» перестанет быть однозначным. Три варианта: (A) подвиды становятся отдельными записями данных (enemy.goblin_forest_archer) — честно, но множит записи на число подвидов; (B) подвид не входит в адрес, уровней остаётся пять — если различие подвидов декоративное (цвет, силуэт); (C) подвид живёт только полем варианта, а адрес точнее id — это тихий костыль, скрайб против. Ответ зависит от того, различаются ли подвиды механически. - Как именно ломается строка у состояния
:corrupt— обрезка, пропуски, подмена символов. - Соответствие цифр фракциям и видам — сама нумерация не назначена.
- Что делать, когда цифр не хватит: один разряд держит девять фракций и девять видов. Нужен ли задел (двузначные поля) или девяти достаточно на всю игру.
- Код локали:
proposed—x-sys(префиксx-по BCP 47 — легальная приватная зона). - Включаемость целиком: если это полноценная локаль, её можно включить на всю игру — готовая открываемая тайна, стоимость нулевая. Подтвердить.
- Шов в UI: Unity Localization берёт активную локаль, поэтому одна строка на
x-sysпосреди русского требует явного запроса таблицы, а не простоLocalizedString.