Добавить production-состояния тел
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# Графы решений уровней 1–10
|
||||
# Графы решений уровней 1–16
|
||||
|
||||
Документ фиксирует **авторский маршрут** каждого уровня текущего vertical slice. Он получен из `LevelCatalog`, моделей `LevelDefinition` и фактической логики `GameView`, затем проверен device-level ботами через production-команды движения и прыжка. `targetDeaths` ниже — целевое число жертв для результата уровня, но оно не доказывает минимальность решения.
|
||||
|
||||
На 18 августа 2026 года intended route всех уровней 1–10 автоматически выполнен по три раза подряд без retry masking. `EarlyLevelPlaythroughTest`, `LevelFivePlaythroughTest`, `LateLevelPlaythroughTest` и `LevelEightPlaythroughTest` управляют production `GameView` через те же флаги, что и touch-контролы. Для уровня 8 отдельно проверено восстановление после истечения таймера на дальней стороне `PIT`.
|
||||
На 19 августа 2026 года intended route всех уровней 1–16 автоматически выполнен по три раза подряд без retry masking. Device-тесты управляют production `GameView` через те же флаги, что и touch-контролы. Для уровня 8 отдельно проверено восстановление после истечения таймера на дальней стороне `PIT`.
|
||||
|
||||
## Семантика, общая для графов
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
- `TIMED` запускает таймер только на фронте контакта; удержание на переключателе не перезапускает истёкший таймер.
|
||||
- `Door.requiredSignals` использует AND-семантику: дверь открыта, только когда активны все указанные сигналы.
|
||||
- Управляемая движущаяся платформа накапливает `motionTime` только при активном `controlId`; при потере сигнала она замирает в текущей фазе `GameMath.pingPong`.
|
||||
- `SPIKES` оставляет закреплённое тело над шипами; `SAW` передаёт телу `impulseX`/`impulseY`; `FREEZER` создаёт неподвижный блок `104×104`; `ELECTRIC` оставляет закреплённое проводящее тело внутри опасности; `PIT` тела не оставляет.
|
||||
- `SPIKES` оставляет закреплённое тело над шипами; `SAW` передаёт телу `impulseX`/`impulseY`; `FREEZER` создаёт неподвижный блок `104×104`; `ELECTRIC` оставляет закреплённое проводящее тело внутри опасности; `CRUSHER` создаёт низкое `CRUSHED`-тело; `FIRE` оставляет твёрдое `BURNED`-тело без pressure mass; `PIT` тела не оставляет.
|
||||
- Тела являются твёрдыми опорами для игрока. Смерть сохраняет тела и состояния уровня, respawn возвращает нового игрока в `spawnX`/`spawnY`; restart очищает состояние.
|
||||
- Пересечение живого игрока с `goal` переводит сцену в `COMPLETE`.
|
||||
|
||||
@@ -360,6 +360,51 @@ Door требует signal "blast-gate" от удалённой PRESSURE
|
||||
доказал перелёт тела за плиту; минимальное authored значение `550` стабильно
|
||||
помещает тело в `firstCorpseX=980`, после чего `allDoorsOpen=true`.
|
||||
|
||||
## Уровень 15 — `Pressed Into Service`
|
||||
|
||||
**Статус:** доказан production-input ботом, 3/3 последовательных прохождения.
|
||||
**Ожидаемые и доказанные смерти:** `1`; сохранённое тело обязано иметь состояние
|
||||
`CRUSHED`, размер `140×24` и оставаться твёрдой опорой.
|
||||
|
||||
```text
|
||||
Верхний ledge начинается на высоте y=720 и недоступен прыжком с floor
|
||||
→ первый доброволец входит в активный CRUSHER
|
||||
→ пресс превращает тело в низкую закреплённую плиту 140×24
|
||||
→ следующий доброволец наблюдает новый активный цикл и ждёт REST
|
||||
→ проходит безопасный пресс и приземляется на crushed body
|
||||
→ отдельным прыжком использует 24 px ступень для достижения ledge
|
||||
→ проходит по верхней платформе к goal
|
||||
→ COMPLETE ровно с одной смертью и одним crushed body
|
||||
```
|
||||
|
||||
**Контракт:** `CRUSHED` композиционно сохраняется в `CorpseManager`, уменьшает
|
||||
коллайдер и не удаляет физическую опору. Save version 3 сохраняет флаг; v1/v2
|
||||
мигрируют его в `false`. Snapshot отдельно публикует state, размеры и pressure
|
||||
capability, а Canvas добавляет текстовую метку `CRUSHED` помимо цвета.
|
||||
|
||||
## Уровень 16 — `Ashen Counterweight`
|
||||
|
||||
**Статус:** доказан production-input ботом, 3/3 последовательных прохождения.
|
||||
**Ожидаемые и доказанные смерти:** `1`; сохранённое тело обязано иметь состояние
|
||||
`BURNED`, оставаться твёрдым и не активировать `PRESSURE`.
|
||||
|
||||
```text
|
||||
Moving bridge над PIT управляется signal "burn-weight"
|
||||
→ первый доброволец пересекает PRESSURE и погибает в FIRE над плитой
|
||||
→ burned body остаётся на плите как твёрдый объект
|
||||
→ burned body не даёт pressure mass: signal остаётся inactive
|
||||
→ мост остаётся в нижней фазе у y≈840 вместо подъёма
|
||||
→ следующий доброволец перепрыгивает FIRE и burned body
|
||||
→ садится на неподвижный мост и пересекает PIT
|
||||
→ достигает goal на правом floor
|
||||
→ COMPLETE ровно с одной смертью и одним burned body
|
||||
```
|
||||
|
||||
**Контракт:** `BURNED` сохраняет коллайдер, но `activatesPressure=false`; это
|
||||
проверяется одновременно состоянием тела, неактивным `firstMovingPlatformPowered`
|
||||
и нижней координатой моста. Save version 3 сохраняет флаг; Canvas добавляет
|
||||
текстовую метку `BURNED`, поэтому состояние не кодируется только цветом.
|
||||
|
||||
## Проверки, следующие из графов
|
||||
|
||||
1. Сохранять полный integrated device-regression: intended route принятых уровней по три раза и отдельный recovery route уровня 8.
|
||||
|
||||
Reference in New Issue
Block a user