Skip to content

Endlink v0.2.0

Choose a tag to compare

@luibara2 luibara2 released this 17 Aug 02:27
· 4 commits to main since this release

Custom content — items, entities, blocks and the resource packs behind them — now survives a backend
switch. Before this release it did not, and no amount of correct pack configuration fixed it.

Bedrock reads a client's resource pack stack, item registry, entity identifier list and custom block
definitions once, at level init. A seamless switch deliberately does not re-run level init, so a
client kept whatever the first backend it joined had told it: another backend's custom items drew
arbitrary vanilla textures, and its custom entities and blocks were invisible — solid and clickable,
but not drawn.

Cross-backend registries

Every client is now given the combined item and entity registries of all backends at login, and each
backend's own network ids are translated to and from that union as packets pass through. The
translation is free per packet: it rides on the codec's existing decode step rather than rewriting
item ids packet by packet.

Custom blocks need no id translation — a modern backend hashes a block's runtime id from its state,
so the number is the same everywhere — but they do need their definitions, which are merged in the
same way. A backend that numbers blocks by palette order instead of hashing them is reported, since
that case cannot be corrected by a proxy.

Each backend's registries are learned the first time anyone visits it and cached in
cache/backend-palettes.nbt, so later logins account for backends nobody has been to this run. After
a backend's addons change, the first player to go there sees the old registry until they rejoin; that
is logged, not silent.

Controlled by crossBackendPalette, on by default.

Resource packs

  • Unpacked pack folders are loaded, not only .mcpack files. A folder holding manifest.json is
    zipped in memory at startup, reproducibly, so an unchanged folder keeps its hash across restarts
    and clients do not redownload it.
  • Backend packs are cached and served by the proxy (resourcePacks.cacheBackendPacks). The proxy
    keeps a copy of the bytes it sees a client download, and downloads a switched-to backend's packs
    itself — nobody else ever asks that backend for them. Later logins include them, which is what
    makes a switched-to backend's content render. Newest version wins; a pack placed in
    resourcePacks.dir by hand wins a tie. Encrypted packs cannot be cached and are named in the log.

Joining

security.rateLimit.packetLimit now defaults to 500 rather than RakNet's 120. A single Bedrock
login is a burst of MTU-sized fragments carrying the identity chain and skin; over loopback or a LAN
they land inside one 10ms tick and exceed 120. That blocked the address for ten seconds, stalled the
handshake into disconnect.timeout, and repeated on every retry — a player in that state could not
join at all. A blocked address now also names itself and the setting that blocked it in the log.

Resource pack chunks are 100KB rather than 1MB, so the acknowledgements a client sends back while
downloading stay inside that budget.

Upgrading

Drop in the new jar. No config changes are required — the new settings default to on, and an existing
config.properties keeps working. Two things worth doing:

  • If your config.properties sets security.rateLimit.packetLimit=120, raise it; the new default
    only applies to newly generated configs.
  • The caches start empty, so the first visit to each backend is what teaches the proxy. Visit each
    backend once and rejoin, and everything is in place from then on.