Добавить production-состояния тел
This commit is contained in:
@@ -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 дней
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
@@ -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 |
|
||||
|
||||
Reference in New Issue
Block a user