mayatnikovandClaude Opus 4.8 0684368ac7 refactor: рабочая база на three.js + меню/правила уровней + доки
Полный рефакторинг проекта в стабильную расширяемую базу рогалика.

Почему: после разнесения single-file на модули потерялся вызов генерации
карты (RoomMap не генерировал комнаты) → игра падала на старте; баг скрывался
тем, что Bun-бандлер не проверяет типы.

Архитектура:
- Логика игры (src/core/) полностью отделена от рендера: без three.js и DOM,
  тестируется без браузера.
- Рендер мира на three.js с ортокамерой (2D-вид); HUD/миникарта — 2D-канвас поверх.
- Фиксированный игровой цикл 60 Гц + интерполяция (раньше скорость зависела
  от частоты кадров).
- Seeded-RNG, ввод через абстрактные «намерения» (InputState).

Возможности:
- Стартовое меню с выбором уровня (Esc → меню).
- Конфигуратор уровней: LevelRules + 5 пресетов (размер карты, плотность/сила
  врагов, HP, фиксированный seed).
- Тема внешнего вида (render/theme.ts) — задел под кастомные ассеты.

Качество:
- 27 юнит-тестов ядра (генерация, симметрия дверей, коллизии, спавн, правила).
- Два круга adversarial-ревью; исправлено 6 реальных багов
  (кнокбэк сквозь стены → софт-лок; незакрываемая сокровищница; фикс-сид после
  рестарта; перенос ввода между забегами; нет source maps; неточности в доках).
- Документация: README, docs/ARCHITECTURE.md, CLAUDE.md, docs/HOWTO.md.
- dist/ исключён из гита; bun.lock зафиксирован.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 14:07:06 +03:00

Dungeon Crawl — рогалик в духе The Binding of Isaac

Top-down рогалик: процедурный данжен из комнат, два режима боя (дальний/ближний), враги, босс. Логика на чистом TypeScript, рендер — на three.js (ортографическая камера, картинка плоская 2D-сверху). Сборка — Bun.

Есть стартовое меню с выбором уровня: данжен генерируется процедурно каждый забег, но параметризуется набором правил (размер, плотность/сила врагов, HP, seed). Внешний вид мира вынесен в «тему» — задел под кастомные ассеты (спрайты/текстуры).

Это рабочая база для развития, а не готовая игра. Архитектура специально сделана так, чтобы её было легко расширять — и человеку, и ИИ-агентам. Перед доработкой прочитай CLAUDE.md и docs/HOWTO.md.

Быстрый старт

bun install        # поставить зависимости (three, typescript)
bun run dev        # дев-сервер с авто-пересборкой → http://localhost:3000

Продакшн-сборка:

bun run build      # минифицированный бандл → dist/  (открой dist/index.html)

Проверки (запускай перед любым коммитом):

bun run typecheck  # tsc --noEmit, строгий режим
bun test           # юнит-тесты ядра
bun run check      # и то, и другое разом

Управление

Клавиша Действие
WASD движение
Стрелки прицельная стрельба/удар в направлении
Пробел атака по ходу движения
Tab / Q сменить оружие (Дальний ↔ Ближний)
R заново (на экране Game Over / Victory)
Esc вернуться в меню выбора уровня

Чтобы перейти в соседнюю комнату — зачисти текущую (двери откроются) и встань на дверь, нажимая в её сторону.

Режимы боя

Режим Оружие Скорость Урон Особенность
Дальний пистолет быстро (cd 10) 1 за выстрел снаряды летят по прямой
Ближний нож медленно (cd 22) 2 + отбрасывание широкий взмах

Типы комнат

Тип Описание
spawn старт, врагов нет
normal 24 врага
treasure без врагов (комната-награда), сразу открыта
boss 1 босс; его зачистка = победа

Стек и устройство

  • Bun — рантайм, бандлер и тест-раннер.
  • three.js — WebGL-рендер мира через ортокамеру.
  • TypeScript (strict) — весь код.
  • Архитектура: логика игры полностью отделена от рендера. Ядро (src/core/) не знает ни про DOM, ни про three.js, поэтому его легко тестировать и при желании можно подменить рендер, не трогая игру.

Подробности — в docs/ARCHITECTURE.md.

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

src/
├── config.ts              ⭐ КОНСТАНТЫ движка: размеры, геометрия дверей, базовый баланс
├── main.ts                точка входа: меню → игра, «склейка» логики/рендера/ввода
├── core/                  ── ИГРОВАЯ ЛОГИКА (без DOM и three.js) ──
│   ├── Game.ts            «мозг»: состояние + один шаг симуляции step()
│   ├── rules.ts           ⭐ ПРАВИЛА УРОВНЯ (пресеты для меню: размер, враги, HP, seed)
│   ├── types.ts           общие типы (Dir, RoomType, Box, …)
│   ├── rng.ts             ГПСЧ с seed (детерминизм для тестов/отладки)
│   ├── util.ts            мат-утилиты (dist, overlap, clamp, lerp)
│   ├── entities/          Player, Enemy, Projectile, MeleeSwing
│   ├── world/             Room, RoomMap (генерация), tiles
│   └── systems/           collision, spawner (чистые функции)
├── input/                 ── ВВОД ──
│   ├── InputState.ts      абстрактные «намерения» (не сырые клавиши)
│   └── KeyboardController.ts  клавиатура → InputState
├── render/                ── РЕНДЕР (читает состояние, рисует) ──
│   ├── Renderer.ts        интерфейс рендера
│   ├── ThreeRenderer.ts   мир на three.js (ортокамера)
│   ├── theme.ts           ⭐ ВНЕШНИЙ ВИД (цвета; задел под спрайты/текстуры)
│   └── HudOverlay.ts      HUD и миникарта на 2D-канвасе поверх
├── ui/
│   └── StartMenu.ts       стартовое меню (DOM) с выбором уровня
└── engine/
    └── GameLoop.ts        игровой цикл с фиксированным шагом (60 Гц)

tests/                     юнит-тесты ядра (bun test)
docs/ARCHITECTURE.md       архитектура и потоки данных
CLAUDE.md                  правила для ИИ-агентов и разработчика
docs/HOWTO.md              рецепты: как добавить врага/оружие/комнату
S
Description
Балдежная игра вдохновленная Исааком
Readme
2.6 MiB
Languages
TypeScript 60.9%
HTML 39.1%