docs: update README for the audio, display and persistence work
Build Delta / Build paperclip jar (push) Successful in 8m2s

The README still described decoupled sound range as planned and had no
`/delta displaylead`, no mention of the config being writable, and a command
list containing a `/delta reload` that does not exist.

Also corrects two claims that no longer hold:
- the Display tracking clamp is in org.spigotmc.TrackingRange, not
  ChunkMap.TrackedEntity. That was a deliberate choice: TrackingRange is
  git-tracked Paper source, so the decompiled Minecraft tree stays untouched.
- the new Bukkit methods are default methods, so plugins referencing them keep
  working on stock Paper instead of failing with NoSuchMethodError.
This commit is contained in:
SashegDev
2026-09-30 12:53:09 +00:00
parent dac80386b5
commit 5186c9b0e2
+85 -14
View File
@@ -28,24 +28,42 @@ Delta — **не форк с поломанным API**. Плагины видя
Отличие только в отображении: `Brand-Name = Delta`, поэтому в F3 видно
`server: Delta`. Это **единственное** пользовательское отличие.
Все новые классы лежат в `me.sashegdev.delta`. Методы Bukkit API, которых
Paper не хватает, добавлены как **default-методы** — так ничего не ломается
бинарно, и плагин, который на них ссылается, продолжает работать на стоковом
Paper через fallback.
## Что добавлено
### `/delta` — инспекция и тюнинг
```
/delta status текущие значения конфигурации
/delta displayrange <блоки|0> дальность трекинга Display, 0 = стоковая
/delta reload перечитать конфиг
/delta displaylead <тики|0> предсказание позиции Display, 0 = стоковое
/delta clear сбросить Display-настройки к стоку
/delta help
```
Периметр `delta.admin`.
Периметр `delta.admin`. Всё, что меняется через `/delta`, **пишется в
`paper-global.yml`** и переживает рестарт. Paper не даёт публичного API для
записи глобального конфига, поэтому добавлен `saveGlobalSection()`: он пишет
только секцию `delta` и не трогает остальные узлы файла, так что сломать чужие
настройки невозможно.
### Бюджет Display-сущностей
В `ChunkMap.TrackedEntity#updatePlayer` добавлен кламп дальности трекинга для
`Display`. Display-сущности не имеют физики и коллизий, поэтому их отсечение по
дальности безопасно: клиент просто их не видит, серверное состояние остаётся
корректным. Это снимает основную нагрузку от способностей, спавнящих
десятки `BlockDisplay` с `viewRange=64`.
Отключено по умолчанию — включается в `paper-global.yml`:
Кламп дальности трекинга для `Display` живёт в
`org.spigotmc.TrackingRange#getEntityTrackingRange` — это git-отслеживаемый
исходник Paper, поэтому декомпилированный код Minecraft патчить не пришлось.
Display-сущности не имеют физики и коллизий, поэтому их отсечение по дальности
безопасно: клиент просто их не видит, серверное состояние остаётся корректным.
Это снимает основную нагрузку от способностей, спавнящих десятки `BlockDisplay`
с `viewRange=64`.
Отключено по умолчанию:
```yaml
delta:
display-tracking-range-enabled: false
@@ -55,11 +73,58 @@ delta:
extended-particle-distance-enabled: false
extended-particle-distance: 128.0
decoupled-sound-range-enabled: false
display:
predictive-lead-ticks: 3
sound:
propagation-blocks-per-tick: 10.0
decay-exponent: 4.0
client-compensation: false
min-audible-gain: 0.004
```
### Звук: раздельные громкость и дальность
В ванилле слышимая дальность выводится из громкости
(`SoundEvent#getRange = 16 * volume`). Единственный способ сделать звук
слышимым за 150 блоков — `volume=10`, и тогда всё клиппит в упор. Delta
разделывает эти параметры:
```java
world.playSound(loc, sound, category, volume, pitch, range);
world.playSoundAttenuated(loc, sound, category, volume, pitch, range);
```
`playSoundAttenuated` отправляет **ровно один пакет на игрока**, отложенный до
тика прихода волны. Кадрового обновления громкости нет вообще — иначе при
десятке источников это N пакетов × M игроков каждый тик, то есть ровно тот
трафик, который здесь и убирается.
Кривая нормализованная: `gain = volume * (1 - d/range)^exponent`. Ноль ровно на
`range`, поэтому параметр дистанции осмыслен. Физический `1/r` не годится: с
порогом слышимости он срезал бы всё дальше ~1000 блоков и `range` просто не
влиял бы на результат. Скорость волны — 10 блоков/тик, то есть 100 блоков за
0.5 с.
### Плавность быстрых визуалов
`DeltaDisplay` держит политику предсказывающей телепортации. Display двигается
пакетами позиции, и клиент интерполирует их у себя — на реальном пинге визуал
отстаёт и дёргается. Лечится не частыми пакетами (это ровно тот трафик, который
мы убираем), а сдвигом старта: визуал рождается сразу на N тиков вперёд по своей
же траектории, и `teleport_duration = N` говорит клиенту растянуть телепорт на
эти же N тиков. Клиент никогда не отстаёт, пакетов столько же.
Диапазон 0–10 тиков. `teleport_duration` — уже стоковый Bukkit API, поэтому
Delta не добавляет плагинам новых методов: политика централизована, сдвиг
позиции делает сам плагин по траектории каждого визуала.
### Баннер при старте
При запуске печатается блок с версией, коммитом, веткой, списком включённых
Delta-фич и предупреждением о статусе ядра.
При запуске печатается блок с версией, коммитом, веткой, списком Delta-фич и
предупреждением о статусе ядра. Баннер выводится из статического инициализатора
`PaperBootstrap` **до** парсинга `paper-global.yml`, поэтому строки описывают
механизм, а фактические значения показывает `/delta status` — иначе баннер
печатал бы дефолты как будто это текущая конфигурация.
## Конфигурация сервера
@@ -77,7 +142,10 @@ Delta-фич и предупреждением о статусе ядра.
./gradlew createMojmapPaperclipJar
```
Артефакты: `paper-server/build/libs/paper-paperclip-*.jar`
Артефакт: `paper-server/build/libs/paper-paperclip-1.21.8-R0.1-SNAPSHOT-mojmap.jar`
Имя `delta` в `fill { project("delta") }` влияет только на публикуемые в Maven
артефакты, локальный jar всегда остаётся `paper-*`.
## CI
@@ -88,14 +156,17 @@ Gitea Actions, воркфлоу `.gitea/workflows/build.yml`. Раннер жи
Node обязателен для `actions/checkout`, git identity — для `applyFeaturePatches`,
который делает commit.
Воркфлоу делает обе фазы отдельными шагами: объединённый `createMojmapPaperclipJar`
падает на неявной зависимости.
## Планируется
- Раздельные громкость и дальность звука (сейчас это один и тот же параметр —
чтобы было слышно за 150 блоков, приходится делать volume=10, и в упор всё
клиппит)
- `force`/`alwaysShow` в публичном API частиц (сейчас недоступны плагинам)
- Вынос симуляции «безопасных» чанков в worker-треды Moonrise — с чек-листом,
исключающим BlockEntity и плагинные блоки, чтобы не сломать совместимость
- Калибровка `client-compensation` для затухающего звука: клиент сам гасит
позиционный звук, поэтому без компенсации итог тише расчётного. Формула
подгоняется по замеру, поэтому вынесена под отдельный тумблер
## Лицензия