exchanger-themes/docs/SPACE_PIXEL.md
Danil Iarosh ca52efbedc Initial commit: Exchanger Theme DLC Builder
Godot 4.7 project for authoring, previewing, validating, and building Exchanger PCK themes. Includes the example and space-pixel themes, binding contracts, editor tooling, validation/build scripts, and project documentation.
2026-09-22 11:43:13 +03:00

442 lines
48 KiB
Markdown
Raw Permalink 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.

# Тема `space-pixel`
## Реализованный вид
- Статический pixel-art фон `background.png` размером 1080×1920.
- Кириллический pixel-font `VCR OSD Mono Cyr` для Label и Button.
- Зелёная текстура `button_big.png` как масштабируемый StyleBoxTexture для normal, hover,
pressed и disabled-состояний.
- Безопасная тёмно-синяя default-панель для существующих экранов Exchanger и отдельная
`WhitePanel`-вариация с настоящей белой заливкой, зелёной шапкой и тонкой рамкой из исходника.
- Семантические вариации текста, кнопок и панелей, включая `ScreenTitle`, `PanelTitle`,
`PanelText`, `AdvertisementPanel`, `FooterPanel`, `StatusPanel` и `WhitePanel`, для точного
воспроизведения контрастов референса без глобальной перекраски всех Control.
- Экранные заголовки используют общий кегль `36 px`; более компактный заголовок сервисного входа
— `30 px`. Блок техподдержки в Home и общем footer начинается с `x = 341 px`, поэтому обе строки
номера остаются левее правой границы при том же масштабе и не пересекаются с логотипом.
- Decoration-сцена с theme-owned скриптом `scripts/ufo_flight_controller.gd`: два кадра звёзд
и два `AnimatedSprite2D` с независимыми двусторонними пролётами. После выхода за край каждый
НЛО выдерживает случайную паузу, разворачивается через `flip_h` и возвращается на новой
случайной высоте в диапазоне `260–1660` исходной системы `1080×1920`. Высота привязана к шагу
`3 px`, чтобы после масштабирования production-экраном до `720×1280` коэффициентом `2/3`
оставаться целочисленной. Оба спрайта независимо переключают `frame_01.png`/`frame_02.png`;
скорость большого набора — `1 fps`, малого — `1,5 fps`.
- Два НЛО ценового блока Home в `visuals/home_top.tscn` сохраняют референсные базовые позиции,
но независимо покачиваются вверх-вниз через `scripts/home_ufo_bobbing.gd`: амплитуда слева
`4 px`, справа `5 px`, периоды `3,2` и `3,8` секунды. Смещение округляется до целого пикселя,
поэтому Nearest-фильтрация остаётся чёткой.
- Двухкадровый нижний баннер экранов Cash, CardAmount, CardCustomAmount и CardTerminal сохраняет
оба исходных кадра, но
`scripts/stable_banner_animation.gd` компенсирует различие их внутренней геометрии. Для
`frame_02` корректируются масштаб и опорная точка, поэтому видимая цветная область обоих
кадров занимает один `Rect2(34.996, 1000.8, 175.421, 111.389)` в координатах экрана.
- Красная текстура `button_cancel.png` используется через variation `CancelButton` для действий
«ОТМЕНА» и через `DangerButton` для всех кнопок «УДАЛИТЬ».
- Nearest-фильтрация в preview и decoration-сцене. Manifest `space-pixel` задаёт
`UseNearestTextureFilter: true`, поэтому Exchanger включает nearest только для этой DLC.
- Корни всех девяти production-сцен также явно задают `texture_filter = 1`. Это необходимо для
self-contained режима: Exchanger не переопределяет визуальные параметры такой сцены, а весь
текст и вложенные изображения наследуют Nearest непосредственно от theme-owned root даже при
физическом разрешении `1080×1920` и коэффициенте масштабирования `1,5`.
Интерполяционное размытие при этом устраняется; из-за дробного коэффициента отдельные исходные
пиксели неизбежно занимают разное число физических пикселей.
## Сравнение с визуальными референсами
Полностью просмотрены восемь JPG и 64 последовательных кадра `interface.mp4` с интервалом
0,5 секунды. Фото и видео находятся только в локальном, игнорируемом Git каталоге
`themes/space-pixel/source/references/` и никогда не экспортируются в PCK.
Подтверждённые паттерны интерфейса:
- фон всегда остаётся одним статическим космическим изображением;
- экранный заголовок белый, крупный и расположен сверху; кнопка `НАЗАД` — слева от него;
- информационные поверхности белые, с зелёной шапкой и тонкой зелёной окантовкой;
- между зелёной шапкой и содержимым сохраняется видимый белый интервал 16–20 px; в текущих
preview-сценах ему соответствует `separation = 28` с учётом внутренних полей текстуры панели;
- заголовки панелей и основной текст — тёмно-синие/почти чёрные;
- основное действие — одна широкая зелёная CTA-кнопка, вспомогательные действия компактнее;
- пинпад ручного ввода занимает основную рабочую область экрана и состоит из двенадцати
одинаковых квадратных клавиш `152×152 px` в сетке `3×4` с зазором `12 px`;
- PIN-клавиатура сервисного входа использует тот же квадратный визуальный стиль: двенадцать
клавиш `112×112 px` в центрированной сетке `3×4` с зазором `12 px`;
- иерархия читается сверху вниз: заголовок → баланс/состав выдачи → инструкция/выбор → действие;
- нижняя зона бренда и технической поддержки постоянна и отделена от основного действия;
- пришелец, НЛО и speech bubble занимают свободные зоны, но не закрывают функциональный контент;
- покадровые bill/coin/card/result-анимации принадлежат конкретным состояниям экрана, а не фону.
- экранные изображения центрируются по внутренней белой области после полей `WhitePanel`, поэтому
их координата не обязана совпадать с геометрическим центром внешней рамки панели.
Home воспроизводит `themes_src/space_pixel/references/photo_2026-08-20_14-09-56.jpg` в его
исходном размере `720×1280`. Bubble-плашки, оба НЛО, панели наличия/оплаты, кнопки, билборд,
логотип и поддержка выставлены по измеренным пиксельным координатам; исходные PNG масштабируются
nearest-фильтром без подмены на приблизительные `StyleBoxFlat`. Скрипты `home_reference_label.gd`
и `home_stock_presenter.gd` сохраняют референсный формат цены/телефона и переключают индикатор
`МНОГО`/`МАЛО`, не меняя app-owned binding-id.
Четыре транзакционных экрана также собраны непосредственно по JPG `720×1280`, без внешнего
preview chrome и без подмены их дерева галереей:
- `screen_cash_payment.tscn` соответствует `photo_2026-08-20_14-10-27.jpg`: восстановлены
две балансные карточки, панель инструкции с исходной bill/coin-анимацией, широкая кнопка выдачи,
нижний НЛО, речевая плашка и footer;
- `screen_card_custom_amount.tscn` соответствует `photo_2026-08-20_14-10-36.jpg`: верхняя карточка
выдачи и панель ручного ввода имеют измеренные границы, клавиши `46×46 px`, а действия
`ОТМЕНА`/`0`/`OK` находятся в том же нижнем ряду, что и на фото;
- `screen_card_amount.tscn` соответствует `photo_2026-08-20_14-10-40.jpg`: показаны восемь
референсных сумм в двух колонках, отдельная кнопка «ДРУГАЯ СУММА», CTA подтверждения и нижняя
композиция с НЛО, bubble и footer; обязательные слоты 08–15 сохранены скрытыми;
- `screen_card_terminal.tscn` соответствует `photo_2026-08-20_14-10-43.jpg`: карточная анимация
остаётся внутри production-сцены, под ней расположена кнопка отмены и исходная нижняя композиция.
Обязательные binding ID и типы узлов во всех четырёх сценах сохранены. Контрольные прямые рендеры
сделаны из самих production `.tscn`, а не из вручную собранного preview-макета.
Последовательность видео подтверждает длительный home-loop с НЛО, cash-инструкцию с чередованием
кадров купюры/монеты, возврат на home, выбор карточной суммы, card-terminal loop и финальную
анимацию неуспешной оплаты.
`tools/preview/preview.tscn` является переключаемой галереей в 720×1280. Девять production-сцен в
`themes/space-pixel/package/scenes/` показывают все текущие `ScreenId`: Home, cash-screen, выбор карточной суммы,
ручной ввод, терминал, успешную и неуспешную оплату, сервисный вход и настройки. SETTINGS содержит
восемь внутренних разделов и демонстрирует LineEdit, SpinBox, OptionButton, CheckButton, HSlider
и полосы прокрутки. Bill/coin/card/success/failed-анимации, кнопки, белые карточки, безопасные зоны
декора и footer принадлежат самим production-сценам. Галерея ничего не добавляет в их дерево и
только переключает сцены; live reload сохраняет основную вкладку и раздел SETTINGS.
Отдельная builder-сцена `tools/preview/interactive_pet_preview.tscn` открывается кнопкой `PET`
основной галереи и динамически загружает `InteractivePetScene` активной темы. Для `space-pixel`
это `components/interactive_pet.tscn`, показанный в масштабе до `4×`. Все 22 анимации получают
кнопки из публичного списка компонента; также работают предыдущая/следующая, пауза, повтор,
счётчик кадров и автопоказ полного цикла каждого состояния. `Esc` и кнопка «← ГАЛЕРЕЯ» возвращают
к девяти production-экранам. Сцена и её `InteractivePetPreview.gd` являются только builder tooling
и в PCK не экспортируются. Кнопка `PET` недоступна для активной темы без питомца.
Runtime-профиль питомца для сцен `720×1280`: scale `0.845`, ходьба `88 px/s`, подъём `72 px/s`,
touch/ЛКМ hit size `128×128`, точка лап `(64,96)`. Host вызывает реальные имена анимаций
напрямую: `idle`, `sitting`, `action`, `dancing`, все парные walking-анимации и
`climbing_start/up/down`;
в composite-действии `interact` увеличение до ×2 завершается за первые `75%` клипа
`come_closer`; заключительная четверть показывается в полном масштабе, затем выдерживается ещё
`0.15` секунды до запуска первого цикла `action`.
при начале выдачи host проигрывает четыре полных цикла `dancing`. `hanging` проигрывается при
удержании/перетаскивании, `falling` — при падении после отпускания и при смене экрана, а
одноразовый `landing` — после контакта с опорой; затем host включает зацикленный `idle`. Запрос
`celebrate` во время `landing` ждёт окончания приземления и только потом запускает четыре цикла
`dancing`. После завершённой ходьбы host выбирает `idle` с вероятностью `35%` или `sitting` с
вероятностью `65%`.
После подъёма или спуска host сразу продолжает маршрут без отдельной hanging-анимации.
Кадры и исходные каталоги текстур не менялись.
Non-sitting состояния используют нулевую локальную поправку дочернего спрайта. `sitting`
использует отдельную поправку `(0,24)`, которая опускает только сидящего питомца на `20,28`
экранного пикселя при runtime scale `0.845`. Root, navigation, hit box и общая точка лап
`(64,96)` при переключении состояний не меняются.
Невидимый `PetNavigation` присутствует во всех восьми production-сценах, кроме Settings, и в
сумме объявляет 51 реальную горизонтальную поверхность и 46 связанных climb edges. Каждый экран
имеет собственные поверхности пола, кнопок и окон; при переключении host сохраняет старую
позицию, переключает граф и опускает питомца на default-floor нового экрана. Settings намеренно
не содержит графа и скрывает питомца.
В `screen_home.tscn` bounds равен `(32,48,656,1192)`, объявлены восемь поверхностей и десять
climb edges. Default surface — пол
`x=40..680, y=1240`. Питомец может останавливаться на верхних гранях billboard
`x=144..576, y=827`, окна способов оплаты `x=40..680, y=490`, окна остатка
`x=40..680, y=337`, кнопок наличной/безналичной оплаты (`y=550`), ценового окна и речевой
плашки (`y=60/61`). Парные переходы у `x=40` и `x=680` дают подъём по левому/правому краю между
полом, платёжным и верхним окном; дополнительные edges связывают billboard, обе кнопки и верхние
плашки. Узлы маршрута — только `Node2D` с metadata, поэтому они ничего не рисуют и не меняют
геометрию production `Control`.
## Инвентаризация исходников
| Группа | Материалы |
| --- | --- |
| Фон | `background.png`, два полноэкранных кадра звёзд |
| Кнопки | big, long, square, back, cancel и стрелки SpinBox вверх/вниз |
| Контейнеры | пять окон, три bubble-панели, billboard |
| Индикаторы | many, less, summa bar и тумблеры ON/OFF |
| Декорации | alien1–alien3, logo |
| Покадровая графика | banner (2), bill (4), coin (3), card (2), payment failed (3), payment success (5), UFO small (2), UFO large (2) |
| Интерактивный питомец | 22 sprite-sheet по сетке `128×128 px`, 414 непустых кадров |
| Шрифт | `VCR OSD Mono Cyr.ttf` |
Всего в production package используется 75 PNG. `Цвета.txt` пуст, поэтому палитра определена по изображениям:
`#00183D` для fallback-фона, тёмно-синие поверхности/текст, зелёные контуры/кнопки,
фиолетовый focus-акцент и почти белый экранный текст.
## Разделение runtime и исходников
- `themes/space-pixel/source/` — сохранённый исходный материал пользователя и references.
- `themes/space-pixel/package/assets/` — копии с ASCII-путями для стабильной сборки PCK.
- `package/scenes/` — девять полноценных сцен с 481 immutable, 24 обязательными и двумя optional supplemental
metadata binding; optional правый персонаж Home также размечен собственным runtime ID.
- `package/components/on_screen_keyboards.tscn` — две оформленные пиксельные экранные
клавиатуры SETTINGS, скрытые по умолчанию и полностью принадлежащие теме.
- `package/components/interactive_pet.tscn` — визуальный компонент интерактивного питомца со всеми 22
анимациями из `source/alien_animation`; runtime-API находится в
`package/scripts/interactive_pet.gd`. Имена `source/alien_animation` и
`package/assets/animations/alien_pet` сохранены только как theme-specific структура исходных
материалов; generic pet contract не требует таких имён от других тем.
- `package/ui_theme.tres`, decoration, visuals и `manifest.json` — исходник темы DLC v2.
- `tools/preview/` — tooling вне PCK; preview читает `package/` напрямую, без корневого staging.
В PCK входят активные зависимости темы. Остальные runtime-копии сохранены в builder для
следующего расширения контракта.
Обновление исходников от 7 сентября добавило `come_closer`, `idle`, `landing`,
`turn_left`, `turn_right`, `action`, `climbing_action_start`, `climbing_action_stop` и
`climbing_action`,
обновило `dancing` и добавило runtime-пиктограммы питомца `home`/`cross`. Собранный PCK содержит
все эти ресурсы; одноимённые дубликаты climbing-action листов сохранены только в `source/`.
## Runtime-supported и preview-only ресурсы
В runtime через DLC v2 поддерживаются:
- базовые стили Godot Control и семантические variations из `ui_theme.tres`;
- один неподвижный фон, встроенный в каждую экранную сцену;
- один инстанс decoration-сцены с тремя покадровыми `AnimatedSprite2D` и theme-owned
GDScript/Tween-контроллером двусторонних пролётов в каждом экране;
- переиспользуемый компонент питомца `components/interactive_pet.tscn`: приложение получает путь
из `InteractivePetScene` manifest, semantic mapping и runtime-профиль; Home предоставляет
theme-owned граф поверхностей/подъёмов, а host исполняет перемещение и touch/ЛКМ drag;
- девять полноценных визуальных сцен, включая ServiceAccess и Settings.
В блоке запаса Home слева остаётся состояние `МНОГО/ДОСТАТОЧНО/МАЛО`, по центру находится
theme-owned полоска, а справа Label `home.scroll.content.stock_status.approximate_count`
показывает приблизительный остаток: например `нет жетонов`, `<100`, `~100` или `>100`.
Manifest сохраняет `UiThemePath` как описание package Theme, но его legacy-пути общего фона
и decoration пусты: production-сцены уже содержат эти слои, поэтому preview и Exchanger не должны
монтировать их повторно.
Manifest `ExchangerThemeDlc` версии 2 использует `ScreenScenes` и временно сохраняет обратно
совместимый словарь `VisualSlots`.
Анимации купюры, монеты, карты и результатов, НЛО главного экрана и рамка промо-блока входят в
`active_theme.pck` и отображаются только в своих контейнерах. Интерактивные элементы и рабочий
текст остаются в Exchanger.
## Семантическая интеграция с Exchanger
Все `theme_type_variation`, размеры и отступы назначены внутри production-сцен, включая
фиксированные строки SETTINGS. Host не стилизует ThemeView. Поддерживаемый набор:
- `ScreenTitle`: `CashPaymentScreen/.../TopBar/Title`, `CardAmountScreen/.../Content/Title`,
`CardCustomAmountScreen/.../TopBar/Title`, `CardTerminalScreen/.../Content/Title`;
- `BackButton`: одноимённые TopBar-кнопки CashPayment, CardAmount и CardCustomAmount;
- `WhitePanel`: Home `PricePanel`, `PaymentPanel` и `TokenStockStatus`; Cash `Summary`,
`BanknotePanel`, `CoinPanel`; CardAmount `AmountPanel`; CardCustom `AmountPanel`;
CardTerminal `InstructionPanel`, `PaymentPanel`; Success `ResultPanel`; Error `ErrorPanel`;
- `PanelTitle`: Home `PricePanel/.../Caption`, `PaymentPanel/.../Title`, TokenStockStatus `Title`;
Cash `Summary/.../Caption`; CardCustom `AmountPanel/.../Caption`; CardTerminal
`PaymentPanel/.../Caption`; Success/Error заголовки внутри result-панелей;
- `PanelText`: значения и описания внутри перечисленных WhitePanel, включая Balance/Tokens/Bonus,
Amount, Instruction, Message и stock State;
- `PrimaryButton`: Cash `DispenseButton`, CardCustom `ConfirmButton`, Success/Error `HomeButton`;
- `CompactButton`: Home `CashButton`/`CardButton`, CardAmount `OtherAmountButton` и динамически
создаваемые preset-кнопки, keypad CardCustom;
- `CancelButton`: CardCustom `ClearButton`, CardTerminal и ServiceAccess `CancelButton`, а также
кнопка отмены theme-owned сервисного диалога SETTINGS;
- `SupportText`: Home `Footer/.../Support` и новый общий footer остальных экранов.
- `ScreenDescription`: пояснения SERVICE и SETTINGS;
- `SectionTabButton`: пять переключателей разделов SETTINGS владельца;
- `SecondaryButton` и `DangerButton`: вторичные и удаляющие действия;
- `FieldLabel`, `StatusText`, `WarningText`, `ErrorText`: формы и состояния служебных экранов.
- `AdvertisementPanel`: промо-блок Home; `FooterPanel`: общий preview-footer;
`StatusPanel`: Home `StockPanel` и компактная панель подключения.
Кроме variations тема задаёт базовые стили `LineEdit`, `SpinBox`, `OptionButton`,
`CheckButton`, `HSlider`, `VScrollBar` и `HScrollBar`; все такие Control уже находятся
в тематических сценах.
Runtime-композиция синхронизирована с preview: host использует ту же сетку 720×1280, общий footer,
BackButton и объединённые панели Cash и Card. Кнопки preset/keypad и все фиксированные слоты
оформлены самой темой. SETTINGS намеренно сохраняет только пять вкладок владельца; технические панели
не возвращаются ради старого preview.
Footer с логотипом `Robotic Retailers` и двухстрочным номером техподдержки занимает нижние
`152 px` и показывается на восьми production-экранах. Home содержит собственную идентичную
композицию с обязательными binding ID, остальные семь экранов подключают
`package/components/footer.tscn`. На SETTINGS footer намеренно отсутствует.
## Проверки
- 11 сентября 2026 года по итогам проверки в Exchanger только `sitting` опущен ещё на `24`
локальных пикселя: его visual offset теперь `(0,24)`, то есть `+20,28` экранного пикселя при
scale `0.845`. Все non-sitting анимации сохраняют исправленную нулевую поправку; verifier
проверяет переход `(0,24) → (0,0) → (0,24)` без движения root. Contract check, validator,
pet verifier, preview smoke и build прошли. Живой PET-preview `720×1280` подтвердил
current offset `(0,24)` и отсутствие clipping. `build/space-pixel.pck` и
`build/active_theme.pck` совпадают: `1700352` bytes, SHA-256
`931A2EAA118722B95E49EA097C8CE41CE9E655F2CF7248CCA050B28A9AF50357`.
- 11 сентября 2026 года удалено ошибочное локальное смещение `(0,-24)` у всех non-sitting
анимаций питомца. Теперь переход `sitting → non-sitting → sitting` сохраняет нулевую поправку,
а положение root и точка лап `(64,96)` не меняются; это опускает прежние поднятые состояния
ровно на `20,28` экранного пикселя при scale `0.845`. Contract check, validator, pet verifier,
preview smoke и build прошли. `build/space-pixel.pck` и `build/active_theme.pck` совпадают:
`1700256` bytes, SHA-256
`C1872763DA443190FA3CA2D281E1599B8C4F772CF290A19F3E4E580CAFE2336F`.
- 7 сентября 2026 года `CardAmount/RewardPanel` повторяет `CashPayment/Summary` по atlas-region,
размеру `649×125`, позиции `(36,148)` и rect заголовка/базового значения/бонуса. Обязательный
`Value` и supplemental `Bonus` сохранили прежние binding-id и канонические пути. Runtime QA
`720×1280`, contract check, validator/preview smoke, build и PCK smoke прошли; PCK — `1435772` bytes,
SHA-256 `F505882620719F154319A9CD93208F42ECB59FCC615410827A44DADED8F61404`.
- 4 сентября 2026 года scale питомца увеличен ровно на 30% (`0.65 → 0.845`), а сниженная высота
оставлена только для `sitting`; verifier подтвердил переход поправок `(0,0) → (0,-24) → (0,0)`
без смещения root. Contract check, validator, preview smoke, build, PCK verifier и host
`InteractivePetBehaviorSmoke` с явным PCK прошли.
Preview `720×1280` подтвердил отсутствие clipping, пересечения с заголовком и сохранение
Nearest для sitting/non-sitting; PCK — `1435452` bytes, SHA-256
`390C9E3F83B026304F0E75E5A6AAD4458684BBCDFC847FFB542B6CFB1AC278E9`.
- Godot 4.7.1 импортирует все runtime-файлы без ошибок; pixel-font распознан автоматически.
- В `assets/fonts/vcr_osd_mono_cyr.ttf.import` отключены antialiasing, hinting и subpixel
positioning, oversampling зафиксирован в `1.0`. Все девять корней экранов имеют
`texture_filter = 1`, поэтому Labels, Buttons, LineEdit, SpinBox и прочий текст наследуют
Nearest без покомпонентных настроек.
- У всех текстовых variations отключены тени и обводка кнопок: при масштабировании preview до
720×1280 символы не смешиваются с полупрозрачной копией. Светлый текст использует чистый белый,
а текст на белых и зелёных поверхностях — контрастный тёмно-синий цвет.
- Все девять вкладок production preview и восемь разделов SETTINGS запускаются без ошибок и визуально
проверены в окне 720×1280.
- В `CardCustomAmount` темы `space-pixel` проверена референсная панель `646×466 px`; все цифровые
клавиши имеют одинаковый квадратный размер `46×46 px`, длинные действия выровнены с нижним
рядом, а содержимое и footer не перекрываются.
- В `ServiceAccess` все двенадцать PIN-клавиш имеют одинаковый размер `112×112 px`; кнопки
`ВОЙТИ`, `ОТМЕНА` и footer остаются видимыми и не перекрываются.
- Нижние служебные ряды текстовой клавиатуры используют отдельный `KeyboardActionButton` без
прозрачных боковых полей исходной текстуры: все кнопки имеют высоту `76 px`, зазоры `12 px`,
стрелки — touch-target `88×76 px`, а `СТЕРЕТЬ`, `ОЧИСТИТЬ` и `ПРОБЕЛ` получили увеличенную
ширину под полные подписи.
- Кнопки скрытия текстовой и цифровой клавиатур остаются обычными `Button` с прежними binding ID,
но вместо надписи используют контрастную стрелку вниз из `button_down.png`. Обе кнопки имеют
квадратную область нажатия `64×64 px`, крупную центрированную пиктограмму и подсказку
«Скрыть клавиатуру».
- Описание приложения `subtitle` остаётся удалённым. Новая отдельная настройка «Короткий текст»
управляет фразой в белой речевой плашке возле НЛО: HOME Label ограничен геометрией bubble,
переносит до 48 символов, центрирует строки и обрезает выход за границы. Для читаемости при
Nearest его кегль увеличен с `12` до `16 px`; Label занимает внутреннюю белую область
`182×73 px`, использует `line_spacing = -2` и переносит текущую фразу на две строки. В SETTINGS
добавлены поле, ошибка и предпросмотр `short_text`; панели увеличены ровно под новый ряд без
пустых мест.
- `CheckButton` использует тёмно-синий текст, крупную зелёную touch-строку и исходные
`tumbler_on.png`/`tumbler_off.png` размером `128×64 px`; в живом SETTINGS проверены оба состояния
без обрезания и растяжения. У всех 12 строк отступ от левого края до текста и от правого края
до тумблера одинаковый — `24 px`.
- Все 57 `SpinBox` используют исходные `button_up.png`/`button_down.png`; их runtime-копии
уменьшены ближайшим соседом с `64×64` до `32×32 px`, поэтому обе квадратные кнопки целиком
помещаются справа от поля. Между полем и кнопками задан единый промежуток `10 px`, а variation
`SpinBoxInnerLineEdit` использует шрифт `18 px`. У 16 полей количества дополнительных жетонов
нет текстового суффикса: вся доступная ширина отведена многозначному числу. В живом SETTINGS
проверено изменение цены `10 → 11 → 10` и отображение бонусных строк.
- Фон всех текстовых полей `LineEdit` (включая focus/read-only), текстовых частей `SpinBox`
и полей выбора `OptionButton` использует видимую область `290×64 px` исходного
`summa_bar.png` через растягиваемый `StyleBoxTexture`. В живом SETTINGS проверены обычные
текстовые и числовые поля без искажения краёв и обрезания текста.
- Обе полосы `HSlider` в разделе SETTINGS → «ЗВУК» имеют высоту `36 px` вместо прежних
`14 px` (примерно в 2,6 раза выше). Видимый круглый grabber отключён; при значении `100%`
заполнение доходит до правого края. В живом Exchanger проверено, что полосы не обрезаются
и не нарушают компоновку соседних элементов.
- Decoration `space-pixel` использует корневой scripted `Node2D` и три `AnimatedSprite2D`.
Звёзды и оба НЛО имеют по два кадра; НЛО воспроизводят собственные покадровые циклы
одновременно с независимыми Tween-траекториями.
Это существенно ниже всех лимитов host.
- Live reload проверен реальным изменением `ScreenTitle/font_sizes/font_size`: новое значение
появилось в запущенной галерее без перезапуска, а активная вкладка сохранилась.
- Фон остаётся статическим; движение ограничено отдельными Sprite2D/AnimatedSprite2D.
- `build-theme.ps1` собирает `build/active_theme.pck`.
- Компонент `interactive_pet.tscn` проверен отдельно в builder и из смонтированного PCK: доступны все
22 имени, 414 кадров, корректные loop/one-shot флаги и неизменная позиция корня. Sprite использует
Nearest-фильтрацию. Отдельная preview-сцена проверена в живом Godot при `720×1280`: стартовое
состояние `sitting`, все 22 кнопки доступны в прокручиваемом списке.
Итоговые `space-pixel.pck` и `active_theme.pck` совпадают: `1325176` bytes,
SHA-256 `7DB9F2108D478E7CDB77E3A85ACA33C8DD2EC27A68FA2CF61A28BF78B4331595`.
- Exchanger загружает пакет и активирует `space-pixel` вместо fallback-темы.
- После настройки Nearest фактический Exchanger повторно запущен в `720×1280`; контрольный кадр
`build/exchanger-speech-bubble-runtime.png` подтверждает жёсткие пиксельные края глифов и
читаемый перенос короткого текста. Собранная, активная и установленная PCK совпадают:
`721192` bytes, SHA-256
`30A8806709BCA315E1F455FED1F438C5CD377B9ACEC35A249BABDFF12F1888C4`.
- После этих изменений `Test-PackagedBindingContract.ps1`, `test-theme example`,
`test-theme space-pixel` и `build-theme space-pixel` завершились успешно.
- Pixel-perfect Home QA выполнен прямым рендером production-сцены в `720×1280`: крупные белые
компоненты совпали с координатами JPG, а средняя абсолютная RGB-разница контрольного кадра
уменьшилась с `75,81` до `6,84` (разница включает JPEG-компрессию и rasterization текста).
- Транзакционные референсы проверены тем же прямым рендером `720×1280`: средняя абсолютная
RGB-разница CashPayment уменьшена с `66,66` до `13,66`, CardTerminal — с `59,14` до `11,58`;
после повторной строгой сверки средняя RGB-разница внутри двух основных панелей
CardCustomAmount уменьшена с `13,28` до `7,64`, CardAmount — с `15,31` до `10,88`.
Вручную подтверждены заголовки, текстурные рамки, квадратные клавиши, CTA, исходные анимации
и общий footer на финальных кадрах. Значение выдачи CardAmount совпадает с reference bounding
box полностью; «ДРУГАЯ СУММА» и CTA отличаются не более чем на один пиксель по краю текста.
- CashPayment использует три раздельных обязательных Label из контракта: `Balance` показывает
только рубли, `Tokens` — базовые жетоны, `Bonus` — дополнительные жетоны двумя строками.
Их исходные значения и расположение соответствуют `photo_2026-08-20_14-10-27.jpg`, а Exchanger
обновляет только текст, не меняя геометрию сцены.
- В CardCustomAmount Label `InputValue` внутри `summa_bar` теперь имеет собственный обязательный
binding и показывает фактически набранную сумму. Верхняя панель «К ВЫДАЧЕ» получает только
базовые и бонусные жетоны; host больше не объединяет рубли и жетоны и не оставляет статическое
значение `1000` в поле ввода.
- Актуальные `build/space-pixel.pck` и `build/active_theme.pck` с единым footer, Nearest-шрифтом
и отдельным `InputValue` binding имеют размер `721192` bytes и SHA-256
`30A8806709BCA315E1F455FED1F438C5CD377B9ACEC35A249BABDFF12F1888C4`.
Штатный PCK smoke смонтировал пакет, инстанцировал девять экранов и подтвердил 10 scripted node
instances. Та же сборка установлена в стандартный каталог Exchanger и подтверждена совпадением
SHA-256. После полного запуска Exchanger в `720×1280` журнал подтвердил активацию `space-pixel`
без theme/resource/fallback-ошибок; актуальный Home-кадр сохранён в
`build/exchanger-speech-bubble-runtime.png`.
- 1 сентября 2026 года красный `button_cancel.png` подтверждён во всех variation
`CancelButton`/`DangerButton`. Пролёты `UfoLarge` и `UfoSmall` повторно измерены по
`interface.mp4`: контрольные позиции проверены на `t=1/2/3/10,5/12/12,5`, лишние старые
одиночные НЛО удалены, двойное уменьшение масштаба устранено. Оба набора остаются покадровыми:
`frame_01.png` и `frame_02.png` подключены к `AnimatedSprite2D` и воспроизводятся параллельно
уже выверенному движению. После
contract check, validator и preview smoke актуальные `build/space-pixel.pck` и
`build/active_theme.pck` совпадают: `741032` bytes, SHA-256
`E97F95F544BC257CB309789FD67585F93FFD1569F5662FE78ACCE7E7D0193D8A`.
Эта же PCK установлена в `%APPDATA%/Godot/app_userdata/Exchanger/theme_dlc/active_theme.pck`;
runtime-журнал Exchanger подтвердил активацию внешней темы `space-pixel` без fallback и
theme/resource-ошибок, а контрольный кадр `720×1280` — корректную отрисовку Home.
- 2 сентября 2026 года runtime-проверка нового двустороннего контроллера подтвердила смену
направления `1 → -1`, `flip_h`, новую случайную высоту и продолжающуюся смену кадров.
Contract check, validator, preview smoke и PCK smoke прошли; PCK smoke инстанцировал девять
экранов и 18 scripted node instances. `build/space-pixel.pck`, `build/active_theme.pck` и
установленная пользовательская копия совпадают: `741708` bytes, SHA-256
`5034C3DB1DA44565ED45F682757C03E44D238ABDB1A0B2947F371A98C80C10BB`. Exchanger загрузил
package-скрипт на всех девяти экранах; Home runtime подтвердил обратный пролёт, новую высоту
и продолжающуюся покадровую анимацию без ошибок журнала.
- Два статичных НЛО возле цены дополнены независимым мягким вертикальным покачиванием. Builder
runtime зафиксировал для левого позиции `132 → 133 → 127`, для правого `81 → 88 → 85` при
исходных `y=130/83`; исходная композиция и Nearest-фильтрация сохранены. Contract check,
validator, preview smoke и PCK smoke прошли; PCK smoke подтвердил 9 экранов и 19 scripted node
instances. Собранная, активная и установленная PCK совпадают: `743376` bytes, SHA-256
`1646AA10C8DD5EA9AE70FA21040507889FC1719FF26E122464E105E9D2012AFE`. Живой Exchanger загрузил
`home_ufo_bobbing.gd` из package и подтвердил движение обоих НЛО без ошибок журнала.
- Для нижнего двухкадрового баннера Cash устранён скачок размера НЛО: исходные цветные области
`263×167` и `257×163 px` нормализуются runtime-трансформацией второго кадра. Принудительная
проверка `frame=0/1` подтвердила полностью одинаковые экранные bounds обоих кадров; autoplay
продолжает переключать изображения с исходной скоростью `1 fps`.
- 7 сентября три клипа ходьбы и их sprite-sheet получили актуальные имена:
`walking_right_stop`, `walking_left_stop` и `walking_left_start`. Semantic actions приложения
остались прежними и теперь сопоставлены новым клипам; `walking_start_right` завершает симметричную
пару стартовых состояний.
Contract check, validator, pet verifier, preview smoke, build и PCK smoke прошли. Итоговые
`build/space-pixel.pck` и `build/active_theme.pck` совпадают: `1658512` bytes, SHA-256
`76518563591159EC4B8087911D2BB29924BC29C12AAA4FF1544D97ED01648E91`.
- 14 сентября у кнопки «ВЫБРАТЬ И ДОБАВИТЬ ПРОМО-РОЛИК» в SETTINGS задан явный кегль `17 px`.
До исправления inherited-кегль создавал минимальную ширину кнопки `636 px` и растягивал все
видимые панели раздела «ПРОМО» до `742 px`; после исправления минимум кнопки равен `365 px`,
поэтому панели укладываются в стандартные `664 px` между боковыми полями экрана `720×1280`.
Contract check, validator/preview smoke и build прошли. Итоговые `build/space-pixel.pck` и
`build/active_theme.pck` совпадают: `1700400` bytes, SHA-256
`8082656B3F8DBAA74D6FC55659FDE99D636BF4A626BCECA99F93BA8C9123ECF7`.
- Production-ресурсы используют относительные ссылки внутри `package/`. Если Godot Editor
пересохранил их как `res://themes/space-pixel/package/...`, перед validator/build нужно вернуть
относительные пути, иначе изолированный workspace не найдёт ассеты.
TTF идентифицирует себя как `VCR OSD Mono [RUS by Daymarius]`, но не содержит copyright/license
metadata. Автор оригинального VCR OSD Mono публично разрешил коммерческое использование; для
кириллической модификации первичное разрешение не найдено. Текущий файл допустим для внутренней
темы, но перед публичным распространением требуется письменное подтверждение Daymarius либо замена.