Добавить общую систему весовых объектов

This commit is contained in:
2026-08-19 07:40:11 +03:00
parent 19bb64edfb
commit 259fcd316b
32 changed files with 1017 additions and 34 deletions
+31 -2
View File
@@ -1,8 +1,8 @@
# Графы решений уровней 1–16
# Графы решений уровней 1–17
Документ фиксирует **авторский маршрут** каждого уровня текущего vertical slice. Он получен из `LevelCatalog`, моделей `LevelDefinition` и фактической логики `GameView`, затем проверен device-level ботами через production-команды движения и прыжка. `targetDeaths` ниже — целевое число жертв для результата уровня, но оно не доказывает минимальность решения.
На 19 августа 2026 года intended route всех уровней 1–16 автоматически выполнен по три раза подряд без retry masking. Device-тесты управляют production `GameView` через те же флаги, что и touch-контролы. Для уровня 8 отдельно проверено восстановление после истечения таймера на дальней стороне `PIT`.
На 19 августа 2026 года intended route всех уровней 1–17 автоматически выполнен по три раза подряд без retry masking. Device-тесты управляют production `GameView` через те же флаги, что и touch-контролы. Для уровня 8 отдельно проверено восстановление после истечения таймера на дальней стороне `PIT`.
## Семантика, общая для графов
@@ -405,6 +405,35 @@ Moving bridge над PIT управляется signal "burn-weight"
и нижней координатой моста. Save version 3 сохраняет флаг; Canvas добавляет
текстовую метку `BURNED`, поэтому состояние не кодируется только цветом.
## Уровень 17 — `The Whole Weight`
**Статус:** доказан production-input ботом, 3/3 последовательных прохождения.
**Ожидаемые и доказанные смерти:** `0`; дверь обязана удерживаться только
физическими объектами после отпускания player input.
```text
Door требует signal "weight-gate" с requiredMass=9
→ на PRESSURE уже стоят Box(1), Rock(2), Ball(1) и IceBlock(2): сумма 6
→ Counterweight(3) находится слева от плиты, поэтому Door закрыта
→ игрок подходит и толкает Counterweight вправо
→ при x≥920 Counterweight пересекает plate x=1000..1650
→ общий IWeightedObject resolver получает массу 6+3=9 и открывает Door
→ игрок отпускает input; объект продолжает удерживать сигнал без player mass
→ игрок двумя отдельными прыжками пересекает Counterweight и ряд объектов
→ проходит открытую Door и достигает goal
→ COMPLETE без смерти и без создания тел
```
**Контракт:** `Player`, `CorpseManager.Body` и `PhysicalObjectState` реализуют
один `IWeightedObject`; plate агрегирует только геометрически пересекающуюся
активную массу, не проверяя тип. Все пять authored типов имеют type/box/mass в
JSON, детерминированный runtime, non-color type+weight label, SVG/TSV preview и
save-v4 состояние. V1–v3 active sessions мигрируют с пустым runtime-object list.
**Bot checkpoints:** каталог публикует пять objects и Counterweight mass 3;
до push `allDoorsOpen=false`; после push `firstPhysicalObjectX≥920` и Door open;
после release Door остаётся open; затем два отдельных jump edge и `completed=true`.
## Проверки, следующие из графов
1. Сохранять полный integrated device-regression: intended route принятых уровней по три раза и отдельный recovery route уровня 8.