Добавить production-состояния тел

This commit is contained in:
2026-08-19 06:34:40 +03:00
parent dc2ebcbf8c
commit 19bb64edfb
21 changed files with 580 additions and 31 deletions
+3 -1
View File
@@ -189,7 +189,9 @@ data-driven модель. Завершён первый mechanics slice: product
(`crusher`, `fire`, `projectile`, `explosion`), обучающие уровни 11–14,
динамическая пагинация каталога и 12/12 bot-прохождений. Последний gate:
99 JVM-тестов и Android 16 matrix `43/43` (`2004.172 s`). Следующая зависимая
итерация — новые corpse states на источниках production hazards.
итерация завершена: `CRUSHED` и `BURNED`, save migration и обучающие уровни
15–16 приняты clean gate `102 JVM` и unfiltered Android matrix `46/46`
(`1,842.248 s`). Доказательства зафиксированы в `STAGE6_CORPSE_STATES.md`.
### Этап 7. Техническая стабилизация и release engineering — P0, 4–8 дней
+48 -3
View File
@@ -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.
+64
View File
@@ -0,0 +1,64 @@
# Stage 6 production corpse states
Date: 19 August 2026
Beads task: `goon-game-corpse-states`
## Contract
The accepted `CorpseManager` transformations now include two production states:
- `CRUSHED`: a pinned `140×24` solid body whose changed collider creates a low
step without becoming a full-height wall;
- `BURNED`: a solid retained body that no longer contributes pressure mass.
Both transformations compose with existing body ownership and pinning, have
distinct non-color Canvas labels, are exposed through read-only automation, and
are serialized in active-session save version 3. Legacy version 1 and version 2
sessions migrate both flags to `false`; progress save versioning is unchanged.
This is the complete set of new gameplay states approved by the GDD. `IsDestroyed`
is a lifecycle field in the corpse data model, not a listed corpse-state variant;
the plan does not define a separate `Shattered` state.
Level 15 teaches the collider difference by requiring the crushed slab to reach
an otherwise inaccessible ledge. Level 16 teaches the mechanism difference by
requiring a burned body to remain on a pressure plate without powering the
bridge above a pit. Normal, pinned, frozen and conductive states retain their
accepted teaching routes in levels 2/3/5, 6 and 7/9/10 respectively.
## TDD evidence
Focused RED cycles covered the missing transformations and behavior, legacy
codec migration, GameView state publication, catalog growth from 14 to 16, and
both production-input scenarios. Device RED on level 16 showed a small bridge
offset caused by the living volunteer touching the plate before death; the
acceptance was corrected to prove the authored behavior (`powered=false` and a
lower bridge) without requiring an impossible exact initial coordinate.
The focused runtime integration test creates crushed and burned bodies through
real level hazards. Each playthrough test runs its intended route three times,
with no restart or direct game-state mutation, and requires exactly one death
and one retained body.
## Acceptance gates
- JSON validator: `16/16`, format `1`, physics `1`.
- Level 15: `3/3` GREEN in `77.563 s`.
- Level 16: `3/3` GREEN in `32.015 s` after the state-based bridge assertion.
- Runtime state integration: `1/1` GREEN in `1.165 s`.
- Combined corpse-state/hazard/pagination matrix: `8/8` methods GREEN in
`408.438 s` (18 production-input playthroughs plus state and pagination tests).
- Clean gate: `102` JVM tests, failures/errors/skipped `0`; `lintDebug`,
`assembleDebug` and `assembleDebugAndroidTest` GREEN.
- Focused exact-candidate save/restore plus runtime state gate: `3/3` GREEN in
`47.489 s`.
- Final unfiltered Android 16 matrix on the exact clean APK/test APK: `46/46`,
failures `0`, errors `0`, skipped `0`, `1,842.248 s`.
- Debug APK ZIP integrity: GREEN; packaged JSON levels: `16`.
- Package: `com.projectsacrifice.game.debug`, versionCode `9`, minSdk `23`,
targetSdk `34`; APK Signature Scheme v1/v2 verification: GREEN.
- Debug APK SHA-256:
`4984f50aa62203060eb254b69dbf2bdf520ab6cd545eff852d22b10a164bf686`.
The dedicated AVD was stopped after the final gate.
+1 -1
View File
@@ -65,7 +65,7 @@ Snapshot на 19 августа 2026 года:
| 3 | 5 | 0 |
| 4 | 4 | 0 |
| 5 | 15 | 0 |
| 6 | 18 | 12 |
| 6 | 18 | 10 |
| 7 | 9 | 9 |
| 8 | 1 | 1 |
| 9 | 1 | 1 |