Newer
Older
rpg / docs / engine / registry.md

Реестр объектов сцены: SceneRegistry

Жанронезависимый примитив «что-то стоит на карте» + индекс по тайлам. Движок не знает ни NPC, ни интерактивов, ни врагов: род (kind) и ссылка на контент (ref) — строки/ссылки, которые задаёт игра. Чистый модуль без Pixi — тестируется в Vitest.

import { SceneRegistry } from '@rpg/engine';

const registry = new SceneRegistry();
registry.add({
    id: 'npc:elder',          // уникален; дубликат — throw (ловится инвариантом сцены)
    kind: 'npc',
    pos: { x: 14.5, y: 9.5 }, // ноги, мировые юниты
    radius: 0.35,             // тело в юнитах (0 — точка)
    ref: npcDef               // ссылка на контент игры — движок не читает
});
registry.add({
    id: 'prop:house', kind: 'prop',
    pos: { x: 20.5, y: 12.5 },
    footprint: { w: 2, h: 2 } // объект накрывает тайлы [20..21]×[12..13]
});

registry.get('npc:elder');       // SceneObject | undefined
registry.byKind('enemy');        // все объекты рода
registry.at(20, 12, 'prop');     // объект, привязанный к тайлу (вкл. footprint)
registry.atWorld(p, 'enemy');    // тайл точки или тело в радиусе из 3×3
registry.near(p, radius, kind);  // объекты в радиусе (для расталкивания тел)
registry.move('enemy:7', pos);   // переиндексация; O(1), если тайл не сменился
registry.remove('enemy:7');      // при смерти/выходе

SceneObject = описание + tile (floor от pos) и нормализованный radius (дефолт 0). pos мутабельно — можно держать ссылку на чужой объект состояния (например, EnemyComp.pos из ECS), тогда move() вызывается после чужого шага.

Связка с остальными подсистемами

  • Клик-роутинг: «что под кликом» — at/atWorld вместо перебора списков (приоритеты клика остаются в игре, см. practices.md).
  • Телесные коллизии: near + расталкивание — см. «Коллизии» в maps.md.
  • IsoDepthLayer: реестр не рисует; вьюхи добавляются в depth-слой сценой, реестр — только данные и запросы.

Правила

  • Идентификаторы — составные (kind:имя, kind:индекс), чтобы сцена могла строить id механически.
  • Инвариант согласованности реестра с контентом области — в снапшоте агента (registry-consistent): каждый def есть в реестре и наоборот.
  • Footprint-объекты (пропы) регистрируются во всех покрытых тайлах — at находит их с любого занятого тайла.