Добавить испытания и прогрессию по LevelID
This commit is contained in:
+10
-4
@@ -161,10 +161,11 @@ baseline-задачи также имели явного владельца по
|
||||
`STAGE5_HUMAN_PLAYTEST_RESULT.md`. Stage 6 разблокирован.
|
||||
|
||||
Текущий статус Stage 6: foundation, production hazards, burned/crushed corpse
|
||||
states и weighted objects приняты. Каталог содержит 17 уровней; последний exact
|
||||
candidate прошёл `108` app JVM, `2` content-tool JVM и нефильтрованную Android 16
|
||||
матрицу `48/48` за `2,223.695 s`. Следующий dependency-order slice — challenges
|
||||
и production progression, после него начинается массовое производство четырёх
|
||||
states, weighted objects и challenge/progression приняты. Каталог содержит 18
|
||||
уровней. Stable `levelId`/`worldId`, casualty/time/cache challenges, progress-v3
|
||||
migration, session-v5 collectible state и persistent three-star result прошли
|
||||
`116` app JVM, `2` content-tool JVM и нефильтрованную Android 16 матрицу `52/52`
|
||||
за `551.773 s`. Следующий dependency-order slice — массовое производство четырёх
|
||||
миров.
|
||||
|
||||
### Этап 6. Production content — P1, несколько итераций
|
||||
@@ -202,6 +203,11 @@ data-driven модель. Завершён первый mechanics slice: product
|
||||
Box/Rock/Ball/IceBlock/Counterweight, save v4 и обучающий уровень 17 прошли clean
|
||||
gate `108` app JVM + `2` content-tool JVM и unfiltered Android matrix `48/48`
|
||||
(`2,223.695 s`). Evidence зафиксирован в `STAGE6_WEIGHTED_OBJECTS.md`.
|
||||
Challenge/progression slice также принят: stable level/world IDs, три независимых
|
||||
challenge-критерия, optional collectible, накопительные лучшие звёзды по `levelId`,
|
||||
progress v1/v2 → v3 и active-session v4 → v5 migration, result UI и обучающий
|
||||
уровень 18 прошли clean gate `116` app JVM + `2` content-tool JVM и unfiltered
|
||||
Android matrix `52/52` (`551.773 s`). Evidence — `STAGE6_CHALLENGES.md`.
|
||||
|
||||
### Этап 7. Техническая стабилизация и release engineering — P0, 4–8 дней
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Графы решений уровней 1–17
|
||||
# Графы решений уровней 1–18
|
||||
|
||||
Документ фиксирует **авторский маршрут** каждого уровня текущего vertical slice. Он получен из `LevelCatalog`, моделей `LevelDefinition` и фактической логики `GameView`, затем проверен device-level ботами через production-команды движения и прыжка. `targetDeaths` ниже — целевое число жертв для результата уровня, но оно не доказывает минимальность решения.
|
||||
|
||||
На 19 августа 2026 года intended route всех уровней 1–17 автоматически выполнен по три раза подряд без retry masking. Device-тесты управляют production `GameView` через те же флаги, что и touch-контролы. Для уровня 8 отдельно проверено восстановление после истечения таймера на дальней стороне `PIT`.
|
||||
На 19 августа 2026 года intended route всех уровней 1–18 автоматически выполнен по три раза подряд без retry masking. Device-тесты управляют production `GameView` через те же флаги, что и touch-контролы. Для уровня 8 отдельно проверено восстановление после истечения таймера на дальней стороне `PIT`.
|
||||
|
||||
## Семантика, общая для графов
|
||||
|
||||
@@ -434,6 +434,34 @@ save-v4 состояние. V1–v3 active sessions мигрируют с пус
|
||||
до push `allDoorsOpen=false`; после push `firstPhysicalObjectX≥920` и Door open;
|
||||
после release Door остаётся open; затем два отдельных jump edge и `completed=true`.
|
||||
|
||||
## Уровень 18 — `Threefold Proof`
|
||||
|
||||
**Статус:** доказан production-input ботом, 3/3 последовательных прохождения.
|
||||
**Ожидаемые и доказанные смерти:** `0`; обязательный challenge-route получает
|
||||
casualty, time и collectible stars.
|
||||
|
||||
```text
|
||||
LevelID="foundations.threefold-proof", WorldID="foundations"
|
||||
→ игрок проходит безопасный teaching floor без смертей
|
||||
→ у x≈650 начинает прыжок к cache=(850,650,58,58)
|
||||
→ пересекает cache: collectibleFound=true, cache исчезает только для этой попытки
|
||||
→ продолжает вправо и достигает goal x=2000..2086
|
||||
→ COMPLETE с deaths=0 и time≤30 s
|
||||
→ ChallengeResult выдаёт casualty/time/collectible = true, stars=3
|
||||
→ ProgressStore сохраняет лучшие критерии по стабильному LevelID
|
||||
→ три последовательных restart-free прохождения воспроизводят 3/3 stars
|
||||
```
|
||||
|
||||
**Контракт:** collectible является опциональным world-space объектом и сохраняется
|
||||
в active session v5. Restart сбрасывает состояние текущей попытки; завершённый
|
||||
collectible challenge накапливается в progress v3 независимо от лучших casualty и
|
||||
time runs. Legacy levels без collectible получают третью звезду за core completion.
|
||||
|
||||
**Bot checkpoints:** `deaths=0`; после прыжка `collectibleFound=true` и
|
||||
`collectibleVisible=false`; затем `completed=true`; `CompletionResult.stars=3`,
|
||||
`bestStars=3`; новый `ProgressStore` после трёх запусков возвращает 3 звезды для
|
||||
`foundations.threefold-proof`.
|
||||
|
||||
## Проверки, следующие из графов
|
||||
|
||||
1. Сохранять полный integrated device-regression: intended route принятых уровней по три раза и отдельный recovery route уровня 8.
|
||||
|
||||
@@ -39,6 +39,8 @@ desktop-команды используют один и тот же JSON parser,
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"physicsVersion": 1,
|
||||
"id": "foundations.dead-weight",
|
||||
"worldId": "foundations",
|
||||
"number": 3,
|
||||
"copy": {
|
||||
"en": {"title": "Dead Weight", "hint": "Leave a body on the plate."},
|
||||
@@ -47,6 +49,7 @@ desktop-команды используют один и тот же JSON parser,
|
||||
"world": {"width": 2050, "height": 1080},
|
||||
"spawn": {"x": 130, "y": 760},
|
||||
"goal": {"x": 1810, "y": 770, "width": 86, "height": 110},
|
||||
"collectible": {"x": 850, "y": 650, "width": 58, "height": 58},
|
||||
"targets": {"deaths": 1, "seconds": 50},
|
||||
"objects": [
|
||||
{"type": "COUNTERWEIGHT", "box": {"x": 300, "y": 780, "width": 80, "height": 100}, "mass": 3}
|
||||
@@ -71,6 +74,11 @@ desktop-команды используют один и тот же JSON parser,
|
||||
|
||||
Поддерживаемые значения:
|
||||
|
||||
- `id` — стабильный lowercase level ID; `worldId` — стабильный lowercase world ID.
|
||||
Legacy JSON без этих полей получает `legacy.level-NN` и `legacy`, поэтому старые
|
||||
сохранения мигрируют без потери;
|
||||
- `collectible` — опциональный world-space `box`. Его отсутствие означает, что
|
||||
третья звезда выдаётся за основное прохождение, а не становится недостижимой;
|
||||
- hazards: `SPIKES`, `SAW`, `FREEZER`, `ELECTRIC`, `PIT`, `CRUSHER`, `FIRE`,
|
||||
`PROJECTILE`, `EXPLOSION`;
|
||||
- physical objects: `BOX`, `ROCK`, `BALL`, `ICE_BLOCK`, `COUNTERWEIGHT`; каждый
|
||||
@@ -88,7 +96,7 @@ desktop-команды используют один и тот же JSON parser,
|
||||
|
||||
- известные format/physics versions;
|
||||
- конечные положительные размеры мира и объектов;
|
||||
- spawn, goal, physical objects, платформы, hazards, switches, doors и конечную позицию moving
|
||||
- стабильные `id`/`worldId`, spawn, goal, optional collectible, physical objects, платформы, hazards, switches, doors и конечную позицию moving
|
||||
platform внутри мира;
|
||||
- наличие хотя бы одной платформы;
|
||||
- неотрицательный target deaths и положительный target seconds;
|
||||
@@ -96,7 +104,8 @@ desktop-команды используют один и тот же JSON parser,
|
||||
`TIMED`;
|
||||
- существование каждого `door.requiredSignals` и `platform.controlId` среди
|
||||
сигналов switches/relays;
|
||||
- целостность index, уникальность ресурсов и последовательную нумерацию.
|
||||
- целостность index, уникальность ресурсов и stable level IDs, последовательную
|
||||
нумерацию.
|
||||
|
||||
Ошибка содержит путь, например:
|
||||
|
||||
@@ -122,7 +131,7 @@ level-03.json.doors[0].requiredSignals[0] references missing signal 'missing'
|
||||
Результат находится в `level-format/build/level-previews`:
|
||||
|
||||
- `level-01.svg` … последний уровень каталога — world-space схема spawn/goal,
|
||||
objects, платформ, hazards, switches и doors;
|
||||
collectible, objects, платформ, hazards, switches и doors;
|
||||
- `catalog.tsv` — координаты, размеры, object mass, travel и signal/control references.
|
||||
|
||||
Вывод использует стабильный порядок и locale-independent числа. Два запуска на
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# Stage 6: challenges, collectibles и production progression
|
||||
|
||||
## Принятый результат
|
||||
|
||||
Срез добавляет стабильную идентичность уровня и три независимых production
|
||||
challenge-критерия: целевое число жертв, целевое время и collectible. Лучший
|
||||
результат накапливается между разными прохождениями и отображается как 0–3 звезды.
|
||||
|
||||
Каталог расширен до 18 уровней. `Threefold Proof` обучает всем трём критериям на
|
||||
одном безопасном маршруте; intended route выполняется production-input ботом три
|
||||
раза подряд без teleport, прямой мутации completion или retry masking.
|
||||
|
||||
## Контракты
|
||||
|
||||
- `LevelDefinition.levelId` и `worldId` являются стабильными lowercase ID.
|
||||
Legacy-контент без полей получает `legacy.level-NN` / `legacy`.
|
||||
- Optional `collectible` — world-space box. После пересечения он исчезает в текущей
|
||||
попытке, сохраняется при Activity recreation и сбрасывается restart.
|
||||
- `ChallengeResult` независимо вычисляет casualty, time и collectible criteria.
|
||||
На legacy-уровне без collectible третья звезда означает core completion.
|
||||
- `ProgressStore` save v3 хранит completion, лучшие deaths/time и collectible по
|
||||
`levelId`. V1/V2 numeric keys мигрируют в ID keys без потери данных.
|
||||
- Active session v5 сохраняет `collectibleFound`; V4 и более старые snapshots
|
||||
восстанавливаются с безопасным `false`.
|
||||
- Result UI и level cards показывают лучший star row. Complete screen сохраняет
|
||||
Stage 3 строки Current/Best/Targets, добавляет три challenge rows и следующую
|
||||
цель. RU/EN и non-color labels являются частью контракта.
|
||||
- SVG/TSV exporter публикует collectible и LevelID; validator проверяет ID и
|
||||
границы collectible до упаковки APK.
|
||||
|
||||
## TDD и найденные регрессии
|
||||
|
||||
RED сначала зафиксировали отсутствующие `ChallengeResult`, stable IDs, JSON schema,
|
||||
ID-based persistence, session collectible, completion/UI copy, catalog level 18 и
|
||||
exporter output. Review добавил отдельный RED на duplicate stable LevelID: catalog
|
||||
loader теперь отклоняет конфликт до того, как два уровня разделят progress key.
|
||||
Каждый контракт проводился в GREEN отдельно.
|
||||
|
||||
Первый полный Android run (`52` tests) нашёл ещё два интеграционных RED:
|
||||
|
||||
1. Stage 3 result snapshot потерял локализованный prefix `Цели` после добавления
|
||||
challenge rows. Prefix и видимая строка targets восстановлены.
|
||||
2. Real-time late-level driver мог пропустить узкое окно пилы уровня 10 между
|
||||
двумя AVD polls. Late-level acceptance переведён на существующие fixed production
|
||||
physics ticks: обычное решение принимает решения каждые 16 ms симуляции, stress
|
||||
сохраняет 96 ms. Физика, input, collision, точные смерти и geometry не менялись.
|
||||
|
||||
После исправления вся late-level matrix прошла `6/6`; level 10 normal выполняется
|
||||
три раза, отдельный stress route — один раз.
|
||||
|
||||
Один предварительный повтор после нескольких непрерывных full runs получил
|
||||
environmental `frameP95=41.02 ms`; тот же неизменённый APK сразу прошёл
|
||||
изолированный 34-ms gate. Финальный exact run выполнен после cold AVD restart на
|
||||
host GPU и прошёл performance test внутри полного порядка. Бюджет не ослаблялся.
|
||||
|
||||
## Финальные gates
|
||||
|
||||
На Android 16 ARM64 candidate:
|
||||
|
||||
- `:level-format:test`: `2/2`;
|
||||
- `testDebugUnitTest`: `116/116`;
|
||||
- `lintDebug`, `assembleDebug`, `assembleDebugAndroidTest`: GREEN после `clean`;
|
||||
- validator: `18` levels, `formatVersion=1`, `physicsVersion=1`;
|
||||
- focused challenge/restore/result matrix: `9/9`;
|
||||
- exact unfiltered instrumentation: `OK (52 tests)`, `551.773 s`;
|
||||
- APK ZIP integrity: no errors; внутри APK `18` level JSON;
|
||||
- debug APK SHA-256:
|
||||
`0b70a0a1a508425c311d7de473318e3bb83407f5f27e9dd4a8e1876b2eb25344`.
|
||||
|
||||
APK: `app/build/outputs/apk/debug/app-debug.apk`.
|
||||
@@ -65,7 +65,7 @@ Snapshot на 19 августа 2026 года:
|
||||
| 3 | 5 | 0 |
|
||||
| 4 | 4 | 0 |
|
||||
| 5 | 15 | 0 |
|
||||
| 6 | 18 | 8 |
|
||||
| 6 | 18 | 6 |
|
||||
| 7 | 9 | 9 |
|
||||
| 8 | 1 | 1 |
|
||||
| 9 | 1 | 1 |
|
||||
|
||||
Reference in New Issue
Block a user