Добавить общую систему весовых объектов
This commit is contained in:
+11
-1
@@ -160,6 +160,13 @@ baseline-задачи также имели явного владельца по
|
||||
переход дальше; границы доступного human evidence зафиксированы в
|
||||
`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, после него начинается массовое производство четырёх
|
||||
миров.
|
||||
|
||||
### Этап 6. Production content — P1, несколько итераций
|
||||
|
||||
Задачи:
|
||||
@@ -191,7 +198,10 @@ data-driven модель. Завершён первый mechanics slice: product
|
||||
99 JVM-тестов и Android 16 matrix `43/43` (`2004.172 s`). Следующая зависимая
|
||||
итерация завершена: `CRUSHED` и `BURNED`, save migration и обучающие уровни
|
||||
15–16 приняты clean gate `102 JVM` и unfiltered Android matrix `46/46`
|
||||
(`1,842.248 s`). Доказательства зафиксированы в `STAGE6_CORPSE_STATES.md`.
|
||||
(`1,842.248 s`). Weighted-object slice также принят: общий `IWeightedObject`,
|
||||
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`.
|
||||
|
||||
### Этап 7. Техническая стабилизация и release engineering — P0, 4–8 дней
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Назначение
|
||||
|
||||
Все десять уровней находятся в Android-independent модуле `level-format` и
|
||||
Все уровни каталога находятся в Android-independent модуле `level-format` и
|
||||
загружаются из `level-format/src/main/resources/levels`. Runtime, unit-тесты и
|
||||
desktop-команды используют один и тот же JSON parser, catalog loader и validator.
|
||||
Изменение геометрии или текста не требует изменения игрового Java-кода.
|
||||
@@ -48,6 +48,9 @@ desktop-команды используют один и тот же JSON parser,
|
||||
"spawn": {"x": 130, "y": 760},
|
||||
"goal": {"x": 1810, "y": 770, "width": 86, "height": 110},
|
||||
"targets": {"deaths": 1, "seconds": 50},
|
||||
"objects": [
|
||||
{"type": "COUNTERWEIGHT", "box": {"x": 300, "y": 780, "width": 80, "height": 100}, "mass": 3}
|
||||
],
|
||||
"platforms": [
|
||||
{"box": {"x": 0, "y": 880, "width": 2050, "height": 200}}
|
||||
],
|
||||
@@ -68,7 +71,10 @@ desktop-команды используют один и тот же JSON parser,
|
||||
|
||||
Поддерживаемые значения:
|
||||
|
||||
- hazards: `SPIKES`, `SAW`, `FREEZER`, `ELECTRIC`, `PIT`;
|
||||
- hazards: `SPIKES`, `SAW`, `FREEZER`, `ELECTRIC`, `PIT`, `CRUSHER`, `FIRE`,
|
||||
`PROJECTILE`, `EXPLOSION`;
|
||||
- physical objects: `BOX`, `ROCK`, `BALL`, `ICE_BLOCK`, `COUNTERWEIGHT`; каждый
|
||||
задаёт `box` и положительный integer `mass`;
|
||||
- switches: `PRESSURE`, `TOGGLE`, `TIMED`;
|
||||
- static platform: только `box`;
|
||||
- moving platform: `box`, ненулевой `travelX` или `travelY`, положительный
|
||||
@@ -82,7 +88,7 @@ desktop-команды используют один и тот же JSON parser,
|
||||
|
||||
- известные format/physics versions;
|
||||
- конечные положительные размеры мира и объектов;
|
||||
- spawn, goal, платформы, hazards, switches, doors и конечную позицию moving
|
||||
- spawn, goal, physical objects, платформы, hazards, switches, doors и конечную позицию moving
|
||||
platform внутри мира;
|
||||
- наличие хотя бы одной платформы;
|
||||
- неотрицательный target deaths и положительный target seconds;
|
||||
@@ -115,9 +121,9 @@ level-03.json.doors[0].requiredSignals[0] references missing signal 'missing'
|
||||
|
||||
Результат находится в `level-format/build/level-previews`:
|
||||
|
||||
- `level-01.svg` … `level-10.svg` — world-space схема spawn/goal, платформ,
|
||||
hazards, switches и doors;
|
||||
- `catalog.tsv` — координаты, размеры, travel и signal/control references.
|
||||
- `level-01.svg` … последний уровень каталога — world-space схема spawn/goal,
|
||||
objects, платформ, hazards, switches и doors;
|
||||
- `catalog.tsv` — координаты, размеры, object mass, travel и signal/control references.
|
||||
|
||||
Вывод использует стабильный порядок и locale-independent числа. Два запуска на
|
||||
неизменном каталоге должны давать byte-identical файлы.
|
||||
@@ -136,4 +142,3 @@ Wall-clock, device identifiers и прямые mutation-команды не за
|
||||
`traceId` — SHA-256 точного UTF-8 JSON и всегда включён в failure diagnostic.
|
||||
Stage 4 сохраняет воспроизводимый артефакт расследования, но намеренно не добавляет
|
||||
runtime replay executor.
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
# Stage 6 weighted objects
|
||||
|
||||
Date: 19 August 2026
|
||||
|
||||
Beads task: `goon-game-weighted-objects`
|
||||
|
||||
## Contract
|
||||
|
||||
`IWeightedObject` is the only pressure-mass contract. It exposes world geometry,
|
||||
integer pressure mass, and whether the object may activate a mechanism. The live
|
||||
player, retained corpse bodies, and authored physical objects implement it;
|
||||
`PressureMassResolver` knows no concrete object types.
|
||||
|
||||
The version-1 level schema now accepts an optional `objects` array with a strict
|
||||
`type`, `box`, and positive `mass`. Supported production types are `BOX`, `ROCK`,
|
||||
`BALL`, `ICE_BLOCK`, and `COUNTERWEIGHT`, matching the Beads scope. Existing JSON
|
||||
without `objects` stays source-compatible. Validation, deterministic SVG/TSV
|
||||
preview, Canvas rendering, collision/push physics, moving-platform support,
|
||||
automation and performance accounting all consume the same definitions.
|
||||
|
||||
Active-session save version 4 stores object type, geometry, velocity, mass,
|
||||
grounding and moving-platform support. V1–v3 decode with an empty runtime object
|
||||
list; levels from those versions had no authored physical objects, so restore
|
||||
uses the level's initial definitions without inventing state.
|
||||
|
||||
## Teaching puzzle
|
||||
|
||||
Level 17, `The Whole Weight`, places Box(1), Rock(2), Ball(1), and IceBlock(2) on
|
||||
a pressure plate. Their total 6 cannot open the mass-9 door. The player must push
|
||||
Counterweight(3) onto the plate, release input to prove object-only retention,
|
||||
then jump across the weighted row and pass the open door.
|
||||
|
||||
## TDD and acceptance evidence
|
||||
|
||||
- RED: missing `IWeightedObject`/resolver and all JSON object symbols (28 compile
|
||||
errors); GREEN: shared pure mass aggregation and five parsed types.
|
||||
- RED: missing runtime/save-v4 symbols (13 compile errors); GREEN: deterministic
|
||||
state, corpse interface parity, v4 round-trip and v1–v3 migrations.
|
||||
- RED: catalog expected 17 but contained 16; GREEN: validator `17/17` and bounded
|
||||
two-page pagination.
|
||||
- RED: Android scenario class absent; GREEN: compiled production-input route.
|
||||
- RED: preview lacked object geometry; GREEN: byte-stable SVG and TSV include
|
||||
object type and mass.
|
||||
- Focused push/door/save integration: `1/1` GREEN in `9.128 s`.
|
||||
- Level 17 intended route: `3/3` GREEN in `31.119 s`, exact zero deaths/bodies.
|
||||
- Focused player/corpse/object pressure and restore matrix: `8/8` GREEN in
|
||||
`315.926 s`.
|
||||
- Clean gate: app JVM `108/108`, content-tool JVM `2/2`, validator `17/17`,
|
||||
lint, app APK and test APK GREEN.
|
||||
- Final exact-candidate unfiltered Android matrix: `48/48` GREEN in
|
||||
`2,223.695 s`, with zero failures and zero skipped tests.
|
||||
- Debug APK ZIP/signature: GREEN; packaged level JSON count: `17`.
|
||||
- Debug APK SHA-256:
|
||||
`141eecd3605d5cc5ab8ac20b52b666650b672c0723e2a3f8ea2187e75adca002`.
|
||||
@@ -65,7 +65,7 @@ Snapshot на 19 августа 2026 года:
|
||||
| 3 | 5 | 0 |
|
||||
| 4 | 4 | 0 |
|
||||
| 5 | 15 | 0 |
|
||||
| 6 | 18 | 10 |
|
||||
| 6 | 18 | 8 |
|
||||
| 7 | 9 | 9 |
|
||||
| 8 | 1 | 1 |
|
||||
| 9 | 1 | 1 |
|
||||
|
||||
Reference in New Issue
Block a user