Files
RustNotMC/PLAN.md
T

27 KiB
Raw Blame History

RustNotMC — данные оригинала, решения и план работ

Файл для перечитывания: после сброса контекста, при передаче работы другому агенту или при возврате к проекту через месяц. Здесь лежит всё, что нужно знать, чтобы продолжить, не выясняя заново.

Порядок работы: сначала этот файл, потом код.


0. Где мы сейчас

модуль что в нём состояние
rsx-protocol формат провода: кадрирование, буфер, рукопожатие, игровые пакеты рабочий, 22 теста
rsx-auth свои аккаунты сервера (PBKDF2, токены, троттлинг) рабочий, используется только когда лаунчер не настроен
rsx-server-core тик-луп, мир (чанки, генерация, сохранение), сессии, вход через лаунчер рабочий, 49 тестов
rsx-client загрузчик модов, API модов, хуки в клиент рабочий, 128 тестов
game-fork форк Minecraft 1.12.2: свой сетевой слой, свой экран входа, свой HUD собирается чисто, 3275 классов

Уже работает целиком: клиент заходит на сервер по токену лаунчера → сервер спрашивает лаунчер «этот ваш?» → клиент получает мир → чанки приходят и рисуются → игрок ходит и ломает блоки.

Не сделано: предметы, инвентарь, крафт, верстаки, изучение чертежей, узлы-ресурсы (деревья/камни/руда как разрушаемые объекты), постройка баз, нормальная генерация мира, транспорт на NIO, дальний вид (DistantView).


1. Данные оригинала (Rust)

Источники: вики Rust (rust.fandom.com), локальный референс G:\decompiled-rustex (Rust-клон на MC 1.8, обфусцирован), Paper API (jd.papermc.io).

1.1 Камень (Rock) — стартовый предмет

«the most basic resource gathering and fighting tool» — инструмент сбора и оружие.

  • Выдаётся первым предметом в тулбаре при спавне. Крафтится из 10 камня.
  • Прочность ограниченная, предмет изнашивается.
  • Собирает дерево и камень; ломает бочки; бьёт постройки.
  • Урон по постройкам: лоза (twig) — 9, дерево/камень — 0.2, металл — 0.1, бронированные — 0.1. То есть обычным камнем постройку не сносят.

Таблица сбора (сколько снимает один удар, сколько нужно ударов, сколько урона):

ресурс доля прочности за удар ударов до разрушения урон за удар
дерево 0.3 2 10
руда 0.3 2 5
животное 0.0 2 10

1.2 Верстак (Workbench) — 3 уровня

  • Разворачиваемый предмет: надо стоять рядом, чтобы крафтить.
  • Открывает тех-дерево: рецепты своего уровня и ниже.
  • Уровень выше → время крафта короче: −50% на один уровень выше, максимум −75% на два уровня выше.
  • Рецепты, открытые верстаком, нельзя передать другому игроку (в отличие от чертежей со стола исследований).

Стоимость и время изготовления:

уровень ingredients время где крафтится
1 500 дерева, 100 металла, 50 скрапа 60 с —
2 500 металла, 20 ХМ, 500 скрапа 60 с верстак 1
3 1000 металла, 100 ХМ, 1250 скрапа 60 с верстак 2

Что открывает каждый уровень (выборочно, полный список — в вики):

  • L1: постройки (пол, решётка, ворота, сетка-фенси, гаражные ворота, мешки с песком, бойницы, ставни, лестница, окна, калитка), предметы (торговый автомат, верстак для ремонта, кровать, лампа, стул, холодильник, мишень, стол исследований, верстак 2), ресурсы (порох), одежда (футболка, штаны, лонгслив, шахтёрская каска, куртка, рубашка, каска, ведро, резиновая каска), инструменты: Salvaged Hammer, Hatchet, Pick Axe (топор, кирка), оружие (пистолеты, револьвер, лом, гвоздомёт, дробовик, пистолет-пулемёт, M16, огнемёт, F1, гранната, мачете, глушитель, фонарь, прицел, коллиматор, 8-кратник), патроны (пистолетная, высокоскоростная стрела), ловушки (капкан, огнемёт, мина).
  • L2: бетонный баррикад, клетка, водосборник, металл-баррикад, люк; предметы (большая печь, дроп-бокс, шкаф, нефтезаводка, прожектор, верстак 3); одежда (тяжёлая броня); инструменты (Salvaged Axe, Salvaged Icepick); оружие (пистолет-пулемёт Python, огнемёт, дробовик, Thompson, тесак, дульный тормоз, глушитель, длинный меч), патроны (5.56, 12 калибра), ловушки (автотурель).
  • L3: каменные врата, бронированные двери, укреплённые окна; взрывчатка; тяжёлая броня; оружие (штурмовая винтовка, bolt action, rocket launcher, MP5A4); боеприпасы; детали (шестерни, труба, маслёнка, пружина, набор для шитья).

1.3 Стол исследований (Research Table) и чертежи (Blueprints)

  • «to create Blueprints by using Scrap and the item to make the blueprint of, which means one has to find the desired item first».
  • Процедура: кладёшь один нужный предмет в верхний слот → показывается требуемый скрап (в нижний слот) → кнопка «Research» → 10 секунд → в верхнем слоте появляется чертёж, предмет уничтожается.
  • Прочность предмета на результат не влияет (если предмет не сломан — иначе не работает).
  • Исследование продолжается, если закрыть интерфейс стола. Звук слышно рядом.
  • Скрап: 20 / 75 / 125 / 500 по тирам предмета.
  • Сам стол: 200 металла + 20 скрапа, крафтится на верстаке 1, 60 с.
  • Столы есть на монументах (аэродром, электростанция, спутниковая тарелка, супермаркет, аванпост) — то есть это вещь, за которой надо сходить.
  • Эксперимент на верстаке: ломаешь 75 / 300 / 1000 скрапа → получаешь случайный ещё неизвестный чертёж уровня этого верстака. Отличие от стола: случайный результат.

1.4 Скрап (Scrap)

  • Выпадает при разрушении постройек игроков, а не из ресурсных узлов.
  • Тратится на исследование и на крафт верстаков.

1.5 Постройка баз (Rust)

Как ставится. Строительный план (Building Plan, 20 дерева) — разворачиваемый предмет: кладёшь в хотбар, выбираешь, видишь «призрак» объекта; ПКМ + движение мышью перебирает варианты объекта, ЛКМ ставит.

Два слоя объектов:

  • Строительные (то, из чего база): фундамент (квадратный/треугольный), пол (квадратный/ треугольный), стена, полустена, низкая стена, дверной проём, окно, настенная рамка, рамка пола, лестница, крыша, столб.
  • Внутренние (то, что внутри): двери, верстаки, печи, сундуки, торговый автомат, шкаф, инструментальный шкаф, замки.

Ставятся свободно, не по сетке мира. Снаппятся внутренние к уже поставленным строительным: стены — к краю фундамента, полы — к верхней кромке стены, двери — внутрь дверного проёма. Правило из вики дословно: «To place walls, select them and aim at the edge of a foundation. Floors must be placed at the top edge of a wall, and doors must be placed inside door frames.»

Проёмы двух видов:

  • малый (дверной проём) — влезает только одиночная дверь;
  • большой — влезают двойные двери и гаражные, но не одиночные.

Уровни (tiers) и прочность:

уровень прочность как получить цена (пример)
Twig (лоза) 10 только строительным планом, напрямую дерево: фундамент 50, стена 50, проём 35, окно 35, пол 25, рамка 25, лестница 50, крыша 50
Wood (дерево) 250 улучшение из лозы молотком дерево ×4
Stone (камень) 500 улучшение молотком камень
Sheet Metal (лист) — улучшение молотком металл (вдвое дешевле камня, но нужна переплавка)
Armored (броня) 2000 улучшение молотком High Quality Metal

Двери: деревянная 200 HP, листовая 250 HP, бронедверь 800 HP. Понизить уровень нельзя.

Куда можно строить: почти везде; крутые склоны и неровная земля мешают, фундамент ставят и под водой.

Прочность конструкции (stability): у постройки есть запас прочности; если он упал в ноль — объект ломается сразу при установке. Столбы ставят до стен, под столбом должен быть фундамент, и на втором этаже столбы должны быть и снизу.

Инструментальный шкаф (Tool Cupboard): разблокирует постройку в радиусе 50 м от любого фундамента базы, в которой он стоит. «Twig floors can be built, regardless of the building privileges» — лозу строить можно всегда, улучшать — нельзя.

Замки: ключевой (дерево) и кодовый (100 металла, 4 цифры). Ставятся на двери, на контейнеры (сундуки, торговый автомат) и на инструментальный шкаф.

Гниение (decay): лоза и дерево теряют здоровье через несколько часов и разваливаются, камень/металл/броня — через дни. Открытие/закрытие двери с замком сбрасывает таймер гниения.

1.6 Что из этого берём мы

  • Строительные объекты — наши кастомные предметы (не блоки мира).
  • Ставятся свободно, внутренние снаппятся к поставленным (сокеты на объектах).
  • Два вида проёмов: малый (только одиночная дверь) и большой (двойные/гаражные, но не одиночные).
  • Уровни (tier) и прочность — как в Rust, плюс тег admin (см. п. 2.2) для объектов, которые нельзя ставить обычному игроку.
  • Столб/устойчивость и гниение — позже, по необходимости.

2. Решения по проекту

2.1 Кто такой админ

Админ — свойство конкретного сервера, а не проекта. Проект коммьюнити-френдли: в разных серверах разные роли и разные права. Роль приходит из лаунчера (у лаунчера есть server/roles.py и роли ROLE_USER / ROLE_PASS_HOLDER / ROLE_MODERATOR / ROLE_ELDER / ROLE_CREATOR).

2.2 Кто что может ставить и ломать

Правило на блоке/предмете (тег admin):

тег admin кто может ставить/ломать/менять
нет кто угодно, включая обычных игроков
есть только админы сервера
  • Тег admin есть, например, у «тестблока» и у всего, что не добавлено в крафт/изучение/дроп.
  • Режим креатива не даёт прав. Даже игрок в креативе без админки не может поставить или сломать блок с тегом admin.
  • Проверка — на сервере. Клиент только показывает или не показывает курсор.

2.3 Ванильные блоки игры

Мир (карта, монолиты, рельеф) — не ломается и не строится обычными игроками: это работа админов. Игроки строят нашими кастомными предметами через наш API.

2.4 Предметы

  • Все предметы игрока — кастомные, через наш код и наше API (не ванильные ItemStack).
  • У предмета: прочность, урон, значение bench.
    • bench = 0 — крафтится сразу.
    • bench = 1 — изначально недоступен для крафта, его надо изучить на верстаке (или получить чертёж через стол исследований).
  • У предмета есть класс инструмента (NONE / PICKAXE / AXE / SWORD / …) и класс ресурса, который он добывает.

2.5 Крафт

  • Как в Rust: верстаки трёх уровней (разворачиваемый предмет, надо стоять рядом), чертежи (стол исследований: нужен найденный предмет + скрап), эксперименты на верстаке (случайный чертёж за скрап).
  • Знание рецепта — состояние игрока, а не свойство предмета.
  • Время крафта, множитель от уровня верстака, стоимость скрапа — как в Rust.

2.6 Структуры вместо блоков мира

Руда, деревья и камни — не блоки мира, а разрушаемые объекты (как узлы в Rust): у них есть прочность, они бьются инструментом и дают дроп. Мир меняют только админы.

2.7 Текстуры

  • Текстуры предметов пока временные, взяты из ремейка как заглушки.
  • Пометка: заменить на свои (см. п. 6).

3. Архитектура

3.1 Модули

модуль про что лицензия
rsx-client загрузчик модов, API модов, хуки в клиент MIT
rsx-protocol формат провода, общий словарь (блоки, формат чанка) MIT
rsx-plugin-api API серверного контента: события, реестр предметов, рецепты, роли MIT (пустой, следующий)
rsx-server-core тик-луп, мир, сущности, масштабирование proprietary
rsx-auth свои аккаунты сервера (когда лаунчер не настроен) proprietary

3.2 Провод

  • Кадр: magic "RSX1", версия, id пакета, длина, тело.
  • Рукопожатие: Hello → HelloAck → Auth|LauncherAuth → AuthAck → Login → LoginAck.
  • Вход через лаунчер: клиент отдаёт токен лаунчера, сервер спрашивает лаунчер POST /auth/validate (у лаунчера такой эндпоинт есть, он же проверяет бан) → если «свой» — выдаёт свой игровой токен.
  • Игровая фаза: JoinWorld → WorldJoin, ChunkData, BlockChange, PlayerMove, EntitySpawn/Move/Remove, BreakProgress, SetGameMode, Inventory, Ping/Pong.

3.3 Мир

  • Чанк 16×16×256, палитра по секциям (4 бита на блок) — плоский массив не годится: 62 500 чанков × 64 КБ = 4 ГБ.
  • Лежат регионами на диске (32×32 чанка в файле), в памяти — LRU-кэш.
  • Генерация — чистая функция от зерна и координат (детерминизм обязателен: чанк может прийти через месяц после соседнего).
  • Сгенерированный чанк не пишется на диск: террейн восстанавливается генератором. На диск уходит только то, во что построили.

3.4 Что взято из Paper/Bukkit (как образец)

у Paper зачем нам у нас
BlockBreakEvent (cancellable, setDropItems) сервер решает, ломается ли блок и что падает BreakEvent: cancelled, drops
BlockPlaceEvent, PlayerInteractEvent кто что нажал InteractEvent (левая/правая), PlaceEvent
ItemMeta + PersistentDataContainer свои данные на предмете ItemStack + ItemData (ключ→значение)
PlayerInventory / InventoryClickEvent инвентарь, хотбар, защита от дюпа свой Inventory + проверки на сервере
Permissible / роли «мир только для админов» роли сервера, тег admin у блоков
ShapedRecipe / ShapelessRecipe рецепты свой реестр с гейтом по чертежу и верстаку (в Paper такого нет)

Чего у Paper нет, а нужно нам: гейт крафта по изученности, прочность/урон/сбор по классам ресурсов, структуры вместо блоков мира.


4. План работ

Каждый шаг — законченный кусок, который можно проверить. Порядок важен.

Шаг A. Фундамент предметов и инвентаря (следующий)

  • ItemType: id, имя, класс инструмента, класс ресурса, прочность, урон по частям тела, скорость сбора, bench, рецепт.
  • ItemStack: тип + количество + прочность + ItemData (свой ключ→значение).
  • Inventory: слоты, хотбар, что в руках. Сервер — источник истины.
  • Реестр предметов + протокол Inventory / InventorySlot.
  • Клиент: свой реестр + свои текстуры + свой рендер предмета в руке и в слоте (наши предметы не ванильные IItem).
  • Текстуры предметов — временные (взяты из ремейка как заглушки). ПОМЕТКА: заменить на свои.
  • Стартовый набор: камень (как в Rust — выдаётся первым).

Критерий готовности: игрок заходит, получает камень в руку, видит его в хотбаре и в руке; сервер знает, что у него в руках.

Шаг B. Ломание и установка — решает сервер

  • Протокол: Dig (START/STOP, позиция, грань) вместо «клиент присылает результат»; BreakProgress (0..9) — трещины у всех.
  • Сервер: состояние ломания по образцу PlayerInteractionManager (PlayerInteractionManager.java:79 updateBlockRemoving, :124 onBlockClicked, :216 tryHarvestBlock): прогресс по твёрдости блока и скорости инструмента, рассылка прогресса, досягаемость, роль/тег admin.
  • Правило из ваниллы: меч в креативе блок не ломает (PlayerInteractionManager.java:217).
  • Клиент ничего не решает: 4 патча (Minecraft.clickMouse → свой Dig, Minecraft.sendClickBlockToController → состояние кнопки, PlayerControllerMP.clickBlock → клиент не ломает сам, EntityRenderer.isDrawBlockOutline → контур только там, где можно).

Критерий готовности: зажатая кнопка ломает один блок; блок с тегом admin обычному игроку не ломается ни в выживании, ни в креативе; у остальных — ломается инструментом того класса, который нужен.

Шаг C. Структуры, узлы, постройка

  • StructureTemplate (блоки + AABB + меш + HP + дроп), StructureInstance, StructureWorld. Деревья/камни/руда — узлы, не блоки мира.
  • Сбор: попадание инструментом → урон по классу ресурса → разрушение → дроп.
  • Постройка: игрок ставит наши кастомные предметы-конструкции (не блоки мира). Снаппинг — см. п. 1.5.
  • Растительность и руда в генерации — через шаблоны структур.

Шаг D. Мир один раз, конфиг, барьер

  • Конфиг: world.size (сторона карты в блоках), world.gamemode, world.seed, world.generate, barrier.distance.
  • Мир генерится один раз и отдаётся; изменения игроков — отдельным слоем.
  • Барьер: сервер не пускает; клиент рисует (прозрачность → 0.5 у границы, блендинг с блоком под игроком в ±5 блоках, дальше размытие в невидимую стену).

Шаг E. Транспорт на NIO (независим, можно раньше)

  • Selector + неблокирующие SocketChannel, ClientSession → конечный автомат, блокирующие места (HTTP к лаунчеру) — в пул потоков.
  • Проверка: 49 существующих тестов идут по сокету и должны пройти без правок; + 100 одновременных соединений.

Шаг F. DistantView

  • Сервер шлёт LOD (высоты + цвет) по регионам; клиент кэширует архивом и досылает недостающее.
  • Рендер: квадродерево, Hi-Z отсечение (пирамида глубины), uCamOffset (float не хватает на ±2000), зажим UV по мипам, свой шейдер GLSL 330.

5. Открытые вопросы

  1. Роли приходят из лаунчера или живут на сервере? Лаунчер знает роли (ROLE_USER … ROLE_CREATOR), но сервер может держать свои.
  2. Эксперимент на верстаке делаем? (случайный чертёж за скрап) — в Rust есть.
  3. Урон по частям тела (голова/грудь/руки/ноги) — сразу или один общий урон?

6. Что дописать

  • Полные таблицы предмет→требуемый верстак и предмет→скрап (из вики).
  • Точная таблица сбора по классам ресурсов (дерево/руда/животное/лоза/камень/металл).
  • Список строительных объектов и их сокеты (что куда снаппится) — по п. 1.5.