Solution: genre-neutral Map Contract
Выбранный подход#
Map authority — directed adjacency graph:
regionsгруппируют visibility и presentation;locations— canonical nodes с optional layout coordinates;edges— единственный источник допустимого direct movement, travel cost, obstacle и LOS;ContentReferenceIndex— read-only граница к adventure content;projectMapForViewerфильтрует authorization и discovery до narrator/UI.
Coordinates не вычисляют движение. Это предотвращает ложный вывод, что две точки рядом на экране обязательно соединены.
Архитектура и поток данных#
MapContract + authoritative content ID index
→ shape/reference/visibility validation
→ static directed reachability
→ accepted contract
├─ viewer + discovered IDs → filtered MapProjection
├─ move request + flags → allow/structured deny + travel cost
└─ LOS request → authorized direct clear edge → boolean
Spatial invariants#
- Region, edge endpoint, start, required location и content refs существуют.
travelCost— положительное конечное число в contract-wide unit.- Conditional obstacle называет хотя бы один required flag.
- Required location достигается из start по направлению потенциально проходимых edges.
- Location visibility не шире parent region.
- Projection включает edge только если viewer авторизован для edge и обоих endpoints и оба endpoints discovered.
- Movement проверяет source/destination authorization до edge/obstacle.
- Private/hidden ID не передаётся narrator/UI projection.
Структура прототипа#
prototype/map-types.ts— contract, projection, move и LOS types.prototype/map.ts— runtime validator, BFS, projection, movement и LOS.prototype/fixtures/sci-fi-comedy-map.ts— original non-canonical topology и authoritative content-ID index fixture.prototype/map.test.ts— positive, mutation, privacy и movement tests.prototype/demo.ts— executable validation/projection/move summary.prototype/README.md— краткие команды.
Требования#
- Проверено: macOS 26.4, Apple Silicon.
- Runtime фактического test path:
/usr/local/bin/nodev22.14.0. - TypeScript выполняется встроенным experimental type stripping.
- Static check: TypeScript 7.0.2 и
@types/node24.13.3 из root toolchain. - Внешние сервисы:
none. - Runtime demo/test не требуют install/network; static check использует установленный root toolchain.
Установка#
Из папки исследования:
node --version
Ожидаемый проверенный runtime: v22.14.0. Prototype не имеет install step.
Запуск#
node --no-warnings --experimental-strip-types prototype/demo.ts
Ожидается validationIssueCount: 0, список пяти structurally reachable
locations, visitor projection только с initial public node и различающиеся
blocked/allowed move results.
Тестирование#
node --no-warnings --experimental-strip-types --test prototype/map.test.ts
Ожидается tests 6, pass 6, fail 0.
Scoped static check из папки исследования:
../../../node_modules/.bin/tsc --ignoreConfig --noEmit --strict \
--noUncheckedIndexedAccess --exactOptionalPropertyTypes --target ES2024 \
--module NodeNext --moduleResolution NodeNext --allowImportingTsExtensions \
--rewriteRelativeImportExtensions --erasableSyntaxOnly --types node \
prototype/*.ts prototype/fixtures/*.ts
Ожидается exit 0 без diagnostics.
Конфигурация#
Environment variables и secrets отсутствуют.
ContentReferenceIndex строится authoritative adventure/encounter layer и
передаётся validator как набор существующих IDs. Map contract не создаёт эти
сущности.
Ограничения и безопасность#
- Static BFS включает conditional edges как потенциальные и исключает только
blocked; inventory/flag attainability не моделируется. - LOS — свойство direct edge, без polygon/raycast geometry.
- Prototype не проверяет state version, simultaneous moves или persistence.
- Coordinates — presentation hints, не authoritative distance.
- Node v22 type stripping experimental; static checking выполняется отдельно.
- Fixture не является product canon и не должен попадать в production content.
Условия переноса в production#
- Добавить versioned serialization и утверждённый static typecheck/build.
- Связать flags, movement и travel cost с canonical rules/events.
- Проверять expected state version и idempotency при move commit.
- Добавить policy для discovery events и safe frontier representation.
- Ввести state-space validation, если flags/obstacles становятся mutually exclusive.
- Добавить geometry study только если подтверждённый gameplay требует grid/raycast, а не заранее.
- Интеграцию выполнять отдельной production-задачей.