Выгрузили из ремейка Rustex всё, на чём будем работать, и переписали план
под реальные цифры.
Ассеты:
- tools/extract-rustex-assets.py распаковывает res/ и game.jar и декодирует
однобайтовый XOR (ключ по сигнатуре: PNG ^0x89, OGG ^0x4F, JSON ^0x7B).
Итог: assets/rustex, 1.65 ГБ, 19 тыс. файлов. В репозиторий не кладём.
- Не прочитались 553 .obj, 106 .rrs, 113 .nbt: у них другой шифр, нужен
разбор кода (REA).
Таблицы (в репозитории):
- items.csv: 218 предметов с уроном, дальностью, темпом, прочностью, добычей
за удар, материалом, иконкой и моделью;
- sounds.csv: 505 звуковых событий с файлами;
- item-texts.json: 543 названия и описания предметов.
План (PLAN.md):
- Сбор теперь по балансу ремейка: камень берёт 50 дерева и 35 руды, топор 85
дерева, каменная кирка 80 руды. Дерево 750 топором рубится за 9 ударов, с
меткой за 6-7 - ровно те 7-10 ударов, которых ждали.
- Исследования - версия после 2020: два пути. Стол (15/30/60/120, нужен сам
предмет, превращается в чертёж) и тех-дерево верстака (125/250/500, ветки с
предками, разблокировка личная). Утверждение "тех-дерево бесплатно" было
ошибкой community-вики.
- Лозы больше нет: она из джунглей, а джунглей нет. Выкинута из HP-таблицы,
цен, таймеров гниения и правил шкафа.
- Новые разделы 1.10 (мусорка на дороге: серая бочка - скрап, синяя -
компоненты, красная - нефть и топливо, плюс ящики с едой) и 1.11 (дороги:
сетка 3-4 полос плюс кольцо, сегменты - точки спавна мусорки).
- Первый источник скрапа - мусорка, лутбоксы отложены: вопрос о прогрессии
крафта снят.
- Узлы: руда - своя 3D-модель с AABB, деревья - пока блоки мира.
Сервер умел принимать игроков и не умел ничего, что можно увидеть. Мир
был не написан: ни чанков, ни генерации, ни сохранения, ни игровых
пакетов.
Сделано:
- Пакет world: ChunkPos, Chunk, Blocks (теперь в протоколе), WorldGenerator,
ChunkStorage, World. Генерация чистая функция от зерна и координат, без
java.util.Random и без общего состояния, потому что чанк может
появиться через месяц после соседнего, на другой машине, и обязан
совпасть с ним побайтово. Сохранение — файл на чанк, запись во временный
файл и перенос, версия и контрольная сумма: половина записанного файла
это мир, который молча испортился.
- Снимок чанка и запись блока теперь под одним замком. Раньше копия могла
сняться посреди записи блока, и на диск уходила половина изменения.
- Player: позиция, вид, список отправленных чанков, проверка досягаемости
блока. Клиент не может переписать блок, до которого не дотянулся.
- Сервер держит мир, крутит его по тику, выкидывает давно не тронутые
чанки, шлет чанки вокруг игрока и рассылает изменения блоков и передвижения
тем, кто их видит.
- Клиентский сетевой слой в игре еще не тронут: это следующий шаг.
Проверено: 45 тестов сервера. Из них 25 на мир (детерминизм, круг
сохранения, автосохранение, вытеснение, отказ битому файлу) и 9 сквозных
через настоящий сокет: игрок входит, получает 25 чанков, чанк совпадает с
террейном сервера, блок ломается и остаётся сломанным после перезапуска
сервера, два игрока видят друг друга.
Проект начинается с двух вещей: клиент, который мы действительно собрали, и
загрузчик, который является его частью, а не чем-то рядом.
Форк
- prepare-game.ps1 пересобирает клиент целиком: ванильный jar, SRG и MCP,
SpecialSource, FernFlower, патчи, автофиксеры, javac. Идемпотентен.
- Свой код игры лежит в src-overlay, потому что src пересоздаётся при каждой
сборке и всё написанное вручную там погибает.
- 116 патчей в patches/decompiler-fixes.txt. Каждый сверялся с оригинальным
байткодом через javap: компиляция не ловит ошибки декомпиляции.
- struct_diff.py сравнивает исходный байткод с нашей сборкой по классам,
интерфейсам, суперклассам, методам и полям, и отдельно проверяет, что
пропавшие классы действительно никому не нужны.
Загрузчик
- Собирается и тестируется без игры: build.ps1 не использует classpath
вообще, поэтому SelfTest из 128 проверок проходит без запущенного форка.
- Клиентский API не содержит ни одного игрового типа, реализацию даёт игра.
- Политика: мод меняет то, что клиент показывает, но никогда то, что истинно
в мире. Мир, предметы, игроки и сеть принадлежат серверу.
- Capability приведены в соответствие с этой политикой: осталось шесть, и
за каждым стоит реальная проверка. Прежние WORLD, PLAYER, NETWORK, TEXT,
INPUT и COMMAND выдавались, но ничего не проверяли.
- Команды модов имеют область CLIENT, SERVER или BOTH. Серверные не
выполняются на клиенте никогда.
- Свой jar загрузчика лежит в classpath игры и сборки форка.
Инструменты
- add_patch.py, чтобы каждое исправление переживало передекомпиляцию
- find_self_comparisons.py, find_remove_index_bugs.py, find_callers.py
- stage_run.py и fetch_missing.py для запуска клиента