rpg / docs / engine /
@root root authored 11 hours ago
..
README.md Фаза 5: документация и смоуки мировых юнитов 11 hours ago
art-pipeline.md Миграция игры на новые API движка + документация docs/engine 14 hours ago
assets-audio-save.md Миграция игры на новые API движка + документация docs/engine 14 hours ago
core.md engine: примитивы боя — Shake+Camera, shapes, Cooldown, TintFlash, particleSim, burst/oneShot, justReleased, transitionAny 14 hours ago
getting-started.md Миграция игры на новые API движка + документация docs/engine 14 hours ago
input.md доки: docs/demo.md (витрина среза), обновление docs/engine, README, CLAUDE 13 hours ago
maps.md Фаза 5: документация и смоуки мировых юнитов 11 hours ago
recipes.md Фаза 5: документация и смоуки мировых юнитов 11 hours ago
render.md Фаза 5: документация и смоуки мировых юнитов 11 hours ago
ui-and-dialogue.md доки: Camera.deadZone/snap и SpriteDebugView 12 hours ago
README.md

Документация движка @rpg/engine

Движок — переиспользуемая основа для 2D-пиксельных игр в браузере. Первая игра на нём — «Пепельные луга» (apps/game), она же живой пример использования всех API.

Карта документации

Файл О чём
getting-started.md Новая игра с нуля: bootstrap, сцены, ассеты
core.md Engine, GameLoop, EventBus, Tween, GameState, StateMachine, Settings
render.md Renderer, pixel-perfect, камера, IsoDepthLayer, частицы
input.md Действия, клавиатура, мышь/тач, геймпад, виртуальный джойстик
maps.md Изометрия, A*, формат карт, импорт из Tiled
ui-and-dialogue.md UI-кит, PixelText, диалоговые графы
assets-audio-save.md AssetLoader, атласы, AudioManager, сейвы
art-pipeline.md Генератор пиксель-арта, палитра, замена на рисованный арт
recipes.md «Как сделать…»: готовые решения типовых задач

Принципы

1. Жёсткая граница API

Игра импортирует движок только через @rpg/engine (весь API реэкспортирован из packages/engine/src/index.ts). Прямые импорты pixi.js в игре — нарушение границы: нужные типы реэкспортируются движком (Container, Graphics, Text, Sprite, Texture). Это позволяет менять внутренности движка, не трогая игры.

2. Fixed timestep

Логика обновляется фиксированным шагом 60 Гц (GameLoop, аккумулятор, максимум 5 шагов за кадр). dt в Scene.update всегда одинаковый — физика и таймеры детерминированы. Рендер происходит после каждого шага.

3. Мир в юнитах, UI в пикселях

  • Внутренние координаты мира — мировые юниты (1 юнит = 1 тайл, float); экран — проекция с округлением до целого пикселя только на границе мир→экран (пиксель-арт резкий, image-rendering: pixelated, roundPixels: true).
  • Виртуальное разрешение (по умолчанию 480×270) растягивается целым числом на экран (computeScale); UI, текст (VT323) и все display-эффекты живут в нём.
  • Дистанции/радиусы/скорости — скаляры в юнитах (px = units·tileW, 32 px/юнит).

4. Движок жанронезависим

В packages/engine нет ни одного упоминания контента конкретной игры: GameState — механика флагов и переменных, DialogueRunner — механика графов. Всё содержимое (тексты, флаги сюжета, карты) живёт в приложении.

5. Инъекция вместо окружения

Всё, что зависит от браузера, инъецируется или изолируется: StorageLike для сейвов, resolveUrl для ассетов, parent для канваса. Чистые модули (математика, A*, диалоги, формат карт) тестируются в Node без браузера — Vitest.

Структура пакетов

packages/engine/src/
  core/       Engine, GameLoop, EventBus, Tween+easing, GameState, StateMachine, Settings
  scene/      SceneManager (стек сцен + fade-переходы)
  render/     Renderer, Camera, IsoDepthLayer, Particles, computeScale
  input/      InputManager (клавиатура/мышь/тач/геймпад), VirtualJoystick
  map/        IsometricTileMap, pathfinding (A*), mapFormat (JSON+RLE), tiled-импортёр
  math/       Vec2, изометрия, seeded RNG
  dialogue/   DialogueRunner (графы диалогов, view-агностик)
  ui/         DialogueBox, Panel, Button, MenuList, PixelText
  anim/       FrameAnimation
  audio/      AudioManager (шины master/music/sfx, кроссфейд)
  assets/     AssetLoader (текстуры, атласы)
  save/       SaveManager (JSON-слоты)
  ecs/        World/createEntity/query/addSystem
  debug/      DebugOverlay

Известные грабли (важно!)

Подробности — в корневом CLAUDE.md; краткий список:

  • Assets.load без предварительного Assets.init({}) висит навсегда без ошибок — AssetLoader делает это сам, но если грузите напрямую через Pixi, не забудьте.
  • app.renderer недоступен до завершения app.init()Renderer.setup() это учитывает.
  • Экранный bbox изометрического ромба уходит в минус по X — но границы камеры задаются в юнитах (map.worldBounds), клэмп через проекцию считает это сам.
  • document.fonts — шрифт загружается асинхронно; ensurePixelFont() вызывается до создания текста, но фолбэк monospace всегда безопасен.